-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecorations.py
59 lines (52 loc) · 2.32 KB
/
decorations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# python
from functools import wraps, partial
from inspect import getargspec
# local
from utils import *
def _metadecorator(decoration, params="maybe"):
"Takes a decoration to pre-apply to a decoratee"
def cap_params(*dec_params, **dec_kwargs):
"Captures decoration parameters"
@wraps(decoration)
def decorator(decoratee):
"The decorator - takes a decoratee to decorate"
@wraps(decoratee)
def decorated(*args, **kwargs):
"The decorated decoratee"
# the decoration will be passed the decoratee and (optionally) two sets of arguments
return apply_some(decoration, decoratee, args=args, kwargs=kwargs, dec_params=dec_params, dec_kwargs=dec_kwargs)
return decorated
if params=="maybe" and not dec_kwargs and len(dec_params)==1 and callable(dec_params[0]):
decoratee = dec_params[0]
dec_params = ()
return decorator(decoratee)
else:
return decorator
return cap_params
def decoration(decoration=None, has_params="maybe"):
"Meta-decorates"
if decoration:
dec_args = getargspec(decoration).args
if 'dec_params' in dec_args or 'dec_kwargs' in dec_args:
return _metadecorator(decoration, params=has_params)
else:
return _metadecorator(decoration, params=has_params)()
else:
return partial(decoration, params=has_params)
@decoration
def predecoration(f, args, kwargs):
"Declares something as a predecoration"
def predecorator(g, **kwds):
# at this point, `f` will be our predecoration and `g` will be our decoratee.
update = apply_some(f, g, **kwds)
gargs, gkwargs = _param_update((kwds['args'], kwds['kwargs']), update)
return g(*gargs, **gkwargs)
return _metadecorator(predecorator)(*args, **kwargs)
@decoration
def postdecoration(f, args, kwargs, dec_kwargs):
"Declares something as a postdecoration"
def postdecorator(g, **kwds):
# at this point, `f` will be our postdecoration and `g` will be our decoratee.
res = g(*kwds['args'], **kwds['kwargs'])
return apply_some(f, res, *kwds['dec_params'], **kwds['dec_kwargs'])
return _metadecorator(postdecorator, dec_kwargs.get('has_params', 'maybe'))(*args, **kwargs)