bpo-36452: dictiter: track maximum iteration count (GH-12596)
This commit is contained in:
parent
738cb42a14
commit
796cc6e3ad
|
@ -470,6 +470,15 @@ class DictTest(unittest.TestCase):
|
|||
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:
|
||||
|
|
|
@ -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.
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue