Files for 2.1b1 distribution.
[python/dscho.git] / Lib / test / test_weakref.py
bloba468575d4498497125de4151a721da55412bd502
1 import sys
2 import weakref
4 from test_support import TestFailed, verify
7 class C:
8 pass
11 print "Basic Weak References"
13 print "-- Liveness and referent identity"
15 o = C()
16 ref = weakref.ref(o)
17 verify(ref() is not None, "weak reference to live object should be live")
18 o2 = ref()
19 verify(ref() is not None, "weak ref should still be live")
20 verify(o is o2, "<ref>() should return original object if live")
21 del o, o2
22 del ref
24 cbcalled = 0
25 def callback(o):
26 global cbcalled
27 cbcalled = 1
29 o = C()
30 ref2 = weakref.ref(o, callback)
31 del o
32 verify(cbcalled,
33 "callback did not properly set 'cbcalled'")
34 verify(ref2() is None,
35 "ref2 should be dead after deleting object reference")
36 del ref2
39 print "-- Reference objects with callbacks"
40 o = C()
41 o.bar = 1
42 ref1 = weakref.ref(o, id)
43 ref2 = weakref.ref(o, id)
44 del o
45 verify(ref1() is None,
46 "expected reference to be invalidated")
47 verify(ref2() is None,
48 "expected reference to be invalidated")
51 print "-- Proxy objects with callbacks"
52 o = C()
53 o.bar = 1
54 ref1 = weakref.proxy(o, id)
55 ref2 = weakref.proxy(o, id)
56 del o
57 try:
58 ref1.bar
59 except weakref.ReferenceError:
60 pass
61 else:
62 raise TestFailed("expected ReferenceError exception")
63 try:
64 ref2.bar
65 except weakref.ReferenceError:
66 pass
67 else:
68 raise TestFailed("expected ReferenceError exception")
71 print "-- Re-use of weak reference objects"
72 print " reference objects"
74 o = C()
75 ref1 = weakref.ref(o)
76 # create a proxy to make sure that there's an intervening creation
77 # between these two; it should make no difference
78 proxy = weakref.proxy(o)
79 ref2 = weakref.ref(o)
80 verify(ref1 is ref2,
81 "reference object w/out callback should have been re-used")
83 o = C()
84 proxy = weakref.proxy(o)
85 ref1 = weakref.ref(o)
86 ref2 = weakref.ref(o)
87 verify(ref1 is ref2,
88 "reference object w/out callback should have been re-used")
89 verify(weakref.getweakrefcount(o) == 2,
90 "wrong weak ref count for object")
91 del proxy
92 verify(weakref.getweakrefcount(o) == 1,
93 "wrong weak ref count for object after deleting proxy")
95 print " proxy objects"
97 o = C()
98 ref3 = weakref.proxy(o)
99 ref4 = weakref.proxy(o)
100 verify(ref3 is ref4,
101 "proxy object w/out callback should have been re-used")
104 def clearing1(r):
105 print "clearing ref 1"
107 def clearing2(r):
108 print "clearing ref 2"
110 o = C()
111 ref1 = weakref.ref(o, clearing1)
112 ref2 = weakref.ref(o, clearing2)
113 verify(weakref.getweakrefcount(o) == 2,
114 "got wrong number of weak reference objects")
115 del o
117 o = C()
118 ref1 = weakref.ref(o, clearing1)
119 ref2 = weakref.ref(o, clearing2)
120 del ref1
121 verify(weakref.getweakrefs(o) == [ref2],
122 "list of refs does not match")
123 del o
125 o = C()
126 ref1 = weakref.ref(o, clearing1)
127 ref2 = weakref.ref(o, clearing2)
128 del ref2
129 verify(weakref.getweakrefs(o) == [ref1],
130 "list of refs does not match")
131 del o
133 print
134 print "Weak Valued Dictionaries"
136 class Object:
137 def __init__(self, arg):
138 self.arg = arg
139 def __repr__(self):
140 return "<Object %r>" % self.arg
142 dict = weakref.mapping()
143 objects = map(Object, range(10))
144 for o in objects:
145 dict[o.arg] = o
146 print "objects are stored in weak dict"
147 for o in objects:
148 verify(weakref.getweakrefcount(o) == 1,
149 "wrong number of weak references to %r!" % o)
150 verify(o is dict[o.arg],
151 "wrong object returned by weak dict!")
152 items1 = dict.items()
153 items2 = dict.copy().items()
154 items1.sort()
155 items2.sort()
156 verify(items1 == items2,
157 "cloning of weak-valued dictionary did not work!")
158 del items1, items2
159 dict.clear()
160 print "weak dict test complete"
162 print
163 print "Weak Keyed Dictionaries"
165 dict = weakref.mapping(weakkeys=1)
166 objects = map(Object, range(10))
167 for o in objects:
168 dict[o] = o.arg
169 print "objects are stored in weak dict"
170 for o in objects:
171 verify(weakref.getweakrefcount(o) == 1,
172 "wrong number of weak references to %r!" % o)
173 verify(o.arg is dict[o],
174 "wrong object returned by weak dict!")
175 items1 = dict.items()
176 items2 = dict.copy().items()
177 items1.sort()
178 items2.sort()
179 verify(items1 == items2,
180 "cloning of weak-keyed dictionary did not work!")
181 del items1, items2
182 del objects, o
183 verify(len(dict)==0, "deleting the keys did not clear the dictionary")
184 print "weak key dict test complete"
187 print
188 print "Non-callable Proxy References"
189 print "XXX -- tests not written!"
192 def test_proxy(o, proxy):
193 o.foo = 1
194 verify(proxy.foo == 1,
195 "proxy does not reflect attribute addition")
196 o.foo = 2
197 verify(proxy.foo == 2,
198 "proxy does not reflect attribute modification")
199 del o.foo
200 verify(not hasattr(proxy, 'foo'),
201 "proxy does not reflect attribute removal")
203 proxy.foo = 1
204 verify(o.foo == 1,
205 "object does not reflect attribute addition via proxy")
206 proxy.foo = 2
207 verify(o.foo == 2,
208 "object does not reflect attribute modification via proxy")
209 del proxy.foo
210 verify(not hasattr(o, 'foo'),
211 "object does not reflect attribute removal via proxy")
214 o = C()
215 test_proxy(o, weakref.proxy(o))
217 print
218 print "Callable Proxy References"
220 class Callable:
221 bar = None
222 def __call__(self, x):
223 self.bar = x
225 o = Callable()
226 ref1 = weakref.proxy(o)
228 test_proxy(o, ref1)
230 verify(type(ref1) is weakref.CallableProxyType,
231 "proxy is not of callable type")
232 ref1('twinkies!')
233 verify(o.bar == 'twinkies!',
234 "call through proxy not passed through to original")
236 try:
237 ref1()
238 except TypeError:
239 # expect due to too few args
240 pass
241 else:
242 raise TestFailed("did not catch expected TypeError -- too few args")
244 try:
245 ref1(1, 2, 3)
246 except TypeError:
247 # expect due to too many args
248 pass
249 else:
250 raise TestFailed("did not catch expected TypeError -- too many args")