Files for 2.1b1 distribution.
[python/dscho.git] / Lib / test / test_gc.py
blob1c008bee00d8341b0384fba14c0697628130bb66
1 from test_support import verify, verbose, TestFailed
2 import gc
4 def run_test(name, thunk):
5 if verbose:
6 print "testing %s..." % name,
7 try:
8 thunk()
9 except TestFailed:
10 if verbose:
11 print "failed (expected %s but got %s)" % (result,
12 test_result)
13 raise TestFailed, name
14 else:
15 if verbose:
16 print "ok"
18 def test_list():
19 l = []
20 l.append(l)
21 gc.collect()
22 del l
23 if gc.collect() != 1:
24 raise TestFailed
26 def test_dict():
27 d = {}
28 d[1] = d
29 gc.collect()
30 del d
31 if gc.collect() != 1:
32 raise TestFailed
34 def test_tuple():
35 # since tuples are immutable we close the loop with a list
36 l = []
37 t = (l,)
38 l.append(t)
39 gc.collect()
40 del t
41 del l
42 if gc.collect() != 2:
43 raise TestFailed
45 def test_class():
46 class A:
47 pass
48 A.a = A
49 gc.collect()
50 del A
51 if gc.collect() == 0:
52 raise TestFailed
54 def test_instance():
55 class A:
56 pass
57 a = A()
58 a.a = a
59 gc.collect()
60 del a
61 if gc.collect() == 0:
62 raise TestFailed
64 def test_method():
65 # Tricky: self.__init__ is a bound method, it references the instance.
66 class A:
67 def __init__(self):
68 self.init = self.__init__
69 a = A()
70 gc.collect()
71 del a
72 if gc.collect() == 0:
73 raise TestFailed
75 def test_finalizer():
76 # A() is uncollectable if it is part of a cycle, make sure it shows up
77 # in gc.garbage.
78 class A:
79 def __del__(self): pass
80 class B:
81 pass
82 a = A()
83 a.a = a
84 id_a = id(a)
85 b = B()
86 b.b = b
87 gc.collect()
88 del a
89 del b
90 if gc.collect() == 0:
91 raise TestFailed
92 for obj in gc.garbage:
93 if id(obj) == id_a:
94 del obj.a
95 break
96 else:
97 raise TestFailed
98 gc.garbage.remove(obj)
100 def test_function():
101 # Tricky: f -> d -> f, code should call d.clear() after the exec to
102 # break the cycle.
103 d = {}
104 exec("def f(): pass\n") in d
105 gc.collect()
106 del d
107 if gc.collect() != 2:
108 raise TestFailed
110 def test_saveall():
111 # Verify that cyclic garbage like lists show up in gc.garbage if the
112 # SAVEALL option is enabled.
113 debug = gc.get_debug()
114 gc.set_debug(debug | gc.DEBUG_SAVEALL)
115 l = []
116 l.append(l)
117 id_l = id(l)
118 del l
119 gc.collect()
120 try:
121 for obj in gc.garbage:
122 if id(obj) == id_l:
123 del obj[:]
124 break
125 else:
126 raise TestFailed
127 gc.garbage.remove(obj)
128 finally:
129 gc.set_debug(debug)
131 def test_del():
132 # __del__ methods can trigger collection, make this to happen
133 thresholds = gc.get_threshold()
134 gc.enable()
135 gc.set_threshold(1)
137 class A:
138 def __del__(self):
139 dir(self)
140 a = A()
141 del a
143 gc.disable()
144 apply(gc.set_threshold, thresholds)
147 def test_all():
148 run_test("lists", test_list)
149 run_test("dicts", test_dict)
150 run_test("tuples", test_tuple)
151 run_test("classes", test_class)
152 run_test("instances", test_instance)
153 run_test("methods", test_method)
154 run_test("functions", test_function)
155 run_test("finalizers", test_finalizer)
156 run_test("__del__", test_del)
157 run_test("saveall", test_saveall)
159 def test():
160 if verbose:
161 print "disabling automatic collection"
162 enabled = gc.isenabled()
163 gc.disable()
164 verify(not gc.isenabled() )
165 debug = gc.get_debug()
166 gc.set_debug(debug & ~gc.DEBUG_LEAK) # this test is supposed to leak
168 try:
169 test_all()
170 finally:
171 gc.set_debug(debug)
172 # test gc.enable() even if GC is disabled by default
173 if verbose:
174 print "restoring automatic collection"
175 # make sure to always test gc.enable()
176 gc.enable()
177 verify(gc.isenabled())
178 if not enabled:
179 gc.disable()
182 test()