1 __all__
= ('decorator', 'memoize', 'interruptable')
6 def decorator(caller
, func
=None):
10 decorator(caller) converts a caller function into a decorator;
11 decorator(caller, func) decorates a function using a caller.
16 def _decorator(f
, *args
, **opts
):
17 def _caller(*args
, **opts
):
18 return caller(f
, *args
, **opts
)
22 # return a decorated function
23 def _decorated(*args
, **opts
):
24 return caller(func
, *args
, **opts
)
30 A decorator for memoizing function calls
32 http://en.wikipedia.org/wiki/Memoization
36 return decorator(_memoize
, func
)
39 def _memoize(func
, *args
, **opts
):
40 """Implements memoized cache lookups"""
41 if opts
: # frozenset is used to ensure hashability
42 key
= args
, frozenset(opts
.items())
45 cache
= func
.cache
# attribute added by memoize
49 result
= cache
[key
] = func(*args
, **opts
)
54 def interruptable(func
, *args
, **opts
):
55 """Handle interruptable system calls
57 OSX and others are known to interrupt system calls
59 http://en.wikipedia.org/wiki/PCLSRing
60 http://en.wikipedia.org/wiki/Unix_philosophy#Worse_is_better
62 The @interruptable decorator handles this situation
67 result
= func(*args
, **opts
)
69 if e
.errno
== errno
.EINTR
:
73 if e
.errno
in (errno
.EINTR
, errno
.EINVAL
):