def test_WeakObject(self):
"""
Tests basic extended weak object support.
"""
obj = TestClass()
ref = weakref.ref(obj)
objref = weakobj.objectref(obj)
objref2 = weakobj.objectref(obj)
self.assertEquals(objref, objref2)
self.assertEquals(objref.foo(), obj.foo())
# Delete what should be the only reference to the original object.
del obj
self.assertEqual(ref(), None)
try:
objref.foo()
except weakref.ReferenceError:
pass
else:
self.fail('Weak object should be invalidated')
python类ReferenceError()的实例源码
def test_WeakBoundMethod(self):
"""
Test that weakly-bound methods can be called like a regular bound
method, and are invalidated on object destruction.
"""
obj = TestClass()
foo = weakobj.boundmethod(obj.foo)
# Check that the weakly-bound method has the same behavior.
self.assertEqual(obj.foo(), foo())
# Check that weakly-bound notifications behave correctly.
self._notificationTest(weakobj.boundmethod(obj.bar))
# Delete the object and ensure that the method is invalidated.
del obj
try:
foo()
except weakref.ReferenceError:
pass
else:
self.fail('Weak bound method should be invalidated')
def test_proxy_ref(self):
o = C()
o.bar = 1
ref1 = weakref.proxy(o, self.callback)
ref2 = weakref.proxy(o, self.callback)
del o
gc_collect()
def check(proxy):
proxy.bar
self.assertRaises(weakref.ReferenceError, check, ref1)
self.assertRaises(weakref.ReferenceError, check, ref2)
ref3 = weakref.proxy(C())
gc_collect()
self.assertRaises(weakref.ReferenceError, bool, ref3)
self.assertEqual(self.cbcalled, 2)
def __getattr__(self, name):
# if we are proxy to a ComponentData
# object, we need to make sure NOT to
# invoke its deepcopy method
if name == "__deepcopy__":
raise AttributeError
if name in Alias.__slots__:
# should never happen
assert False
if name in Alias._component_slots:
return super(Alias, self).__dict__[name].__get__(self)
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return getattr(self.aliased_object, name)
#
# __setattr__ and __delattr__ will always be invoked
#
def __delattr__(self, name):
# avoid infinite recursion
if name in Alias.__slots__:
raise TypeError("'dictproxy' object does not support item deletion")
if name in Alias._component_slots:
del super(Alias, self).__dict__[name]
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is not longer valid")
return delattr(self.aliased_object, name)
#
# In addition to overloading __getattr__, the following magic
# methods need to be redirected as Python does not access them
# through __getitem__. If the aliased object does not implement
# them an exception will be thrown
#
# E.g., IndexedComponent
def test_WeakObjectInstanceMethodLifetime(self):
"""
Checks that bound functions returned from a weak object do not prevent
the referenced object from being deleted, as compared to weakref.proxy.
"""
obj = TestClass()
# Get a local reference to the bound method through a proxy; it will
# increase obj's reference count.
reffoo = weakref.proxy(obj).foo
# Get a local reference to the bound method through a weak object; it
# should not increase obj's reference count.
objfoo = weakobj.objectref(obj).foo
# Remove the original reference, and call the functions; this should
# succeed because of reffoo's im_self.
del obj
reffoo()
objfoo()
# Remove the local reference-via-proxy, which should now allow the
# original object to be deleted.
del reffoo
try:
objfoo()
except weakref.ReferenceError:
pass
else:
self.fail('Weak object should be invalidated')
def __getref__(self):
ref = self.__ref__()
if ref is None:
raise weakref.ReferenceError('weakly-referenced object no longer exists')
return ref
def __getref__(self):
ref = self.im_self()
if ref is None:
raise weakref.ReferenceError('weakly-referenced object no longer exists')
return self.__functype__(self.im_func, ref, self.im_class)
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.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C()))
self.assertEqual(self.cbcalled, 2)
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.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C()))
self.assertEqual(self.cbcalled, 2)
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.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C()))
self.assertTrue(self.cbcalled == 2)
def __setattr__(self, name, attr):
# avoid infinite recursion
if name in Alias.__slots__:
# this is how you access a slot while bypassing __setattr__
return Alias.__dict__[name].__set__(self, attr)
if name in Alias._component_slots:
super(Alias, self).__dict__[name] = attr
return
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is not longer valid")
return setattr(self.aliased_object, name, attr)
def __len__(self):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__len__()
def __contains__(self, key):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__contains__(key)
def __getitem__(self, key):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__getitem__(key)
def __setitem__(self, key, value):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__setitem__(key, value)
# E.g., NumValue
def __float__(self):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__float__()
def __int__(self):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__int__()
def __lt__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__lt__(other)
def __le__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__le__(other)
def __ge__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__ge__(other)
def __eq__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__eq__(other)
def __add__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__add__(other)
def __sub__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__sub__(other)
def __div__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__div__(other)
def __truediv__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__truediv__(other)
def __pow__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__pow__(other)
def __radd__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__radd__(other)
def __rsub__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__rsub__(other)
def __rdiv__(self, other):
if self.aliased_object is None:
raise weakref.ReferenceError("Proxy is no longer valid")
return self.aliased_object.__rdiv__(other)