I have a base decorator that takes arguments but that also is built upon by other decorators. I can't seem to figure where to put the functools.wraps in order to preserve the full signature of the decorated function.
import inspect from functools import wraps # Base decorator def _process_arguments(func, *indices): """ Apply the pre-processing function to each selected parameter """ @wraps(func) def wrap(f): @wraps(f) def wrapped_f(*args): params = inspect.getargspec(f)[0] args_out = list() for ind, arg in enumerate(args): if ind in indices: args_out.append(func(arg)) else: args_out.append(arg) return f(*args_out) return wrapped_f return wrap # Function that will be used to process each parameter def double(x): return x * 2 # Decorator called by end user def double_selected(*args): return _process_arguments(double, *args) # End-user's function @double_selected(2, 0) def say_hello(a1, a2, a3): """ doc string for say_hello """ print('{} {} {}'.format(a1, a2, a3)) say_hello('say', 'hello', 'arguments') The result of this code should be and is:
saysay hello argumentsarguments However, running help on say_hello gives me:
say_hello(*args, **kwargs) doc string for say_hello Everything is preserved except the parameter names.
It seems like I just need to add another @wraps() somewhere, but where?