I said it was very little tested! ;) This should work better:
#<decorate.py> def _signature_gen(varnames, n_default_args, n_args, rm_defaults=False): n_non_default_args = n_args - n_default_args non_default_names = varnames[:n_non_default_args] default_names = varnames[n_non_default_args:n_args] other_names = varnames[n_args:] n_other_names = len(other_names) for name in non_default_names: yield "%s" % name for i, name in enumerate(default_names): if rm_defaults: yield name else: yield "%s = arg[%s]" % (name, i) if n_other_names == 1: yield "*%s" % other_names[0] elif n_other_names == 2: yield "*%s" % other_names[0] yield "**%s" % other_names[1] def decorate(func, caller): argdefs = func.func_defaults or () argcount = func.func_code.co_argcount varnames = func.func_code.co_varnames signature = ", ".join(_signature_gen(varnames, len(argdefs), argcount)) variables = ", ".join(_signature_gen(varnames, len(argdefs), argcount, rm_defaults=True)) lambda_src = "lambda %s: call(func, %s)" % (signature, variables) dec_func = eval(lambda_src, dict(func=func, call=caller, arg=argdefs)) dec_func.__name__ = func.__name__ dec_func.__doc__ = func.__doc__ dec_func.__dict__ = func.__dict__.copy() return dec_func #</decorate.py> -- http://mail.python.org/mailman/listinfo/python-list