summaryrefslogtreecommitdiff
path: root/Lib/test
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-12-08 21:15:26 +0100
committerAntoine Pitrou <solipsis@pitrou.net>2012-12-08 21:15:26 +0100
commit62a0d6ea402d18f528629c6e84ed6f46e7c0912a (patch)
tree72f36fc075688276626f59fb7138baf52d4077ed /Lib/test
parent09974b4e9e8da3c9ba0469f4812e68cf9f700ffd (diff)
downloadcpython-git-62a0d6ea402d18f528629c6e84ed6f46e7c0912a.tar.gz
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/test')
-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 92a47133cb..571e33f492 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -776,6 +776,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):