¿Cómo puedo cambiar mediante progtwigción el argspec de una función en un decorador de python?

Dada una función:

def func(f1, kw='default'): pass bare_argspec = inspect.getargspec(func) @decorator def func2(f1, kw='default'): pass decorated_argspec = inspect.getargspec(func2) 

¿Cómo puedo crear un decorador tal que bare_argspec == decorated_argspec ?

(En cuanto a por qué, el marco que llama a la función decorada realiza una inspección argspec para elegir qué pasar, por lo que el decorador debe conservar el mismo argspec para jugar bien. Cuando hice esta pregunta en #python, obtuve una larga discurso sobre por qué el marco apesta, que no es lo que estoy buscando; tengo que resolver el problema aquí. Además, también me interesa la respuesta)

El módulo decorador de Michele Simionato tiene un decorador llamado decorador que conserva los argspecs de funciones.

 import inspect import decorator def func(f1, kw='default'): pass bare_argspec = inspect.getargspec(func) print(bare_argspec) # ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',)) @decorator.decorator def mydecorator(func,*args,**kw): result=func(*args,**kw) return result @mydecorator def func2(f1, kw='default'): pass decorated_argspec = inspect.getargspec(func2) print(decorated_argspec) # ArgSpec(args=['f1', 'kw'], varargs=None, keywords=None, defaults=('default',)) assert(bare_argspec==decorated_argspec) 

Ahí está el módulo decorador :

 from decorator import decorator @decorator def trace(func, *args, **kw): print 'calling', func, 'with', args, kw return func(*args, **kw) 

Eso hace que el trace sea ​​un decorador con los mismos argspecs que la función decorada. Ejemplo:

 >>> @trace ... def f(x, y=1, z=2, *args, **kw): ... pass >>> f(0, 3) calling f with (0, 3, 2), {} >>> from inspect import getargspec >>> print getargspec(f) ArgSpec(args=['x', 'y', 'z'], varargs='args', keywords='kw', defaults=(1, 2)) 

¿Son functools.update_wrapper() y / o functools.wraps() lo suficientemente buenos?