Merge with ongoing work in 3.5 branch.
This commit is contained in:
commit
ab30353adb
|
@ -937,6 +937,20 @@ class DictTest(unittest.TestCase):
|
|||
d.popitem()
|
||||
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
|
||||
|
||||
|
|
|
@ -128,6 +128,9 @@ Dict display element unpacking
|
|||
... for i in range(1000)) + "}"))
|
||||
1000
|
||||
|
||||
>>> {0:1, **{0:2}, 0:3, 0:4}
|
||||
{0: 4}
|
||||
|
||||
List comprehension element unpacking
|
||||
|
||||
>>> a, b, c = [0, 1, 2], 3, 4
|
||||
|
|
|
@ -10,6 +10,10 @@ Release date: 2015-07-26
|
|||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #24569: Make PEP 448 dictionary evaluation more consistent.
|
||||
|
||||
- Issue #24407: Fix crash when dict is mutated while being updated.
|
||||
|
||||
Library
|
||||
-------
|
||||
|
||||
|
|
|
@ -2039,20 +2039,32 @@ PyDict_Merge(PyObject *a, PyObject *b, int override)
|
|||
if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0)
|
||||
return -1;
|
||||
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];
|
||||
key = entry->me_key;
|
||||
hash = entry->me_hash;
|
||||
if (other->ma_values)
|
||||
value = other->ma_values[i];
|
||||
else
|
||||
value = entry->me_value;
|
||||
|
||||
if (value != NULL &&
|
||||
(override ||
|
||||
PyDict_GetItem(a, entry->me_key) == NULL)) {
|
||||
if (insertdict(mp, entry->me_key,
|
||||
entry->me_hash,
|
||||
value) != 0)
|
||||
if (value != NULL) {
|
||||
int err = 0;
|
||||
Py_INCREF(key);
|
||||
Py_INCREF(value);
|
||||
if (override || PyDict_GetItem(a, key) == NULL)
|
||||
err = insertdict(mp, key, hash, value);
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(key);
|
||||
if (err != 0)
|
||||
return -1;
|
||||
|
||||
if (n != DK_SIZE(other->ma_keys)) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"dict mutated during update");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2561,22 +2561,25 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
}
|
||||
|
||||
TARGET(BUILD_MAP) {
|
||||
int i;
|
||||
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
|
||||
if (map == NULL)
|
||||
goto error;
|
||||
while (--oparg >= 0) {
|
||||
for (i = oparg; i > 0; i--) {
|
||||
int err;
|
||||
PyObject *value = TOP();
|
||||
PyObject *key = SECOND();
|
||||
STACKADJ(-2);
|
||||
PyObject *key = PEEK(2*i);
|
||||
PyObject *value = PEEK(2*i - 1);
|
||||
err = PyDict_SetItem(map, key, value);
|
||||
Py_DECREF(value);
|
||||
Py_DECREF(key);
|
||||
if (err != 0) {
|
||||
Py_DECREF(map);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
while (oparg--) {
|
||||
Py_DECREF(POP());
|
||||
Py_DECREF(POP());
|
||||
}
|
||||
PUSH(map);
|
||||
DISPATCH();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild">
|
||||
<Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild" Inputs="@(WxlTemplate);$(PySourcePath)include\patchlevel.h" Outputs="$(IntermediateOutputPath)%(Filename).wxl">
|
||||
<PropertyGroup>
|
||||
<_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)`).Replace(`{{LongVersion}}`, `$(PythonVersion)`).Replace(`{{Bitness}}`, `$(Bitness)`))</_Content>
|
||||
<_ExistingContent Condition="Exists('$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl')">$([System.IO.File]::ReadAllText($(IntermediateOutputPath)%(WxlTemplate.Filename).wxl))</_ExistingContent>
|
||||
|
|
Loading…
Reference in New Issue