Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(35222)

Delta Between Two Patch Sets: Lib/test/test_gc.py

Issue 16510: Using appropriate checks in tests
Left Patch Set: Created 5 years, 10 months ago
Right Patch Set: Created 5 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Lib/test/test_functools.py ('k') | Lib/test/test_gdb.py » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 import _testcapi
2 import unittest 1 import unittest
3 from test.support import (verbose, refcount_test, run_unittest, 2 from test.support import (verbose, refcount_test, run_unittest,
4 strip_python_stderr) 3 strip_python_stderr, cpython_only)
5 from test.script_helper import assert_python_ok, make_script, temp_dir 4 from test.script_helper import assert_python_ok, make_script, temp_dir
6 5
7 import sys 6 import sys
8 import time 7 import time
9 import gc 8 import gc
10 import weakref 9 import weakref
11 10
12 try: 11 try:
13 import threading 12 import threading
14 except ImportError: 13 except ImportError:
15 threading = None 14 threading = None
15
16 try:
17 from _testcapi import with_tp_del
18 except 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
16 24
17 ### Support code 25 ### Support code
18 ############################################################################### 26 ###############################################################################
19 27
20 # Bug 1055820 has several tests of longstanding bugs involving weakrefs and 28 # Bug 1055820 has several tests of longstanding bugs involving weakrefs and
21 # cyclic gc. 29 # cyclic gc.
22 30
23 # An instance of C1055820 has a self-loop, so becomes cyclic trash when 31 # An instance of C1055820 has a self-loop, so becomes cyclic trash when
24 # unreachable. 32 # unreachable.
25 class C1055820(object): 33 class C1055820(object):
26 def __init__(self, i): 34 def __init__(self, i):
27 self.i = i 35 self.i = i
28 self.loop = self 36 self.loop = self
29 37
30 class GC_Detector(object): 38 class GC_Detector(object):
31 # Create an instance I. Then gc hasn't happened again so long as 39 # Create an instance I. Then gc hasn't happened again so long as
32 # I.gc_happened is false. 40 # I.gc_happened is false.
33 41
34 def __init__(self): 42 def __init__(self):
35 self.gc_happened = False 43 self.gc_happened = False
36 44
37 def it_happened(ignored): 45 def it_happened(ignored):
38 self.gc_happened = True 46 self.gc_happened = True
39 47
40 # Create a piece of cyclic trash that triggers it_happened when 48 # Create a piece of cyclic trash that triggers it_happened when
41 # gc collects it. 49 # gc collects it.
42 self.wr = weakref.ref(C1055820(666), it_happened) 50 self.wr = weakref.ref(C1055820(666), it_happened)
43 51
44 @_testcapi.with_tp_del 52 @with_tp_del
45 class Uncollectable(object): 53 class Uncollectable(object):
46 """Create a reference cycle with multiple __del__ methods. 54 """Create a reference cycle with multiple __del__ methods.
47 55
48 An object in a reference cycle will never have zero references, 56 An object in a reference cycle will never have zero references,
49 and so must be garbage collected. If one or more objects in the 57 and so must be garbage collected. If one or more objects in the
50 cycle have __del__ methods, the gc refuses to guess an order, 58 cycle have __del__ methods, the gc refuses to guess an order,
51 and leaves the cycle uncollected.""" 59 and leaves the cycle uncollected."""
52 def __init__(self, partner=None): 60 def __init__(self, partner=None):
53 if partner is None: 61 if partner is None:
54 self.partner = Uncollectable(partner=self) 62 self.partner = Uncollectable(partner=self)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 def test_method(self): 144 def test_method(self):
137 # Tricky: self.__init__ is a bound method, it references the instance. 145 # Tricky: self.__init__ is a bound method, it references the instance.
138 class A: 146 class A:
139 def __init__(self): 147 def __init__(self):
140 self.init = self.__init__ 148 self.init = self.__init__
141 a = A() 149 a = A()
142 gc.collect() 150 gc.collect()
143 del a 151 del a
144 self.assertNotEqual(gc.collect(), 0) 152 self.assertNotEqual(gc.collect(), 0)
145 153
154 @cpython_only
146 def test_legacy_finalizer(self): 155 def test_legacy_finalizer(self):
147 # A() is uncollectable if it is part of a cycle, make sure it shows up 156 # A() is uncollectable if it is part of a cycle, make sure it shows up
148 # in gc.garbage. 157 # in gc.garbage.
149 @_testcapi.with_tp_del 158 @with_tp_del
150 class A: 159 class A:
151 def __tp_del__(self): pass 160 def __tp_del__(self): pass
152 class B: 161 class B:
153 pass 162 pass
154 a = A() 163 a = A()
155 a.a = a 164 a.a = a
156 id_a = id(a) 165 id_a = id(a)
157 b = B() 166 b = B()
158 b.b = b 167 b.b = b
159 gc.collect() 168 gc.collect()
160 del a 169 del a
161 del b 170 del b
162 self.assertNotEqual(gc.collect(), 0) 171 self.assertNotEqual(gc.collect(), 0)
163 for obj in gc.garbage: 172 for obj in gc.garbage:
164 if id(obj) == id_a: 173 if id(obj) == id_a:
165 del obj.a 174 del obj.a
166 break 175 break
167 else: 176 else:
168 self.fail("didn't find obj in garbage (finalizer)") 177 self.fail("didn't find obj in garbage (finalizer)")
169 gc.garbage.remove(obj) 178 gc.garbage.remove(obj)
170 179
180 @cpython_only
171 def test_legacy_finalizer_newclass(self): 181 def test_legacy_finalizer_newclass(self):
172 # A() is uncollectable if it is part of a cycle, make sure it shows up 182 # A() is uncollectable if it is part of a cycle, make sure it shows up
173 # in gc.garbage. 183 # in gc.garbage.
174 @_testcapi.with_tp_del 184 @with_tp_del
175 class A(object): 185 class A(object):
176 def __tp_del__(self): pass 186 def __tp_del__(self): pass
177 class B(object): 187 class B(object):
178 pass 188 pass
179 a = A() 189 a = A()
180 a.a = a 190 a.a = a
181 id_a = id(a) 191 id_a = id(a)
182 b = B() 192 b = B()
183 b.b = b 193 b.b = b
184 gc.collect() 194 gc.collect()
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 # the callback materialized a strong reference to an instance, but gc 573 # the callback materialized a strong reference to an instance, but gc
564 # cleared the instance's dict anyway. 574 # cleared the instance's dict anyway.
565 Cs = None 575 Cs = None
566 gc.collect() 576 gc.collect()
567 self.assertEqual(len(ouch), 2) # else the callbacks didn't run 577 self.assertEqual(len(ouch), 2) # else the callbacks didn't run
568 for x in ouch: 578 for x in ouch:
569 # If the callback resurrected one of these guys, the instance 579 # If the callback resurrected one of these guys, the instance
570 # would be damaged, with an empty __dict__. 580 # would be damaged, with an empty __dict__.
571 self.assertEqual(x, None) 581 self.assertEqual(x, None)
572 582
583 @cpython_only
573 def test_garbage_at_shutdown(self): 584 def test_garbage_at_shutdown(self):
574 import subprocess 585 import subprocess
575 code = """if 1: 586 code = """if 1:
576 import gc 587 import gc
577 import _testcapi 588 import _testcapi
578 @_testcapi.with_tp_del 589 @_testcapi.with_tp_del
579 class X: 590 class X:
580 def __init__(self, name): 591 def __init__(self, name):
581 self.name = name 592 self.name = name
582 def __repr__(self): 593 def __repr__(self):
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 self.assertIn("collected", info) 768 self.assertIn("collected", info)
758 self.assertIn("uncollectable", info) 769 self.assertIn("uncollectable", info)
759 770
760 def test_collect_generation(self): 771 def test_collect_generation(self):
761 self.preclean() 772 self.preclean()
762 gc.collect(2) 773 gc.collect(2)
763 for v in self.visit: 774 for v in self.visit:
764 info = v[2] 775 info = v[2]
765 self.assertEqual(info["generation"], 2) 776 self.assertEqual(info["generation"], 2)
766 777
778 @cpython_only
767 def test_collect_garbage(self): 779 def test_collect_garbage(self):
768 self.preclean() 780 self.preclean()
769 # Each of these cause four objects to be garbage: Two 781 # Each of these cause four objects to be garbage: Two
770 # Uncolectables and their instance dicts. 782 # Uncolectables and their instance dicts.
771 Uncollectable() 783 Uncollectable()
772 Uncollectable() 784 Uncollectable()
773 C1055820(666) 785 C1055820(666)
774 gc.collect() 786 gc.collect()
775 for v in self.visit: 787 for v in self.visit:
776 if v[1] != "stop": 788 if v[1] != "stop":
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 if verbose: 972 if verbose:
961 print("restoring automatic collection") 973 print("restoring automatic collection")
962 # make sure to always test gc.enable() 974 # make sure to always test gc.enable()
963 gc.enable() 975 gc.enable()
964 assert gc.isenabled() 976 assert gc.isenabled()
965 if not enabled: 977 if not enabled:
966 gc.disable() 978 gc.disable()
967 979
968 if __name__ == "__main__": 980 if __name__ == "__main__":
969 test_main() 981 test_main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+