mirror of
https://github.com/python/cpython.git
synced 2025-07-31 23:23:11 +00:00
merge 3.5 (#24407)
This commit is contained in:
commit
d34c246baf
3 changed files with 35 additions and 7 deletions
|
@ -937,6 +937,20 @@ class DictTest(unittest.TestCase):
|
||||||
d.popitem()
|
d.popitem()
|
||||||
self.check_reentrant_insertion(mutate)
|
self.check_reentrant_insertion(mutate)
|
||||||
|
|
||||||
|
def test_merge_and_mutate(self):
|
||||||
|
class X:
|
||||||
|
def __hash__(self):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def __eq__(self, o):
|
||||||
|
other.clear()
|
||||||
|
return False
|
||||||
|
|
||||||
|
l = [(i,0) for i in range(1, 1337)]
|
||||||
|
other = dict(l)
|
||||||
|
other[X()] = 0
|
||||||
|
d = {X(): 0, 1: 1}
|
||||||
|
self.assertRaises(RuntimeError, d.update, other)
|
||||||
|
|
||||||
from test import mapping_tests
|
from test import mapping_tests
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,8 @@ Core and Builtins
|
||||||
|
|
||||||
- Issue #19235: Add new RecursionError exception. Patch by Georg Brandl.
|
- Issue #19235: Add new RecursionError exception. Patch by Georg Brandl.
|
||||||
|
|
||||||
|
- Issue #24407: Fix crash when dict is mutated while being updated.
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -2039,20 +2039,32 @@ PyDict_Merge(PyObject *a, PyObject *b, int override)
|
||||||
if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0)
|
if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
for (i = 0, n = DK_SIZE(other->ma_keys); i < n; i++) {
|
for (i = 0, n = DK_SIZE(other->ma_keys); i < n; i++) {
|
||||||
PyObject *value;
|
PyObject *key, *value;
|
||||||
|
Py_hash_t hash;
|
||||||
entry = &other->ma_keys->dk_entries[i];
|
entry = &other->ma_keys->dk_entries[i];
|
||||||
|
key = entry->me_key;
|
||||||
|
hash = entry->me_hash;
|
||||||
if (other->ma_values)
|
if (other->ma_values)
|
||||||
value = other->ma_values[i];
|
value = other->ma_values[i];
|
||||||
else
|
else
|
||||||
value = entry->me_value;
|
value = entry->me_value;
|
||||||
|
|
||||||
if (value != NULL &&
|
if (value != NULL) {
|
||||||
(override ||
|
int err = 0;
|
||||||
PyDict_GetItem(a, entry->me_key) == NULL)) {
|
Py_INCREF(key);
|
||||||
if (insertdict(mp, entry->me_key,
|
Py_INCREF(value);
|
||||||
entry->me_hash,
|
if (override || PyDict_GetItem(a, key) == NULL)
|
||||||
value) != 0)
|
err = insertdict(mp, key, hash, value);
|
||||||
|
Py_DECREF(value);
|
||||||
|
Py_DECREF(key);
|
||||||
|
if (err != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (n != DK_SIZE(other->ma_keys)) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"dict mutated during update");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue