def call(func, args):
"""Call the function with args normalized and cast to the correct types.
Args:
func: The function to call.
args: The arguments parsed by docopt.
Returns:
The return value of func.
"""
assert hasattr(func, '__call__'), 'Cannot call func: {}'.format(
func.__name__)
raw_func = (
func if isinstance(func, FunctionType) else func.__class__.__call__)
hints = collections.defaultdict(lambda: Any, get_type_hints(raw_func))
argspec = _getargspec(raw_func)
named_args = {}
varargs = ()
for k, nk, v in _normalize(args):
if nk == argspec.varargs:
hints[nk] = Tuple[hints[nk], ...]
elif nk not in argspec.args and argspec.varkw in hints:
hints[nk] = hints[argspec.varkw]
try:
value = cast(hints[nk], v)
except TypeError as e:
_LOGGER.exception(e)
six.raise_from(exc.InvalidCliValueError(k, v), e)
if nk == argspec.varargs:
varargs = value
elif (nk in argspec.args or argspec.varkw) and (
nk not in named_args or named_args[nk] is None):
named_args[nk] = value
return func(*varargs, **named_args)
评论列表
文章目录