Index: third_party/logilab/common/decorators.py |
=================================================================== |
--- third_party/logilab/common/decorators.py (revision 293047) |
+++ third_party/logilab/common/decorators.py (working copy) |
@@ -1,4 +1,4 @@ |
-# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
+# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
# |
# This file is part of logilab-common. |
@@ -16,26 +16,28 @@ |
# You should have received a copy of the GNU Lesser General Public License along |
# with logilab-common. If not, see <http://www.gnu.org/licenses/>. |
""" A few useful function/method decorators. """ |
+ |
+from __future__ import print_function |
+ |
__docformat__ = "restructuredtext en" |
import sys |
+import types |
from time import clock, time |
+from inspect import isgeneratorfunction, getargspec |
-from logilab.common.compat import callable, method_type |
+from logilab.common.compat import method_type |
# XXX rewrite so we can use the decorator syntax when keyarg has to be specified |
-def _is_generator_function(callableobj): |
- return callableobj.func_code.co_flags & 0x20 |
- |
class cached_decorator(object): |
def __init__(self, cacheattr=None, keyarg=None): |
self.cacheattr = cacheattr |
self.keyarg = keyarg |
def __call__(self, callableobj=None): |
- assert not _is_generator_function(callableobj), \ |
+ assert not isgeneratorfunction(callableobj), \ |
'cannot cache generator function: %s' % callableobj |
- if callableobj.func_code.co_argcount == 1 or self.keyarg == 0: |
+ if len(getargspec(callableobj).args) == 1 or self.keyarg == 0: |
cache = _SingleValueCache(callableobj, self.cacheattr) |
elif self.keyarg: |
cache = _MultiValuesKeyArgCache(callableobj, self.keyarg, self.cacheattr) |
@@ -67,7 +69,6 @@ |
try: |
wrapped.__doc__ = self.callable.__doc__ |
wrapped.__name__ = self.callable.__name__ |
- wrapped.func_name = self.callable.func_name |
except: |
pass |
return wrapped |
@@ -226,8 +227,8 @@ |
t = time() |
c = clock() |
res = f(*args, **kwargs) |
- print '%s clock: %.9f / time: %.9f' % (f.__name__, |
- clock() - c, time() - t) |
+ print('%s clock: %.9f / time: %.9f' % (f.__name__, |
+ clock() - c, time() - t)) |
return res |
return wrap |
@@ -249,7 +250,9 @@ |
def monkeypatch(klass, methodname=None): |
- """Decorator extending class with the decorated callable |
+ """Decorator extending class with the decorated callable. This is basically |
+ a syntactic sugar vs class assignment. |
+ |
>>> class A: |
... pass |
>>> @monkeypatch(A) |
@@ -273,11 +276,6 @@ |
raise AttributeError('%s has no __name__ attribute: ' |
'you should provide an explicit `methodname`' |
% func) |
- if callable(func) and sys.version_info < (3, 0): |
- setattr(klass, name, method_type(func, None, klass)) |
- else: |
- # likely a property |
- # this is quite borderline but usage already in the wild ... |
- setattr(klass, name, func) |
+ setattr(klass, name, func) |
return func |
return decorator |