mirror of https://github.com/python/cpython
Issue #24359: Check for changed OrderedDict size during iteration.
This commit is contained in:
parent
d171975609
commit
b952ab43f2
|
@ -1746,10 +1746,6 @@ class OrderedDictTests:
|
||||||
self.assertEqual(list(reversed(od.items())), list(reversed(pairs)))
|
self.assertEqual(list(reversed(od.items())), list(reversed(pairs)))
|
||||||
|
|
||||||
def test_detect_deletion_during_iteration(self):
|
def test_detect_deletion_during_iteration(self):
|
||||||
# XXX This test should also work under cOrderedDict.
|
|
||||||
if self.module is c_coll:
|
|
||||||
raise unittest.SkipTest("only valid for pure Python OrderedDict")
|
|
||||||
|
|
||||||
OrderedDict = self.module.OrderedDict
|
OrderedDict = self.module.OrderedDict
|
||||||
od = OrderedDict.fromkeys('abc')
|
od = OrderedDict.fromkeys('abc')
|
||||||
it = iter(od)
|
it = iter(od)
|
||||||
|
|
|
@ -19,6 +19,8 @@ Library
|
||||||
|
|
||||||
- Issue #24348: Drop superfluous incref/decref.
|
- Issue #24348: Drop superfluous incref/decref.
|
||||||
|
|
||||||
|
- Issue #24359: Check for changed OrderedDict size during iteration.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 3.5.0 beta 2?
|
What's New in Python 3.5.0 beta 2?
|
||||||
==================================
|
==================================
|
||||||
|
|
|
@ -1796,6 +1796,7 @@ typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
int kind;
|
int kind;
|
||||||
PyODictObject *di_odict;
|
PyODictObject *di_odict;
|
||||||
|
Py_ssize_t di_size;
|
||||||
PyObject *di_current;
|
PyObject *di_current;
|
||||||
PyObject *di_result; /* reusable result tuple for iteritems */
|
PyObject *di_result; /* reusable result tuple for iteritems */
|
||||||
} odictiterobject;
|
} odictiterobject;
|
||||||
|
@ -1835,6 +1836,14 @@ odictiter_nextkey(odictiterobject *di)
|
||||||
if (di->di_current == NULL)
|
if (di->di_current == NULL)
|
||||||
goto done; /* We're already done. */
|
goto done; /* We're already done. */
|
||||||
|
|
||||||
|
/* Check for unsupported changes. */
|
||||||
|
if (di->di_size != PyODict_SIZE(di->di_odict)) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
|
"OrderedDict changed size during iteration");
|
||||||
|
di->di_size = -1; /* Make this state sticky */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the key. */
|
/* Get the key. */
|
||||||
node = _odict_find_node(di->di_odict, di->di_current);
|
node = _odict_find_node(di->di_odict, di->di_current);
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
|
@ -2033,6 +2042,7 @@ odictiter_new(PyODictObject *od, int kind)
|
||||||
node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
|
node = reversed ? _odict_LAST(od) : _odict_FIRST(od);
|
||||||
di->di_current = node ? _odictnode_KEY(node) : NULL;
|
di->di_current = node ? _odictnode_KEY(node) : NULL;
|
||||||
Py_XINCREF(di->di_current);
|
Py_XINCREF(di->di_current);
|
||||||
|
di->di_size = PyODict_SIZE(od);
|
||||||
di->di_odict = od;
|
di->di_odict = od;
|
||||||
Py_INCREF(od);
|
Py_INCREF(od);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue