Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def decorator(caller, func=None):
"""
decorator(caller) converts a caller function into a decorator;
decorator(caller, func) decorates a function using a caller.
"""
if func is not None: # returns a decorated function
evaldict = func.__globals__.copy()
evaldict['_call_'] = caller
evaldict['_func_'] = func
return FunctionMaker.create(
func, "return _call_(_func_, %(shortsignature)s)",
evaldict, undecorated=func, __wrapped__=func)
else: # returns a decorator
if inspect.isclass(caller):
name = caller.__name__.lower()
callerfunc = get_init(caller)
doc = 'decorator(%s) converts functions/generators into ' \
'factories of %s objects' % (caller.__name__, caller.__name__)
fun = getfullargspec(callerfunc).args[1] # second arg
elif inspect.isfunction(caller):
name = '_lambda_' if caller.__name__ == '' \
else caller.__name__
callerfunc = caller
doc = caller.__doc__
fun = getfullargspec(callerfunc).args[0] # first arg
else: # assume caller is an object with a __call__ method
def init_wrapper(cls, delegate_class_list):
"""Returns a function that calls the wrapped class' __init__ function
and then creates an instance of each delegate class in delegate_class_list.
"""
fnc = cls.__init__
spec = getargspec(fnc)
sig = formatargspec(*spec)
template = ["if not hasattr(self, '_delegates_'): self._delegates_ = {}"]
for name, delegate in delegate_class_list:
template.append('self.%s = %s(self)' % (name, delegate.__name__))
template.append("self._delegates_['%s'] = self.%s" % (name,name))
template.append('old_init__(%s)' % ','.join(spec[0]))
f = FunctionMaker.create('__init__%s' % sig, '\n'.join(template),
dict([(c.__name__,c) for n,c in delegate_class_list]+
[('old_init__',fnc)]),
doc=fnc.__doc__, defaults=spec[3])
return types.MethodType(f, None, cls)
def forwarder(cls, fnc, delegatename):
"""Returns a method that forwards calls on the scoping object to calls
on the delegate object. The signature of the delegate method is preserved
in the forwarding method.
"""
fname = fnc.__name__
spec = getargspec(fnc)
sig = formatargspec(*spec)
body = 'return self.%s.%s(%s)' % (delegatename, fname, ','.join(spec[0][1:]))
f = FunctionMaker.create('%s%s' % (fname,sig), body, {}, defaults=spec[3],
doc=fnc.__doc__)
return types.MethodType(f, None, cls)
fun = getfullargspec(callerfunc).args[1] # second arg
elif inspect.isfunction(caller):
name = '_lambda_' if caller.__name__ == '' \
else caller.__name__
callerfunc = caller
doc = caller.__doc__
fun = getfullargspec(callerfunc).args[0] # first arg
else: # assume caller is an object with a __call__ method
name = caller.__class__.__name__.lower()
callerfunc = caller.__call__.__func__
doc = caller.__call__.__doc__
fun = getfullargspec(callerfunc).args[1] # second arg
evaldict = callerfunc.__globals__.copy()
evaldict['_call_'] = caller
evaldict['decorator'] = decorator
return FunctionMaker.create(
'%s(%s)' % (name, fun),
'return decorator(_call_, %s)' % fun,
evaldict, undecorated=caller, __wrapped__=caller,
doc=doc, module=caller.__module__)
def replace_funct(fnc, body):
"""Returns a function with a new body that replaces the given function. The
signature of the original function is preserved in the new function.
"""
fname = fnc.__name__
spec = getargspec(fnc)
sig = formatargspec(*spec)
return FunctionMaker.create('%s%s' % (fname,sig), body, {}, defaults=spec[3],
doc=fnc.__doc__)