summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-12-08 20:18:50 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-12-08 20:18:50 (GMT)
commit53f604c79458861553d0ea00db44074b7c4d4333 (patch)
treef8c5f24af759b24aaf235b6227325b1da622dcbb /Lib
parentd9569fa90d9046f9019fe8e89dacc7c4d886e529 (diff)
parentf93ed3fa67260fa0023a1360a37ab7e320550455 (diff)
downloadcpython-53f604c79458861553d0ea00db44074b7c4d4333.zip
cpython-53f604c79458861553d0ea00db44074b7c4d4333.tar.gz
cpython-53f604c79458861553d0ea00db44074b7c4d4333.tar.bz2
Issue #16602: When a weakref's target was part of a long deallocation chain, the object could remain reachable through its weakref even though its refcount had dropped to zero.
Thanks to Eugene Toder for diagnosing and reporting the issue.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_weakref.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index dc6bf77..cdd26c7 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -781,6 +781,27 @@ class ReferencesTestCase(TestBase):
self.assertEqual(hash(a), hash(42))
self.assertRaises(TypeError, hash, b)
+ def test_trashcan_16602(self):
+ # Issue #16602: when a weakref's target was part of a long
+ # deallocation chain, the trashcan mechanism could delay clearing
+ # of the weakref and make the target object visible from outside
+ # code even though its refcount had dropped to 0. A crash ensued.
+ class C:
+ def __init__(self, parent):
+ if not parent:
+ return
+ wself = weakref.ref(self)
+ def cb(wparent):
+ o = wself()
+ self.wparent = weakref.ref(parent, cb)
+
+ d = weakref.WeakKeyDictionary()
+ root = c = C(None)
+ for n in range(100):
+ d[c] = c = C(c)
+ del root
+ gc.collect()
+
class SubclassableWeakrefTestCase(TestBase):