Skip to content

Commit f7aa13d

Browse files
Bug fix
1 parent 44b6eea commit f7aa13d

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

Lib/test/test_dict.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,21 @@ def __hash__(self):
16011601
with self.assertRaises(KeyError):
16021602
d.get(key2)
16031603

1604+
def test_clear_at_lookup(self):
1605+
d = {}
1606+
1607+
class X(object):
1608+
def __hash__(self):
1609+
return 1
1610+
def __eq__(self, other):
1611+
nonlocal d
1612+
d.clear()
1613+
1614+
for _ in range(10):
1615+
d[X()] = None
1616+
1617+
self.assertEqual(len(d), 1)
1618+
16041619

16051620
class CAPITest(unittest.TestCase):
16061621

Objects/dictobject.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,14 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
18991899
if (ix == DKIX_ERROR)
19001900
goto Fail;
19011901

1902+
// gh-140551: If dict was cleaned in _Py_dict_lookup,
1903+
// we have to resize one more time to force general key kind.
1904+
if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) {
1905+
if (insertion_resize(mp, 0) < 0)
1906+
goto Fail;
1907+
assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL);
1908+
}
1909+
19021910
if (ix == DKIX_EMPTY) {
19031911
assert(!_PyDict_HasSplitTable(mp));
19041912
/* Insert into new slot. */

0 commit comments

Comments
 (0)