Reputation: 23
Working on a new version of the library I change one of the default arguments of several functions. So I'd like to add a temporary warning that occurs when user calls a function without explicitly specified parameters (so function is called with its defaults).
It could be easily done just by adding the warning function and calling it inside each of base functions:
def warning(formatting):
if formatting is None:
sys.stderr.write("WARNING: The default format has changed to new_format")
return 'new_format'
return formatting
def my_function(arg1, arg2, formatting=None):
formatting = warning(formatting)
... # the following function code
However it would be more convenient to do it using decorator (for code readability). So I've implemented something like this:
def check_default_format(fun):
def warning(*a, **kw):
if 'formatting' not in kw.keys() or kw['formatting'] is None:
kw['formatting'] = 'new_format'
sys.stderr.write("WARNING: The default format has changed to new_format")
return fun(*a, **kw)
return warning
@check_default_format
def my_function(arg1, arg2, formatting=None):
... # the function code
That works as expected when I call my_function
without formatting
parameter and if formatting
is specified as a keyword parameter.
But how to include the possibility that my_function
can be called with only positional parameters? Calling decorated my_function('arg1', 'arg2', 'some_format')
will produce an TypeError
due to duplication of formatting
parameter.
Note: I cannot assume that the formatting
is always the 3rd parameter as I need to decorate different functions. I also cannot change the parameters order to preserve backward compatibility.
Upvotes: 0
Views: 229
Reputation: 43136
In python 3, you can use the inspect module's Signature.bind_partial
:
def check_default_format(fun):
@wraps(fun)
def wrapper(*a, **kw):
sig= inspect.signature(fun)
args= sig.bind_partial(*a, **kw)
if 'formatting' not in args.arguments or args.arguments['formatting'] is None:
kw['formatting'] = 'new_format'
sys.stderr.write("WARNING: The default format has changed to new_format")
return fun(*a, **kw)
return wrapper
Upvotes: 1