changeset: 96473:141eb4d1b766 branch: 3.5 parent: 96471:8631b88c23f6 user: Eric Snow date: Mon Jun 01 23:35:13 2015 -0600 files: Lib/test/test_collections.py Misc/NEWS Objects/odictobject.c description: Issue #24359: Check for changed OrderedDict size during iteration. diff -r 8631b88c23f6 -r 141eb4d1b766 Lib/test/test_collections.py --- a/Lib/test/test_collections.py Mon Jun 01 23:12:13 2015 -0600 +++ b/Lib/test/test_collections.py Mon Jun 01 23:35:13 2015 -0600 @@ -1746,10 +1746,6 @@ self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) 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 od = OrderedDict.fromkeys('abc') it = iter(od) diff -r 8631b88c23f6 -r 141eb4d1b766 Misc/NEWS --- a/Misc/NEWS Mon Jun 01 23:12:13 2015 -0600 +++ b/Misc/NEWS Mon Jun 01 23:35:13 2015 -0600 @@ -19,6 +19,8 @@ - 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? ================================== diff -r 8631b88c23f6 -r 141eb4d1b766 Objects/odictobject.c --- a/Objects/odictobject.c Mon Jun 01 23:12:13 2015 -0600 +++ b/Objects/odictobject.c Mon Jun 01 23:35:13 2015 -0600 @@ -1796,6 +1796,7 @@ PyObject_HEAD int kind; PyODictObject *di_odict; + Py_ssize_t di_size; PyObject *di_current; PyObject *di_result; /* reusable result tuple for iteritems */ } odictiterobject; @@ -1835,6 +1836,14 @@ if (di->di_current == NULL) 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. */ node = _odict_find_node(di->di_odict, di->di_current); if (node == NULL) { @@ -2033,6 +2042,7 @@ node = reversed ? _odict_LAST(od) : _odict_FIRST(od); di->di_current = node ? _odictnode_KEY(node) : NULL; Py_XINCREF(di->di_current); + di->di_size = PyODict_SIZE(od); di->di_odict = od; Py_INCREF(od);