Issue
In Python3 I can do (thanks to pep 3102):
def some_fun(a, *args, log=None, verbose=0):
pass
and be sure that if I call this with:
some_fun(1, 2, 3, lob=debug_log)
I get a type error on the unexpected keyword argument lob
.
On Python2 I cannot define some_fun()
with keyword-only arguments after an arbitrary argument list. I have to do:
def some_fun(a, *args, **kw):
log = kw.get("log", None)
verbose = kw.get("verbose", 0)
this works all fine and dandy when called correctly, but I would like to get a type error just as with Python3 when I provide one or more wrong keyword arguments to some_fun()
.
Solution
Instead of using .get()
to retrieve the values, use .pop()
and check if kw
is empty after popping all keyword-only arguments.
I use a small helper function for this:
def check_empty_kwargs(kwargs):
import inspect
try:
keys = kwargs.keys()
assert len(keys) == 0
except AssertionError:
# uncomment if you want only one of the unexpected kwargs in the msg
# keys = keys[:1]
msg = "{0}() got an unexpected keyword argument{1} {2}".format(
inspect.stack()[1][3], # caller name
's' if len(keys) > 1 else '',
', '.join(["'{0}'".format(k) for k in keys]))
raise TypeError(msg)
And you would use it like:
def some_fun(a, *args, **kw):
log = kw.pop("log", None)
verbose = kw.pop("verbose", 0)
check_empty_kwargs(kw)
calling that with (assuming debug_log
is defined)
some_fun(1, 2, 3, lob=debug_log)
....
TypeError: some_fun() got an unexpected keyword argument 'lob'
The traceback will (of course) be different from Python3
Answered By - Anthon
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.