Skip to content

Commit 547d8da

Browse files
authored
gh-142218: Fix split table dictionary crash (gh-142229)
This fixes a regression introduced in gh-140558. The interpreter would crash if we inserted a non `str` key into a split table that matches an existing key.
1 parent 618dc36 commit 547d8da

File tree

3 files changed

+17
-3
lines changed

3 files changed

+17
-3
lines changed

Lib/test/test_dict.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,14 @@ def __eq__(self, other):
16211621

16221622
self.assertEqual(len(d), 1)
16231623

1624+
def test_split_table_update_with_str_subclass(self):
1625+
class MyStr(str): pass
1626+
class MyClass: pass
1627+
obj = MyClass()
1628+
obj.attr = 1
1629+
obj.__dict__[MyStr('attr')] = 2
1630+
self.assertEqual(obj.attr, 2)
1631+
16241632

16251633
class CAPITest(unittest.TestCase):
16261634

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when inserting into a split table dictionary with a non
2+
:class:`str` key that matches an existing key.

Objects/dictobject.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,10 +1914,14 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
19141914
if (old_value != value) {
19151915
_PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
19161916
assert(old_value != NULL);
1917-
assert(!_PyDict_HasSplitTable(mp));
19181917
if (DK_IS_UNICODE(mp->ma_keys)) {
1919-
PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
1920-
STORE_VALUE(ep, value);
1918+
if (_PyDict_HasSplitTable(mp)) {
1919+
STORE_SPLIT_VALUE(mp, ix, value);
1920+
}
1921+
else {
1922+
PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
1923+
STORE_VALUE(ep, value);
1924+
}
19211925
}
19221926
else {
19231927
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];

0 commit comments

Comments
 (0)