Package logilab-common-0 :: Package 36 :: Package 1 :: Module decorators
[frames] | no frames]

Source Code for Module logilab-common-0.36.1.decorators

  1  """A few useful function/method decorators. 
  2   
  3  :copyright: 2006-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  4  :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  5  :license: General Public License version 2 - http://www.gnu.org/licenses 
  6  """ 
  7  __docformat__ = "restructuredtext en" 
  8   
  9  from types import MethodType 
 10  from time import clock 
 11  import sys, re 
 12   
 13  # XXX rewrite so we can use the decorator syntax when keyarg has to be specified 
 14   
15 -def cached(callableobj, keyarg=None):
16 """Simple decorator to cache result of method call.""" 17 #print callableobj, keyarg, callableobj.func_code.co_argcount 18 if callableobj.func_code.co_argcount == 1 or keyarg == 0: 19 20 def cache_wrapper1(self, *args): 21 cache = '_%s_cache_' % callableobj.__name__ 22 #print 'cache1?', cache 23 try: 24 return self.__dict__[cache] 25 except KeyError: 26 #print 'miss' 27 value = callableobj(self, *args) 28 setattr(self, cache, value) 29 return value
30 return cache_wrapper1 31 32 elif keyarg: 33 34 def cache_wrapper2(self, *args, **kwargs): 35 cache = '_%s_cache_' % callableobj.__name__ 36 key = args[keyarg-1] 37 #print 'cache2?', cache, self, key 38 try: 39 _cache = self.__dict__[cache] 40 except KeyError: 41 #print 'init' 42 _cache = {} 43 setattr(self, cache, _cache) 44 try: 45 return _cache[key] 46 except KeyError: 47 #print 'miss', self, cache, key 48 _cache[key] = callableobj(self, *args, **kwargs) 49 return _cache[key] 50 return cache_wrapper2 51 52 def cache_wrapper3(self, *args): 53 cache = '_%s_cache_' % callableobj.__name__ 54 #print 'cache3?', cache, self, args 55 try: 56 _cache = self.__dict__[cache] 57 except KeyError: 58 #print 'init' 59 _cache = {} 60 setattr(self, cache, _cache) 61 try: 62 return _cache[args] 63 except KeyError: 64 #print 'miss' 65 _cache[args] = callableobj(self, *args) 66 return _cache[args] 67 return cache_wrapper3 68
69 -def clear_cache(obj, funcname):
70 """Function to clear a cache handled by the cached decorator.""" 71 try: 72 del obj.__dict__['_%s_cache_' % funcname] 73 except KeyError: 74 pass
75
76 -def copy_cache(obj, funcname, cacheobj):
77 """Copy cache for <funcname> from cacheobj to obj.""" 78 cache = '_%s_cache_' % funcname 79 try: 80 setattr(obj, cache, cacheobj.__dict__[cache]) 81 except KeyError: 82 pass
83 84
85 -class wproperty(object):
86 """Simple descriptor expecting to take a modifier function as first argument 87 and looking for a _<function name> to retrieve the attribute. 88 """
89 - def __init__(self, setfunc):
90 self.setfunc = setfunc 91 self.attrname = '_%s' % setfunc.__name__
92
93 - def __set__(self, obj, value):
94 self.setfunc(obj, value)
95
96 - def __get__(self, obj, cls):
97 assert obj is not None 98 return getattr(obj, self.attrname)
99 100
101 -class classproperty(object):
102 - def __init__(self, get):
103 self.get = get
104 - def __get__(self, inst, cls):
105 return self.get(cls)
106 107
108 -class iclassmethod(object):
109 '''Descriptor for method which should be available as class method if called 110 on the class or instance method if called on an instance. 111 '''
112 - def __init__(self, func):
113 self.func = func
114 - def __get__(self, instance, objtype):
115 if instance is None: 116 return MethodType(self.func, objtype, objtype.__class__) 117 return MethodType(self.func, instance, objtype)
118 - def __set__(self, instance, value):
119 raise AttributeError("can't set attribute")
120 121
122 -def timed(f):
123 def wrap(*args, **kwargs): 124 t = clock() 125 #for i in range(100): 126 res = f(*args, **kwargs) 127 print '%s time: %.9f' % (f.__name__, clock() - t) 128 return res
129 return wrap 130 131
132 -def locked(acquire, release):
133 """Decorator taking two methods to acquire/release a lock as argument, 134 returning a decorator function which will call the inner method after 135 having called acquire(self) et will call release(self) afterwards. 136 """ 137 def decorator(f): 138 def wrapper(self, *args, **kwargs): 139 acquire(self) 140 try: 141 return f(self, *args, **kwargs) 142 finally: 143 release(self)
144 return wrapper 145 return decorator 146