Package turbogears :: Module decorator

Source Code for Module turbogears.decorator

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