mirror of
https://github.com/python/cpython.git
synced 2026-01-26 12:55:08 +00:00
gh-143189: fix insertdict() for non-Unicode key (#143285)
This commit is contained in:
parent
bd83a57463
commit
43c76587c1
@ -1602,6 +1602,7 @@ class DictTest(unittest.TestCase):
|
||||
d.get(key2)
|
||||
|
||||
def test_clear_at_lookup(self):
|
||||
# gh-140551 dict crash if clear is called at lookup stage
|
||||
class X:
|
||||
def __hash__(self):
|
||||
return 1
|
||||
@ -1622,6 +1623,8 @@ class DictTest(unittest.TestCase):
|
||||
self.assertEqual(len(d), 1)
|
||||
|
||||
def test_split_table_update_with_str_subclass(self):
|
||||
# gh-142218: inserting into a split table dictionary with a non str
|
||||
# key that matches an existing key.
|
||||
class MyStr(str): pass
|
||||
class MyClass: pass
|
||||
obj = MyClass()
|
||||
@ -1629,6 +1632,22 @@ class DictTest(unittest.TestCase):
|
||||
obj.__dict__[MyStr('attr')] = 2
|
||||
self.assertEqual(obj.attr, 2)
|
||||
|
||||
def test_split_table_insert_with_str_subclass(self):
|
||||
# gh-143189: inserting into split table dictionary with a non str
|
||||
# key that matches an existing key in the shared table but not in
|
||||
# the dict yet.
|
||||
|
||||
class MyStr(str): pass
|
||||
class MyClass: pass
|
||||
|
||||
obj = MyClass()
|
||||
obj.attr1 = 1
|
||||
|
||||
obj2 = MyClass()
|
||||
d = obj2.__dict__
|
||||
d[MyStr("attr1")] = 2
|
||||
self.assertIsInstance(list(d)[0], MyStr)
|
||||
|
||||
|
||||
class CAPITest(unittest.TestCase):
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
Fix crash when inserting a non-:class:`str` key into a split table
|
||||
dictionary when the key matches an existing key in the split table
|
||||
but has no corresponding value in the dict.
|
||||
@ -1877,7 +1877,7 @@ static int
|
||||
insertdict(PyDictObject *mp,
|
||||
PyObject *key, Py_hash_t hash, PyObject *value)
|
||||
{
|
||||
PyObject *old_value;
|
||||
PyObject *old_value = NULL;
|
||||
Py_ssize_t ix;
|
||||
|
||||
ASSERT_DICT_LOCKED(mp);
|
||||
@ -1898,11 +1898,14 @@ insertdict(PyDictObject *mp,
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if (ix == DKIX_EMPTY) {
|
||||
if (old_value == NULL) {
|
||||
// insert_combined_dict() will convert from non DICT_KEYS_GENERAL table
|
||||
// into DICT_KEYS_GENERAL table if key is not Unicode.
|
||||
// We don't convert it before _Py_dict_lookup because non-Unicode key
|
||||
// may change generic table into Unicode table.
|
||||
//
|
||||
// NOTE: ix may not be DKIX_EMPTY because split table may have key
|
||||
// without value.
|
||||
if (insert_combined_dict(mp, hash, key, value) < 0) {
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user