forked from vokimon/testfarm-server2
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathspike_expanddecorator.py
executable file
·63 lines (52 loc) · 1.81 KB
/
spike_expanddecorator.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
60
61
#!/usr/bin/python
import decorator
import inspect
def check_signature(signature, **kwd) :
print "check_signature", signature, kwd
def check_signature2(signature, id, **kwd) :
print "check_signature2", signature, id, kwd
def expand_decorator(expander) :
"""
Decorator that expands the decorated function argument
specification with the one from expander function.
For example if we have:
original(a, b, c=1, *args1, **kwd1)
expander(x, y, y=2, *args2, **kwd2)
a expanded function will be created as:
result(a, b, x, y, c=1, y=2, *args1, **kwd1)
The expander function is called just before the decorated one.
The exit value is the one of the decorated one.
"""
def decorator(decorated) :
expanderfun = expander # required to create it as local
targetargs = inspect.getargspec(decorated)
expandargs = inspect.getargspec(expanderfun)
# TODO: expander with optional
wrapperspec = [
arg for arg in expandargs.args
if arg not in targetargs.args] + [
inspect.formatargspec(*targetargs)[1:-1]
]
targetcall = ["%s=%s"%(arg,arg) for arg in targetargs.args]
checkercall = targetcall+["%s=%s"%(arg,arg) for arg in expandargs.args]
if targetargs.varargs : targetcall.append("*%s"%targetargs.varargs)
if targetargs.keywords : targetcall.append("**%s"%targetargs.keywords)
source = """\
def wrapper ({wrapperspec}) :
# print "wrapper locals", locals()
expanderfun({checkercall})
return decorated({targetcall})
""".format(
wrapperspec = ",".join(wrapperspec),
checkercall=", ".join(checkercall),
targetcall=", ".join(targetcall),
)
exec source in locals(), globals()
return wrapper
return decorator
if __name__ == "__main__" :
@expand_decorator(check_signature2)
def f(a,b=3, *pos, **kwd) :
print a, b, pos, kwd
f(signature="boo",id="tu",a=1,b=2,c=3,d=4)
f("boo","tu","a","b",c=3,d=4)