]> granicus.if.org Git - python/commitdiff
Add missing PyObject_GC_Track call, causing *some* itertools.tee objects to
authorThomas Wouters <thomas@python.org>
Sat, 15 Apr 2006 22:33:13 +0000 (22:33 +0000)
committerThomas Wouters <thomas@python.org>
Sat, 15 Apr 2006 22:33:13 +0000 (22:33 +0000)
not be tracked by GC. This fixes 254 of test_generators' refleaks on my
machine, but I'm sure something else will make them come back :>

Not adding a separate test for this kind of cycle, since the existing
fib/m235 already test them in more extensive ways than any 'minimal' test
has been able to manage.

Lib/test/test_generators.py
Modules/itertoolsmodule.c

index 4b2ed8fff41a0f2d000553b881a8443374053b2b..9f8334346b0d59216211febab3b58758216c6e3a 100644 (file)
@@ -668,10 +668,7 @@ concept, viz. produce the results only as needed instead of producing them
 all and thereby wasting memory.
 
 Thanks to itertools.tee, it is now clear "how to get the internal uses of
-m235 to share a single generator". Unfortunately, using generators this way
-creates a reference-cycle that the garbage collector (currently) can't clean
-up, so we have to explicitly break the cycle (by calling the inner
-generator's close() method)
+m235 to share a single generator".
 
 >>> from itertools import tee
 >>> def m235():
@@ -683,9 +680,9 @@ generator's close() method)
 ...             yield n
 ...     m1 = _m235()
 ...     m2, m3, m5, mRes = tee(m1, 4)
-...     return m1.close, mRes
+...     return mRes
 
->>> closer, it = m235()
+>>> it = m235()
 >>> for i in range(5):
 ...     print firstn(it, 15)
 [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24]
@@ -693,7 +690,6 @@ generator's close() method)
 [81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 162, 180, 192]
 [200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375, 384]
 [400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
->>> closer()
 
 The "tee" function does just what we want. It internally keeps a generated
 result for as long as it has not been "consumed" from all of the duplicated
@@ -701,11 +697,7 @@ iterators, whereupon it is deleted. You can therefore print the hamming
 sequence during hours without increasing memory usage, or very little.
 
 The beauty of it is that recursive running-after-their-tail FP algorithms
-are quite straightforwardly expressed with this Python idiom. The problem is
-that this creates an uncollectable reference cycle, and we have to explicitly
-close the innermost generator to clean up the cycle.
-XXX As of 14-Apr-2006, Tim doubts that anyone understands _why_ some cycle
-XXX is uncollectable here.
+are quite straightforwardly expressed with this Python idiom.
 
 Ye olde Fibonacci generator, tee style.
 
@@ -724,14 +716,11 @@ Ye olde Fibonacci generator, tee style.
 ...
 ...     realfib = _fib()
 ...     fibHead, fibTail, fibRes = tee(realfib, 3)
-...     return realfib.close, fibRes
+...     return fibRes
 
->>> closer, fibber = fib()
->>> firstn(fibber, 17)
+>>> firstn(fib(), 17)
 [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
->>> closer()
 
-XXX Again the tee-based approach leaks without an explicit close().
 """
 
 leak_test1 = """
index 71081fbe43b6f13b84265bbe75d4f0753efd4a03..94617a9e10cdb82abf0437808ed5674cced28367 100644 (file)
@@ -498,6 +498,7 @@ tee_copy(teeobject *to)
        newto->dataobj = to->dataobj;
        newto->index = to->index;
        newto->weakreflist = NULL;
+       PyObject_GC_Track(newto);
        return (PyObject *)newto;
 }