I have a decorator that validates some parameters and passes an validated key to various functions:
from functools import wraps
ref validate(f):
@wraps(f) # This is to ensure docstrings are passed through the decorated function
def redirect_if_invalid(request, *args, **kwargs):
if request.valid == False:
return HttpResponseRedirect('/login')
else:
newkwargs = { 'key': request.key }
return f(request, *args, **newkwargs)
return redirect_if_invalid
This is used by some other functions:
@validate
def genericHandler(request, key)
pass
I'd call the function like this:
genericHandler(request)
And the decorator generates the 'key' kwarg. However, I'd like to optionally pass in the key at some other point, ie call:
genericHandler(request, 'keydata')
Currently this gives me an error:
TypeError: genericHandler() got multiple values for keyword argument 'key'
How can I get around this? To reiterate, the main goal is to be able to call genericHandler() with or without the optional parameter, and have the decorator generate the parameter only if it's missing.
So far inside the decorator, I can't figure out how to determine whether the 'key' parameter was passed in or not because functools.wraps() seems to hide it.
There's not any reasonable way to do this if you want your wrapper's signature to still be
(request, *args, **kwargs)
. On the other hand, it looks like your decorator already assumes that the wrapped function takes akey
parameter, so why not rewrite the wrapper to take one as well? In that case it becomes trivial to check if it's been passed or not.You can add the
*args
and**kwargs
parameters back if you like, of course.