Package turbogears :: Module decorator

Source Code for Module turbogears.decorator

  1  """Decorator tools""" 
  2   
  3  __all__ = ['decorate', 'make_weak_signature', 'compose', 
  4      'decorator', 'weak_signature_decorator', 
  5      'simple_decorator', 'simple_weak_signature_decorator', 
  6      'func_id', 'func_eq', 'func_original', 'func_composition'] 
  7   
  8  import itertools 
  9  from inspect import getargspec, formatargspec 
 10   
 11   
12 -def decorate(func, caller, signature=None):
13 """Decorate func with caller. 14 15 Inspired by Michele Simionato's decorator library: 16 http://www.phyast.pitt.edu/~micheles/python/documentation.html 17 18 """ 19 argnames, varargs, kwargs, defaults = \ 20 signature is None and getargspec(func) or signature 21 if defaults is None: 22 defaults = () 23 parameters = formatargspec(argnames, varargs, kwargs, defaults)[1:-1] 24 defval = itertools.count(len(argnames) - len(defaults)) 25 args = formatargspec(argnames, varargs, kwargs, defaults, 26 formatvalue=lambda value:"=%s" % argnames[defval.next()])[1:-1] 27 exec_dict = dict(func=func, caller=caller) 28 exec "\ndef %s(%s):\n\treturn caller(func, %s)\n" % ( 29 func.__name__, parameters, args) in exec_dict 30 new_func = exec_dict[func.__name__] 31 new_func.__doc__ = func.__doc__ 32 new_func.__dict__ = func.__dict__.copy() 33 new_func.__module__ = func.__module__ 34 new_func.__composition__ = getattr(func, '__composition__', 35 [func]) + [new_func] 36 return new_func
37 38
39 -def decorator(entangler, signature=None):
40 """Decorate function with entangler. 41 42 Use new signature or preserve original signature if signature is None. 43 44 """ 45 def entangle(func): 46 return decorate(func, entangler(func), signature)
47 return entangle 48 49
50 -def weak_signature_decorator(entangler):
51 """Decorate function with entangler and weak signature. 52 53 Changes signature to accept arbitrary additional arguments. 54 55 """ 56 def entangle(func): 57 return decorate(func, entangler(func), make_weak_signature(func))
58 return entangle 59 60
61 -def simple_decorator(caller, signature=None):
62 """Decorate function with caller.""" 63 def entangle(func): 64 return decorate(func, caller, signature)
65 return entangle 66 67
68 -def simple_weak_signature_decorator(caller):
69 """Decorate function with caller and weak signature. 70 71 Changes signature to accept arbitrary additional arguments. 72 73 """ 74 def entangle(func): 75 return decorate(func, caller, make_weak_signature(func))
76 return entangle 77 78
79 -def make_weak_signature(func):
80 """Change signature to accept arbitrary additional arguments.""" 81 argnames, varargs, kwargs, defaults = getargspec(func) 82 if kwargs is None: 83 kwargs = "_decorator__kwargs" 84 if varargs is None: 85 varargs = "_decorator__varargs" 86 return argnames, varargs, kwargs, defaults
87 88
89 -def compose(*decorators):
90 """Compose decorators.""" 91 return lambda func: reduce(lambda f, g: g(f), decorators, func)
92 93
94 -def func_composition(func):
95 """Return composition (decorator wise) of function.""" 96 return getattr(func, "__composition__", [func])
97 98
99 -def func_original(func):
100 """Return original (undecorated) function.""" 101 return func_composition(func)[0]
102 103
104 -def func_id(func):
105 """Return identity of function. 106 107 If decorator was created with decorator() or weak_signature_decorator(), 108 identity is invariant under decorator application. 109 110 """ 111 return id(func_original(func))
112 113
114 -def func_eq(f, g):
115 """Check if functions are identical.""" 116 return func_id(f) == func_id(g)
117