3 """Define the `@callback` decorator.
5 See :pep:`318` for an introduction to decorators.
10 """Enable callbacks on `method`.
12 This decorator should make it easy to setup callbacks in a rich
13 GUI. You only need to decorate potential hooks, and maintain a
14 single dict with all the callbacks for the class. This beats
15 passing each of the callbacks into the class' `__init__` function
21 Callbacks are called with the class instance, method instance, and
22 returned arguments of the method they're attached to.
24 >>> def c(self, method, *args):
25 ... print '\\n '.join([
27 ... 'class: %s' % self,
28 ... 'method: %s' % method,
29 ... 'returned: %s' % args])
31 For some class, decorate any functions you're interested in
32 attaching callbacks too. Also, add a `_callbacks` attribute
33 holding the callbacks, keyed by function name.
36 ... def __init__(self):
37 ... self._callbacks = {'xyz': c}
42 ... print 'usual xyz business'
43 ... return (0, 1, 1, 2, 3, 5)
48 ... print 'usual abc business'
52 Here's our callback on `xyz`.
54 >>> r = x.xyz() # doctest: +ELLIPSIS
57 class: <hooke.util.callback.X object at 0x...>
58 method: <bound method X.xyz of <hooke.util.callback.X object at 0x...>>
59 returned: (0, 1, 1, 2, 3, 5)
63 Note that we haven't attached a callback to `abc`.
68 Now we attach the callback to `abc`.
70 >>> x._callbacks['abc'] = c
71 >>> r = x.abc() # doctest: +ELLIPSIS
74 class: <hooke.util.callback.X object at 0x...>
75 method: <bound method X.abc of <hooke.util.callback.X object at 0x...>>
78 You can also place an iterable in the `_callbacks` dict to run an
79 array of callbacks in series.
80 >>> def d(self, method, *args):
81 ... print 'callback d'
82 >>> x._callbacks['abc'] = [d, c, d]
83 >>> r = x.abc() # doctest: +ELLIPSIS
87 class: <hooke.util.callback.X object at 0x...>
88 method: <bound method X.abc of <hooke.util.callback.X object at 0x...>>
92 def new_m(self, *args, **kwargs):
93 result = method(self, *args, **kwargs)
94 callback = self._callbacks.get(method.func_name, None)
95 nm = getattr(self, method.func_name)
101 callback(self, nm, result)
103 new_m.func_name = method.func_name
104 new_m.func_doc = method.func_doc
105 new_m.original_method = method