blob: a468575d4498497125de4151a721da55412bd502 [file] [log] [blame]
Fred Drake41deb1e2001-02-01 05:27:45 +00001import sys
2import weakref
3
4from test_support import TestFailed, verify
5
6
7class C:
8 pass
9
10
11print "Basic Weak References"
12
13print "-- Liveness and referent identity"
14
15o = C()
16ref = weakref.ref(o)
17verify(ref() is not None, "weak reference to live object should be live")
18o2 = ref()
19verify(ref() is not None, "weak ref should still be live")
20verify(o is o2, "<ref>() should return original object if live")
21del o, o2
22del ref
23
24cbcalled = 0
25def callback(o):
26 global cbcalled
27 cbcalled = 1
28
29o = C()
30ref2 = weakref.ref(o, callback)
31del o
32verify(cbcalled,
33 "callback did not properly set 'cbcalled'")
34verify(ref2() is None,
35 "ref2 should be dead after deleting object reference")
36del ref2
37
38
39print "-- Reference objects with callbacks"
40o = C()
41o.bar = 1
42ref1 = weakref.ref(o, id)
43ref2 = weakref.ref(o, id)
44del o
45verify(ref1() is None,
46 "expected reference to be invalidated")
47verify(ref2() is None,
48 "expected reference to be invalidated")
49
50
51print "-- Proxy objects with callbacks"
52o = C()
53o.bar = 1
54ref1 = weakref.proxy(o, id)
55ref2 = weakref.proxy(o, id)
56del o
57try:
58 ref1.bar
59except weakref.ReferenceError:
60 pass
61else:
62 raise TestFailed("expected ReferenceError exception")
63try:
64 ref2.bar
65except weakref.ReferenceError:
66 pass
67else:
68 raise TestFailed("expected ReferenceError exception")
69
70
71print "-- Re-use of weak reference objects"
72print " reference objects"
73
74o = C()
75ref1 = 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
78proxy = weakref.proxy(o)
79ref2 = weakref.ref(o)
80verify(ref1 is ref2,
81 "reference object w/out callback should have been re-used")
82
83o = C()
84proxy = weakref.proxy(o)
85ref1 = weakref.ref(o)
86ref2 = weakref.ref(o)
87verify(ref1 is ref2,
88 "reference object w/out callback should have been re-used")
89verify(weakref.getweakrefcount(o) == 2,
90 "wrong weak ref count for object")
91del proxy
92verify(weakref.getweakrefcount(o) == 1,
93 "wrong weak ref count for object after deleting proxy")
94
95print " proxy objects"
96
97o = C()
98ref3 = weakref.proxy(o)
99ref4 = weakref.proxy(o)
100verify(ref3 is ref4,
101 "proxy object w/out callback should have been re-used")
102
103
104def clearing1(r):
105 print "clearing ref 1"
106
107def clearing2(r):
108 print "clearing ref 2"
109
110o = C()
111ref1 = weakref.ref(o, clearing1)
112ref2 = weakref.ref(o, clearing2)
113verify(weakref.getweakrefcount(o) == 2,
114 "got wrong number of weak reference objects")
115del o
116
117o = C()
118ref1 = weakref.ref(o, clearing1)
119ref2 = weakref.ref(o, clearing2)
120del ref1
121verify(weakref.getweakrefs(o) == [ref2],
122 "list of refs does not match")
123del o
124
125o = C()
126ref1 = weakref.ref(o, clearing1)
127ref2 = weakref.ref(o, clearing2)
128del ref2
129verify(weakref.getweakrefs(o) == [ref1],
130 "list of refs does not match")
131del o
132
133print
134print "Weak Valued Dictionaries"
135
136class Object:
137 def __init__(self, arg):
138 self.arg = arg
139 def __repr__(self):
140 return "<Object %r>" % self.arg
141
142dict = weakref.mapping()
143objects = map(Object, range(10))
144for o in objects:
145 dict[o.arg] = o
146print "objects are stored in weak dict"
147for 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!")
Fred Drake5c015342001-03-01 03:06:53 +0000152items1 = dict.items()
153items2 = dict.copy().items()
154items1.sort()
155items2.sort()
156verify(items1 == items2,
157 "cloning of weak-valued dictionary did not work!")
158del items1, items2
Fred Drake41deb1e2001-02-01 05:27:45 +0000159dict.clear()
160print "weak dict test complete"
161
162print
Martin v. Löwis5e163332001-02-27 18:36:56 +0000163print "Weak Keyed Dictionaries"
164
165dict = weakref.mapping(weakkeys=1)
166objects = map(Object, range(10))
167for o in objects:
168 dict[o] = o.arg
169print "objects are stored in weak dict"
170for 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!")
Fred Drake5c015342001-03-01 03:06:53 +0000175items1 = dict.items()
176items2 = dict.copy().items()
177items1.sort()
178items2.sort()
179verify(items1 == items2,
180 "cloning of weak-keyed dictionary did not work!")
181del items1, items2
182del objects, o
Martin v. Löwis5e163332001-02-27 18:36:56 +0000183verify(len(dict)==0, "deleting the keys did not clear the dictionary")
184print "weak key dict test complete"
185
186
187print
Fred Drake41deb1e2001-02-01 05:27:45 +0000188print "Non-callable Proxy References"
189print "XXX -- tests not written!"
190
191
192def 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")
202
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")
212
213
214o = C()
215test_proxy(o, weakref.proxy(o))
216
217print
218print "Callable Proxy References"
219
220class Callable:
221 bar = None
222 def __call__(self, x):
223 self.bar = x
224
225o = Callable()
226ref1 = weakref.proxy(o)
227
228test_proxy(o, ref1)
229
230verify(type(ref1) is weakref.CallableProxyType,
231 "proxy is not of callable type")
232ref1('twinkies!')
233verify(o.bar == 'twinkies!',
234 "call through proxy not passed through to original")
235
236try:
237 ref1()
238except TypeError:
239 # expect due to too few args
240 pass
241else:
242 raise TestFailed("did not catch expected TypeError -- too few args")
243
244try:
245 ref1(1, 2, 3)
246except TypeError:
247 # expect due to too many args
248 pass
249else:
250 raise TestFailed("did not catch expected TypeError -- too many args")