blob: 904fc7d88c03181a8a589cc161641f47f1229335 [file] [log] [blame]
Guido van Rossumd8faa362007-04-27 19:54:29 +00001import unittest
Brett Cannon7a540732011-02-22 03:04:06 +00002from test.support import (verbose, refcount_test, run_unittest,
Serhiy Storchakaa7930372016-07-03 22:27:26 +03003 strip_python_stderr, cpython_only, start_threads,
4 temp_dir, requires_type_collecting)
Berker Peksagce643912015-05-06 06:33:17 +03005from test.support.script_helper import assert_python_ok, make_script
Antoine Pitrou5f454a02013-05-06 21:15:57 +02006
Neil Schemenauer88c761a2001-07-12 13:25:53 +00007import sys
Antoine Pitrou2b0218a2012-09-06 00:59:49 +02008import time
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +00009import gc
Tim Petersead8b7a2004-10-30 23:09:22 +000010import weakref
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020011import threading
Antoine Pitrou2b0218a2012-09-06 00:59:49 +020012
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020013try:
14 from _testcapi import with_tp_del
15except ImportError:
16 def with_tp_del(cls):
17 class C(object):
18 def __new__(cls, *args, **kwargs):
19 raise TypeError('requires _testcapi.with_tp_del')
20 return C
21
Guido van Rossumd8faa362007-04-27 19:54:29 +000022### Support code
23###############################################################################
Tim Peters0f81ab62003-04-08 16:39:48 +000024
Tim Petersead8b7a2004-10-30 23:09:22 +000025# Bug 1055820 has several tests of longstanding bugs involving weakrefs and
26# cyclic gc.
27
28# An instance of C1055820 has a self-loop, so becomes cyclic trash when
29# unreachable.
30class C1055820(object):
31 def __init__(self, i):
32 self.i = i
33 self.loop = self
34
35class GC_Detector(object):
36 # Create an instance I. Then gc hasn't happened again so long as
37 # I.gc_happened is false.
38
39 def __init__(self):
40 self.gc_happened = False
41
42 def it_happened(ignored):
43 self.gc_happened = True
44
45 # Create a piece of cyclic trash that triggers it_happened when
46 # gc collects it.
47 self.wr = weakref.ref(C1055820(666), it_happened)
48
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020049@with_tp_del
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +000050class Uncollectable(object):
51 """Create a reference cycle with multiple __del__ methods.
52
53 An object in a reference cycle will never have zero references,
54 and so must be garbage collected. If one or more objects in the
55 cycle have __del__ methods, the gc refuses to guess an order,
56 and leaves the cycle uncollected."""
57 def __init__(self, partner=None):
58 if partner is None:
59 self.partner = Uncollectable(partner=self)
60 else:
61 self.partner = partner
Antoine Pitrou796564c2013-07-30 19:59:21 +020062 def __tp_del__(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +000063 pass
Tim Petersead8b7a2004-10-30 23:09:22 +000064
Guido van Rossumd8faa362007-04-27 19:54:29 +000065### Tests
66###############################################################################
Tim Petersead8b7a2004-10-30 23:09:22 +000067
Guido van Rossumd8faa362007-04-27 19:54:29 +000068class GCTests(unittest.TestCase):
69 def test_list(self):
70 l = []
71 l.append(l)
72 gc.collect()
73 del l
74 self.assertEqual(gc.collect(), 1)
Tim Petersead8b7a2004-10-30 23:09:22 +000075
Guido van Rossumd8faa362007-04-27 19:54:29 +000076 def test_dict(self):
77 d = {}
78 d[1] = d
79 gc.collect()
80 del d
81 self.assertEqual(gc.collect(), 1)
Tim Petersead8b7a2004-10-30 23:09:22 +000082
Guido van Rossumd8faa362007-04-27 19:54:29 +000083 def test_tuple(self):
84 # since tuples are immutable we close the loop with a list
85 l = []
86 t = (l,)
87 l.append(t)
88 gc.collect()
89 del t
90 del l
91 self.assertEqual(gc.collect(), 2)
Tim Petersead8b7a2004-10-30 23:09:22 +000092
Guido van Rossumd8faa362007-04-27 19:54:29 +000093 def test_class(self):
94 class A:
95 pass
96 A.a = A
97 gc.collect()
98 del A
99 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000100
Guido van Rossumd8faa362007-04-27 19:54:29 +0000101 def test_newstyleclass(self):
102 class A(object):
103 pass
104 gc.collect()
105 del A
106 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000107
Guido van Rossumd8faa362007-04-27 19:54:29 +0000108 def test_instance(self):
109 class A:
110 pass
111 a = A()
112 a.a = a
113 gc.collect()
114 del a
115 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000116
Serhiy Storchakaa7930372016-07-03 22:27:26 +0300117 @requires_type_collecting
Guido van Rossumd8faa362007-04-27 19:54:29 +0000118 def test_newinstance(self):
119 class A(object):
120 pass
121 a = A()
122 a.a = a
123 gc.collect()
124 del a
125 self.assertNotEqual(gc.collect(), 0)
126 class B(list):
127 pass
128 class C(B, A):
129 pass
130 a = C()
131 a.a = a
132 gc.collect()
133 del a
134 self.assertNotEqual(gc.collect(), 0)
135 del B, C
136 self.assertNotEqual(gc.collect(), 0)
137 A.a = A()
138 del A
139 self.assertNotEqual(gc.collect(), 0)
140 self.assertEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000141
Guido van Rossumd8faa362007-04-27 19:54:29 +0000142 def test_method(self):
143 # Tricky: self.__init__ is a bound method, it references the instance.
144 class A:
145 def __init__(self):
146 self.init = self.__init__
147 a = A()
148 gc.collect()
149 del a
150 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000151
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200152 @cpython_only
Antoine Pitrou796564c2013-07-30 19:59:21 +0200153 def test_legacy_finalizer(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000154 # A() is uncollectable if it is part of a cycle, make sure it shows up
155 # in gc.garbage.
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200156 @with_tp_del
Guido van Rossumd8faa362007-04-27 19:54:29 +0000157 class A:
Antoine Pitrou796564c2013-07-30 19:59:21 +0200158 def __tp_del__(self): pass
Guido van Rossumd8faa362007-04-27 19:54:29 +0000159 class B:
160 pass
161 a = A()
162 a.a = a
163 id_a = id(a)
164 b = B()
165 b.b = b
166 gc.collect()
167 del a
168 del b
169 self.assertNotEqual(gc.collect(), 0)
170 for obj in gc.garbage:
171 if id(obj) == id_a:
172 del obj.a
173 break
174 else:
175 self.fail("didn't find obj in garbage (finalizer)")
176 gc.garbage.remove(obj)
Tim Petersead8b7a2004-10-30 23:09:22 +0000177
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200178 @cpython_only
Antoine Pitrou796564c2013-07-30 19:59:21 +0200179 def test_legacy_finalizer_newclass(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000180 # A() is uncollectable if it is part of a cycle, make sure it shows up
181 # in gc.garbage.
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200182 @with_tp_del
Guido van Rossumd8faa362007-04-27 19:54:29 +0000183 class A(object):
Antoine Pitrou796564c2013-07-30 19:59:21 +0200184 def __tp_del__(self): pass
Guido van Rossumd8faa362007-04-27 19:54:29 +0000185 class B(object):
186 pass
187 a = A()
188 a.a = a
189 id_a = id(a)
190 b = B()
191 b.b = b
192 gc.collect()
193 del a
194 del b
195 self.assertNotEqual(gc.collect(), 0)
196 for obj in gc.garbage:
197 if id(obj) == id_a:
198 del obj.a
199 break
200 else:
201 self.fail("didn't find obj in garbage (finalizer)")
202 gc.garbage.remove(obj)
Tim Petersead8b7a2004-10-30 23:09:22 +0000203
Guido van Rossumd8faa362007-04-27 19:54:29 +0000204 def test_function(self):
205 # Tricky: f -> d -> f, code should call d.clear() after the exec to
206 # break the cycle.
207 d = {}
208 exec("def f(): pass\n", d)
209 gc.collect()
210 del d
211 self.assertEqual(gc.collect(), 2)
Tim Petersead8b7a2004-10-30 23:09:22 +0000212
Brett Cannon7a540732011-02-22 03:04:06 +0000213 @refcount_test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000214 def test_frame(self):
215 def f():
216 frame = sys._getframe()
217 gc.collect()
218 f()
219 self.assertEqual(gc.collect(), 1)
Tim Petersead8b7a2004-10-30 23:09:22 +0000220
Guido van Rossumd8faa362007-04-27 19:54:29 +0000221 def test_saveall(self):
222 # Verify that cyclic garbage like lists show up in gc.garbage if the
223 # SAVEALL option is enabled.
Tim Petersead8b7a2004-10-30 23:09:22 +0000224
Guido van Rossumd8faa362007-04-27 19:54:29 +0000225 # First make sure we don't save away other stuff that just happens to
226 # be waiting for collection.
227 gc.collect()
228 # if this fails, someone else created immortal trash
229 self.assertEqual(gc.garbage, [])
230
231 L = []
232 L.append(L)
233 id_L = id(L)
234
235 debug = gc.get_debug()
236 gc.set_debug(debug | gc.DEBUG_SAVEALL)
237 del L
238 gc.collect()
239 gc.set_debug(debug)
240
241 self.assertEqual(len(gc.garbage), 1)
242 obj = gc.garbage.pop()
243 self.assertEqual(id(obj), id_L)
244
245 def test_del(self):
246 # __del__ methods can trigger collection, make this to happen
247 thresholds = gc.get_threshold()
248 gc.enable()
249 gc.set_threshold(1)
250
251 class A:
252 def __del__(self):
253 dir(self)
254 a = A()
255 del a
256
257 gc.disable()
258 gc.set_threshold(*thresholds)
259
260 def test_del_newclass(self):
261 # __del__ methods can trigger collection, make this to happen
262 thresholds = gc.get_threshold()
263 gc.enable()
264 gc.set_threshold(1)
265
266 class A(object):
267 def __del__(self):
268 dir(self)
269 a = A()
270 del a
271
272 gc.disable()
273 gc.set_threshold(*thresholds)
274
Christian Heimesa156e092008-02-16 07:38:31 +0000275 # The following two tests are fragile:
276 # They precisely count the number of allocations,
277 # which is highly implementation-dependent.
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200278 # For example, disposed tuples are not freed, but reused.
279 # To minimize variations, though, we first store the get_count() results
280 # and check them at the end.
Brett Cannon7a540732011-02-22 03:04:06 +0000281 @refcount_test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000282 def test_get_count(self):
283 gc.collect()
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200284 a, b, c = gc.get_count()
285 x = []
286 d, e, f = gc.get_count()
287 self.assertEqual((b, c), (0, 0))
288 self.assertEqual((e, f), (0, 0))
289 # This is less fragile than asserting that a equals 0.
290 self.assertLess(a, 5)
291 # Between the two calls to get_count(), at least one object was
292 # created (the list).
293 self.assertGreater(d, a)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000294
Brett Cannon7a540732011-02-22 03:04:06 +0000295 @refcount_test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000296 def test_collect_generations(self):
297 gc.collect()
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200298 # This object will "trickle" into generation N + 1 after
299 # each call to collect(N)
300 x = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000301 gc.collect(0)
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200302 # x is now in gen 1
303 a, b, c = gc.get_count()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000304 gc.collect(1)
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200305 # x is now in gen 2
306 d, e, f = gc.get_count()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000307 gc.collect(2)
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200308 # x is now in gen 3
309 g, h, i = gc.get_count()
310 # We don't check a, d, g since their exact values depends on
311 # internal implementation details of the interpreter.
312 self.assertEqual((b, c), (1, 0))
313 self.assertEqual((e, f), (0, 1))
314 self.assertEqual((h, i), (0, 0))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000315
316 def test_trashcan(self):
317 class Ouch:
318 n = 0
319 def __del__(self):
320 Ouch.n = Ouch.n + 1
321 if Ouch.n % 17 == 0:
322 gc.collect()
323
324 # "trashcan" is a hack to prevent stack overflow when deallocating
325 # very deeply nested tuples etc. It works in part by abusing the
326 # type pointer and refcount fields, and that can yield horrible
327 # problems when gc tries to traverse the structures.
328 # If this test fails (as it does in 2.0, 2.1 and 2.2), it will
329 # most likely die via segfault.
330
331 # Note: In 2.3 the possibility for compiling without cyclic gc was
332 # removed, and that in turn allows the trashcan mechanism to work
333 # via much simpler means (e.g., it never abuses the type pointer or
334 # refcount fields anymore). Since it's much less likely to cause a
335 # problem now, the various constants in this expensive (we force a lot
336 # of full collections) test are cut back from the 2.2 version.
337 gc.enable()
338 N = 150
339 for count in range(2):
340 t = []
341 for i in range(N):
342 t = [t, Ouch()]
343 u = []
344 for i in range(N):
345 u = [u, Ouch()]
346 v = {}
347 for i in range(N):
348 v = {1: v, 2: Ouch()}
349 gc.disable()
350
Antoine Pitrou2b0218a2012-09-06 00:59:49 +0200351 def test_trashcan_threads(self):
352 # Issue #13992: trashcan mechanism should be thread-safe
353 NESTING = 60
354 N_THREADS = 2
355
356 def sleeper_gen():
357 """A generator that releases the GIL when closed or dealloc'ed."""
358 try:
359 yield
360 finally:
361 time.sleep(0.000001)
362
363 class C(list):
364 # Appending to a list is atomic, which avoids the use of a lock.
365 inits = []
366 dels = []
367 def __init__(self, alist):
368 self[:] = alist
369 C.inits.append(None)
370 def __del__(self):
371 # This __del__ is called by subtype_dealloc().
372 C.dels.append(None)
373 # `g` will release the GIL when garbage-collected. This
374 # helps assert subtype_dealloc's behaviour when threads
375 # switch in the middle of it.
376 g = sleeper_gen()
377 next(g)
378 # Now that __del__ is finished, subtype_dealloc will proceed
379 # to call list_dealloc, which also uses the trashcan mechanism.
380
381 def make_nested():
382 """Create a sufficiently nested container object so that the
383 trashcan mechanism is invoked when deallocating it."""
384 x = C([])
385 for i in range(NESTING):
386 x = [C([x])]
387 del x
388
389 def run_thread():
390 """Exercise make_nested() in a loop."""
391 while not exit:
392 make_nested()
393
394 old_switchinterval = sys.getswitchinterval()
395 sys.setswitchinterval(1e-5)
396 try:
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300397 exit = []
Antoine Pitrou2b0218a2012-09-06 00:59:49 +0200398 threads = []
399 for i in range(N_THREADS):
400 t = threading.Thread(target=run_thread)
401 threads.append(t)
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300402 with start_threads(threads, lambda: exit.append(1)):
Serhiy Storchaka9db55002015-03-28 20:38:37 +0200403 time.sleep(1.0)
Antoine Pitrou2b0218a2012-09-06 00:59:49 +0200404 finally:
405 sys.setswitchinterval(old_switchinterval)
406 gc.collect()
407 self.assertEqual(len(C.inits), len(C.dels))
408
Guido van Rossumd8faa362007-04-27 19:54:29 +0000409 def test_boom(self):
410 class Boom:
411 def __getattr__(self, someattribute):
412 del self.attr
413 raise AttributeError
414
415 a = Boom()
416 b = Boom()
417 a.attr = b
418 b.attr = a
419
420 gc.collect()
421 garbagelen = len(gc.garbage)
422 del a, b
423 # a<->b are in a trash cycle now. Collection will invoke
424 # Boom.__getattr__ (to see whether a and b have __del__ methods), and
425 # __getattr__ deletes the internal "attr" attributes as a side effect.
426 # That causes the trash cycle to get reclaimed via refcounts falling to
427 # 0, thus mutating the trash graph as a side effect of merely asking
428 # whether __del__ exists. This used to (before 2.3b1) crash Python.
429 # Now __getattr__ isn't called.
430 self.assertEqual(gc.collect(), 4)
431 self.assertEqual(len(gc.garbage), garbagelen)
432
433 def test_boom2(self):
434 class Boom2:
435 def __init__(self):
436 self.x = 0
437
438 def __getattr__(self, someattribute):
439 self.x += 1
440 if self.x > 1:
441 del self.attr
442 raise AttributeError
443
444 a = Boom2()
445 b = Boom2()
446 a.attr = b
447 b.attr = a
448
449 gc.collect()
450 garbagelen = len(gc.garbage)
451 del a, b
452 # Much like test_boom(), except that __getattr__ doesn't break the
453 # cycle until the second time gc checks for __del__. As of 2.3b1,
454 # there isn't a second time, so this simply cleans up the trash cycle.
455 # We expect a, b, a.__dict__ and b.__dict__ (4 objects) to get
456 # reclaimed this way.
457 self.assertEqual(gc.collect(), 4)
458 self.assertEqual(len(gc.garbage), garbagelen)
459
460 def test_boom_new(self):
461 # boom__new and boom2_new are exactly like boom and boom2, except use
462 # new-style classes.
463
464 class Boom_New(object):
465 def __getattr__(self, someattribute):
466 del self.attr
467 raise AttributeError
468
469 a = Boom_New()
470 b = Boom_New()
471 a.attr = b
472 b.attr = a
473
474 gc.collect()
475 garbagelen = len(gc.garbage)
476 del a, b
477 self.assertEqual(gc.collect(), 4)
478 self.assertEqual(len(gc.garbage), garbagelen)
479
480 def test_boom2_new(self):
481 class Boom2_New(object):
482 def __init__(self):
483 self.x = 0
484
485 def __getattr__(self, someattribute):
486 self.x += 1
487 if self.x > 1:
488 del self.attr
489 raise AttributeError
490
491 a = Boom2_New()
492 b = Boom2_New()
493 a.attr = b
494 b.attr = a
495
496 gc.collect()
497 garbagelen = len(gc.garbage)
498 del a, b
499 self.assertEqual(gc.collect(), 4)
500 self.assertEqual(len(gc.garbage), garbagelen)
501
502 def test_get_referents(self):
503 alist = [1, 3, 5]
504 got = gc.get_referents(alist)
505 got.sort()
506 self.assertEqual(got, alist)
507
508 atuple = tuple(alist)
509 got = gc.get_referents(atuple)
510 got.sort()
511 self.assertEqual(got, alist)
512
513 adict = {1: 3, 5: 7}
514 expected = [1, 3, 5, 7]
515 got = gc.get_referents(adict)
516 got.sort()
517 self.assertEqual(got, expected)
518
519 got = gc.get_referents([1, 2], {3: 4}, (0, 0, 0))
520 got.sort()
Guido van Rossum805365e2007-05-07 22:24:25 +0000521 self.assertEqual(got, [0, 0] + list(range(5)))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000522
523 self.assertEqual(gc.get_referents(1, 'a', 4j), [])
524
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000525 def test_is_tracked(self):
526 # Atomic built-in types are not tracked, user-defined objects and
527 # mutable containers are.
528 # NOTE: types with special optimizations (e.g. tuple) have tests
529 # in their own test files instead.
530 self.assertFalse(gc.is_tracked(None))
531 self.assertFalse(gc.is_tracked(1))
532 self.assertFalse(gc.is_tracked(1.0))
533 self.assertFalse(gc.is_tracked(1.0 + 5.0j))
534 self.assertFalse(gc.is_tracked(True))
535 self.assertFalse(gc.is_tracked(False))
536 self.assertFalse(gc.is_tracked(b"a"))
537 self.assertFalse(gc.is_tracked("a"))
538 self.assertFalse(gc.is_tracked(bytearray(b"a")))
539 self.assertFalse(gc.is_tracked(type))
540 self.assertFalse(gc.is_tracked(int))
541 self.assertFalse(gc.is_tracked(object))
542 self.assertFalse(gc.is_tracked(object()))
543
544 class UserClass:
545 pass
Antoine Pitroua63cc212015-04-13 20:10:06 +0200546
547 class UserInt(int):
548 pass
549
550 # Base class is object; no extra fields.
551 class UserClassSlots:
552 __slots__ = ()
553
554 # Base class is fixed size larger than object; no extra fields.
555 class UserFloatSlots(float):
556 __slots__ = ()
557
558 # Base class is variable size; no extra fields.
559 class UserIntSlots(int):
560 __slots__ = ()
561
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000562 self.assertTrue(gc.is_tracked(gc))
563 self.assertTrue(gc.is_tracked(UserClass))
564 self.assertTrue(gc.is_tracked(UserClass()))
Antoine Pitroua63cc212015-04-13 20:10:06 +0200565 self.assertTrue(gc.is_tracked(UserInt()))
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000566 self.assertTrue(gc.is_tracked([]))
567 self.assertTrue(gc.is_tracked(set()))
Antoine Pitroua63cc212015-04-13 20:10:06 +0200568 self.assertFalse(gc.is_tracked(UserClassSlots()))
569 self.assertFalse(gc.is_tracked(UserFloatSlots()))
570 self.assertFalse(gc.is_tracked(UserIntSlots()))
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000571
Guido van Rossumd8faa362007-04-27 19:54:29 +0000572 def test_bug1055820b(self):
573 # Corresponds to temp2b.py in the bug report.
574
575 ouch = []
576 def callback(ignored):
577 ouch[:] = [wr() for wr in WRs]
578
579 Cs = [C1055820(i) for i in range(2)]
580 WRs = [weakref.ref(c, callback) for c in Cs]
581 c = None
582
583 gc.collect()
584 self.assertEqual(len(ouch), 0)
585 # Make the two instances trash, and collect again. The bug was that
586 # the callback materialized a strong reference to an instance, but gc
587 # cleared the instance's dict anyway.
588 Cs = None
589 gc.collect()
590 self.assertEqual(len(ouch), 2) # else the callbacks didn't run
591 for x in ouch:
592 # If the callback resurrected one of these guys, the instance
593 # would be damaged, with an empty __dict__.
594 self.assertEqual(x, None)
595
Tim Peters5fbc7b12014-05-08 17:42:19 -0500596 def test_bug21435(self):
597 # This is a poor test - its only virtue is that it happened to
598 # segfault on Tim's Windows box before the patch for 21435 was
599 # applied. That's a nasty bug relying on specific pieces of cyclic
600 # trash appearing in exactly the right order in finalize_garbage()'s
601 # input list.
602 # But there's no reliable way to force that order from Python code,
603 # so over time chances are good this test won't really be testing much
604 # of anything anymore. Still, if it blows up, there's _some_
605 # problem ;-)
606 gc.collect()
607
608 class A:
609 pass
610
611 class B:
612 def __init__(self, x):
613 self.x = x
614
615 def __del__(self):
616 self.attr = None
617
618 def do_work():
619 a = A()
620 b = B(A())
621
622 a.attr = b
623 b.attr = a
624
625 do_work()
626 gc.collect() # this blows up (bad C pointer) when it fails
627
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200628 @cpython_only
Antoine Pitrou696e0352010-08-08 22:18:46 +0000629 def test_garbage_at_shutdown(self):
630 import subprocess
631 code = """if 1:
632 import gc
Antoine Pitrou796564c2013-07-30 19:59:21 +0200633 import _testcapi
634 @_testcapi.with_tp_del
Antoine Pitrou696e0352010-08-08 22:18:46 +0000635 class X:
636 def __init__(self, name):
637 self.name = name
638 def __repr__(self):
639 return "<X %%r>" %% self.name
Antoine Pitrou796564c2013-07-30 19:59:21 +0200640 def __tp_del__(self):
Antoine Pitrou696e0352010-08-08 22:18:46 +0000641 pass
642
643 x = X('first')
644 x.x = x
645 x.y = X('second')
646 del x
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000647 gc.set_debug(%s)
Antoine Pitrou696e0352010-08-08 22:18:46 +0000648 """
649 def run_command(code):
Georg Brandl08be72d2010-10-24 15:11:22 +0000650 p = subprocess.Popen([sys.executable, "-Wd", "-c", code],
Antoine Pitrou696e0352010-08-08 22:18:46 +0000651 stdout=subprocess.PIPE,
652 stderr=subprocess.PIPE)
653 stdout, stderr = p.communicate()
Brian Curtin8291af22010-11-01 16:40:17 +0000654 p.stdout.close()
655 p.stderr.close()
Antoine Pitrou696e0352010-08-08 22:18:46 +0000656 self.assertEqual(p.returncode, 0)
657 self.assertEqual(stdout.strip(), b"")
658 return strip_python_stderr(stderr)
659
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000660 stderr = run_command(code % "0")
Georg Brandl08be72d2010-10-24 15:11:22 +0000661 self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at "
662 b"shutdown; use", stderr)
Antoine Pitrouaee47562010-09-16 15:04:49 +0000663 self.assertNotIn(b"<X 'first'>", stderr)
Antoine Pitrou696e0352010-08-08 22:18:46 +0000664 # With DEBUG_UNCOLLECTABLE, the garbage list gets printed
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000665 stderr = run_command(code % "gc.DEBUG_UNCOLLECTABLE")
Georg Brandl08be72d2010-10-24 15:11:22 +0000666 self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at "
667 b"shutdown", stderr)
Antoine Pitrouaee47562010-09-16 15:04:49 +0000668 self.assertTrue(
669 (b"[<X 'first'>, <X 'second'>]" in stderr) or
670 (b"[<X 'second'>, <X 'first'>]" in stderr), stderr)
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000671 # With DEBUG_SAVEALL, no additional message should get printed
672 # (because gc.garbage also contains normally reclaimable cyclic
673 # references, and its elements get printed at runtime anyway).
674 stderr = run_command(code % "gc.DEBUG_SAVEALL")
675 self.assertNotIn(b"uncollectable objects at shutdown", stderr)
676
Serhiy Storchakaa7930372016-07-03 22:27:26 +0300677 @requires_type_collecting
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200678 def test_gc_main_module_at_shutdown(self):
679 # Create a reference cycle through the __main__ module and check
680 # it gets collected at interpreter shutdown.
681 code = """if 1:
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200682 class C:
683 def __del__(self):
684 print('__del__ called')
685 l = [C()]
686 l.append(l)
687 """
688 rc, out, err = assert_python_ok('-c', code)
689 self.assertEqual(out.strip(), b'__del__ called')
690
Serhiy Storchakaa7930372016-07-03 22:27:26 +0300691 @requires_type_collecting
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200692 def test_gc_ordinary_module_at_shutdown(self):
693 # Same as above, but with a non-__main__ module.
694 with temp_dir() as script_dir:
695 module = """if 1:
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200696 class C:
697 def __del__(self):
698 print('__del__ called')
699 l = [C()]
700 l.append(l)
701 """
702 code = """if 1:
703 import sys
704 sys.path.insert(0, %r)
705 import gctest
706 """ % (script_dir,)
707 make_script(script_dir, 'gctest', module)
708 rc, out, err = assert_python_ok('-c', code)
709 self.assertEqual(out.strip(), b'__del__ called')
710
Antoine Pitroud4156c12012-10-30 22:43:19 +0100711 def test_get_stats(self):
712 stats = gc.get_stats()
713 self.assertEqual(len(stats), 3)
714 for st in stats:
715 self.assertIsInstance(st, dict)
716 self.assertEqual(set(st),
717 {"collected", "collections", "uncollectable"})
718 self.assertGreaterEqual(st["collected"], 0)
719 self.assertGreaterEqual(st["collections"], 0)
720 self.assertGreaterEqual(st["uncollectable"], 0)
721 # Check that collection counts are incremented correctly
722 if gc.isenabled():
723 self.addCleanup(gc.enable)
724 gc.disable()
725 old = gc.get_stats()
726 gc.collect(0)
727 new = gc.get_stats()
728 self.assertEqual(new[0]["collections"], old[0]["collections"] + 1)
729 self.assertEqual(new[1]["collections"], old[1]["collections"])
730 self.assertEqual(new[2]["collections"], old[2]["collections"])
731 gc.collect(2)
732 new = gc.get_stats()
733 self.assertEqual(new[0]["collections"], old[0]["collections"] + 1)
734 self.assertEqual(new[1]["collections"], old[1]["collections"])
735 self.assertEqual(new[2]["collections"], old[2]["collections"] + 1)
736
brainfvckc75edab2017-10-16 12:49:41 -0700737 def test_freeze(self):
738 gc.freeze()
739 self.assertGreater(gc.get_freeze_count(), 0)
740 gc.unfreeze()
741 self.assertEqual(gc.get_freeze_count(), 0)
742
Antoine Pitrou696e0352010-08-08 22:18:46 +0000743
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000744class GCCallbackTests(unittest.TestCase):
745 def setUp(self):
746 # Save gc state and disable it.
747 self.enabled = gc.isenabled()
748 gc.disable()
749 self.debug = gc.get_debug()
750 gc.set_debug(0)
751 gc.callbacks.append(self.cb1)
752 gc.callbacks.append(self.cb2)
Antoine Pitrou6b64fc62012-04-16 21:29:02 +0200753 self.othergarbage = []
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000754
755 def tearDown(self):
756 # Restore gc state
757 del self.visit
758 gc.callbacks.remove(self.cb1)
759 gc.callbacks.remove(self.cb2)
760 gc.set_debug(self.debug)
761 if self.enabled:
762 gc.enable()
763 # destroy any uncollectables
764 gc.collect()
765 for obj in gc.garbage:
766 if isinstance(obj, Uncollectable):
767 obj.partner = None
768 del gc.garbage[:]
Antoine Pitrou6b64fc62012-04-16 21:29:02 +0200769 del self.othergarbage
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000770 gc.collect()
771
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000772 def preclean(self):
773 # Remove all fluff from the system. Invoke this function
774 # manually rather than through self.setUp() for maximum
775 # safety.
776 self.visit = []
777 gc.collect()
778 garbage, gc.garbage[:] = gc.garbage[:], []
779 self.othergarbage.append(garbage)
780 self.visit = []
781
782 def cb1(self, phase, info):
783 self.visit.append((1, phase, dict(info)))
784
785 def cb2(self, phase, info):
786 self.visit.append((2, phase, dict(info)))
787 if phase == "stop" and hasattr(self, "cleanup"):
788 # Clean Uncollectable from garbage
789 uc = [e for e in gc.garbage if isinstance(e, Uncollectable)]
790 gc.garbage[:] = [e for e in gc.garbage
791 if not isinstance(e, Uncollectable)]
792 for e in uc:
793 e.partner = None
794
Antoine Pitroude3c73b2012-04-16 21:29:58 +0200795 def test_collect(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000796 self.preclean()
797 gc.collect()
798 # Algorithmically verify the contents of self.visit
799 # because it is long and tortuous.
800
801 # Count the number of visits to each callback
802 n = [v[0] for v in self.visit]
803 n1 = [i for i in n if i == 1]
804 n2 = [i for i in n if i == 2]
805 self.assertEqual(n1, [1]*2)
806 self.assertEqual(n2, [2]*2)
807
808 # Count that we got the right number of start and stop callbacks.
809 n = [v[1] for v in self.visit]
810 n1 = [i for i in n if i == "start"]
811 n2 = [i for i in n if i == "stop"]
812 self.assertEqual(n1, ["start"]*2)
813 self.assertEqual(n2, ["stop"]*2)
814
815 # Check that we got the right info dict for all callbacks
816 for v in self.visit:
817 info = v[2]
818 self.assertTrue("generation" in info)
819 self.assertTrue("collected" in info)
820 self.assertTrue("uncollectable" in info)
821
Antoine Pitroude3c73b2012-04-16 21:29:58 +0200822 def test_collect_generation(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000823 self.preclean()
824 gc.collect(2)
825 for v in self.visit:
826 info = v[2]
827 self.assertEqual(info["generation"], 2)
828
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200829 @cpython_only
Antoine Pitroude3c73b2012-04-16 21:29:58 +0200830 def test_collect_garbage(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000831 self.preclean()
832 # Each of these cause four objects to be garbage: Two
833 # Uncolectables and their instance dicts.
834 Uncollectable()
835 Uncollectable()
836 C1055820(666)
837 gc.collect()
838 for v in self.visit:
839 if v[1] != "stop":
840 continue
841 info = v[2]
842 self.assertEqual(info["collected"], 2)
843 self.assertEqual(info["uncollectable"], 8)
844
845 # We should now have the Uncollectables in gc.garbage
846 self.assertEqual(len(gc.garbage), 4)
847 for e in gc.garbage:
848 self.assertIsInstance(e, Uncollectable)
849
850 # Now, let our callback handle the Uncollectable instances
851 self.cleanup=True
852 self.visit = []
853 gc.garbage[:] = []
854 gc.collect()
855 for v in self.visit:
856 if v[1] != "stop":
857 continue
858 info = v[2]
859 self.assertEqual(info["collected"], 0)
860 self.assertEqual(info["uncollectable"], 4)
861
862 # Uncollectables should be gone
863 self.assertEqual(len(gc.garbage), 0)
864
865
Guido van Rossumd8faa362007-04-27 19:54:29 +0000866class GCTogglingTests(unittest.TestCase):
867 def setUp(self):
868 gc.enable()
869
870 def tearDown(self):
871 gc.disable()
872
873 def test_bug1055820c(self):
874 # Corresponds to temp2c.py in the bug report. This is pretty
875 # elaborate.
876
877 c0 = C1055820(0)
878 # Move c0 into generation 2.
879 gc.collect()
880
881 c1 = C1055820(1)
882 c1.keep_c0_alive = c0
883 del c0.loop # now only c1 keeps c0 alive
884
885 c2 = C1055820(2)
886 c2wr = weakref.ref(c2) # no callback!
887
888 ouch = []
889 def callback(ignored):
Tim Petersead8b7a2004-10-30 23:09:22 +0000890 ouch[:] = [c2wr()]
891
Guido van Rossumd8faa362007-04-27 19:54:29 +0000892 # The callback gets associated with a wr on an object in generation 2.
893 c0wr = weakref.ref(c0, callback)
Tim Petersead8b7a2004-10-30 23:09:22 +0000894
Guido van Rossumd8faa362007-04-27 19:54:29 +0000895 c0 = c1 = c2 = None
Tim Petersead8b7a2004-10-30 23:09:22 +0000896
Guido van Rossumd8faa362007-04-27 19:54:29 +0000897 # What we've set up: c0, c1, and c2 are all trash now. c0 is in
898 # generation 2. The only thing keeping it alive is that c1 points to
899 # it. c1 and c2 are in generation 0, and are in self-loops. There's a
900 # global weakref to c2 (c2wr), but that weakref has no callback.
901 # There's also a global weakref to c0 (c0wr), and that does have a
902 # callback, and that callback references c2 via c2wr().
903 #
904 # c0 has a wr with callback, which references c2wr
905 # ^
906 # |
907 # | Generation 2 above dots
908 #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
909 # | Generation 0 below dots
910 # |
911 # |
912 # ^->c1 ^->c2 has a wr but no callback
913 # | | | |
914 # <--v <--v
915 #
916 # So this is the nightmare: when generation 0 gets collected, we see
917 # that c2 has a callback-free weakref, and c1 doesn't even have a
918 # weakref. Collecting generation 0 doesn't see c0 at all, and c0 is
919 # the only object that has a weakref with a callback. gc clears c1
920 # and c2. Clearing c1 has the side effect of dropping the refcount on
921 # c0 to 0, so c0 goes away (despite that it's in an older generation)
922 # and c0's wr callback triggers. That in turn materializes a reference
923 # to c2 via c2wr(), but c2 gets cleared anyway by gc.
Tim Petersead8b7a2004-10-30 23:09:22 +0000924
Guido van Rossumd8faa362007-04-27 19:54:29 +0000925 # We want to let gc happen "naturally", to preserve the distinction
926 # between generations.
927 junk = []
928 i = 0
929 detector = GC_Detector()
930 while not detector.gc_happened:
931 i += 1
932 if i > 10000:
933 self.fail("gc didn't happen after 10000 iterations")
934 self.assertEqual(len(ouch), 0)
935 junk.append([]) # this will eventually trigger gc
Tim Petersead8b7a2004-10-30 23:09:22 +0000936
Guido van Rossumd8faa362007-04-27 19:54:29 +0000937 self.assertEqual(len(ouch), 1) # else the callback wasn't invoked
938 for x in ouch:
939 # If the callback resurrected c2, the instance would be damaged,
940 # with an empty __dict__.
941 self.assertEqual(x, None)
Tim Petersead8b7a2004-10-30 23:09:22 +0000942
Guido van Rossumd8faa362007-04-27 19:54:29 +0000943 def test_bug1055820d(self):
944 # Corresponds to temp2d.py in the bug report. This is very much like
945 # test_bug1055820c, but uses a __del__ method instead of a weakref
946 # callback to sneak in a resurrection of cyclic trash.
Tim Petersead8b7a2004-10-30 23:09:22 +0000947
Guido van Rossumd8faa362007-04-27 19:54:29 +0000948 ouch = []
949 class D(C1055820):
950 def __del__(self):
951 ouch[:] = [c2wr()]
Tim Petersead8b7a2004-10-30 23:09:22 +0000952
Guido van Rossumd8faa362007-04-27 19:54:29 +0000953 d0 = D(0)
954 # Move all the above into generation 2.
955 gc.collect()
Tim Petersead8b7a2004-10-30 23:09:22 +0000956
Guido van Rossumd8faa362007-04-27 19:54:29 +0000957 c1 = C1055820(1)
958 c1.keep_d0_alive = d0
959 del d0.loop # now only c1 keeps d0 alive
Tim Petersead8b7a2004-10-30 23:09:22 +0000960
Guido van Rossumd8faa362007-04-27 19:54:29 +0000961 c2 = C1055820(2)
962 c2wr = weakref.ref(c2) # no callback!
Tim Petersead8b7a2004-10-30 23:09:22 +0000963
Guido van Rossumd8faa362007-04-27 19:54:29 +0000964 d0 = c1 = c2 = None
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000965
Guido van Rossumd8faa362007-04-27 19:54:29 +0000966 # What we've set up: d0, c1, and c2 are all trash now. d0 is in
967 # generation 2. The only thing keeping it alive is that c1 points to
968 # it. c1 and c2 are in generation 0, and are in self-loops. There's
969 # a global weakref to c2 (c2wr), but that weakref has no callback.
970 # There are no other weakrefs.
971 #
972 # d0 has a __del__ method that references c2wr
973 # ^
974 # |
975 # | Generation 2 above dots
976 #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
977 # | Generation 0 below dots
978 # |
979 # |
980 # ^->c1 ^->c2 has a wr but no callback
981 # | | | |
982 # <--v <--v
983 #
984 # So this is the nightmare: when generation 0 gets collected, we see
985 # that c2 has a callback-free weakref, and c1 doesn't even have a
986 # weakref. Collecting generation 0 doesn't see d0 at all. gc clears
987 # c1 and c2. Clearing c1 has the side effect of dropping the refcount
988 # on d0 to 0, so d0 goes away (despite that it's in an older
989 # generation) and d0's __del__ triggers. That in turn materializes
990 # a reference to c2 via c2wr(), but c2 gets cleared anyway by gc.
991
992 # We want to let gc happen "naturally", to preserve the distinction
993 # between generations.
994 detector = GC_Detector()
995 junk = []
996 i = 0
997 while not detector.gc_happened:
998 i += 1
999 if i > 10000:
1000 self.fail("gc didn't happen after 10000 iterations")
1001 self.assertEqual(len(ouch), 0)
1002 junk.append([]) # this will eventually trigger gc
1003
1004 self.assertEqual(len(ouch), 1) # else __del__ wasn't invoked
1005 for x in ouch:
1006 # If __del__ resurrected c2, the instance would be damaged, with an
1007 # empty __dict__.
1008 self.assertEqual(x, None)
1009
1010def test_main():
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001011 enabled = gc.isenabled()
1012 gc.disable()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001013 assert not gc.isenabled()
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001014 debug = gc.get_debug()
1015 gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001016
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001017 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001018 gc.collect() # Delete 2nd generation garbage
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +00001019 run_unittest(GCTests, GCTogglingTests, GCCallbackTests)
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001020 finally:
1021 gc.set_debug(debug)
1022 # test gc.enable() even if GC is disabled by default
1023 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001024 print("restoring automatic collection")
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001025 # make sure to always test gc.enable()
1026 gc.enable()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001027 assert gc.isenabled()
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001028 if not enabled:
1029 gc.disable()
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001030
Guido van Rossumd8faa362007-04-27 19:54:29 +00001031if __name__ == "__main__":
1032 test_main()