def testWorksWithUnboundMethods(self): self.SetupTestAttributes() meth = self.C.f rf = WeakMethodRef(meth) pf = WeakMethodProxy(meth) assert meth(self.c) == 1 assert rf()(self.c) == 1 assert pf(self.c) == 1 assert not rf.is_dead() assert not pf.is_dead()
def testHash(self): self.SetupTestAttributes() r = WeakMethodRef(self.c.f) r2 = WeakMethodRef(self.c.f) assert r == r2 h = hash(r) assert hash(r) == hash(r2) del self.c assert r() is None assert hash(r) == h
def testRepr(self): self.SetupTestAttributes() r = WeakMethodRef(self.c.f) assert str(r)[:33] == '<WeakMethodRef to C.f for object ' def Foo(): 'Never called' r = WeakMethodRef(Foo) assert str(r) == '<WeakMethodRef to Foo>'
def testEq(self): self.SetupTestAttributes() rf1 = WeakMethodRef(self.c.f) rf2 = WeakMethodRef(self.c.f) assert rf1 == rf2 rf3 = WeakMethodRef(self.d.f) assert rf1 != rf3 del self.c assert rf1.is_dead() assert rf2.is_dead() assert rf1 == rf2
def testWorksWithFunctions(self): self.SetupTestAttributes() def foo(y): return y + 1 rf = WeakMethodRef(foo) pf = WeakMethodProxy(foo) assert foo(1) == 2 assert rf()(1) == 2 assert pf(1) == 2 assert not rf.is_dead() assert not pf.is_dead()
def testDies(self): self.SetupTestAttributes() rf = WeakMethodRef(self.c.f) pf = WeakMethodProxy(self.c.f) assert not rf.is_dead() assert not pf.is_dead() assert rf()() == 1 assert pf(2) == 3 self.c = None assert rf.is_dead() assert pf.is_dead() assert rf() == None with pytest.raises(ReferenceError): pf()
def __init__(self, method): self._before = None self._after = None self._method = WeakMethodRef(method) self._name = method.__name__ # Maintaining the OriginalMethod() interface that clients expect. self.OriginalMethod = self._method
def testRefcount(self): self.SetupTestAttributes() self.CustomAssertEqual(sys.getrefcount( self.c), 2) # 2: one in self, and one as argument to getrefcount() cf = self.c.f self.CustomAssertEqual(sys.getrefcount(self.c), 3) # 3: as above, plus cf rf = WeakMethodRef(self.c.f) pf = WeakMethodProxy(self.c.f) self.CustomAssertEqual(sys.getrefcount(self.c), 3) del cf self.CustomAssertEqual(sys.getrefcount(self.c), 2) rf2 = WeakMethodRef(self.c.f) self.CustomAssertEqual(sys.getrefcount(self.c), 2) del rf del rf2 del pf self.CustomAssertEqual(sys.getrefcount(self.c), 2)
def _CreateBeforeOrAfter(method, callback, sender_as_parameter, before=True): wrapper = WrapForCallback(method) original_method = wrapper.OriginalMethod() extra_args = [] if sender_as_parameter: im_self = original_method.im_self extra_args.append(weakref.ref(im_self)) # this is not garbage collected directly when added to the wrapper (which will create a WeakMethodRef to it) # because it's not a real method, so, WeakMethodRef will actually maintain a strong reference to it. callback = _CallbackWrapper(WeakMethodRef(callback)) if before: wrapper.AppendBefore(callback, extra_args) else: wrapper.AppendAfter(callback, extra_args) return wrapper
def testKeyReusedAfterDead(self, monkeypatch): self._gotten_key = False def GetKey(*args, **kwargs): self._gotten_key = True return 1 monkeypatch.setattr(callback.Callback, '_GetKey', GetKey) def AfterMethod(*args): 'Not called!' def AfterMethodB(*args): 'Not called!' c = callback.Callback() c.Register(AfterMethod) self._gotten_key = False assert not c.Contains(AfterMethodB) assert c.Contains(AfterMethod) assert self._gotten_key # As we made _GetKey return always the same, this will make it remove one and add the # other one, so, the contains will have to check if they're actually the same or not. c.Register(AfterMethodB) self._gotten_key = False assert c.Contains(AfterMethodB) assert not c.Contains(AfterMethod) assert self._gotten_key class A(object): def __init__(self): self._a = 0 def GetA(self): return self._a def SetA(self, value): self._a = value a = property(GetA, SetA) a = A() # Coverage exercise assert a.a == 0 a.a = 10 assert a.a == 10 # If registering a bound, it doesn't contain the unbound c.Register(a.SetA) assert not c.Contains(AfterMethodB) assert not c.Contains(A.SetA) assert c.Contains(a.SetA) # But if registering an unbound, it contains the bound c.Register(A.SetA) assert not c.Contains(AfterMethodB) assert c.Contains(A.SetA) assert c.Contains(a.SetA) c.Register(a.SetA) assert len(c) == 1 del a assert not c.Contains(AfterMethodB) assert len(c) == 0 a = A() c.Register(_CallbackWrapper(WeakMethodRef(a.SetA))) assert len(c) == 1 del a assert not c.Contains(AfterMethodB) assert len(c) == 0
def __init__(self, cached_method=None): # REMARKS: Use WeakMethodRef to avoid cyclic reference. self._method = WeakMethodRef(cached_method) self.enabled = True self.ResetCounters()