forked from doctaphred/phrecipes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunccools.py
88 lines (66 loc) · 2.36 KB
/
funccools.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def nop(*args, **kwargs):
pass
def passthrough(x):
return x
def generate(x):
yield x
def call(*args, **kwargs):
def decorator(callable):
return callable(*args, **kwargs)
return decorator
magic = call()
def combine(*funcs):
def multifunc(*args, **kwargs):
return [func(*args, **kwargs) for func in funcs]
return multifunc
def only_when(condition):
"""Only apply a decorator if the condition is met.
This function is designed as a decorator for other decorators
("re-decorator", perhaps?). If the given condition evaluates True,
the decorated function is evaluated as usual, wrapping or replacing
whatever functions it in turn decorates. If the condition evaluates
False, though, it replaces the decorated function with a direct call
to the function it wraps, bypassing evaluation of the decorated
function altogether.
This evaluation is only performed once, when the decorated function
is first created (usually when the module is loaded); afterward, it
adds zero overhead to the actual evaluation of the function.
"""
def conditional(decorator):
def redecorator(function):
if condition:
return decorator(function)
else:
return function
return redecorator
return conditional
only_when.csvoss_edition = lambda condition: (
(lambda decorator: lambda function: decorator(function))
if condition else
(lambda decorator: lambda function: function)
)
def wrap(before=None, after=None, ex=None):
"""Apply additional functions before and afterward."""
def decorator(func):
def wrapper(*args, **kwargs):
mutable_args = list(args)
if before:
before(mutable_args, kwargs)
try:
result = func(*mutable_args, **kwargs)
except Exception as exception:
if ex:
return ex(exception, args, kwargs)
else:
raise
else:
if after:
result = after(result, args, kwargs)
return result
return wrapper
return decorator
def debug(before=None, after=None):
"""Apply additional functions, unless compiled with -O."""
if not __debug__:
return passthrough
return wrap(before, after)