https://github.com/python/cpython/commit/f0a88e2ce54bee23bdcdcd0c045425ffaea605e8 commit: f0a88e2ce54bee23bdcdcd0c045425ffaea605e8 branch: 3.13 author: Inada Naoki <songofaca...@gmail.com> committer: methane <songofaca...@gmail.com> date: 2025-05-11T15:14:11+09:00 summary:
gh-133703: dict: fix calculate_log2_keysize() (GH-133809) (cherry picked from commit 92337f666e8a076a68305a8d6dc8bc9c095000e9) files: A Misc/NEWS.d/next/Core and Builtins/2025-05-10-17-12-27.gh-issue-133703.bVM-re.rst M Lib/test/test_dict.py M Objects/dictobject.c diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 587099a6f60663..40b0c210ab34b0 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -1120,10 +1120,8 @@ class C: a = C() a.x = 1 d = a.__dict__ - before_resize = sys.getsizeof(d) d[2] = 2 # split table is resized to a generic combined table - self.assertGreater(sys.getsizeof(d), before_resize) self.assertEqual(list(d), ['x', 2]) def test_iterator_pickling(self): diff --git a/Misc/NEWS.d/next/Core and Builtins/2025-05-10-17-12-27.gh-issue-133703.bVM-re.rst b/Misc/NEWS.d/next/Core and Builtins/2025-05-10-17-12-27.gh-issue-133703.bVM-re.rst new file mode 100644 index 00000000000000..05bf6103314a74 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2025-05-10-17-12-27.gh-issue-133703.bVM-re.rst @@ -0,0 +1 @@ +Fix hashtable in dict can be bigger than intended in some situations. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 355986248bac2c..e89ed467bf7c27 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -580,13 +580,13 @@ static inline uint8_t calculate_log2_keysize(Py_ssize_t minsize) { #if SIZEOF_LONG == SIZEOF_SIZE_T - minsize = (minsize | PyDict_MINSIZE) - 1; - return _Py_bit_length(minsize | (PyDict_MINSIZE-1)); + minsize = Py_MAX(minsize, PyDict_MINSIZE); + return _Py_bit_length(minsize - 1); #elif defined(_MSC_VER) - // On 64bit Windows, sizeof(long) == 4. - minsize = (minsize | PyDict_MINSIZE) - 1; + // On 64bit Windows, sizeof(long) == 4. We cannot use _Py_bit_length. + minsize = Py_MAX(minsize, PyDict_MINSIZE); unsigned long msb; - _BitScanReverse64(&msb, (uint64_t)minsize); + _BitScanReverse64(&msb, (uint64_t)minsize - 1); return (uint8_t)(msb + 1); #else uint8_t log2_size; _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com