6 from test
import test_support
17 def __call__(self
, x
):
21 def create_function():
25 def create_bound_method():
28 def create_unbound_method():
32 class TestBase(unittest
.TestCase
):
37 def callback(self
, ref
):
41 class ReferencesTestCase(TestBase
):
43 def test_basic_ref(self
):
44 self
.check_basic_ref(C
)
45 self
.check_basic_ref(create_function
)
46 self
.check_basic_ref(create_bound_method
)
47 self
.check_basic_ref(create_unbound_method
)
49 # Just make sure the tp_repr handler doesn't raise an exception.
58 def test_basic_callback(self
):
59 self
.check_basic_callback(C
)
60 self
.check_basic_callback(create_function
)
61 self
.check_basic_callback(create_bound_method
)
62 self
.check_basic_callback(create_unbound_method
)
64 def test_multiple_callbacks(self
):
66 ref1
= weakref
.ref(o
, self
.callback
)
67 ref2
= weakref
.ref(o
, self
.callback
)
69 self
.assert_(ref1() is None,
70 "expected reference to be invalidated")
71 self
.assert_(ref2() is None,
72 "expected reference to be invalidated")
73 self
.assert_(self
.cbcalled
== 2,
74 "callback not called the right number of times")
76 def test_multiple_selfref_callbacks(self
):
77 # Make sure all references are invalidated before callbacks are called
79 # What's important here is that we're using the first
80 # reference in the callback invoked on the second reference
81 # (the most recently created ref is cleaned up first). This
82 # tests that all references to the object are invalidated
83 # before any of the callbacks are invoked, so that we only
84 # have one invocation of _weakref.c:cleanup_helper() active
85 # for a particular object at a time.
87 def callback(object, self
=self
):
90 self
.ref
= weakref
.ref(c
, callback
)
91 ref1
= weakref
.ref(c
, callback
)
94 def test_proxy_ref(self
):
97 ref1
= weakref
.proxy(o
, self
.callback
)
98 ref2
= weakref
.proxy(o
, self
.callback
)
104 self
.assertRaises(weakref
.ReferenceError, check
, ref1
)
105 self
.assertRaises(weakref
.ReferenceError, check
, ref2
)
106 self
.assert_(self
.cbcalled
== 2)
108 def check_basic_ref(self
, factory
):
111 self
.assert_(ref() is not None,
112 "weak reference to live object should be live")
114 self
.assert_(o
is o2
,
115 "<ref>() should return original object if live")
117 def check_basic_callback(self
, factory
):
120 ref
= weakref
.ref(o
, self
.callback
)
122 self
.assert_(self
.cbcalled
== 1,
123 "callback did not properly set 'cbcalled'")
124 self
.assert_(ref() is None,
125 "ref2 should be dead after deleting object reference")
127 def test_ref_reuse(self
):
129 ref1
= weakref
.ref(o
)
130 # create a proxy to make sure that there's an intervening creation
131 # between these two; it should make no difference
132 proxy
= weakref
.proxy(o
)
133 ref2
= weakref
.ref(o
)
134 self
.assert_(ref1
is ref2
,
135 "reference object w/out callback should be re-used")
138 proxy
= weakref
.proxy(o
)
139 ref1
= weakref
.ref(o
)
140 ref2
= weakref
.ref(o
)
141 self
.assert_(ref1
is ref2
,
142 "reference object w/out callback should be re-used")
143 self
.assert_(weakref
.getweakrefcount(o
) == 2,
144 "wrong weak ref count for object")
146 self
.assert_(weakref
.getweakrefcount(o
) == 1,
147 "wrong weak ref count for object after deleting proxy")
149 def test_proxy_reuse(self
):
151 proxy1
= weakref
.proxy(o
)
153 proxy2
= weakref
.proxy(o
)
154 self
.assert_(proxy1
is proxy2
,
155 "proxy object w/out callback should have been re-used")
157 def test_basic_proxy(self
):
159 self
.check_proxy(o
, weakref
.proxy(o
))
161 L
= UserList
.UserList()
163 self
.failIf(p
, "proxy for empty UserList should be false")
165 self
.assertEqual(len(L
), 1)
166 self
.failUnless(p
, "proxy for non-empty UserList should be true")
168 self
.assertEqual(len(L
), 2)
169 self
.assertEqual(len(p
), 2)
170 self
.failUnless(3 in p
, "proxy didn't support __contains__() properly")
172 self
.assertEqual(L
[1], 5)
173 self
.assertEqual(p
[1], 5)
174 L2
= UserList
.UserList(L
)
175 p2
= weakref
.proxy(L2
)
176 self
.assertEqual(p
, p2
)
177 ## self.assertEqual(`L2`, `p2`)
178 L3
= UserList
.UserList(range(10))
179 p3
= weakref
.proxy(L3
)
180 self
.assertEqual(L3
[:], p3
[:])
181 self
.assertEqual(L3
[5:], p3
[5:])
182 self
.assertEqual(L3
[:5], p3
[:5])
183 self
.assertEqual(L3
[2:5], p3
[2:5])
185 def test_callable_proxy(self
):
187 ref1
= weakref
.proxy(o
)
189 self
.check_proxy(o
, ref1
)
191 self
.assert_(type(ref1
) is weakref
.CallableProxyType
,
192 "proxy is not of callable type")
194 self
.assert_(o
.bar
== 'twinkies!',
195 "call through proxy not passed through to original")
197 self
.assert_(o
.bar
== 'Splat.',
198 "call through proxy not passed through to original")
200 # expect due to too few args
201 self
.assertRaises(TypeError, ref1
)
203 # expect due to too many args
204 self
.assertRaises(TypeError, ref1
, 1, 2, 3)
206 def check_proxy(self
, o
, proxy
):
208 self
.assert_(proxy
.foo
== 1,
209 "proxy does not reflect attribute addition")
211 self
.assert_(proxy
.foo
== 2,
212 "proxy does not reflect attribute modification")
214 self
.assert_(not hasattr(proxy
, 'foo'),
215 "proxy does not reflect attribute removal")
218 self
.assert_(o
.foo
== 1,
219 "object does not reflect attribute addition via proxy")
223 "object does not reflect attribute modification via proxy")
225 self
.assert_(not hasattr(o
, 'foo'),
226 "object does not reflect attribute removal via proxy")
228 def test_getweakrefcount(self
):
230 ref1
= weakref
.ref(o
)
231 ref2
= weakref
.ref(o
, self
.callback
)
232 self
.assert_(weakref
.getweakrefcount(o
) == 2,
233 "got wrong number of weak reference objects")
235 proxy1
= weakref
.proxy(o
)
236 proxy2
= weakref
.proxy(o
, self
.callback
)
237 self
.assert_(weakref
.getweakrefcount(o
) == 4,
238 "got wrong number of weak reference objects")
240 def test_getweakrefs(self
):
242 ref1
= weakref
.ref(o
, self
.callback
)
243 ref2
= weakref
.ref(o
, self
.callback
)
245 self
.assert_(weakref
.getweakrefs(o
) == [ref2
],
246 "list of refs does not match")
249 ref1
= weakref
.ref(o
, self
.callback
)
250 ref2
= weakref
.ref(o
, self
.callback
)
252 self
.assert_(weakref
.getweakrefs(o
) == [ref1
],
253 "list of refs does not match")
255 def test_newstyle_number_ops(self
):
260 self
.assert_(p
+ 1.0 == 3.0)
261 self
.assert_(1.0 + p
== 3.0) # this used to SEGV
263 def test_callbacks_protected(self
):
264 # Callbacks protected from already-set exceptions?
265 # Regression test for SF bug #478534.
266 class BogusError(Exception):
273 data
[weakref
.ref(f
, remove
)] = None
280 self
.fail("exception not properly restored")
286 self
.fail("exception not properly restored")
290 def __init__(self
, arg
):
293 return "<Object %r>" % self
.arg
296 class MappingTestCase(TestBase
):
300 def test_weak_values(self
):
302 # This exercises d.copy(), d.items(), d[], del d[], len(d).
304 dict, objects
= self
.make_weak_valued_dict()
306 self
.assert_(weakref
.getweakrefcount(o
) == 1,
307 "wrong number of weak references to %r!" % o
)
308 self
.assert_(o
is dict[o
.arg
],
309 "wrong object returned by weak dict!")
310 items1
= dict.items()
311 items2
= dict.copy().items()
314 self
.assert_(items1
== items2
,
315 "cloning of weak-valued dictionary did not work!")
317 self
.assert_(len(dict) == self
.COUNT
)
319 self
.assert_(len(dict) == (self
.COUNT
- 1),
320 "deleting object did not cause dictionary update")
322 self
.assert_(len(dict) == 0,
323 "deleting the values did not clear the dictionary")
324 # regression on SF bug #447152:
325 dict = weakref
.WeakValueDictionary()
326 self
.assertRaises(KeyError, dict.__getitem
__, 1)
328 self
.assertRaises(KeyError, dict.__getitem
__, 2)
330 def test_weak_keys(self
):
332 # This exercises d.copy(), d.items(), d[] = v, d[], del d[],
333 # len(d), d.has_key().
335 dict, objects
= self
.make_weak_keyed_dict()
337 self
.assert_(weakref
.getweakrefcount(o
) == 1,
338 "wrong number of weak references to %r!" % o
)
339 self
.assert_(o
.arg
is dict[o
],
340 "wrong object returned by weak dict!")
341 items1
= dict.items()
342 items2
= dict.copy().items()
345 self
.assert_(items1
== items2
,
346 "cloning of weak-keyed dictionary did not work!")
348 self
.assert_(len(dict) == self
.COUNT
)
350 self
.assert_(len(dict) == (self
.COUNT
- 1),
351 "deleting object did not cause dictionary update")
353 self
.assert_(len(dict) == 0,
354 "deleting the keys did not clear the dictionary")
356 dict[o
] = "What is the meaning of the universe?"
357 self
.assert_(dict.has_key(o
))
358 self
.assert_(not dict.has_key(34))
360 def test_weak_keyed_iters(self
):
361 dict, objects
= self
.make_weak_keyed_dict()
362 self
.check_iters(dict)
364 def test_weak_valued_iters(self
):
365 dict, objects
= self
.make_weak_valued_dict()
366 self
.check_iters(dict)
368 def check_iters(self
, dict):
371 for item
in dict.iteritems():
373 self
.assert_(len(items
) == 0, "iteritems() did not touch all items")
375 # key iterator, via __iter__():
379 self
.assert_(len(keys
) == 0, "__iter__() did not touch all keys")
381 # key iterator, via iterkeys():
383 for k
in dict.iterkeys():
385 self
.assert_(len(keys
) == 0, "iterkeys() did not touch all keys")
388 values
= dict.values()
389 for v
in dict.itervalues():
391 self
.assert_(len(values
) == 0, "itervalues() did not touch all values")
393 def test_make_weak_keyed_dict_from_dict(self
):
395 dict = weakref
.WeakKeyDictionary({o
:364})
396 self
.assert_(dict[o
] == 364)
398 def test_make_weak_keyed_dict_from_weak_keyed_dict(self
):
400 dict = weakref
.WeakKeyDictionary({o
:364})
401 dict2
= weakref
.WeakKeyDictionary(dict)
402 self
.assert_(dict[o
] == 364)
404 def make_weak_keyed_dict(self
):
405 dict = weakref
.WeakKeyDictionary()
406 objects
= map(Object
, range(self
.COUNT
))
411 def make_weak_valued_dict(self
):
412 dict = weakref
.WeakValueDictionary()
413 objects
= map(Object
, range(self
.COUNT
))
418 def check_popitem(self
, klass
, key1
, value1
, key2
, value2
):
420 weakdict
[key1
] = value1
421 weakdict
[key2
] = value2
422 self
.assert_(len(weakdict
) == 2)
423 k
, v
= weakdict
.popitem()
424 self
.assert_(len(weakdict
) == 1)
426 self
.assert_(v
is value1
)
428 self
.assert_(v
is value2
)
429 k
, v
= weakdict
.popitem()
430 self
.assert_(len(weakdict
) == 0)
432 self
.assert_(v
is value1
)
434 self
.assert_(v
is value2
)
436 def test_weak_valued_dict_popitem(self
):
437 self
.check_popitem(weakref
.WeakValueDictionary
,
438 "key1", C(), "key2", C())
440 def test_weak_keyed_dict_popitem(self
):
441 self
.check_popitem(weakref
.WeakKeyDictionary
,
442 C(), "value 1", C(), "value 2")
444 def check_setdefault(self
, klass
, key
, value1
, value2
):
445 self
.assert_(value1
is not value2
,
447 " -- value parameters must be distinct objects")
449 o
= weakdict
.setdefault(key
, value1
)
450 self
.assert_(o
is value1
)
451 self
.assert_(weakdict
.has_key(key
))
452 self
.assert_(weakdict
.get(key
) is value1
)
453 self
.assert_(weakdict
[key
] is value1
)
455 o
= weakdict
.setdefault(key
, value2
)
456 self
.assert_(o
is value1
)
457 self
.assert_(weakdict
.has_key(key
))
458 self
.assert_(weakdict
.get(key
) is value1
)
459 self
.assert_(weakdict
[key
] is value1
)
461 def test_weak_valued_dict_setdefault(self
):
462 self
.check_setdefault(weakref
.WeakValueDictionary
,
465 def test_weak_keyed_dict_setdefault(self
):
466 self
.check_setdefault(weakref
.WeakKeyDictionary
,
467 C(), "value 1", "value 2")
469 def check_update(self
, klass
, dict):
471 # This exercises d.update(), len(d), d.keys(), d.has_key(),
475 weakdict
.update(dict)
476 self
.assert_(len(weakdict
) == len(dict))
477 for k
in weakdict
.keys():
478 self
.assert_(dict.has_key(k
),
479 "mysterious new key appeared in weak dict")
481 self
.assert_(v
is weakdict
[k
])
482 self
.assert_(v
is weakdict
.get(k
))
483 for k
in dict.keys():
484 self
.assert_(weakdict
.has_key(k
),
485 "original key disappeared in weak dict")
487 self
.assert_(v
is weakdict
[k
])
488 self
.assert_(v
is weakdict
.get(k
))
490 def test_weak_valued_dict_update(self
):
491 self
.check_update(weakref
.WeakValueDictionary
,
492 {1: C(), 'a': C(), C(): C()})
494 def test_weak_keyed_dict_update(self
):
495 self
.check_update(weakref
.WeakKeyDictionary
,
496 {C(): 1, C(): 2, C(): 3})
498 def test_weak_keyed_delitem(self
):
499 d
= weakref
.WeakKeyDictionary()
504 self
.assert_(len(d
) == 2)
506 self
.assert_(len(d
) == 1)
507 self
.assert_(d
.keys() == [o2
])
509 def test_weak_valued_delitem(self
):
510 d
= weakref
.WeakValueDictionary()
514 d
['something else'] = o2
515 self
.assert_(len(d
) == 2)
517 self
.assert_(len(d
) == 1)
518 self
.assert_(d
.items() == [('something else', o2
)])
520 from test_userdict
import TestMappingProtocol
522 class WeakValueDictionaryTestCase(TestMappingProtocol
):
523 """Check that WeakValueDictionary class conforms to the mapping protocol"""
524 __ref
= {"key1":Object(1), "key2":Object(2), "key3":Object(3)}
525 _tested_class
= weakref
.WeakValueDictionary
526 def _reference(self
):
527 return self
.__ref
.copy()
529 class WeakKeyDictionaryTestCase(TestMappingProtocol
):
530 """Check that WeakKeyDictionary class conforms to the mapping protocol"""
531 __ref
= {Object("key1"):1, Object("key2"):2, Object("key3"):3}
532 _tested_class
= weakref
.WeakKeyDictionary
533 def _reference(self
):
534 return self
.__ref
.copy()
537 suite
= unittest
.TestSuite()
538 suite
.addTest(unittest
.makeSuite(ReferencesTestCase
))
539 suite
.addTest(unittest
.makeSuite(MappingTestCase
))
540 suite
.addTest(unittest
.makeSuite(WeakValueDictionaryTestCase
))
541 suite
.addTest(unittest
.makeSuite(WeakKeyDictionaryTestCase
))
542 test_support
.run_suite(suite
)
545 if __name__
== "__main__":