"""An example of the mark and recapture decorator pattern,
designed to make connecting bound methods as callbacks easy.
Gareth Latty <gareth@lattyware.co.uk>
http://b...content-available-to-author-only...o.uk/post/29793030567/mark-and-recapture-decorators-in-python"""
import inspect
def connect(signal, f):
print(signal, f)
def naive_callback(*args):
def decorate(f):
connect(args, f)
return f
return decorate
def callback(*args):
def decorate(f):
try:
f._marks.add(args)
except AttributeError:
f._marks = {args}
return f
return decorate
def connect_callbacks(obj):
for _, f in inspect.getmembers(obj, inspect.ismethod):
try:
for mark in f.__func__._marks:
connect(mark, f)
except AttributeError:
pass
class Test:
def __init__(self):
connect_callbacks(self)
@naive_callback("test")
def test1():
pass
@callback("test")
def test2():
pass
test = Test()
IiIiQW4gZXhhbXBsZSBvZiB0aGUgbWFyayBhbmQgcmVjYXB0dXJlIGRlY29yYXRvciBwYXR0ZXJuLCAKZGVzaWduZWQgdG8gbWFrZSBjb25uZWN0aW5nIGJvdW5kIG1ldGhvZHMgYXMgY2FsbGJhY2tzIGVhc3kuCkdhcmV0aCBMYXR0eSA8Z2FyZXRoQGxhdHR5d2FyZS5jby51az4gCmh0dHA6Ly9iLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5vLnVrL3Bvc3QvMjk3OTMwMzA1NjcvbWFyay1hbmQtcmVjYXB0dXJlLWRlY29yYXRvcnMtaW4tcHl0aG9uIiIiCgppbXBvcnQgaW5zcGVjdAoKZGVmIGNvbm5lY3Qoc2lnbmFsLCBmKToKCXByaW50KHNpZ25hbCwgZikKCmRlZiBuYWl2ZV9jYWxsYmFjaygqYXJncyk6CglkZWYgZGVjb3JhdGUoZik6CgkJY29ubmVjdChhcmdzLCBmKQoJCXJldHVybiBmCglyZXR1cm4gZGVjb3JhdGUKCmRlZiBjYWxsYmFjaygqYXJncyk6CiAgICBkZWYgZGVjb3JhdGUoZik6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBmLl9tYXJrcy5hZGQoYXJncykKICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CiAgICAgICAgICAgIGYuX21hcmtzID0ge2FyZ3N9CiAgICAgICAgcmV0dXJuIGYKICAgIHJldHVybiBkZWNvcmF0ZQogICAgCmRlZiBjb25uZWN0X2NhbGxiYWNrcyhvYmopOgogICAgZm9yIF8sIGYgaW4gaW5zcGVjdC5nZXRtZW1iZXJzKG9iaiwgaW5zcGVjdC5pc21ldGhvZCk6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBmb3IgbWFyayBpbiBmLl9fZnVuY19fLl9tYXJrczoKICAgICAgICAgICAgICAgIGNvbm5lY3QobWFyaywgZikKICAgICAgICBleGNlcHQgQXR0cmlidXRlRXJyb3I6CiAgICAgICAgICAgICBwYXNzCgpjbGFzcyBUZXN0OgoJZGVmIF9faW5pdF9fKHNlbGYpOgoJCWNvbm5lY3RfY2FsbGJhY2tzKHNlbGYpCgoJQG5haXZlX2NhbGxiYWNrKCJ0ZXN0IikKCWRlZiB0ZXN0MSgpOgoJCXBhc3MKCglAY2FsbGJhY2soInRlc3QiKQoJZGVmIHRlc3QyKCk6CgkJcGFzcwoJCQp0ZXN0ID0gVGVzdCgp