diff -r 741ef17e9b86 Lib/test/test_collections.py --- a/Lib/test/test_collections.py Sun Oct 18 09:54:42 2015 +0300 +++ b/Lib/test/test_collections.py Sun Oct 18 13:28:41 2015 +0300 @@ -2033,6 +2033,14 @@ class OrderedDictTests: items = [('a', 1), ('c', 3), ('b', 2)] self.assertEqual(list(MyOD(items).items()), items) + def test_highly_nested(self): + # Issue 25395: crashes during garbage collection + obj = None + for _ in range(1000): + obj = self.module.OrderedDict([(None, obj)]) + del obj + support.gc_collect() + class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): diff -r 741ef17e9b86 Misc/NEWS --- a/Misc/NEWS Sun Oct 18 09:54:42 2015 +0300 +++ b/Misc/NEWS Sun Oct 18 13:28:41 2015 +0300 @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- Issue #25395: Fix crash when highly nested OrderedDict structures were + garbage collected. + - Issue #25401: Optimize bytes.fromhex() and bytearray.fromhex(): they are now between 2x and 3.5x faster. diff -r 741ef17e9b86 Objects/odictobject.c --- a/Objects/odictobject.c Sun Oct 18 09:54:42 2015 +0300 +++ b/Objects/odictobject.c Sun Oct 18 13:28:41 2015 +0300 @@ -1438,16 +1438,19 @@ static void odict_dealloc(PyODictObject *self) { PyObject_GC_UnTrack(self); - Py_TRASHCAN_SAFE_BEGIN(self); + Py_TRASHCAN_SAFE_BEGIN(self) + Py_XDECREF(self->od_inst_dict); if (self->od_weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); _odict_clear_nodes(self); - Py_TRASHCAN_SAFE_END(self); /* must be last */ + Py_TYPE(self) = &PyDict_Type; PyDict_Type.tp_dealloc((PyObject *)self); + + Py_TRASHCAN_SAFE_END(self) }; /* tp_repr */