socketIO-client/experiments/callableweakref.py
2013-02-11 08:32:22 -08:00

52 lines
1.7 KiB
Python

import types
import weakref
def ref(function):
return CallableWeakReference(function)
class CallableWeakReference(object):
def __init__(self, function):
'Create a weak reference to a callable'
try:
if function.im_self:
# We have a bound method or class method
self._reference = weakref.ref(function.im_self)
else:
# We have an unbound method
self._reference = None
self._function = function.im_func
self._class = function.im_class
except AttributeError:
try:
function.func_code
# We have a normal function or static method
self._reference = None
self._function = function
self._class = None
except AttributeError:
function = function.__call__
# We have a class masquerading as a function
self._reference = weakref.ref(function.im_self)
self._function = function.im_func
self._class = function.im_class
def __call__(self):
if self.dead:
return
if self._reference:
# We have a bound method
return types.MethodType(self._function, self._reference(), self._class)
elif self._class:
return types.MethodType(self._function, None, self._class)
else:
return self._function
@property
def dead(self):
if self._reference and not self._reference():
# We have a bound method whose parent reference has died
return True
return False