Issue #3680: Reference cycles created through a dict, set or deque iterator did not get collected.
diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py
index 0f0d098..4e2de3d 100644
--- a/Lib/test/test_deque.py
+++ b/Lib/test/test_deque.py
@@ -1,7 +1,8 @@
from collections import deque
import unittest
from test import test_support, seq_tests
-from weakref import proxy
+import gc
+import weakref
import copy
import cPickle as pickle
import random
@@ -418,6 +419,22 @@
d.append(1)
gc.collect()
+ def test_container_iterator(self):
+ # Bug # XXX: tp_traverse was not implemented for deque iterator objects
+ class C(object):
+ pass
+ for i in range(2):
+ obj = C()
+ ref = weakref.ref(obj)
+ if i == 0:
+ container = deque([obj, 1])
+ else:
+ container = reversed(deque([obj, 1]))
+ obj.x = iter(container)
+ del obj, container
+ gc.collect()
+ self.assert_(ref() is None, "Cycle was not collected")
+
class TestVariousIteratorArgs(unittest.TestCase):
def test_constructor(self):
@@ -528,7 +545,7 @@
def test_weakref(self):
d = deque('gallahad')
- p = proxy(d)
+ p = weakref.proxy(d)
self.assertEqual(str(p), str(d))
d = None
self.assertRaises(ReferenceError, str, p)
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index f715657..14d62f5 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -2,6 +2,7 @@
from test import test_support
import UserDict, random, string
+import gc, weakref
class DictTest(unittest.TestCase):
@@ -554,6 +555,19 @@
pass
d = {}
+ def test_container_iterator(self):
+ # Bug # XXX: tp_traverse was not implemented for dictiter objects
+ class C(object):
+ pass
+ iterators = (dict.iteritems, dict.itervalues, dict.iterkeys)
+ for i in iterators:
+ obj = C()
+ ref = weakref.ref(obj)
+ container = {obj: 1}
+ obj.x = i(container)
+ del obj, container
+ gc.collect()
+ self.assert_(ref() is None, "Cycle was not collected")
from test import mapping_tests
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index d38a675..8d05712 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -1,6 +1,7 @@
import unittest
from test import test_support
-from weakref import proxy
+import gc
+import weakref
import operator
import copy
import pickle
@@ -322,6 +323,18 @@
self.assertEqual(sum(elem.hash_count for elem in d), n)
self.assertEqual(d3, dict.fromkeys(d, 123))
+ def test_container_iterator(self):
+ # Bug # XXX: tp_traverse was not implemented for set iterator object
+ class C(object):
+ pass
+ obj = C()
+ ref = weakref.ref(obj)
+ container = set([obj, 1])
+ obj.x = iter(container)
+ del obj, container
+ gc.collect()
+ self.assert_(ref() is None, "Cycle was not collected")
+
class TestSet(TestJointOps):
thetype = set
@@ -538,7 +551,7 @@
def test_weakref(self):
s = self.thetype('gallahad')
- p = proxy(s)
+ p = weakref.proxy(s)
self.assertEqual(str(p), str(s))
s = None
self.assertRaises(ReferenceError, str, p)