[Python-checkins] bpo-36452: dictiter: track maximum iteration count (GH-12596)
Inada Naoki
webhook-mailer at python.org
Thu Mar 28 02:03:28 EDT 2019
https://github.com/python/cpython/commit/796cc6e3ad3617c1ea9e528663aac1a206230a28
commit: 796cc6e3ad3617c1ea9e528663aac1a206230a28
branch: master
author: Thomas Perl <m at thp.io>
committer: Inada Naoki <songofacandy at gmail.com>
date: 2019-03-28T15:03:25+09:00
summary:
bpo-36452: dictiter: track maximum iteration count (GH-12596)
files:
A Misc/NEWS.d/next/Core and Builtins/2019-03-27-23-53-00.bpo-36452.xhK2lT.rst
M Lib/test/test_dict.py
M Objects/dictobject.c
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index 03afd5b2a6c7..eecdc8beec69 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -470,6 +470,15 @@ def test_mutating_iteration(self):
for i in d:
d[i+1] = 1
+ def test_mutating_iteration_delete(self):
+ # change dict content during iteration
+ d = {}
+ d[0] = 0
+ with self.assertRaises(RuntimeError):
+ for i in d:
+ del d[0]
+ d[1] = 1
+
def test_mutating_lookup(self):
# changing dict during a lookup (issue #14417)
class NastyKey:
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-03-27-23-53-00.bpo-36452.xhK2lT.rst b/Misc/NEWS.d/next/Core and Builtins/2019-03-27-23-53-00.bpo-36452.xhK2lT.rst
new file mode 100644
index 000000000000..37c0c503edec
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-03-27-23-53-00.bpo-36452.xhK2lT.rst
@@ -0,0 +1 @@
+Changing `dict` keys during iteration will now be detected in certain corner cases where the number of keys isn't changed (but they keys themselves are), and a `RuntimeError` will be raised.
\ No newline at end of file
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index e2603e190b62..7ea979cd1761 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -3543,6 +3543,12 @@ dictiter_iternextkey(dictiterobject *di)
goto fail;
key = entry_ptr->me_key;
}
+ // We found an element (key), but did not expect it
+ if (di->len == 0) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "dictionary keys changed during iteration");
+ goto fail;
+ }
di->di_pos = i+1;
di->len--;
Py_INCREF(key);
More information about the Python-checkins
mailing list