Python源码示例:weakref.WeakMethod()
示例1
def connect(self, s, func):
"""Register *func* to be called when signal *s* is generated.
"""
self._func_cid_map.setdefault(s, {})
try:
proxy = WeakMethod(func, self._remove_proxy)
except TypeError:
proxy = _StrongRef(func)
if proxy in self._func_cid_map[s]:
return self._func_cid_map[s][proxy]
cid = next(self._cid_gen)
self._func_cid_map[s][proxy] = cid
self.callbacks.setdefault(s, {})
self.callbacks[s][cid] = proxy
return cid
示例2
def _dispatch(self, event, sender, **kwargs):
"""Issue a dispatch for `event` coming from `sender.
Parameters
----------
event: str
event name from EVENTS
sender: DispatchClient
object requesting the dispatch
**kwargs
"""
for client, callback_ref in self.get_clients_dict(event).items():
logging.debug("Central dispatch calling {} about {}.".format(type(client).__name__, event))
callback_ref(event, sender=sender, **kwargs)
# When using WeakMethod references, this should rather be:
# callback_ref()(event, sender=sender, **kwargs)
示例3
def connect(self, s, func):
"""Register *func* to be called when signal *s* is generated.
"""
self._func_cid_map.setdefault(s, {})
try:
proxy = WeakMethod(func, self._remove_proxy)
except TypeError:
proxy = _StrongRef(func)
if proxy in self._func_cid_map[s]:
return self._func_cid_map[s][proxy]
cid = next(self._cid_gen)
self._func_cid_map[s][proxy] = cid
self.callbacks.setdefault(s, {})
self.callbacks[s][cid] = proxy
return cid
示例4
def connect(self, s, func):
"""Register *func* to be called when signal *s* is generated.
"""
self._func_cid_map.setdefault(s, {})
try:
proxy = WeakMethod(func, self._remove_proxy)
except TypeError:
proxy = _StrongRef(func)
if proxy in self._func_cid_map[s]:
return self._func_cid_map[s][proxy]
cid = next(self._cid_gen)
self._func_cid_map[s][proxy] = cid
self.callbacks.setdefault(s, {})
self.callbacks[s][cid] = proxy
return cid
示例5
def test_hashing(self):
# Alive WeakMethods are hashable if the underlying object is
# hashable.
x = Object(1)
y = Object(1)
a = weakref.WeakMethod(x.some_method)
b = weakref.WeakMethod(y.some_method)
c = weakref.WeakMethod(y.other_method)
# Since WeakMethod objects are equal, the hashes should be equal.
self.assertEqual(hash(a), hash(b))
ha = hash(a)
# Dead WeakMethods retain their old hash value
del x, y
gc.collect()
self.assertEqual(hash(a), ha)
self.assertEqual(hash(b), ha)
# If it wasn't hashed when alive, a dead WeakMethod cannot be hashed.
self.assertRaises(TypeError, hash, c)
示例6
def __init__(self):
super().__init__()
self._state = MediaState.Null
self._elements = []
self._old_pipe = ''
self._loop_count = 0
self._gst_pipe = Gst.Pipeline()
self._gst_state = Gst.State.NULL
self._time_query = Gst.Query.new_position(Gst.Format.TIME)
bus = self._gst_pipe.get_bus()
bus.add_signal_watch()
# Use a weakref instead of the method or the object will not be
# garbage-collected
on_message = weakref.WeakMethod(self.__on_message)
handler = bus.connect('message', lambda *args: on_message()(*args))
weakref.finalize(self, self.__finalizer, self._gst_pipe, handler,
self._elements)
self.changed('loop').connect(self.__prepare_loops)
self.changed('pipe').connect(self.__prepare_pipe)
示例7
def connect(self, slot_callable, mode=Connection.Direct):
"""Connect the given slot, if not already connected.
:param slot_callable: The slot (a python callable) to be connected
:param mode: Connection mode
:type mode: Connection
:raise ValueError: if mode not in Connection enum
"""
if mode not in Connection:
raise ValueError('invalid mode value: {0}'.format(mode))
with self.__lock:
# Create a new Slot object, use a weakref for the callback
# to avoid cyclic references.
callback = weak_call_proxy(weakref.WeakMethod(self.__remove_slot))
self.__slots[slot_id(slot_callable)] = mode.new_slot(slot_callable,
callback)
示例8
def test_hashing(self):
# Alive WeakMethods are hashable if the underlying object is
# hashable.
x = Object(1)
y = Object(1)
a = weakref.WeakMethod(x.some_method)
b = weakref.WeakMethod(y.some_method)
c = weakref.WeakMethod(y.other_method)
# Since WeakMethod objects are equal, the hashes should be equal.
self.assertEqual(hash(a), hash(b))
ha = hash(a)
# Dead WeakMethods retain their old hash value
del x, y
gc.collect()
self.assertEqual(hash(a), ha)
self.assertEqual(hash(b), ha)
# If it wasn't hashed when alive, a dead WeakMethod cannot be hashed.
self.assertRaises(TypeError, hash, c)
示例9
def _remove_handler(self, name, handler):
"""Used internally to remove all handler instances for the given event name.
This is normally called from a dead ``WeakMethod`` to remove itself from the
event stack.
"""
# Iterate over a copy as we might mutate the list
for frame in list(self._event_stack):
if name in frame:
try:
if frame[name] == handler:
del frame[name]
if not frame:
self._event_stack.remove(frame)
except TypeError:
# weakref is already dead
pass
示例10
def connect(self, slot):
"""Connect a slot to the signal.
If the input slot is already connected, nothing is done.
Args:
slot: Instance method or function to connect.
"""
# Create a weak reference to the method or function.
if inspect.ismethod(slot):
wr_slot = weakref.WeakMethod(slot)
else:
wr_slot = weakref.ref(slot)
# Only insert the slot if it doesn't already exist. If the index
# method throws, the slot doesn't exist yet. Insert it at the
# beginning so that when we call the slots in reverse order, they
# will be called in the order inserted.
if wr_slot not in self.slots:
self.slots.insert(0, wr_slot)
#-----------------------------------------------------------------------
示例11
def disconnect(self, slot):
"""Disconnect a slot from the signal.
If the input slot is not connected, nothing is done.
Args:
slot: Instance method or function to disconnect.
"""
# Create a weak reference to the method or function so that we can
# use the comparison operator on the weakref to find the slot.
if inspect.ismethod(slot):
wr_slot = weakref.WeakMethod(slot)
else:
wr_slot = weakref.ref(slot)
try:
self.slots.remove(wr_slot)
except ValueError:
pass
#-----------------------------------------------------------------------
示例12
def test_hashing(self):
# Alive WeakMethods are hashable if the underlying object is
# hashable.
x = Object(1)
y = Object(1)
a = weakref.WeakMethod(x.some_method)
b = weakref.WeakMethod(y.some_method)
c = weakref.WeakMethod(y.other_method)
# Since WeakMethod objects are equal, the hashes should be equal.
self.assertEqual(hash(a), hash(b))
ha = hash(a)
# Dead WeakMethods retain their old hash value
del x, y
gc.collect()
self.assertEqual(hash(a), ha)
self.assertEqual(hash(b), ha)
# If it wasn't hashed when alive, a dead WeakMethod cannot be hashed.
self.assertRaises(TypeError, hash, c)
示例13
def __init__(self, func, asynchronous=False, priority=PRIORITIES.NONE, times=None, identifier=None, **kw):
self.func = kwargs_resilient(func)
self._func = get_original_func(func) # save the original funtion so we can unregister based on the function
# identifier only applicable to methods
if inspect.ismethod(self._func) or isinstance(self._func, weakref.WeakMethod):
self.identifier = identifier
else:
self.identifier = None
# Backwards compatibility
self.asynchronous = kw.pop("async", asynchronous)
assert not kw, "SignalHandler's kwargs should contain only 'async' argument for backwards compatibility"
self.priority = priority
self.times = times
self.idx = next(self._idx_gen)
if isinstance(func, weakref.WeakMethod):
func = func() # to allow accessing it's __code__ and __name__
self.filename = func.__code__.co_filename
self.lineno = func.__code__.co_firstlineno
self.name = self.__name__ = func.__name__
示例14
def connect(self, s, func):
"""Register *func* to be called when signal *s* is generated.
"""
self._func_cid_map.setdefault(s, {})
try:
proxy = WeakMethod(func, self._remove_proxy)
except TypeError:
proxy = _StrongRef(func)
if proxy in self._func_cid_map[s]:
return self._func_cid_map[s][proxy]
cid = next(self._cid_gen)
self._func_cid_map[s][proxy] = cid
self.callbacks.setdefault(s, {})
self.callbacks[s][cid] = proxy
return cid
示例15
def connect(self, s, func):
"""Register *func* to be called when signal *s* is generated.
"""
self._func_cid_map.setdefault(s, {})
try:
proxy = WeakMethod(func, self._remove_proxy)
except TypeError:
proxy = _StrongRef(func)
if proxy in self._func_cid_map[s]:
return self._func_cid_map[s][proxy]
cid = next(self._cid_gen)
self._func_cid_map[s][proxy] = cid
self.callbacks.setdefault(s, {})
self.callbacks[s][cid] = proxy
return cid
示例16
def __init__(self, slot, weak=False):
self._weak = weak or isinstance(slot, weakref.ref)
if weak and not isinstance(slot, weakref.ref):
if isinstance(slot, types.MethodType):
slot = WeakMethod(slot)
else:
slot = weakref.ref(slot)
self._slot = slot
示例17
def __set__(self, obj, value):
if value is None:
self.__delete__(obj)
else:
try:
weakMethod = weakref.WeakMethod(value)
except TypeError:
setattr(obj, self.weakrefCallbackName, lambda: value)
else:
setattr(obj, self.weakrefCallbackName, weakMethod)
示例18
def __init__(self):
self.clients_dict = {event: weakref.WeakKeyDictionary() for event in EVENTS} # central dispatch information
# For each event, store a dict that maps the clients registered for that event to their callback routines
# The objects are keys in the inner dict, implemented as a WeakKeyDictionary to allow deletion/garbage collection
# when object should expire. Callback methods are stored as weakref.WeakMethod for the same reason.
示例19
def register(self, event, who, callback=None):
"""
Register object `who` for event `event`. (This modifies `clients_dict`.)
Parameters
----------
event: str
event name from EVENTS
who: DispatchClient
object to be registered
callback: method, optional
custom callback method other than `.receive()`
"""
logging.debug("Registering {} for {}. welcome.".format(type(who).__name__, event))
if callback is None:
callback_ref = getattr(who, 'receive')
# For purposes of garbage collection, this should preferably be:
# callback_ref = weakref.WeakMethod(getattr(who, 'receive'))
# However, as of 06/12/20, pathos balks on this on Windows (while Linux is passing).
# Note that reference to callback methods is likely to prevent proper garbage collection,
# so may have to revisit this issue if necessary.
else:
callback_ref = callback
# For purposes of garbage collection, this should preferably be:
# callback_ref = weakref.WeakMethod(callback)
# However, as of 06/12/20, pathos balks on this on Windows (while Linux is passing).
# Note that the reference to callback methods is likely to prevent proper garbage collection,
# so may have to revisit this issue if necessary.
self.get_clients_dict(event)[who] = callback_ref
示例20
def test_alive(self):
o = Object(1)
r = weakref.WeakMethod(o.some_method)
self.assertIsInstance(r, weakref.ReferenceType)
self.assertIsInstance(r(), type(o.some_method))
self.assertIs(r().__self__, o)
self.assertIs(r().__func__, o.some_method.__func__)
self.assertEqual(r()(), 4)
示例21
def test_object_dead(self):
o = Object(1)
r = weakref.WeakMethod(o.some_method)
del o
gc.collect()
self.assertIs(r(), None)
示例22
def test_method_dead(self):
C = self._subclass()
o = C(1)
r = weakref.WeakMethod(o.some_method)
del C.some_method
gc.collect()
self.assertIs(r(), None)
示例23
def test_callback_when_object_dead(self):
# Test callback behaviour when object dies first.
C = self._subclass()
calls = []
def cb(arg):
calls.append(arg)
o = C(1)
r = weakref.WeakMethod(o.some_method, cb)
del o
gc.collect()
self.assertEqual(calls, [r])
# Callback is only called once.
C.some_method = Object.some_method
gc.collect()
self.assertEqual(calls, [r])
示例24
def test_callback_when_method_dead(self):
# Test callback behaviour when method dies first.
C = self._subclass()
calls = []
def cb(arg):
calls.append(arg)
o = C(1)
r = weakref.WeakMethod(o.some_method, cb)
del C.some_method
gc.collect()
self.assertEqual(calls, [r])
# Callback is only called once.
del o
gc.collect()
self.assertEqual(calls, [r])
示例25
def test_equality(self):
def _eq(a, b):
self.assertTrue(a == b)
self.assertFalse(a != b)
def _ne(a, b):
self.assertTrue(a != b)
self.assertFalse(a == b)
x = Object(1)
y = Object(1)
a = weakref.WeakMethod(x.some_method)
b = weakref.WeakMethod(y.some_method)
c = weakref.WeakMethod(x.other_method)
d = weakref.WeakMethod(y.other_method)
# Objects equal, same method
_eq(a, b)
_eq(c, d)
# Objects equal, different method
_ne(a, c)
_ne(a, d)
_ne(b, c)
_ne(b, d)
# Objects unequal, same or different method
z = Object(2)
e = weakref.WeakMethod(z.some_method)
f = weakref.WeakMethod(z.other_method)
_ne(a, e)
_ne(a, f)
_ne(b, e)
_ne(b, f)
del x, y, z
gc.collect()
# Dead WeakMethods compare by identity
refs = a, b, c, d, e, f
for q in refs:
for r in refs:
self.assertEqual(q == r, q is r)
self.assertEqual(q != r, q is not r)
示例26
def __init__(self, slot_callable, callback=None):
if isinstance(slot_callable, MethodType):
self._reference = weakref.WeakMethod(slot_callable, self._expired)
elif callable(slot_callable):
self._reference = weakref.ref(slot_callable, self._expired)
else:
raise TypeError('slot must be callable')
self._callback = callback
self._slot_id = slot_id(slot_callable)
self._no_args = len(inspect.signature(slot_callable).parameters) == 0
示例27
def test_alive(self):
o = Object(1)
r = weakref.WeakMethod(o.some_method)
self.assertIsInstance(r, weakref.ReferenceType)
self.assertIsInstance(r(), type(o.some_method))
self.assertIs(r().__self__, o)
self.assertIs(r().__func__, o.some_method.__func__)
self.assertEqual(r()(), 4)
示例28
def test_object_dead(self):
o = Object(1)
r = weakref.WeakMethod(o.some_method)
del o
gc.collect()
self.assertIs(r(), None)
示例29
def test_method_dead(self):
C = self._subclass()
o = C(1)
r = weakref.WeakMethod(o.some_method)
del C.some_method
gc.collect()
self.assertIs(r(), None)
示例30
def test_callback_when_object_dead(self):
# Test callback behaviour when object dies first.
C = self._subclass()
calls = []
def cb(arg):
calls.append(arg)
o = C(1)
r = weakref.WeakMethod(o.some_method, cb)
del o
gc.collect()
self.assertEqual(calls, [r])
# Callback is only called once.
C.some_method = Object.some_method
gc.collect()
self.assertEqual(calls, [r])