Copying A Python Function's Signature

Like all Python programmers, I'm writing a minimal blogging platform. In my particular case, I'm building my blog using Tornado, MongoDB, and an experimental MongoDB driver I wrote, which I'll announce soon. Rather than build an admin UI where I can create, edit, and delete blog posts, I rely on MarsEdit. My blog simply implements the portion of the metaWeblog XML-RPC API that MarsEdit uses. To implement this API I use Josh Marshall's excellent Tornado-RPC package.
With Tornado-RPC, I declare my particular handlers (e.g., the
metaWeblog.getRecentPosts handler), and Tornado-RPC introspects my
methods' signatures to check if they're receiving the right arguments at
run time:
args, varargs, varkw, defaults = inspect.getargspec(func)This is fantastic. But my XML-RPC handlers tend to all have similar signatures:
def metaWeblog_newPost(self, blogid, user, password, struct, publish):
    pass
def metaWeblog_editPost(self, postid, user, password, struct, publish):
    pass
def metaWeblog_getPost(self, postid, user, password):
    passI want to check that the user and password are correct in each handler method, without duplicating a ton of code. The obvious approach is a decorator:
@auth
def metaWeblog_newPost(self, blogid, user, password, struct, publish):
    pass
def auth(fn):
    argspec = inspect.getargspec(fn)
    @functools.wraps(fn)
    def _auth(*args, **kwargs):
        self = args[0]
        user = args[argspec.args.index('user')]
        password = args[argspec.args.index('password')]
        if not check_authentication(user, password):
            self.result(xmlrpclib.Fault(
                403, 'Bad login/pass combination.'))
        else:
            return fn(*args, **kwargs)
    return _authSimple enough, right? My decorated method checks the user and password, and either returns an authentication fault, or executes the wrapped method.
Problem is, a simple functools.wraps() isn't enough to fool
Tornado-RPC when it inspects my handler methods' signatures using
inspect.getargspec(). functools.wraps() can change a wrapper's
module, name, docstring, and __dict__ to the wrapped function's
values, but it doesn't change the wrapper's actual method signature.
Inspired by Mock, I found this solution:
def auth(fn):
    argspec = inspect.getargspec(fn)
    def _auth(*args, **kwargs):
        user = args[argspec.args.index('user')]
        password = args[argspec.args.index('password')]
        if not check_authentication(user, password):
            self.result(xmlrpclib.Fault(403, 'Bad login/pass combination.'))
        else:
            return fn(*args, **kwargs)
    # For tornadorpc to think _auth has the same arguments as fn,
    # functools.wraps() isn't enough.
    formatted_args = inspect.formatargspec(*argspec)
    fndef = 'lambda %s: _auth%s' % (
        formatted_args.lstrip('(').rstrip(')'), formatted_args)
    fake_fn = eval(fndef, {'_auth': _auth})
    return functools.wraps(fn)(fake_fn)Yes, eval is evil. But for this case, it's the only way to create a
new wrapper function with the same signature as the wrapped function. My
decorator formats a string like:
lambda self, blogid, user, password, struct, publish:\
        _auth(self, blogid, user, password, struct, publish)And evals it to create a lambda. This lambda is the final wrapper. It's
what the @auth decorator returns in lieu of the wrapped function. Now
when Tornado-RPC does inspect.getargspec() on the wrapped function to
check its arguments, it thinks the wrapper has the proper method
signature.