[3.14] gh-142218: Fix split table dictionary crash (gh-142229) (gh-142244)

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.
(cherry picked from commit 547d8daf78)

Co-authored-by: Sam Gross <colesbury@gmail.com>
This commit is contained in:
Miss Islington (bot) 2025-12-04 01:03:18 +01:00 committed by GitHub
parent 027f21e417
commit 319c6a2ae1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 3 deletions

View file

@ -1621,6 +1621,14 @@ def __eq__(self, other):
self.assertEqual(len(d), 1)
def test_split_table_update_with_str_subclass(self):
class MyStr(str): pass
class MyClass: pass
obj = MyClass()
obj.attr = 1
obj.__dict__[MyStr('attr')] = 2
self.assertEqual(obj.attr, 2)
class CAPITest(unittest.TestCase):

View file

@ -0,0 +1,2 @@
Fix crash when inserting into a split table dictionary with a non
:class:`str` key that matches an existing key.

View file

@ -1863,11 +1863,15 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
if (old_value != value) {
_PyDict_NotifyEvent(interp, PyDict_EVENT_MODIFIED, mp, key, value);
assert(old_value != NULL);
assert(!_PyDict_HasSplitTable(mp));
if (DK_IS_UNICODE(mp->ma_keys)) {
if (_PyDict_HasSplitTable(mp)) {
STORE_SPLIT_VALUE(mp, ix, value);
}
else {
PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
STORE_VALUE(ep, value);
}
}
else {
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
STORE_VALUE(ep, value);