summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2020-03-02 23:55:20 (GMT)
committerGitHub <noreply@github.com>2020-03-02 23:55:20 (GMT)
commit9ddcb914f9c2debe7c1359b2450cd1573e86b91c (patch)
tree1967dd5ab55fd5eab0193f042481ec054c655684
parent7ad99821d8ae75222c50e69194a39f535bb058f5 (diff)
downloadcpython-9ddcb914f9c2debe7c1359b2450cd1573e86b91c.zip
cpython-9ddcb914f9c2debe7c1359b2450cd1573e86b91c.tar.gz
cpython-9ddcb914f9c2debe7c1359b2450cd1573e86b91c.tar.bz2
[3.8] bpo-39778: Don't traverse weak-reference lists OrderedDict's tp_traverse and tp_clear (GH-18749) (GH-18756)
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 0c2b509)
-rw-r--r--Lib/test/test_ordered_dict.py20
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2020-03-02-19-21-21.bpo-39778._YGLEc.rst2
-rw-r--r--Objects/odictobject.c2
3 files changed, 22 insertions, 2 deletions
diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py
index 148a9bd..085e5f6 100644
--- a/Lib/test/test_ordered_dict.py
+++ b/Lib/test/test_ordered_dict.py
@@ -753,6 +753,26 @@ class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase):
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):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-03-02-19-21-21.bpo-39778._YGLEc.rst b/Misc/NEWS.d/next/Core and Builtins/2020-03-02-19-21-21.bpo-39778._YGLEc.rst
new file mode 100644
index 0000000..dc49512
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-03-02-19-21-21.bpo-39778._YGLEc.rst
@@ -0,0 +1,2 @@
+Fixed a crash due to incorrect handling of weak references in
+``collections.OrderedDict`` classes. Patch by Pablo Galindo.
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index 4c9ae3b..ac0da9b 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -1453,7 +1453,6 @@ odict_traverse(PyODictObject *od, visitproc visit, void *arg)
_ODictNode *node;
Py_VISIT(od->od_inst_dict);
- Py_VISIT(od->od_weakreflist);
_odict_FOREACH(od, node) {
Py_VISIT(_odictnode_KEY(node));
}
@@ -1466,7 +1465,6 @@ static int
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;