Skip to content

Instantly share code, notes, and snippets.

@dlobue
Created March 4, 2010 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlobue/322085 to your computer and use it in GitHub Desktop.
Save dlobue/322085 to your computer and use it in GitHub Desktop.
from weakref import WeakKeyDictionary
class MetaSignals(type):
"""
register the list of signals in the class varable signals,
including signals in superclasses.
"""
def __init__(cls, name, bases, d):
signals = d.get("signals", [])
for superclass in cls.__bases__:
signals.extend(getattr(superclass, 'signals', []))
signals = dict([(x,None) for x in signals]).keys()
d["signals"] = signals
Signals.register(cls, signals)
super(MetaSignals, cls).__init__(name, bases, d)
class Signals(object):
_connections = WeakKeyDictionary()
_supported = {}
def register(cls, sig_cls, signals):
cls._supported[sig_cls] = signals
register = classmethod(register)
def connect(cls, obj, name, callback, user_arg=None):
sig_cls = obj.__class__
if not name in cls._supported.get(sig_cls, []):
raise NameError, "No such signal %r for object %r" % \
(name, obj)
d = cls._connections.setdefault(obj, {})
d.setdefault(name, []).append((callback, user_arg))
connect = classmethod(connect)
def disconnect(cls, obj, name, callback, user_arg=None):
d = cls._connections.get(obj, {})
if name not in d:
return
if (callback, user_arg) not in d[name]:
return
d[name].remove((callback, user_arg))
disconnect = classmethod(disconnect)
def emit(cls, obj, name, *args):
result = False
d = cls._connections.get(obj, {})
for callback, user_arg in d.get(name, []):
args_copy = args
if user_arg is not None:
args_copy = args + [user_arg]
result |= bool(callback(*args_copy))
return result
emit = classmethod(emit)
_signals = Signals()
emit_signal = _signals.emit
register_signal = _signals.register
connect_signal = _signals.connect
disconnect_signal = _signals.disconnect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment