summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_weakref.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_weakref.py')
-rw-r--r--Lib/test/test_weakref.py488
1 files changed, 252 insertions, 236 deletions
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index a468575..1e193f1 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -1,137 +1,202 @@
import sys
+import unittest
import weakref
-from test_support import TestFailed, verify
+from test_support import run_unittest, verify
class C:
- pass
-
-
-print "Basic Weak References"
-
-print "-- Liveness and referent identity"
-
-o = C()
-ref = weakref.ref(o)
-verify(ref() is not None, "weak reference to live object should be live")
-o2 = ref()
-verify(ref() is not None, "weak ref should still be live")
-verify(o is o2, "<ref>() should return original object if live")
-del o, o2
-del ref
-
-cbcalled = 0
-def callback(o):
- global cbcalled
- cbcalled = 1
-
-o = C()
-ref2 = weakref.ref(o, callback)
-del o
-verify(cbcalled,
- "callback did not properly set 'cbcalled'")
-verify(ref2() is None,
- "ref2 should be dead after deleting object reference")
-del ref2
-
-
-print "-- Reference objects with callbacks"
-o = C()
-o.bar = 1
-ref1 = weakref.ref(o, id)
-ref2 = weakref.ref(o, id)
-del o
-verify(ref1() is None,
- "expected reference to be invalidated")
-verify(ref2() is None,
- "expected reference to be invalidated")
-
-
-print "-- Proxy objects with callbacks"
-o = C()
-o.bar = 1
-ref1 = weakref.proxy(o, id)
-ref2 = weakref.proxy(o, id)
-del o
-try:
- ref1.bar
-except weakref.ReferenceError:
- pass
-else:
- raise TestFailed("expected ReferenceError exception")
-try:
- ref2.bar
-except weakref.ReferenceError:
- pass
-else:
- raise TestFailed("expected ReferenceError exception")
-
-
-print "-- Re-use of weak reference objects"
-print " reference objects"
-
-o = C()
-ref1 = weakref.ref(o)
-# create a proxy to make sure that there's an intervening creation
-# between these two; it should make no difference
-proxy = weakref.proxy(o)
-ref2 = weakref.ref(o)
-verify(ref1 is ref2,
- "reference object w/out callback should have been re-used")
-
-o = C()
-proxy = weakref.proxy(o)
-ref1 = weakref.ref(o)
-ref2 = weakref.ref(o)
-verify(ref1 is ref2,
- "reference object w/out callback should have been re-used")
-verify(weakref.getweakrefcount(o) == 2,
- "wrong weak ref count for object")
-del proxy
-verify(weakref.getweakrefcount(o) == 1,
- "wrong weak ref count for object after deleting proxy")
-
-print " proxy objects"
-
-o = C()
-ref3 = weakref.proxy(o)
-ref4 = weakref.proxy(o)
-verify(ref3 is ref4,
- "proxy object w/out callback should have been re-used")
-
-
-def clearing1(r):
- print "clearing ref 1"
-
-def clearing2(r):
- print "clearing ref 2"
-
-o = C()
-ref1 = weakref.ref(o, clearing1)
-ref2 = weakref.ref(o, clearing2)
-verify(weakref.getweakrefcount(o) == 2,
- "got wrong number of weak reference objects")
-del o
-
-o = C()
-ref1 = weakref.ref(o, clearing1)
-ref2 = weakref.ref(o, clearing2)
-del ref1
-verify(weakref.getweakrefs(o) == [ref2],
- "list of refs does not match")
-del o
-
-o = C()
-ref1 = weakref.ref(o, clearing1)
-ref2 = weakref.ref(o, clearing2)
-del ref2
-verify(weakref.getweakrefs(o) == [ref1],
- "list of refs does not match")
-del o
-
-print
-print "Weak Valued Dictionaries"
+ def method(self):
+ pass
+
+
+class Callable:
+ bar = None
+
+ def __call__(self, x):
+ self.bar = x
+
+
+def create_function():
+ def f(): pass
+ return f
+
+def create_bound_method():
+ return C().method
+
+def create_unbound_method():
+ return C.method
+
+
+class TestBase(unittest.TestCase):
+
+ def setUp(self):
+ self.cbcalled = 0
+
+ def callback(self, ref):
+ self.cbcalled += 1
+
+
+class ReferencesTestCase(TestBase):
+
+ def test_basic_ref(self):
+ self.check_basic_ref(C)
+ self.check_basic_ref(create_function)
+ self.check_basic_ref(create_bound_method)
+ self.check_basic_ref(create_unbound_method)
+
+ def test_basic_callback(self):
+ self.check_basic_callback(C)
+ self.check_basic_callback(create_function)
+ self.check_basic_callback(create_bound_method)
+ self.check_basic_callback(create_unbound_method)
+
+ def test_multiple_callbacks(self):
+ o = C()
+ ref1 = weakref.ref(o, self.callback)
+ ref2 = weakref.ref(o, self.callback)
+ del o
+ self.assert_(ref1() is None,
+ "expected reference to be invalidated")
+ self.assert_(ref2() is None,
+ "expected reference to be invalidated")
+ self.assert_(self.cbcalled == 2,
+ "callback not called the right number of times")
+
+ def test_proxy_ref(self):
+ o = C()
+ o.bar = 1
+ ref1 = weakref.proxy(o, self.callback)
+ ref2 = weakref.proxy(o, self.callback)
+ del o
+
+ def check(proxy):
+ proxy.bar
+
+ self.assertRaises(weakref.ReferenceError, check, ref1)
+ self.assertRaises(weakref.ReferenceError, check, ref2)
+ self.assert_(self.cbcalled == 2)
+
+ def check_basic_ref(self, factory):
+ o = factory()
+ ref = weakref.ref(o)
+ self.assert_(ref() is not None,
+ "weak reference to live object should be live")
+ o2 = ref()
+ self.assert_(o is o2,
+ "<ref>() should return original object if live")
+
+ def check_basic_callback(self, factory):
+ self.cbcalled = 0
+ o = factory()
+ ref = weakref.ref(o, self.callback)
+ del o
+ verify(self.cbcalled == 1,
+ "callback did not properly set 'cbcalled'")
+ verify(ref() is None,
+ "ref2 should be dead after deleting object reference")
+
+ def test_ref_reuse(self):
+ o = C()
+ ref1 = weakref.ref(o)
+ # create a proxy to make sure that there's an intervening creation
+ # between these two; it should make no difference
+ proxy = weakref.proxy(o)
+ ref2 = weakref.ref(o)
+ self.assert_(ref1 is ref2,
+ "reference object w/out callback should be re-used")
+
+ o = C()
+ proxy = weakref.proxy(o)
+ ref1 = weakref.ref(o)
+ ref2 = weakref.ref(o)
+ self.assert_(ref1 is ref2,
+ "reference object w/out callback should be re-used")
+ self.assert_(weakref.getweakrefcount(o) == 2,
+ "wrong weak ref count for object")
+ del proxy
+ self.assert_(weakref.getweakrefcount(o) == 1,
+ "wrong weak ref count for object after deleting proxy")
+
+ def test_proxy_reuse(self):
+ o = C()
+ proxy1 = weakref.proxy(o)
+ ref = weakref.ref(o)
+ proxy2 = weakref.proxy(o)
+ self.assert_(proxy1 is proxy2,
+ "proxy object w/out callback should have been re-used")
+
+ def test_basic_proxy(self):
+ o = C()
+ self.check_proxy(o, weakref.proxy(o))
+
+ def test_callable_proxy(self):
+ o = Callable()
+ ref1 = weakref.proxy(o)
+
+ self.check_proxy(o, ref1)
+
+ self.assert_(type(ref1) is weakref.CallableProxyType,
+ "proxy is not of callable type")
+ ref1('twinkies!')
+ self.assert_(o.bar == 'twinkies!',
+ "call through proxy not passed through to original")
+
+ # expect due to too few args
+ self.assertRaises(TypeError, ref1)
+
+ # expect due to too many args
+ self.assertRaises(TypeError, ref1, 1, 2, 3)
+
+ def check_proxy(self, o, proxy):
+ o.foo = 1
+ self.assert_(proxy.foo == 1,
+ "proxy does not reflect attribute addition")
+ o.foo = 2
+ self.assert_(proxy.foo == 2,
+ "proxy does not reflect attribute modification")
+ del o.foo
+ self.assert_(not hasattr(proxy, 'foo'),
+ "proxy does not reflect attribute removal")
+
+ proxy.foo = 1
+ self.assert_(o.foo == 1,
+ "object does not reflect attribute addition via proxy")
+ proxy.foo = 2
+ self.assert_(
+ o.foo == 2,
+ "object does not reflect attribute modification via proxy")
+ del proxy.foo
+ self.assert_(not hasattr(o, 'foo'),
+ "object does not reflect attribute removal via proxy")
+
+ def test_getweakrefcount(self):
+ o = C()
+ ref1 = weakref.ref(o)
+ ref2 = weakref.ref(o, self.callback)
+ self.assert_(weakref.getweakrefcount(o) == 2,
+ "got wrong number of weak reference objects")
+
+ proxy1 = weakref.proxy(o)
+ proxy2 = weakref.proxy(o, self.callback)
+ self.assert_(weakref.getweakrefcount(o) == 4,
+ "got wrong number of weak reference objects")
+
+ def test_getweakrefs(self):
+ o = C()
+ ref1 = weakref.ref(o, self.callback)
+ ref2 = weakref.ref(o, self.callback)
+ del ref1
+ self.assert_(weakref.getweakrefs(o) == [ref2],
+ "list of refs does not match")
+
+ o = C()
+ ref1 = weakref.ref(o, self.callback)
+ ref2 = weakref.ref(o, self.callback)
+ del ref2
+ self.assert_(weakref.getweakrefs(o) == [ref1],
+ "list of refs does not match")
+
class Object:
def __init__(self, arg):
@@ -139,112 +204,63 @@ class Object:
def __repr__(self):
return "<Object %r>" % self.arg
-dict = weakref.mapping()
-objects = map(Object, range(10))
-for o in objects:
- dict[o.arg] = o
-print "objects are stored in weak dict"
-for o in objects:
- verify(weakref.getweakrefcount(o) == 1,
- "wrong number of weak references to %r!" % o)
- verify(o is dict[o.arg],
- "wrong object returned by weak dict!")
-items1 = dict.items()
-items2 = dict.copy().items()
-items1.sort()
-items2.sort()
-verify(items1 == items2,
- "cloning of weak-valued dictionary did not work!")
-del items1, items2
-dict.clear()
-print "weak dict test complete"
-
-print
-print "Weak Keyed Dictionaries"
-
-dict = weakref.mapping(weakkeys=1)
-objects = map(Object, range(10))
-for o in objects:
- dict[o] = o.arg
-print "objects are stored in weak dict"
-for o in objects:
- verify(weakref.getweakrefcount(o) == 1,
- "wrong number of weak references to %r!" % o)
- verify(o.arg is dict[o],
- "wrong object returned by weak dict!")
-items1 = dict.items()
-items2 = dict.copy().items()
-items1.sort()
-items2.sort()
-verify(items1 == items2,
- "cloning of weak-keyed dictionary did not work!")
-del items1, items2
-del objects, o
-verify(len(dict)==0, "deleting the keys did not clear the dictionary")
-print "weak key dict test complete"
-
-
-print
-print "Non-callable Proxy References"
-print "XXX -- tests not written!"
-
-
-def test_proxy(o, proxy):
- o.foo = 1
- verify(proxy.foo == 1,
- "proxy does not reflect attribute addition")
- o.foo = 2
- verify(proxy.foo == 2,
- "proxy does not reflect attribute modification")
- del o.foo
- verify(not hasattr(proxy, 'foo'),
- "proxy does not reflect attribute removal")
-
- proxy.foo = 1
- verify(o.foo == 1,
- "object does not reflect attribute addition via proxy")
- proxy.foo = 2
- verify(o.foo == 2,
- "object does not reflect attribute modification via proxy")
- del proxy.foo
- verify(not hasattr(o, 'foo'),
- "object does not reflect attribute removal via proxy")
-
-
-o = C()
-test_proxy(o, weakref.proxy(o))
-
-print
-print "Callable Proxy References"
-
-class Callable:
- bar = None
- def __call__(self, x):
- self.bar = x
-o = Callable()
-ref1 = weakref.proxy(o)
-
-test_proxy(o, ref1)
-
-verify(type(ref1) is weakref.CallableProxyType,
- "proxy is not of callable type")
-ref1('twinkies!')
-verify(o.bar == 'twinkies!',
- "call through proxy not passed through to original")
-
-try:
- ref1()
-except TypeError:
- # expect due to too few args
- pass
-else:
- raise TestFailed("did not catch expected TypeError -- too few args")
-
-try:
- ref1(1, 2, 3)
-except TypeError:
- # expect due to too many args
- pass
-else:
- raise TestFailed("did not catch expected TypeError -- too many args")
+class MappingTestCase(TestBase):
+
+ COUNT = 10
+
+ def test_weak_values(self):
+ dict = weakref.mapping()
+ objects = map(Object, range(self.COUNT))
+ for o in objects:
+ dict[o.arg] = o
+
+ for o in objects:
+ self.assert_(weakref.getweakrefcount(o) == 1,
+ "wrong number of weak references to %r!" % o)
+ self.assert_(o is dict[o.arg],
+ "wrong object returned by weak dict!")
+ items1 = dict.items()
+ items2 = dict.copy().items()
+ items1.sort()
+ items2.sort()
+ self.assert_(items1 == items2,
+ "cloning of weak-valued dictionary did not work!")
+ del items1, items2
+ self.assert_(len(dict) == self.COUNT)
+ del objects[0]
+ self.assert_(len(dict) == (self.COUNT - 1),
+ "deleting object did not cause dictionary update")
+ del objects, o
+ self.assert_(len(dict) == 0,
+ "deleting the values did not clear the dictionary")
+
+ def test_weak_keys(self):
+ dict = weakref.mapping(weakkeys=1)
+ objects = map(Object, range(self.COUNT))
+ for o in objects:
+ dict[o] = o.arg
+
+ for o in objects:
+ self.assert_(weakref.getweakrefcount(o) == 1,
+ "wrong number of weak references to %r!" % o)
+ self.assert_(o.arg is dict[o],
+ "wrong object returned by weak dict!")
+ items1 = dict.items()
+ items2 = dict.copy().items()
+ items1.sort()
+ items2.sort()
+ self.assert_(items1 == items2,
+ "cloning of weak-keyed dictionary did not work!")
+ del items1, items2
+ self.assert_(len(dict) == self.COUNT)
+ del objects[0]
+ self.assert_(len(dict) == (self.COUNT - 1),
+ "deleting object did not cause dictionary update")
+ del objects, o
+ self.assert_(len(dict) == 0,
+ "deleting the keys did not clear the dictionary")
+
+
+run_unittest(ReferencesTestCase)
+run_unittest(MappingTestCase)