Objects do not own weak references to them directly through the __weakref__ list so these
do not need to be traversed by the GC.
(cherry picked from commit
0c2b509f9d1d3a9065bc62c2407e1dc2ed70e9c2)
Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
self.assertEqual(list(unpickled), expected)
self.assertEqual(list(it), expected)
+ @support.cpython_only
+ def test_weakref_list_is_not_traversed(self):
+ # Check that the weakref list is not traversed when collecting
+ # OrderedDict objects. See bpo-39778 for more information.
+
+ gc.collect()
+
+ x = self.OrderedDict()
+ x.cycle = x
+
+ cycle = []
+ cycle.append(cycle)
+
+ x_ref = weakref.ref(x)
+ cycle.append(x_ref)
+
+ del x, cycle, x_ref
+
+ gc.collect()
+
class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests):
--- /dev/null
+Fixed a crash due to incorrect handling of weak references in
+``collections.OrderedDict`` classes. Patch by Pablo Galindo.
_ODictNode *node;
Py_VISIT(od->od_inst_dict);
- Py_VISIT(od->od_weakreflist);
_odict_FOREACH(od, node) {
Py_VISIT(_odictnode_KEY(node));
}
odict_tp_clear(PyODictObject *od)
{
Py_CLEAR(od->od_inst_dict);
- Py_CLEAR(od->od_weakreflist);
PyDict_Clear((PyObject *)od);
_odict_clear_nodes(od);
return 0;