mirror of
https://github.com/python/cpython.git
synced 2025-09-27 10:50:04 +00:00
Merge with ongoing work in 3.5 branch.
This commit is contained in:
commit
ab30353adb
6 changed files with 50 additions and 14 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
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,9 @@ Dict display element unpacking
|
||||||
... for i in range(1000)) + "}"))
|
... for i in range(1000)) + "}"))
|
||||||
1000
|
1000
|
||||||
|
|
||||||
|
>>> {0:1, **{0:2}, 0:3, 0:4}
|
||||||
|
{0: 4}
|
||||||
|
|
||||||
List comprehension element unpacking
|
List comprehension element unpacking
|
||||||
|
|
||||||
>>> a, b, c = [0, 1, 2], 3, 4
|
>>> a, b, c = [0, 1, 2], 3, 4
|
||||||
|
|
|
@ -10,6 +10,10 @@ Release date: 2015-07-26
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #24569: Make PEP 448 dictionary evaluation more consistent.
|
||||||
|
|
||||||
|
- 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2561,22 +2561,25 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(BUILD_MAP) {
|
TARGET(BUILD_MAP) {
|
||||||
|
int i;
|
||||||
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
|
PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg);
|
||||||
if (map == NULL)
|
if (map == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
while (--oparg >= 0) {
|
for (i = oparg; i > 0; i--) {
|
||||||
int err;
|
int err;
|
||||||
PyObject *value = TOP();
|
PyObject *key = PEEK(2*i);
|
||||||
PyObject *key = SECOND();
|
PyObject *value = PEEK(2*i - 1);
|
||||||
STACKADJ(-2);
|
|
||||||
err = PyDict_SetItem(map, key, value);
|
err = PyDict_SetItem(map, key, value);
|
||||||
Py_DECREF(value);
|
|
||||||
Py_DECREF(key);
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
Py_DECREF(map);
|
Py_DECREF(map);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (oparg--) {
|
||||||
|
Py_DECREF(POP());
|
||||||
|
Py_DECREF(POP());
|
||||||
|
}
|
||||||
PUSH(map);
|
PUSH(map);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild">
|
<Target Name="_TransformWxlTemplates" AfterTargets="PrepareForBuild" Inputs="@(WxlTemplate);$(PySourcePath)include\patchlevel.h" Outputs="$(IntermediateOutputPath)%(Filename).wxl">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)`).Replace(`{{LongVersion}}`, `$(PythonVersion)`).Replace(`{{Bitness}}`, `$(Bitness)`))</_Content>
|
<_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>
|
<_ExistingContent Condition="Exists('$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl')">$([System.IO.File]::ReadAllText($(IntermediateOutputPath)%(WxlTemplate.Filename).wxl))</_ExistingContent>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue