Skip to content

Instantly share code, notes, and snippets.

@EntityReborn
Created November 6, 2011 23:02
Show Gist options
  • Save EntityReborn/1343746 to your computer and use it in GitHub Desktop.
Save EntityReborn/1343746 to your computer and use it in GitHub Desktop.
from threading import RLock
import traceback, inspect
class BadArgLength(AttributeError): pass
class Subscriber(object):
def __init__(self, func, subscriberargs):
self.func = func
self.args = subscriberargs
def fire(self, args):
allargs = args + self.args
self.func(*allargs)
__call__ = fire
class Hook(object):
def __init__(self, numargs, doc=None):
self._numargs = numargs
if doc:
self.__doc__ = doc
self.subscribers = list()
self._lock = RLock()
def attach(self, func, *customargs):
if callable(func):
# Lets make sure that the function's signature has the
# right amount of arguments!
arglength = len(inspect.getargspec(func).args)
reqlength = self._numargs + len(customargs)
if reqlength == arglength:
s = Subscriber(func, customargs)
with self._lock:
self.subscribers.append(s)
return s
# Incorrect number of arguments!
raise BadArgLength(
"%s needs to support %d native and %d custom args, but has %d!" %
(func, self._numargs, len(customargs), arglength))
# Purposely raise an error, as at this point, it's not callable.
raise TypeError("%s is not callable!" % func)
def detach(self, func):
with self._lock:
for subscriber in self.subscribers:
if subscriber.func == func:
self.subscribers.remove(subscriber)
def fire(self, *args):
with self._lock:
subscribers = self.subscribers[:]
for subscriber in subscribers:
try:
subscriber(args)
except Exception:
print "----- Exception! -----"
traceback.print_exc(5)
print "----------------------"
__call__ = fire
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment