bpo-36473: add maximum iteration check for dict .values() and .items() (GH-12619)
This commit is contained in:
parent
04694a306b
commit
b8311cf5e5
|
@ -477,7 +477,25 @@ class DictTest(unittest.TestCase):
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
for i in d:
|
for i in d:
|
||||||
del d[0]
|
del d[0]
|
||||||
d[1] = 1
|
d[0] = 0
|
||||||
|
|
||||||
|
def test_mutating_iteration_delete_over_values(self):
|
||||||
|
# change dict content during iteration
|
||||||
|
d = {}
|
||||||
|
d[0] = 0
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
for i in d.values():
|
||||||
|
del d[0]
|
||||||
|
d[0] = 0
|
||||||
|
|
||||||
|
def test_mutating_iteration_delete_over_items(self):
|
||||||
|
# change dict content during iteration
|
||||||
|
d = {}
|
||||||
|
d[0] = 0
|
||||||
|
with self.assertRaises(RuntimeError):
|
||||||
|
for i in d.items():
|
||||||
|
del d[0]
|
||||||
|
d[0] = 0
|
||||||
|
|
||||||
def test_mutating_lookup(self):
|
def test_mutating_lookup(self):
|
||||||
# changing dict during a lookup (issue #14417)
|
# changing dict during a lookup (issue #14417)
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
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.
|
Changing ``dict`` keys during iteration of the dict itself, ``keys()``,
|
||||||
|
``values()``, or ``items()`` will now be detected in certain corner cases where
|
||||||
|
keys are deleted/added so that the number of keys isn't changed.
|
||||||
|
A `RuntimeError` will be raised after ``len(dict)`` iterations.
|
||||||
|
Contributed by Thomas Perl.
|
||||||
|
|
|
@ -3630,6 +3630,12 @@ dictiter_iternextvalue(dictiterobject *di)
|
||||||
goto fail;
|
goto fail;
|
||||||
value = entry_ptr->me_value;
|
value = entry_ptr->me_value;
|
||||||
}
|
}
|
||||||
|
// We found an element, 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->di_pos = i+1;
|
||||||
di->len--;
|
di->len--;
|
||||||
Py_INCREF(value);
|
Py_INCREF(value);
|
||||||
|
@ -3713,6 +3719,12 @@ dictiter_iternextitem(dictiterobject *di)
|
||||||
key = entry_ptr->me_key;
|
key = entry_ptr->me_key;
|
||||||
value = entry_ptr->me_value;
|
value = entry_ptr->me_value;
|
||||||
}
|
}
|
||||||
|
// We found an element, 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->di_pos = i+1;
|
||||||
di->len--;
|
di->len--;
|
||||||
Py_INCREF(key);
|
Py_INCREF(key);
|
||||||
|
|
Loading…
Reference in New Issue