Package cliutils :: Module decorators
[hide private]
[frames] | no frames]

Source Code for Module cliutils.decorators

  1  import os 
  2  import sys 
  3  __all__ = ["cliargs", "logged", "log_decorator"] 
4 5 -def decorator(callable):
6 """ 7 Simple meta-decorator that makes decorators preserve the attributes of the 8 modified function. 9 10 Stolen from innumerable online recipes, but most directly from 11 U{http://wiki.python.org/moin/PythonDecoratorLibrary}. 12 """ 13 def inner(f): 14 dec = callable(f) 15 dec.__name__ = f.__name__ 16 dec.__doc__ = f.__doc__ 17 dec.__module__ = f.__module__ 18 dec.__dict__.update(f.__dict__) 19 return dec
20 inner.__name__ = callable.__name__ 21 inner.__module__ = callable.__module__ 22 inner.__doc__ = callable.__doc__ 23 inner.__dict__.update(callable.__dict__) 24 return inner 25
26 @decorator 27 -def cliargs(callable):
28 """ 29 Decorator that parses C{sys.argv} and passes the results into the function. 30 31 Meant for functions that are a target of setuptools' automatic script 32 creation (by default, nothing is passed in, and the function must handle 33 sys.argv parsing itself). If something very simple is all that is required, 34 this is the answer. Fancier arguments should use C{getopt} or C{optparse}. 35 36 If the wrong args/kwargs are passed in such that a TypeError is raised, the 37 docstring is printed, so that's an ideal place to put usage information. 38 """ 39 def inner(): 40 args = sys.argv[1:] 41 opts = {} 42 prog_args = [] 43 while args: 44 if args[0].startswith('-'): 45 if args[1].startswith('-'): 46 opts[args[0].lstrip('-')] = True 47 args = args[1:] 48 else: 49 opts[args[0].lstrip('-')] = args[1] 50 args = args[2:] 51 else: 52 prog_args.append(args[0]) 53 args = args[1:] 54 try: return callable(*prog_args, **opts) 55 except TypeError: print callable.__doc__
56 return inner 57
58 -def logged(fobj):
59 """ 60 Factory for a decorator that redirects sys.stdout to a given file-like 61 object during function execution. Thus, C{print} statements can become 62 logged statements. 63 """ 64 @decorator 65 def logdecorator(callable): 66 def inner(*args, **kwargs): 67 stdout_backup = sys.stdout 68 sys.stdout = fobj 69 result = callable(*args, **kwargs) 70 sys.stdout = stdout_backup 71 return result
72 return inner 73 return logdecorator 74
75 -def log_decorator(fobj):
76 """ 77 Create a L{logged} decorator for re-use. 78 79 >>> from StringIO import StringIO 80 >>> logfile = StringIO() 81 >>> logger = log_decorator(logfile) 82 >>> @logger 83 ... def func(): 84 ... print "ABCDEFGHIJK" 85 ... 86 >>> func() 87 >>> logfile.seek(0) 88 >>> logfile.read().strip() 89 'ABCDEFGHIJK' 90 91 """ 92 return logged(fobj)
93
94 95 -def indir(newdir):
96 """ 97 Factory for decorator that ensures the decorated function is run in a 98 specified directory, then changes back to original directory. 99 100 >>> import tempfile 101 >>> realpath = os.path.realpath 102 >>> new, cur = map(realpath, (tempfile.mkdtemp(), os.curdir)) 103 >>> @indir(new) 104 ... def whereami(): 105 ... return realpath(os.curdir) 106 ... 107 >>> whereami() == new 108 True 109 >>> realpath(os.curdir) == cur 110 True 111 112 """ 113 @decorator 114 def dec(f): 115 def inner(*args, **kwargs): 116 olddir = os.path.abspath(os.curdir) 117 os.chdir(newdir) 118 result = f(*args, **kwargs) 119 os.chdir(olddir) 120 return result
121 return inner 122 return dec 123