Source code for pulsar.utils.tools.arity
import inspect
__all__ = ['checkarity']
[docs]def checkarity(func, args, kwargs, discount=0):
'''Check if arguments respect a given function arity and return
an error message if the check did not pass,
otherwise it returns ``None``.
:parameter func: the function.
:parameter args: function arguments.
:parameter kwargs: function key-valued parameters.
:parameter discount: optional integer which discount the number of
positional argument to check. Default ``0``.
'''
spec = inspect.getargspec(func)
self = getattr(func, '__self__', None)
if self and spec.args:
discount += 1
args = list(args)
defaults = list(spec.defaults or ())
len_defaults = len(defaults)
len_args = len(spec.args) - discount
len_args_input = len(args)
minlen = len_args - len_defaults
totlen = len_args_input + len(kwargs)
maxlen = len_args
if spec.varargs or spec.keywords:
maxlen = None
if not minlen:
return
if not spec.defaults and maxlen:
start = '"{0}" takes'.format(func.__name__)
else:
if maxlen and totlen > maxlen:
start = '"{0}" takes at most'.format(func.__name__)
else:
start = '"{0}" takes at least'.format(func.__name__)
if totlen < minlen:
return '{0} {1} parameters. {2} given.'.format(start, minlen, totlen)
elif maxlen and totlen > maxlen:
return '{0} {1} parameters. {2} given.'.format(start, maxlen, totlen)
# Length of parameter OK, check names
if len_args_input < len_args:
l = minlen - len_args_input
for arg in spec.args[discount:]:
if args:
args.pop(0)
else:
if l > 0:
if defaults:
defaults.pop(0)
elif arg not in kwargs:
return ('"{0}" has missing "{1}" parameter.'
.format(func.__name__, arg))
kwargs.pop(arg, None)
l -= 1
if kwargs and maxlen:
s = ''
if len(kwargs) > 1:
s = 's'
p = ', '.join('"{0}"'.format(p) for p in kwargs)
return ('"{0}" does not accept {1} parameter{2}.'
.format(func.__name__, p, s))
elif len_args_input > len_args + len_defaults:
n = len_args + len_defaults
start = '"{0}" takes'.format(func.__name__)
return ('{0} {1} positional parameters. {2} given.'
.format(start, n, len_args_input))