Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Lib/test/libregrtest/single.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def regrtest_runner(result: TestResult, test_func, runtests: RunTests) -> None:


# Storage of uncollectable GC objects (gc.garbage)
GC_GARBAGE = []
GC_GARBAGE: list[object] = []


def _load_run_test(result: TestResult, runtests: RunTests) -> None:
Expand Down
5 changes: 5 additions & 0 deletions Lib/test/test_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -1868,6 +1868,11 @@ def test_merge(self):
self.assertEqual(fd | {}, fd)
self.assertEqual(frozendict() | fd, fd)

# gh-149676: Test hash(frozendict | frozendict)
a = frozendict({"a": 1})
b = frozendict({"b": 2})
self.assertEqual(hash(a | b), hash(frozendict({"a": 1, "b": 2})))

def test_update(self):
# test "a |= b" operator
d = frozendict(x=1)
Expand Down
2 changes: 0 additions & 2 deletions Lib/tomllib/mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,4 @@ pretty = True
# Enable most stricter settings
enable_error_code = ignore-without-code
strict = True
strict_bytes = True
local_partial_types = True
warn_unreachable = True
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix ``frozendict | frozendict`` hash.
9 changes: 6 additions & 3 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ free_values(PyDictValues *values, bool use_qsbr)
static inline PyObject *
new_dict_impl(PyDictObject *mp, PyDictKeysObject *keys,
PyDictValues *values, Py_ssize_t used,
int free_values_on_failure)
int free_values_on_failure, int frozendict)
{
assert(keys != NULL);
if (mp == NULL) {
Expand All @@ -915,6 +915,9 @@ new_dict_impl(PyDictObject *mp, PyDictKeysObject *keys,
mp->ma_values = values;
mp->ma_used = used;
mp->_ma_watcher_tag = 0;
if (frozendict) {
((PyFrozenDictObject *)mp)->ma_hash = -1;
}
ASSERT_CONSISTENT(mp);
_PyObject_GC_TRACK(mp);
return (PyObject *)mp;
Expand All @@ -931,7 +934,7 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values,
}
assert(mp == NULL || Py_IS_TYPE(mp, &PyDict_Type));

return new_dict_impl(mp, keys, values, used, free_values_on_failure);
return new_dict_impl(mp, keys, values, used, free_values_on_failure, 0);
}

/* Consumes a reference to the keys object */
Expand All @@ -940,7 +943,7 @@ new_frozendict(PyDictKeysObject *keys, PyDictValues *values,
Py_ssize_t used, int free_values_on_failure)
{
PyDictObject *mp = PyObject_GC_New(PyDictObject, &PyFrozenDict_Type);
return new_dict_impl(mp, keys, values, used, free_values_on_failure);
return new_dict_impl(mp, keys, values, used, free_values_on_failure, 1);
}

static PyObject *
Expand Down
2 changes: 1 addition & 1 deletion Tools/build/check_extension_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def get_location(self, modinfo: ModuleInfo) -> pathlib.Path | None:
def _check_file(self, modinfo: ModuleInfo, spec: ModuleSpec) -> None:
"""Check that the module file is present and not empty"""
if spec.loader is BuiltinImporter: # type: ignore[comparison-overlap]
return
return # type: ignore[unreachable]
try:
assert spec.origin is not None
st = os.stat(spec.origin)
Expand Down
2 changes: 0 additions & 2 deletions Tools/build/mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ python_version = 3.10

# ...And be strict:
strict = True
strict_bytes = True
local_partial_types = True
extra_checks = True
enable_error_code = ignore-without-code,redundant-expr,truthy-bool,possibly-undefined
warn_unreachable = True
6 changes: 3 additions & 3 deletions Tools/requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Requirements file for external linters and checks we run on
# Tools/clinic, Tools/cases_generator/, and Tools/peg_generator/ in CI
mypy==1.19.1
mypy==2.1.0

# needed for peg_generator:
types-psutil==7.2.2.20260130
types-setuptools==82.0.0.20260210
types-psutil==7.2.2.20260508
types-setuptools==82.0.0.20260508
Loading