Source code for bronx.syntax.decorators
# -*- coding: utf-8 -*-
"""
Useful decorators.
"""
from __future__ import print_function, absolute_import, unicode_literals, division
import six
import time
#: No automatic export
__all__ = []
[docs]def nicedeco(decorator):
"""
A decorator of decorator, this decorator enforces that the resulting
decorated functions looks like the original one.
"""
def new_decorator(f):
g = decorator(f)
g.__name__ = f.__name__
g.__doc__ = f.__doc__
g.__dict__.update(f.__dict__)
return g
return new_decorator
[docs]def nicedeco_plusdoc(doc_bonus):
"""
A decorator of decorator, this decorator enforces that the resulting
decorated functions looks like the original one but an extra bit of
documentation is added.
"""
def nicedeco_doc(decorator):
def new_decorator(f):
g = decorator(f)
g.__name__ = f.__name__
g.__doc__ = (f.__doc__ +
doc_bonus.format(name=f.__name__))
g.__dict__.update(f.__dict__)
return g
return new_decorator
return nicedeco_doc
[docs]@nicedeco
def disabled(func): # @UnusedVariable
"""This decorator disables the provided function, and does nothing."""
def empty_func(*args, **kw):
pass
return empty_func
[docs]@nicedeco
def printargs(func):
"""This decorator prints out the arguments passed to a function before calling it."""
argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
fname = func.__name__
def echo_func_args(*args, **kw):
print('> > >', fname, '(', ', '.join(
'%s=%r' % entry
for entry in zip(argnames, args) + kw.items()), ')')
return func(*args, **kw)
return echo_func_args
[docs]@nicedeco
def unicode_filter(func):
"""This decorator force unicode when a string is returned."""
def unicode_func(*args, **kw):
out = func(*args, **kw)
if isinstance(out, str):
out = six.text_type(out)
return out
return unicode_func
[docs]def timelimit(logger, nbsec):
"""This decorator warn if the function is more than ``nbsec`` seconds long."""
@nicedeco
def internal_decorator(func):
def timed_func(*args, **kw):
t0 = time.time()
results = func(*args, **kw)
tt = time.time() - t0
if tt >= nbsec:
logger.warn('Function %s took %f seconds', func.__name__, tt)
return results
return timed_func
return internal_decorator
[docs]@nicedeco
def secure_getattr(func):
"""
This decorator is to be used on __getattr__ methods to ensure that essential
method such as __getstate__/__setstate__ are not looked for.
"""
def secured_getattr(self, key):
# Avoid nasty interactions when copying/pickling
if key in ('__bases__',
'__deepcopy__', '__copy__',
'__reduce__', '__reduce_ex__',
'__getinitargs__', '__getnewargs__', '__getnewargs_ex__',
'__getstate__', '__setstate__'):
raise AttributeError(key)
else:
return func(self, key)
return secured_getattr