blob: 16b22422528fb718b29fe348859108567fa0c181 [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,
Victor Stinner626bff82018-10-25 17:31:10 +02004 temp_dir, requires_type_collecting, TESTFN, unlink,
5 import_module)
Berker Peksagce643912015-05-06 06:33:17 +03006from test.support.script_helper import assert_python_ok, make_script
Antoine Pitrou5f454a02013-05-06 21:15:57 +02007
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +00008import gc
Victor Stinner626bff82018-10-25 17:31:10 +02009import sys
10import sysconfig
11import textwrap
Antoine Pitroua6a4dc82017-09-07 18:56:24 +020012import threading
Victor Stinner626bff82018-10-25 17:31:10 +020013import time
14import weakref
Antoine Pitrou2b0218a2012-09-06 00:59:49 +020015
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020016try:
17 from _testcapi import with_tp_del
18except ImportError:
19 def with_tp_del(cls):
20 class C(object):
21 def __new__(cls, *args, **kwargs):
22 raise TypeError('requires _testcapi.with_tp_del')
23 return C
24
Guido van Rossumd8faa362007-04-27 19:54:29 +000025### Support code
26###############################################################################
Tim Peters0f81ab62003-04-08 16:39:48 +000027
Tim Petersead8b7a2004-10-30 23:09:22 +000028# Bug 1055820 has several tests of longstanding bugs involving weakrefs and
29# cyclic gc.
30
31# An instance of C1055820 has a self-loop, so becomes cyclic trash when
32# unreachable.
33class C1055820(object):
34 def __init__(self, i):
35 self.i = i
36 self.loop = self
37
38class GC_Detector(object):
39 # Create an instance I. Then gc hasn't happened again so long as
40 # I.gc_happened is false.
41
42 def __init__(self):
43 self.gc_happened = False
44
45 def it_happened(ignored):
46 self.gc_happened = True
47
48 # Create a piece of cyclic trash that triggers it_happened when
49 # gc collects it.
50 self.wr = weakref.ref(C1055820(666), it_happened)
51
Serhiy Storchakaf28ba362014-02-07 10:10:55 +020052@with_tp_del
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +000053class Uncollectable(object):
54 """Create a reference cycle with multiple __del__ methods.
55
56 An object in a reference cycle will never have zero references,
57 and so must be garbage collected. If one or more objects in the
58 cycle have __del__ methods, the gc refuses to guess an order,
59 and leaves the cycle uncollected."""
60 def __init__(self, partner=None):
61 if partner is None:
62 self.partner = Uncollectable(partner=self)
63 else:
64 self.partner = partner
Antoine Pitrou796564c2013-07-30 19:59:21 +020065 def __tp_del__(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +000066 pass
Tim Petersead8b7a2004-10-30 23:09:22 +000067
Victor Stinner626bff82018-10-25 17:31:10 +020068if sysconfig.get_config_vars().get('PY_CFLAGS', ''):
69 BUILD_WITH_NDEBUG = ('-DNDEBUG' in sysconfig.get_config_vars()['PY_CFLAGS'])
70else:
71 # Usually, sys.gettotalrefcount() is only present if Python has been
72 # compiled in debug mode. If it's missing, expect that Python has
73 # been released in release mode: with NDEBUG defined.
74 BUILD_WITH_NDEBUG = (not hasattr(sys, 'gettotalrefcount'))
75
Guido van Rossumd8faa362007-04-27 19:54:29 +000076### Tests
77###############################################################################
Tim Petersead8b7a2004-10-30 23:09:22 +000078
Guido van Rossumd8faa362007-04-27 19:54:29 +000079class GCTests(unittest.TestCase):
80 def test_list(self):
81 l = []
82 l.append(l)
83 gc.collect()
84 del l
85 self.assertEqual(gc.collect(), 1)
Tim Petersead8b7a2004-10-30 23:09:22 +000086
Guido van Rossumd8faa362007-04-27 19:54:29 +000087 def test_dict(self):
88 d = {}
89 d[1] = d
90 gc.collect()
91 del d
92 self.assertEqual(gc.collect(), 1)
Tim Petersead8b7a2004-10-30 23:09:22 +000093
Guido van Rossumd8faa362007-04-27 19:54:29 +000094 def test_tuple(self):
95 # since tuples are immutable we close the loop with a list
96 l = []
97 t = (l,)
98 l.append(t)
99 gc.collect()
100 del t
101 del l
102 self.assertEqual(gc.collect(), 2)
Tim Petersead8b7a2004-10-30 23:09:22 +0000103
Guido van Rossumd8faa362007-04-27 19:54:29 +0000104 def test_class(self):
105 class A:
106 pass
107 A.a = A
108 gc.collect()
109 del A
110 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000111
Guido van Rossumd8faa362007-04-27 19:54:29 +0000112 def test_newstyleclass(self):
113 class A(object):
114 pass
115 gc.collect()
116 del A
117 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000118
Guido van Rossumd8faa362007-04-27 19:54:29 +0000119 def test_instance(self):
120 class A:
121 pass
122 a = A()
123 a.a = a
124 gc.collect()
125 del a
126 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000127
Serhiy Storchakaa7930372016-07-03 22:27:26 +0300128 @requires_type_collecting
Guido van Rossumd8faa362007-04-27 19:54:29 +0000129 def test_newinstance(self):
130 class A(object):
131 pass
132 a = A()
133 a.a = a
134 gc.collect()
135 del a
136 self.assertNotEqual(gc.collect(), 0)
137 class B(list):
138 pass
139 class C(B, A):
140 pass
141 a = C()
142 a.a = a
143 gc.collect()
144 del a
145 self.assertNotEqual(gc.collect(), 0)
146 del B, C
147 self.assertNotEqual(gc.collect(), 0)
148 A.a = A()
149 del A
150 self.assertNotEqual(gc.collect(), 0)
151 self.assertEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000152
Guido van Rossumd8faa362007-04-27 19:54:29 +0000153 def test_method(self):
154 # Tricky: self.__init__ is a bound method, it references the instance.
155 class A:
156 def __init__(self):
157 self.init = self.__init__
158 a = A()
159 gc.collect()
160 del a
161 self.assertNotEqual(gc.collect(), 0)
Tim Petersead8b7a2004-10-30 23:09:22 +0000162
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200163 @cpython_only
Antoine Pitrou796564c2013-07-30 19:59:21 +0200164 def test_legacy_finalizer(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000165 # A() is uncollectable if it is part of a cycle, make sure it shows up
166 # in gc.garbage.
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200167 @with_tp_del
Guido van Rossumd8faa362007-04-27 19:54:29 +0000168 class A:
Antoine Pitrou796564c2013-07-30 19:59:21 +0200169 def __tp_del__(self): pass
Guido van Rossumd8faa362007-04-27 19:54:29 +0000170 class B:
171 pass
172 a = A()
173 a.a = a
174 id_a = id(a)
175 b = B()
176 b.b = b
177 gc.collect()
178 del a
179 del b
180 self.assertNotEqual(gc.collect(), 0)
181 for obj in gc.garbage:
182 if id(obj) == id_a:
183 del obj.a
184 break
185 else:
186 self.fail("didn't find obj in garbage (finalizer)")
187 gc.garbage.remove(obj)
Tim Petersead8b7a2004-10-30 23:09:22 +0000188
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200189 @cpython_only
Antoine Pitrou796564c2013-07-30 19:59:21 +0200190 def test_legacy_finalizer_newclass(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000191 # A() is uncollectable if it is part of a cycle, make sure it shows up
192 # in gc.garbage.
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200193 @with_tp_del
Guido van Rossumd8faa362007-04-27 19:54:29 +0000194 class A(object):
Antoine Pitrou796564c2013-07-30 19:59:21 +0200195 def __tp_del__(self): pass
Guido van Rossumd8faa362007-04-27 19:54:29 +0000196 class B(object):
197 pass
198 a = A()
199 a.a = a
200 id_a = id(a)
201 b = B()
202 b.b = b
203 gc.collect()
204 del a
205 del b
206 self.assertNotEqual(gc.collect(), 0)
207 for obj in gc.garbage:
208 if id(obj) == id_a:
209 del obj.a
210 break
211 else:
212 self.fail("didn't find obj in garbage (finalizer)")
213 gc.garbage.remove(obj)
Tim Petersead8b7a2004-10-30 23:09:22 +0000214
Guido van Rossumd8faa362007-04-27 19:54:29 +0000215 def test_function(self):
216 # Tricky: f -> d -> f, code should call d.clear() after the exec to
217 # break the cycle.
218 d = {}
219 exec("def f(): pass\n", d)
220 gc.collect()
221 del d
222 self.assertEqual(gc.collect(), 2)
Tim Petersead8b7a2004-10-30 23:09:22 +0000223
Brett Cannon7a540732011-02-22 03:04:06 +0000224 @refcount_test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000225 def test_frame(self):
226 def f():
227 frame = sys._getframe()
228 gc.collect()
229 f()
230 self.assertEqual(gc.collect(), 1)
Tim Petersead8b7a2004-10-30 23:09:22 +0000231
Guido van Rossumd8faa362007-04-27 19:54:29 +0000232 def test_saveall(self):
233 # Verify that cyclic garbage like lists show up in gc.garbage if the
234 # SAVEALL option is enabled.
Tim Petersead8b7a2004-10-30 23:09:22 +0000235
Guido van Rossumd8faa362007-04-27 19:54:29 +0000236 # First make sure we don't save away other stuff that just happens to
237 # be waiting for collection.
238 gc.collect()
239 # if this fails, someone else created immortal trash
240 self.assertEqual(gc.garbage, [])
241
242 L = []
243 L.append(L)
244 id_L = id(L)
245
246 debug = gc.get_debug()
247 gc.set_debug(debug | gc.DEBUG_SAVEALL)
248 del L
249 gc.collect()
250 gc.set_debug(debug)
251
252 self.assertEqual(len(gc.garbage), 1)
253 obj = gc.garbage.pop()
254 self.assertEqual(id(obj), id_L)
255
256 def test_del(self):
257 # __del__ methods can trigger collection, make this to happen
258 thresholds = gc.get_threshold()
259 gc.enable()
260 gc.set_threshold(1)
261
262 class A:
263 def __del__(self):
264 dir(self)
265 a = A()
266 del a
267
268 gc.disable()
269 gc.set_threshold(*thresholds)
270
271 def test_del_newclass(self):
272 # __del__ methods can trigger collection, make this to happen
273 thresholds = gc.get_threshold()
274 gc.enable()
275 gc.set_threshold(1)
276
277 class A(object):
278 def __del__(self):
279 dir(self)
280 a = A()
281 del a
282
283 gc.disable()
284 gc.set_threshold(*thresholds)
285
Christian Heimesa156e092008-02-16 07:38:31 +0000286 # The following two tests are fragile:
287 # They precisely count the number of allocations,
288 # which is highly implementation-dependent.
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200289 # For example, disposed tuples are not freed, but reused.
290 # To minimize variations, though, we first store the get_count() results
291 # and check them at the end.
Brett Cannon7a540732011-02-22 03:04:06 +0000292 @refcount_test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000293 def test_get_count(self):
294 gc.collect()
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200295 a, b, c = gc.get_count()
296 x = []
297 d, e, f = gc.get_count()
298 self.assertEqual((b, c), (0, 0))
299 self.assertEqual((e, f), (0, 0))
300 # This is less fragile than asserting that a equals 0.
301 self.assertLess(a, 5)
302 # Between the two calls to get_count(), at least one object was
303 # created (the list).
304 self.assertGreater(d, a)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000305
Brett Cannon7a540732011-02-22 03:04:06 +0000306 @refcount_test
Guido van Rossumd8faa362007-04-27 19:54:29 +0000307 def test_collect_generations(self):
308 gc.collect()
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200309 # This object will "trickle" into generation N + 1 after
310 # each call to collect(N)
311 x = []
Guido van Rossumd8faa362007-04-27 19:54:29 +0000312 gc.collect(0)
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200313 # x is now in gen 1
314 a, b, c = gc.get_count()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000315 gc.collect(1)
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200316 # x is now in gen 2
317 d, e, f = gc.get_count()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000318 gc.collect(2)
Antoine Pitroub35f29a2011-04-04 19:50:42 +0200319 # x is now in gen 3
320 g, h, i = gc.get_count()
321 # We don't check a, d, g since their exact values depends on
322 # internal implementation details of the interpreter.
323 self.assertEqual((b, c), (1, 0))
324 self.assertEqual((e, f), (0, 1))
325 self.assertEqual((h, i), (0, 0))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000326
327 def test_trashcan(self):
328 class Ouch:
329 n = 0
330 def __del__(self):
331 Ouch.n = Ouch.n + 1
332 if Ouch.n % 17 == 0:
333 gc.collect()
334
335 # "trashcan" is a hack to prevent stack overflow when deallocating
336 # very deeply nested tuples etc. It works in part by abusing the
337 # type pointer and refcount fields, and that can yield horrible
338 # problems when gc tries to traverse the structures.
339 # If this test fails (as it does in 2.0, 2.1 and 2.2), it will
340 # most likely die via segfault.
341
342 # Note: In 2.3 the possibility for compiling without cyclic gc was
343 # removed, and that in turn allows the trashcan mechanism to work
344 # via much simpler means (e.g., it never abuses the type pointer or
345 # refcount fields anymore). Since it's much less likely to cause a
346 # problem now, the various constants in this expensive (we force a lot
347 # of full collections) test are cut back from the 2.2 version.
348 gc.enable()
349 N = 150
350 for count in range(2):
351 t = []
352 for i in range(N):
353 t = [t, Ouch()]
354 u = []
355 for i in range(N):
356 u = [u, Ouch()]
357 v = {}
358 for i in range(N):
359 v = {1: v, 2: Ouch()}
360 gc.disable()
361
Antoine Pitrou2b0218a2012-09-06 00:59:49 +0200362 def test_trashcan_threads(self):
363 # Issue #13992: trashcan mechanism should be thread-safe
364 NESTING = 60
365 N_THREADS = 2
366
367 def sleeper_gen():
368 """A generator that releases the GIL when closed or dealloc'ed."""
369 try:
370 yield
371 finally:
372 time.sleep(0.000001)
373
374 class C(list):
375 # Appending to a list is atomic, which avoids the use of a lock.
376 inits = []
377 dels = []
378 def __init__(self, alist):
379 self[:] = alist
380 C.inits.append(None)
381 def __del__(self):
382 # This __del__ is called by subtype_dealloc().
383 C.dels.append(None)
384 # `g` will release the GIL when garbage-collected. This
385 # helps assert subtype_dealloc's behaviour when threads
386 # switch in the middle of it.
387 g = sleeper_gen()
388 next(g)
389 # Now that __del__ is finished, subtype_dealloc will proceed
390 # to call list_dealloc, which also uses the trashcan mechanism.
391
392 def make_nested():
393 """Create a sufficiently nested container object so that the
394 trashcan mechanism is invoked when deallocating it."""
395 x = C([])
396 for i in range(NESTING):
397 x = [C([x])]
398 del x
399
400 def run_thread():
401 """Exercise make_nested() in a loop."""
402 while not exit:
403 make_nested()
404
405 old_switchinterval = sys.getswitchinterval()
406 sys.setswitchinterval(1e-5)
407 try:
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300408 exit = []
Antoine Pitrou2b0218a2012-09-06 00:59:49 +0200409 threads = []
410 for i in range(N_THREADS):
411 t = threading.Thread(target=run_thread)
412 threads.append(t)
Serhiy Storchaka263dcd22015-04-01 13:01:14 +0300413 with start_threads(threads, lambda: exit.append(1)):
Serhiy Storchaka9db55002015-03-28 20:38:37 +0200414 time.sleep(1.0)
Antoine Pitrou2b0218a2012-09-06 00:59:49 +0200415 finally:
416 sys.setswitchinterval(old_switchinterval)
417 gc.collect()
418 self.assertEqual(len(C.inits), len(C.dels))
419
Guido van Rossumd8faa362007-04-27 19:54:29 +0000420 def test_boom(self):
421 class Boom:
422 def __getattr__(self, someattribute):
423 del self.attr
424 raise AttributeError
425
426 a = Boom()
427 b = Boom()
428 a.attr = b
429 b.attr = a
430
431 gc.collect()
432 garbagelen = len(gc.garbage)
433 del a, b
434 # a<->b are in a trash cycle now. Collection will invoke
435 # Boom.__getattr__ (to see whether a and b have __del__ methods), and
436 # __getattr__ deletes the internal "attr" attributes as a side effect.
437 # That causes the trash cycle to get reclaimed via refcounts falling to
438 # 0, thus mutating the trash graph as a side effect of merely asking
439 # whether __del__ exists. This used to (before 2.3b1) crash Python.
440 # Now __getattr__ isn't called.
441 self.assertEqual(gc.collect(), 4)
442 self.assertEqual(len(gc.garbage), garbagelen)
443
444 def test_boom2(self):
445 class Boom2:
446 def __init__(self):
447 self.x = 0
448
449 def __getattr__(self, someattribute):
450 self.x += 1
451 if self.x > 1:
452 del self.attr
453 raise AttributeError
454
455 a = Boom2()
456 b = Boom2()
457 a.attr = b
458 b.attr = a
459
460 gc.collect()
461 garbagelen = len(gc.garbage)
462 del a, b
463 # Much like test_boom(), except that __getattr__ doesn't break the
464 # cycle until the second time gc checks for __del__. As of 2.3b1,
465 # there isn't a second time, so this simply cleans up the trash cycle.
466 # We expect a, b, a.__dict__ and b.__dict__ (4 objects) to get
467 # reclaimed this way.
468 self.assertEqual(gc.collect(), 4)
469 self.assertEqual(len(gc.garbage), garbagelen)
470
471 def test_boom_new(self):
472 # boom__new and boom2_new are exactly like boom and boom2, except use
473 # new-style classes.
474
475 class Boom_New(object):
476 def __getattr__(self, someattribute):
477 del self.attr
478 raise AttributeError
479
480 a = Boom_New()
481 b = Boom_New()
482 a.attr = b
483 b.attr = a
484
485 gc.collect()
486 garbagelen = len(gc.garbage)
487 del a, b
488 self.assertEqual(gc.collect(), 4)
489 self.assertEqual(len(gc.garbage), garbagelen)
490
491 def test_boom2_new(self):
492 class Boom2_New(object):
493 def __init__(self):
494 self.x = 0
495
496 def __getattr__(self, someattribute):
497 self.x += 1
498 if self.x > 1:
499 del self.attr
500 raise AttributeError
501
502 a = Boom2_New()
503 b = Boom2_New()
504 a.attr = b
505 b.attr = a
506
507 gc.collect()
508 garbagelen = len(gc.garbage)
509 del a, b
510 self.assertEqual(gc.collect(), 4)
511 self.assertEqual(len(gc.garbage), garbagelen)
512
513 def test_get_referents(self):
514 alist = [1, 3, 5]
515 got = gc.get_referents(alist)
516 got.sort()
517 self.assertEqual(got, alist)
518
519 atuple = tuple(alist)
520 got = gc.get_referents(atuple)
521 got.sort()
522 self.assertEqual(got, alist)
523
524 adict = {1: 3, 5: 7}
525 expected = [1, 3, 5, 7]
526 got = gc.get_referents(adict)
527 got.sort()
528 self.assertEqual(got, expected)
529
530 got = gc.get_referents([1, 2], {3: 4}, (0, 0, 0))
531 got.sort()
Guido van Rossum805365e2007-05-07 22:24:25 +0000532 self.assertEqual(got, [0, 0] + list(range(5)))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000533
534 self.assertEqual(gc.get_referents(1, 'a', 4j), [])
535
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000536 def test_is_tracked(self):
537 # Atomic built-in types are not tracked, user-defined objects and
538 # mutable containers are.
539 # NOTE: types with special optimizations (e.g. tuple) have tests
540 # in their own test files instead.
541 self.assertFalse(gc.is_tracked(None))
542 self.assertFalse(gc.is_tracked(1))
543 self.assertFalse(gc.is_tracked(1.0))
544 self.assertFalse(gc.is_tracked(1.0 + 5.0j))
545 self.assertFalse(gc.is_tracked(True))
546 self.assertFalse(gc.is_tracked(False))
547 self.assertFalse(gc.is_tracked(b"a"))
548 self.assertFalse(gc.is_tracked("a"))
549 self.assertFalse(gc.is_tracked(bytearray(b"a")))
550 self.assertFalse(gc.is_tracked(type))
551 self.assertFalse(gc.is_tracked(int))
552 self.assertFalse(gc.is_tracked(object))
553 self.assertFalse(gc.is_tracked(object()))
554
555 class UserClass:
556 pass
Antoine Pitroua63cc212015-04-13 20:10:06 +0200557
558 class UserInt(int):
559 pass
560
561 # Base class is object; no extra fields.
562 class UserClassSlots:
563 __slots__ = ()
564
565 # Base class is fixed size larger than object; no extra fields.
566 class UserFloatSlots(float):
567 __slots__ = ()
568
569 # Base class is variable size; no extra fields.
570 class UserIntSlots(int):
571 __slots__ = ()
572
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000573 self.assertTrue(gc.is_tracked(gc))
574 self.assertTrue(gc.is_tracked(UserClass))
575 self.assertTrue(gc.is_tracked(UserClass()))
Antoine Pitroua63cc212015-04-13 20:10:06 +0200576 self.assertTrue(gc.is_tracked(UserInt()))
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000577 self.assertTrue(gc.is_tracked([]))
578 self.assertTrue(gc.is_tracked(set()))
Antoine Pitroua63cc212015-04-13 20:10:06 +0200579 self.assertFalse(gc.is_tracked(UserClassSlots()))
580 self.assertFalse(gc.is_tracked(UserFloatSlots()))
581 self.assertFalse(gc.is_tracked(UserIntSlots()))
Antoine Pitrou3a652b12009-03-23 18:52:06 +0000582
Guido van Rossumd8faa362007-04-27 19:54:29 +0000583 def test_bug1055820b(self):
584 # Corresponds to temp2b.py in the bug report.
585
586 ouch = []
587 def callback(ignored):
588 ouch[:] = [wr() for wr in WRs]
589
590 Cs = [C1055820(i) for i in range(2)]
591 WRs = [weakref.ref(c, callback) for c in Cs]
592 c = None
593
594 gc.collect()
595 self.assertEqual(len(ouch), 0)
596 # Make the two instances trash, and collect again. The bug was that
597 # the callback materialized a strong reference to an instance, but gc
598 # cleared the instance's dict anyway.
599 Cs = None
600 gc.collect()
601 self.assertEqual(len(ouch), 2) # else the callbacks didn't run
602 for x in ouch:
603 # If the callback resurrected one of these guys, the instance
604 # would be damaged, with an empty __dict__.
605 self.assertEqual(x, None)
606
Tim Peters5fbc7b12014-05-08 17:42:19 -0500607 def test_bug21435(self):
608 # This is a poor test - its only virtue is that it happened to
609 # segfault on Tim's Windows box before the patch for 21435 was
610 # applied. That's a nasty bug relying on specific pieces of cyclic
611 # trash appearing in exactly the right order in finalize_garbage()'s
612 # input list.
613 # But there's no reliable way to force that order from Python code,
614 # so over time chances are good this test won't really be testing much
615 # of anything anymore. Still, if it blows up, there's _some_
616 # problem ;-)
617 gc.collect()
618
619 class A:
620 pass
621
622 class B:
623 def __init__(self, x):
624 self.x = x
625
626 def __del__(self):
627 self.attr = None
628
629 def do_work():
630 a = A()
631 b = B(A())
632
633 a.attr = b
634 b.attr = a
635
636 do_work()
637 gc.collect() # this blows up (bad C pointer) when it fails
638
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200639 @cpython_only
Antoine Pitrou696e0352010-08-08 22:18:46 +0000640 def test_garbage_at_shutdown(self):
641 import subprocess
642 code = """if 1:
643 import gc
Antoine Pitrou796564c2013-07-30 19:59:21 +0200644 import _testcapi
645 @_testcapi.with_tp_del
Antoine Pitrou696e0352010-08-08 22:18:46 +0000646 class X:
647 def __init__(self, name):
648 self.name = name
649 def __repr__(self):
650 return "<X %%r>" %% self.name
Antoine Pitrou796564c2013-07-30 19:59:21 +0200651 def __tp_del__(self):
Antoine Pitrou696e0352010-08-08 22:18:46 +0000652 pass
653
654 x = X('first')
655 x.x = x
656 x.y = X('second')
657 del x
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000658 gc.set_debug(%s)
Antoine Pitrou696e0352010-08-08 22:18:46 +0000659 """
660 def run_command(code):
Georg Brandl08be72d2010-10-24 15:11:22 +0000661 p = subprocess.Popen([sys.executable, "-Wd", "-c", code],
Antoine Pitrou696e0352010-08-08 22:18:46 +0000662 stdout=subprocess.PIPE,
663 stderr=subprocess.PIPE)
664 stdout, stderr = p.communicate()
Brian Curtin8291af22010-11-01 16:40:17 +0000665 p.stdout.close()
666 p.stderr.close()
Antoine Pitrou696e0352010-08-08 22:18:46 +0000667 self.assertEqual(p.returncode, 0)
668 self.assertEqual(stdout.strip(), b"")
669 return strip_python_stderr(stderr)
670
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000671 stderr = run_command(code % "0")
Georg Brandl08be72d2010-10-24 15:11:22 +0000672 self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at "
673 b"shutdown; use", stderr)
Antoine Pitrouaee47562010-09-16 15:04:49 +0000674 self.assertNotIn(b"<X 'first'>", stderr)
Antoine Pitrou696e0352010-08-08 22:18:46 +0000675 # With DEBUG_UNCOLLECTABLE, the garbage list gets printed
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000676 stderr = run_command(code % "gc.DEBUG_UNCOLLECTABLE")
Georg Brandl08be72d2010-10-24 15:11:22 +0000677 self.assertIn(b"ResourceWarning: gc: 2 uncollectable objects at "
678 b"shutdown", stderr)
Antoine Pitrouaee47562010-09-16 15:04:49 +0000679 self.assertTrue(
680 (b"[<X 'first'>, <X 'second'>]" in stderr) or
681 (b"[<X 'second'>, <X 'first'>]" in stderr), stderr)
Antoine Pitrou2ed94eb2010-09-14 09:48:39 +0000682 # With DEBUG_SAVEALL, no additional message should get printed
683 # (because gc.garbage also contains normally reclaimable cyclic
684 # references, and its elements get printed at runtime anyway).
685 stderr = run_command(code % "gc.DEBUG_SAVEALL")
686 self.assertNotIn(b"uncollectable objects at shutdown", stderr)
687
Serhiy Storchakaa7930372016-07-03 22:27:26 +0300688 @requires_type_collecting
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200689 def test_gc_main_module_at_shutdown(self):
690 # Create a reference cycle through the __main__ module and check
691 # it gets collected at interpreter shutdown.
692 code = """if 1:
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200693 class C:
694 def __del__(self):
695 print('__del__ called')
696 l = [C()]
697 l.append(l)
698 """
699 rc, out, err = assert_python_ok('-c', code)
700 self.assertEqual(out.strip(), b'__del__ called')
701
Serhiy Storchakaa7930372016-07-03 22:27:26 +0300702 @requires_type_collecting
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200703 def test_gc_ordinary_module_at_shutdown(self):
704 # Same as above, but with a non-__main__ module.
705 with temp_dir() as script_dir:
706 module = """if 1:
Antoine Pitrou5f454a02013-05-06 21:15:57 +0200707 class C:
708 def __del__(self):
709 print('__del__ called')
710 l = [C()]
711 l.append(l)
712 """
713 code = """if 1:
714 import sys
715 sys.path.insert(0, %r)
716 import gctest
717 """ % (script_dir,)
718 make_script(script_dir, 'gctest', module)
719 rc, out, err = assert_python_ok('-c', code)
720 self.assertEqual(out.strip(), b'__del__ called')
721
Zackery Spytzd8cba5d2018-07-03 13:47:22 -0600722 @requires_type_collecting
723 def test_global_del_SystemExit(self):
724 code = """if 1:
725 class ClassWithDel:
726 def __del__(self):
727 print('__del__ called')
728 a = ClassWithDel()
729 a.link = a
730 raise SystemExit(0)"""
731 self.addCleanup(unlink, TESTFN)
732 with open(TESTFN, 'w') as script:
733 script.write(code)
734 rc, out, err = assert_python_ok(TESTFN)
735 self.assertEqual(out.strip(), b'__del__ called')
736
Antoine Pitroud4156c12012-10-30 22:43:19 +0100737 def test_get_stats(self):
738 stats = gc.get_stats()
739 self.assertEqual(len(stats), 3)
740 for st in stats:
741 self.assertIsInstance(st, dict)
742 self.assertEqual(set(st),
743 {"collected", "collections", "uncollectable"})
744 self.assertGreaterEqual(st["collected"], 0)
745 self.assertGreaterEqual(st["collections"], 0)
746 self.assertGreaterEqual(st["uncollectable"], 0)
747 # Check that collection counts are incremented correctly
748 if gc.isenabled():
749 self.addCleanup(gc.enable)
750 gc.disable()
751 old = gc.get_stats()
752 gc.collect(0)
753 new = gc.get_stats()
754 self.assertEqual(new[0]["collections"], old[0]["collections"] + 1)
755 self.assertEqual(new[1]["collections"], old[1]["collections"])
756 self.assertEqual(new[2]["collections"], old[2]["collections"])
757 gc.collect(2)
758 new = gc.get_stats()
759 self.assertEqual(new[0]["collections"], old[0]["collections"] + 1)
760 self.assertEqual(new[1]["collections"], old[1]["collections"])
761 self.assertEqual(new[2]["collections"], old[2]["collections"] + 1)
762
brainfvckc75edab2017-10-16 12:49:41 -0700763 def test_freeze(self):
764 gc.freeze()
765 self.assertGreater(gc.get_freeze_count(), 0)
766 gc.unfreeze()
767 self.assertEqual(gc.get_freeze_count(), 0)
768
Antoine Pitrou696e0352010-08-08 22:18:46 +0000769
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000770class GCCallbackTests(unittest.TestCase):
771 def setUp(self):
772 # Save gc state and disable it.
773 self.enabled = gc.isenabled()
774 gc.disable()
775 self.debug = gc.get_debug()
776 gc.set_debug(0)
777 gc.callbacks.append(self.cb1)
778 gc.callbacks.append(self.cb2)
Antoine Pitrou6b64fc62012-04-16 21:29:02 +0200779 self.othergarbage = []
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000780
781 def tearDown(self):
782 # Restore gc state
783 del self.visit
784 gc.callbacks.remove(self.cb1)
785 gc.callbacks.remove(self.cb2)
786 gc.set_debug(self.debug)
787 if self.enabled:
788 gc.enable()
789 # destroy any uncollectables
790 gc.collect()
791 for obj in gc.garbage:
792 if isinstance(obj, Uncollectable):
793 obj.partner = None
794 del gc.garbage[:]
Antoine Pitrou6b64fc62012-04-16 21:29:02 +0200795 del self.othergarbage
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000796 gc.collect()
797
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000798 def preclean(self):
799 # Remove all fluff from the system. Invoke this function
800 # manually rather than through self.setUp() for maximum
801 # safety.
802 self.visit = []
803 gc.collect()
804 garbage, gc.garbage[:] = gc.garbage[:], []
805 self.othergarbage.append(garbage)
806 self.visit = []
807
808 def cb1(self, phase, info):
809 self.visit.append((1, phase, dict(info)))
810
811 def cb2(self, phase, info):
812 self.visit.append((2, phase, dict(info)))
813 if phase == "stop" and hasattr(self, "cleanup"):
814 # Clean Uncollectable from garbage
815 uc = [e for e in gc.garbage if isinstance(e, Uncollectable)]
816 gc.garbage[:] = [e for e in gc.garbage
817 if not isinstance(e, Uncollectable)]
818 for e in uc:
819 e.partner = None
820
Antoine Pitroude3c73b2012-04-16 21:29:58 +0200821 def test_collect(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000822 self.preclean()
823 gc.collect()
824 # Algorithmically verify the contents of self.visit
825 # because it is long and tortuous.
826
827 # Count the number of visits to each callback
828 n = [v[0] for v in self.visit]
829 n1 = [i for i in n if i == 1]
830 n2 = [i for i in n if i == 2]
831 self.assertEqual(n1, [1]*2)
832 self.assertEqual(n2, [2]*2)
833
834 # Count that we got the right number of start and stop callbacks.
835 n = [v[1] for v in self.visit]
836 n1 = [i for i in n if i == "start"]
837 n2 = [i for i in n if i == "stop"]
838 self.assertEqual(n1, ["start"]*2)
839 self.assertEqual(n2, ["stop"]*2)
840
841 # Check that we got the right info dict for all callbacks
842 for v in self.visit:
843 info = v[2]
844 self.assertTrue("generation" in info)
845 self.assertTrue("collected" in info)
846 self.assertTrue("uncollectable" in info)
847
Antoine Pitroude3c73b2012-04-16 21:29:58 +0200848 def test_collect_generation(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000849 self.preclean()
850 gc.collect(2)
851 for v in self.visit:
852 info = v[2]
853 self.assertEqual(info["generation"], 2)
854
Serhiy Storchakaf28ba362014-02-07 10:10:55 +0200855 @cpython_only
Antoine Pitroude3c73b2012-04-16 21:29:58 +0200856 def test_collect_garbage(self):
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +0000857 self.preclean()
858 # Each of these cause four objects to be garbage: Two
859 # Uncolectables and their instance dicts.
860 Uncollectable()
861 Uncollectable()
862 C1055820(666)
863 gc.collect()
864 for v in self.visit:
865 if v[1] != "stop":
866 continue
867 info = v[2]
868 self.assertEqual(info["collected"], 2)
869 self.assertEqual(info["uncollectable"], 8)
870
871 # We should now have the Uncollectables in gc.garbage
872 self.assertEqual(len(gc.garbage), 4)
873 for e in gc.garbage:
874 self.assertIsInstance(e, Uncollectable)
875
876 # Now, let our callback handle the Uncollectable instances
877 self.cleanup=True
878 self.visit = []
879 gc.garbage[:] = []
880 gc.collect()
881 for v in self.visit:
882 if v[1] != "stop":
883 continue
884 info = v[2]
885 self.assertEqual(info["collected"], 0)
886 self.assertEqual(info["uncollectable"], 4)
887
888 # Uncollectables should be gone
889 self.assertEqual(len(gc.garbage), 0)
890
891
Victor Stinner626bff82018-10-25 17:31:10 +0200892 @unittest.skipIf(BUILD_WITH_NDEBUG,
893 'built with -NDEBUG')
894 def test_refcount_errors(self):
895 self.preclean()
896 # Verify the "handling" of objects with broken refcounts
897
898 # Skip the test if ctypes is not available
899 import_module("ctypes")
900
901 import subprocess
902 code = textwrap.dedent('''
903 from test.support import gc_collect, SuppressCrashReport
904
905 a = [1, 2, 3]
906 b = [a]
907
908 # Avoid coredump when Py_FatalError() calls abort()
909 SuppressCrashReport().__enter__()
910
911 # Simulate the refcount of "a" being too low (compared to the
912 # references held on it by live data), but keeping it above zero
913 # (to avoid deallocating it):
914 import ctypes
915 ctypes.pythonapi.Py_DecRef(ctypes.py_object(a))
916
917 # The garbage collector should now have a fatal error
918 # when it reaches the broken object
919 gc_collect()
920 ''')
921 p = subprocess.Popen([sys.executable, "-c", code],
922 stdout=subprocess.PIPE,
923 stderr=subprocess.PIPE)
924 stdout, stderr = p.communicate()
925 p.stdout.close()
926 p.stderr.close()
927 # Verify that stderr has a useful error message:
928 self.assertRegex(stderr,
929 br'gcmodule\.c:[0-9]+: gc_decref: Assertion "gc_get_refs\(g\) > 0" failed.')
930 self.assertRegex(stderr,
931 br'refcount is too small')
932 self.assertRegex(stderr,
933 br'object : \[1, 2, 3\]')
934 self.assertRegex(stderr,
935 br'type : list')
936 self.assertRegex(stderr,
937 br'refcount: 1')
938 # "address : 0x7fb5062efc18"
939 # "address : 7FB5062EFC18"
940 self.assertRegex(stderr,
941 br'address : [0-9a-fA-Fx]+')
942
943
Guido van Rossumd8faa362007-04-27 19:54:29 +0000944class GCTogglingTests(unittest.TestCase):
945 def setUp(self):
946 gc.enable()
947
948 def tearDown(self):
949 gc.disable()
950
951 def test_bug1055820c(self):
952 # Corresponds to temp2c.py in the bug report. This is pretty
953 # elaborate.
954
955 c0 = C1055820(0)
956 # Move c0 into generation 2.
957 gc.collect()
958
959 c1 = C1055820(1)
960 c1.keep_c0_alive = c0
961 del c0.loop # now only c1 keeps c0 alive
962
963 c2 = C1055820(2)
964 c2wr = weakref.ref(c2) # no callback!
965
966 ouch = []
967 def callback(ignored):
Tim Petersead8b7a2004-10-30 23:09:22 +0000968 ouch[:] = [c2wr()]
969
Guido van Rossumd8faa362007-04-27 19:54:29 +0000970 # The callback gets associated with a wr on an object in generation 2.
971 c0wr = weakref.ref(c0, callback)
Tim Petersead8b7a2004-10-30 23:09:22 +0000972
Guido van Rossumd8faa362007-04-27 19:54:29 +0000973 c0 = c1 = c2 = None
Tim Petersead8b7a2004-10-30 23:09:22 +0000974
Guido van Rossumd8faa362007-04-27 19:54:29 +0000975 # What we've set up: c0, c1, and c2 are all trash now. c0 is in
976 # generation 2. The only thing keeping it alive is that c1 points to
977 # it. c1 and c2 are in generation 0, and are in self-loops. There's a
978 # global weakref to c2 (c2wr), but that weakref has no callback.
979 # There's also a global weakref to c0 (c0wr), and that does have a
980 # callback, and that callback references c2 via c2wr().
981 #
982 # c0 has a wr with callback, which references c2wr
983 # ^
984 # |
985 # | Generation 2 above dots
986 #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
987 # | Generation 0 below dots
988 # |
989 # |
990 # ^->c1 ^->c2 has a wr but no callback
991 # | | | |
992 # <--v <--v
993 #
994 # So this is the nightmare: when generation 0 gets collected, we see
995 # that c2 has a callback-free weakref, and c1 doesn't even have a
996 # weakref. Collecting generation 0 doesn't see c0 at all, and c0 is
997 # the only object that has a weakref with a callback. gc clears c1
998 # and c2. Clearing c1 has the side effect of dropping the refcount on
999 # c0 to 0, so c0 goes away (despite that it's in an older generation)
1000 # and c0's wr callback triggers. That in turn materializes a reference
1001 # to c2 via c2wr(), but c2 gets cleared anyway by gc.
Tim Petersead8b7a2004-10-30 23:09:22 +00001002
Guido van Rossumd8faa362007-04-27 19:54:29 +00001003 # We want to let gc happen "naturally", to preserve the distinction
1004 # between generations.
1005 junk = []
1006 i = 0
1007 detector = GC_Detector()
1008 while not detector.gc_happened:
1009 i += 1
1010 if i > 10000:
1011 self.fail("gc didn't happen after 10000 iterations")
1012 self.assertEqual(len(ouch), 0)
1013 junk.append([]) # this will eventually trigger gc
Tim Petersead8b7a2004-10-30 23:09:22 +00001014
Guido van Rossumd8faa362007-04-27 19:54:29 +00001015 self.assertEqual(len(ouch), 1) # else the callback wasn't invoked
1016 for x in ouch:
1017 # If the callback resurrected c2, the instance would be damaged,
1018 # with an empty __dict__.
1019 self.assertEqual(x, None)
Tim Petersead8b7a2004-10-30 23:09:22 +00001020
Guido van Rossumd8faa362007-04-27 19:54:29 +00001021 def test_bug1055820d(self):
1022 # Corresponds to temp2d.py in the bug report. This is very much like
1023 # test_bug1055820c, but uses a __del__ method instead of a weakref
1024 # callback to sneak in a resurrection of cyclic trash.
Tim Petersead8b7a2004-10-30 23:09:22 +00001025
Guido van Rossumd8faa362007-04-27 19:54:29 +00001026 ouch = []
1027 class D(C1055820):
1028 def __del__(self):
1029 ouch[:] = [c2wr()]
Tim Petersead8b7a2004-10-30 23:09:22 +00001030
Guido van Rossumd8faa362007-04-27 19:54:29 +00001031 d0 = D(0)
1032 # Move all the above into generation 2.
1033 gc.collect()
Tim Petersead8b7a2004-10-30 23:09:22 +00001034
Guido van Rossumd8faa362007-04-27 19:54:29 +00001035 c1 = C1055820(1)
1036 c1.keep_d0_alive = d0
1037 del d0.loop # now only c1 keeps d0 alive
Tim Petersead8b7a2004-10-30 23:09:22 +00001038
Guido van Rossumd8faa362007-04-27 19:54:29 +00001039 c2 = C1055820(2)
1040 c2wr = weakref.ref(c2) # no callback!
Tim Petersead8b7a2004-10-30 23:09:22 +00001041
Guido van Rossumd8faa362007-04-27 19:54:29 +00001042 d0 = c1 = c2 = None
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001043
Guido van Rossumd8faa362007-04-27 19:54:29 +00001044 # What we've set up: d0, c1, and c2 are all trash now. d0 is in
1045 # generation 2. The only thing keeping it alive is that c1 points to
1046 # it. c1 and c2 are in generation 0, and are in self-loops. There's
1047 # a global weakref to c2 (c2wr), but that weakref has no callback.
1048 # There are no other weakrefs.
1049 #
1050 # d0 has a __del__ method that references c2wr
1051 # ^
1052 # |
1053 # | Generation 2 above dots
1054 #. . . . . . . .|. . . . . . . . . . . . . . . . . . . . . . . .
1055 # | Generation 0 below dots
1056 # |
1057 # |
1058 # ^->c1 ^->c2 has a wr but no callback
1059 # | | | |
1060 # <--v <--v
1061 #
1062 # So this is the nightmare: when generation 0 gets collected, we see
1063 # that c2 has a callback-free weakref, and c1 doesn't even have a
1064 # weakref. Collecting generation 0 doesn't see d0 at all. gc clears
1065 # c1 and c2. Clearing c1 has the side effect of dropping the refcount
1066 # on d0 to 0, so d0 goes away (despite that it's in an older
1067 # generation) and d0's __del__ triggers. That in turn materializes
1068 # a reference to c2 via c2wr(), but c2 gets cleared anyway by gc.
1069
1070 # We want to let gc happen "naturally", to preserve the distinction
1071 # between generations.
1072 detector = GC_Detector()
1073 junk = []
1074 i = 0
1075 while not detector.gc_happened:
1076 i += 1
1077 if i > 10000:
1078 self.fail("gc didn't happen after 10000 iterations")
1079 self.assertEqual(len(ouch), 0)
1080 junk.append([]) # this will eventually trigger gc
1081
1082 self.assertEqual(len(ouch), 1) # else __del__ wasn't invoked
1083 for x in ouch:
1084 # If __del__ resurrected c2, the instance would be damaged, with an
1085 # empty __dict__.
1086 self.assertEqual(x, None)
1087
1088def test_main():
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001089 enabled = gc.isenabled()
1090 gc.disable()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001091 assert not gc.isenabled()
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001092 debug = gc.get_debug()
1093 gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001094
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001095 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +00001096 gc.collect() # Delete 2nd generation garbage
Kristján Valur Jónsson69c63522012-04-15 11:41:32 +00001097 run_unittest(GCTests, GCTogglingTests, GCCallbackTests)
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001098 finally:
1099 gc.set_debug(debug)
1100 # test gc.enable() even if GC is disabled by default
1101 if verbose:
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001102 print("restoring automatic collection")
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001103 # make sure to always test gc.enable()
1104 gc.enable()
Guido van Rossumd8faa362007-04-27 19:54:29 +00001105 assert gc.isenabled()
Neil Schemenauerfaae2662000-09-22 15:26:20 +00001106 if not enabled:
1107 gc.disable()
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +00001108
Guido van Rossumd8faa362007-04-27 19:54:29 +00001109if __name__ == "__main__":
1110 test_main()