Can you list the keyword arguments a function receives?
This will print names of all passable arguments, keyword and non-keyword ones:
def func(one, two="value"):
y = one, two
return y
print func.func_code.co_varnames[:func.func_code.co_argcount]
This is because first co_varnames
are always parameters (next are local variables, like y
in the example above).
So now you could have a function:
def get_valid_args(func, args_dict):
'''Return dictionary without invalid function arguments.'''
validArgs = func.func_code.co_varnames[:func.func_code.co_argcount]
return dict((key, value) for key, value in args_dict.iteritems()
if key in validArgs)
Which you then could use like this:
>>> func(**get_valid_args(func, args))
if you really need only keyword arguments of a function, you can use the func_defaults
attribute to extract them:
def get_valid_kwargs(func, args_dict):
validArgs = func.func_code.co_varnames[:func.func_code.co_argcount]
kwargsLen = len(func.func_defaults) # number of keyword arguments
validKwargs = validArgs[-kwargsLen:] # because kwargs are last
return dict((key, value) for key, value in args_dict.iteritems()
if key in validKwargs)
You could now call your function with known args, but extracted kwargs, e.g.:
func(param1, param2, **get_valid_kwargs(func, kwargs_dict))
This assumes that func
uses no *args
or **kwargs
magic in its signature.
A little nicer than inspecting the code object directly and working out the variables is to use the inspect module.
>>> import inspect
>>> def func(a,b,c=42, *args, **kwargs): pass
>>> inspect.getargspec(func)
(['a', 'b', 'c'], 'args', 'kwargs', (42,))
If you want to know if its callable with a particular set of args, you need the args without a default already specified. These can be got by:
def get_required_args(func):
args, varargs, varkw, defaults = inspect.getargspec(func)
if defaults:
args = args[:-len(defaults)]
return args # *args and **kwargs are not required, so ignore them.
Then a function to tell what you are missing from your particular dict is:
def missing_args(func, argdict):
return set(get_required_args(func)).difference(argdict)
Similarly, to check for invalid args, use:
def invalid_args(func, argdict):
args, varargs, varkw, defaults = inspect.getargspec(func)
if varkw: return set() # All accepted
return set(argdict) - set(args)
And so a full test if it is callable is :
def is_callable_with_args(func, argdict):
return not missing_args(func, argdict) and not invalid_args(func, argdict)
(This is good only as far as python's arg parsing. Any runtime checks for invalid values in kwargs
obviously can't be detected.)