diff options
author | Benjamin Peterson <benjamin@python.org> | 2012-10-31 18:09:11 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2012-10-31 18:09:11 (GMT) |
commit | d97eb0d338f3d5746ba4bbd3cfe6e7c28948d41e (patch) | |
tree | 4704ed3c037ea0e78224c15767d2ac04777491d9 | |
parent | 616f8035a8d7cdbb34f8a6a485d8d9d83767d207 (diff) | |
parent | 275c848736f1c15efc15b84ced315218ac639899 (diff) | |
download | cpython-d97eb0d338f3d5746ba4bbd3cfe6e7c28948d41e.zip cpython-d97eb0d338f3d5746ba4bbd3cfe6e7c28948d41e.tar.gz cpython-d97eb0d338f3d5746ba4bbd3cfe6e7c28948d41e.tar.bz2 |
merge 3.2 (#16345)
-rw-r--r-- | Lib/test/test_dict.py | 8 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/dictobject.c | 59 |
3 files changed, 41 insertions, 29 deletions
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index dd4d552..d1f3192 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -256,6 +256,14 @@ class DictTest(unittest.TestCase): d = dict(zip(range(6), range(6))) self.assertEqual(dict.fromkeys(d, 0), dict(zip(range(6), [0]*6))) + class baddict3(dict): + def __new__(cls): + return d + d = {i : i for i in range(10)} + res = d.copy() + res.update(a=None, b=None, c=None) + self.assertEqual(baddict3.fromkeys({"a", "b", "c"}), res) + def test_copy(self): d = {1:1, 2:2, 3:3} self.assertEqual(d.copy(), {1:1, 2:2, 3:3}) @@ -15,6 +15,9 @@ Core and Builtins - Fix segfaults on setting __qualname__ on builtin types and attempting to delete it on any type. +- Issue #16345: Fix an infinite loop when ``fromkeys`` on a dict subclass + recieved a nonempty dict from the constructor. + - Issue #16271: Fix strange bugs that resulted from __qualname__ appearing in a class's __dict__ and on type. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index aef8d10..02dcf7b 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1707,45 +1707,46 @@ dict_fromkeys(PyObject *cls, PyObject *args) if (d == NULL) return NULL; - if (PyDict_CheckExact(d) && PyDict_CheckExact(seq)) { - PyDictObject *mp = (PyDictObject *)d; - PyObject *oldvalue; - Py_ssize_t pos = 0; - PyObject *key; - Py_hash_t hash; - - if (dictresize(mp, Py_SIZE(seq))) { - Py_DECREF(d); - return NULL; - } - - while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { - if (insertdict(mp, key, hash, value)) { + if (PyDict_CheckExact(d) && PyDict_Size(d) == 0) { + if (PyDict_CheckExact(seq)) { + PyDictObject *mp = (PyDictObject *)d; + PyObject *oldvalue; + Py_ssize_t pos = 0; + PyObject *key; + Py_hash_t hash; + + if (dictresize(mp, Py_SIZE(seq))) { Py_DECREF(d); return NULL; } - } - return d; - } - - if (PyDict_CheckExact(d) && PyAnySet_CheckExact(seq)) { - PyDictObject *mp = (PyDictObject *)d; - Py_ssize_t pos = 0; - PyObject *key; - Py_hash_t hash; - if (dictresize(mp, PySet_GET_SIZE(seq))) { - Py_DECREF(d); - return NULL; + while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { + if (insertdict(mp, key, hash, value)) { + Py_DECREF(d); + return NULL; + } + } + return d; } + if (PyAnySet_CheckExact(seq)) { + PyDictObject *mp = (PyDictObject *)d; + Py_ssize_t pos = 0; + PyObject *key; + Py_hash_t hash; - while (_PySet_NextEntry(seq, &pos, &key, &hash)) { - if (insertdict(mp, key, hash, value)) { + if (dictresize(mp, PySet_GET_SIZE(seq))) { Py_DECREF(d); return NULL; } + + while (_PySet_NextEntry(seq, &pos, &key, &hash)) { + if (insertdict(mp, key, hash, value)) { + Py_DECREF(d); + return NULL; + } + } + return d; } - return d; } it = PyObject_GetIter(seq); |