Refactor how cmdutils.ArgInfo works
It's now a real class, and some other aspects about how it's handled were cleaned up as well.
This commit is contained in:
parent
9eeaeb95c3
commit
04367851c3
@ -190,12 +190,6 @@ class argument: # pylint: disable=invalid-name
|
|||||||
if self._argname not in inspect.signature(func).parameters:
|
if self._argname not in inspect.signature(func).parameters:
|
||||||
raise ValueError("{} has no argument {}!".format(funcname,
|
raise ValueError("{} has no argument {}!".format(funcname,
|
||||||
self._argname))
|
self._argname))
|
||||||
|
|
||||||
# Fill up args which weren't passed
|
|
||||||
for arg in command.ArgInfo._fields:
|
|
||||||
if arg not in self._kwargs:
|
|
||||||
self._kwargs[arg] = None
|
|
||||||
|
|
||||||
if not hasattr(func, 'qute_args'):
|
if not hasattr(func, 'qute_args'):
|
||||||
func.qute_args = {}
|
func.qute_args = {}
|
||||||
elif func.qute_args is None:
|
elif func.qute_args is None:
|
||||||
@ -203,5 +197,4 @@ class argument: # pylint: disable=invalid-name
|
|||||||
"@cmdutils.register for {}!".format(funcname))
|
"@cmdutils.register for {}!".format(funcname))
|
||||||
|
|
||||||
func.qute_args[self._argname] = command.ArgInfo(**self._kwargs)
|
func.qute_args[self._argname] = command.ArgInfo(**self._kwargs)
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
@ -35,7 +35,23 @@ def arg_name(name):
|
|||||||
return name.rstrip('_').replace('_', '-')
|
return name.rstrip('_').replace('_', '-')
|
||||||
|
|
||||||
|
|
||||||
ArgInfo = collections.namedtuple('ArgInfo', ['flag'])
|
class ArgInfo:
|
||||||
|
|
||||||
|
"""Information about an argument."""
|
||||||
|
|
||||||
|
def __init__(self, win_id=False, count=False, flag=None):
|
||||||
|
self.win_id = win_id
|
||||||
|
self.count = count
|
||||||
|
self.flag = flag
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (self.win_id == other.win_id and
|
||||||
|
self.count == other.count and
|
||||||
|
self.flag == other.flag)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return utils.get_repr(self, win_id=self.win_id, count=self.count,
|
||||||
|
flag=self.flag, constructor=True)
|
||||||
|
|
||||||
|
|
||||||
class Command:
|
class Command:
|
||||||
@ -57,6 +73,7 @@ class Command:
|
|||||||
win_id_arg: The name of the win_id parameter, or None.
|
win_id_arg: The name of the win_id parameter, or None.
|
||||||
flags_with_args: A list of flags which take an argument.
|
flags_with_args: A list of flags which take an argument.
|
||||||
no_cmd_split: If true, ';;' to split sub-commands is ignored.
|
no_cmd_split: If true, ';;' to split sub-commands is ignored.
|
||||||
|
_qute_args: The saved data from @cmdutils.argument
|
||||||
_type_conv: A mapping of conversion functions for arguments.
|
_type_conv: A mapping of conversion functions for arguments.
|
||||||
_needs_js: Whether the command needs javascript enabled
|
_needs_js: Whether the command needs javascript enabled
|
||||||
_modes: The modes the command can be executed in.
|
_modes: The modes the command can be executed in.
|
||||||
@ -126,12 +143,13 @@ class Command:
|
|||||||
self.flags_with_args = []
|
self.flags_with_args = []
|
||||||
self._type_conv = {}
|
self._type_conv = {}
|
||||||
|
|
||||||
args = self._inspect_func()
|
|
||||||
|
|
||||||
# This is checked by future @cmdutils.argument calls so they fail
|
# This is checked by future @cmdutils.argument calls so they fail
|
||||||
# (as they'd be silently ignored otherwise)
|
# (as they'd be silently ignored otherwise)
|
||||||
|
self._qute_args = getattr(self.handler, 'qute_args', {})
|
||||||
self.handler.qute_args = None
|
self.handler.qute_args = None
|
||||||
|
|
||||||
|
args = self._inspect_func()
|
||||||
|
|
||||||
if self.completion is not None and len(self.completion) > len(args):
|
if self.completion is not None and len(self.completion) > len(args):
|
||||||
raise ValueError("Got {} completions, but only {} "
|
raise ValueError("Got {} completions, but only {} "
|
||||||
"arguments!".format(len(self.completion),
|
"arguments!".format(len(self.completion),
|
||||||
@ -178,6 +196,10 @@ class Command:
|
|||||||
raise TypeError("{}: functions with varkw arguments are not "
|
raise TypeError("{}: functions with varkw arguments are not "
|
||||||
"supported!".format(self.name[0]))
|
"supported!".format(self.name[0]))
|
||||||
|
|
||||||
|
def _get_arg_info(self, param):
|
||||||
|
"""Get an ArgInfo tuple for the given inspect.Parameter."""
|
||||||
|
return self._qute_args.get(param.name, ArgInfo())
|
||||||
|
|
||||||
def _get_typeconv(self, param, typ):
|
def _get_typeconv(self, param, typ):
|
||||||
"""Get a dict with a type conversion for the parameter.
|
"""Get a dict with a type conversion for the parameter.
|
||||||
|
|
||||||
@ -204,6 +226,7 @@ class Command:
|
|||||||
True if the parameter is special, False otherwise.
|
True if the parameter is special, False otherwise.
|
||||||
"""
|
"""
|
||||||
if param.name == self.count_arg:
|
if param.name == self.count_arg:
|
||||||
|
arg_info = self._get_arg_info(param)
|
||||||
if param.default is inspect.Parameter.empty:
|
if param.default is inspect.Parameter.empty:
|
||||||
raise TypeError("{}: handler has count parameter "
|
raise TypeError("{}: handler has count parameter "
|
||||||
"without default!".format(self.name))
|
"without default!".format(self.name))
|
||||||
@ -239,13 +262,6 @@ class Command:
|
|||||||
if not self.ignore_args:
|
if not self.ignore_args:
|
||||||
for param in signature.parameters.values():
|
for param in signature.parameters.values():
|
||||||
annotation_info = self._parse_annotation(param)
|
annotation_info = self._parse_annotation(param)
|
||||||
|
|
||||||
try:
|
|
||||||
arg_info = self.handler.qute_args[param.name]
|
|
||||||
except (KeyError, AttributeError):
|
|
||||||
arg_info = ArgInfo(**{name: None
|
|
||||||
for name in ArgInfo._fields})
|
|
||||||
|
|
||||||
if param.name == 'self':
|
if param.name == 'self':
|
||||||
continue
|
continue
|
||||||
if self._inspect_special_param(param):
|
if self._inspect_special_param(param):
|
||||||
@ -302,19 +318,19 @@ class Command:
|
|||||||
kwargs['nargs'] = '?'
|
kwargs['nargs'] = '?'
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def _param_to_argparse_args(self, param, annotation_info, arg_info):
|
def _param_to_argparse_args(self, param, annotation_info):
|
||||||
"""Get argparse positional arguments for a parameter.
|
"""Get argparse positional arguments for a parameter.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
param: The inspect.Parameter object to get the args for.
|
param: The inspect.Parameter object to get the args for.
|
||||||
annotation_info: An AnnotationInfo tuple for the parameter.
|
annotation_info: An AnnotationInfo tuple for the parameter.
|
||||||
arg_info: An ArgInfo tuple for the parameter or None
|
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
A list of args.
|
A list of args.
|
||||||
"""
|
"""
|
||||||
args = []
|
args = []
|
||||||
name = arg_name(param.name)
|
name = arg_name(param.name)
|
||||||
|
arg_info = self._get_arg_info(param)
|
||||||
|
|
||||||
if arg_info.flag is not None:
|
if arg_info.flag is not None:
|
||||||
shortname = arg_info.flag
|
shortname = arg_info.flag
|
||||||
@ -463,6 +479,7 @@ class Command:
|
|||||||
return args, kwargs
|
return args, kwargs
|
||||||
|
|
||||||
for i, param in enumerate(signature.parameters.values()):
|
for i, param in enumerate(signature.parameters.values()):
|
||||||
|
arg_info = self._get_arg_info(param)
|
||||||
if i == 0 and self._instance is not None:
|
if i == 0 and self._instance is not None:
|
||||||
# Special case for 'self'.
|
# Special case for 'self'.
|
||||||
self._get_self_arg(win_id, param, args)
|
self._get_self_arg(win_id, param, args)
|
||||||
|
@ -234,13 +234,6 @@ class TestArgument:
|
|||||||
|
|
||||||
# pylint: disable=unused-variable
|
# pylint: disable=unused-variable
|
||||||
|
|
||||||
def _arginfo(self, **kwargs):
|
|
||||||
"""Helper method to get an ArgInfo tuple."""
|
|
||||||
for arg in command.ArgInfo._fields:
|
|
||||||
if arg not in kwargs:
|
|
||||||
kwargs[arg] = None
|
|
||||||
return command.ArgInfo(**kwargs)
|
|
||||||
|
|
||||||
def test_invalid_argument(self):
|
def test_invalid_argument(self):
|
||||||
with pytest.raises(ValueError) as excinfo:
|
with pytest.raises(ValueError) as excinfo:
|
||||||
@cmdutils.argument('foo')
|
@cmdutils.argument('foo')
|
||||||
@ -256,8 +249,8 @@ class TestArgument:
|
|||||||
"""Blah."""
|
"""Blah."""
|
||||||
pass
|
pass
|
||||||
expected = {
|
expected = {
|
||||||
'foo': self._arginfo(flag='x'),
|
'foo': command.ArgInfo(flag='x'),
|
||||||
'bar': self._arginfo(flag='y')
|
'bar': command.ArgInfo(flag='y')
|
||||||
}
|
}
|
||||||
assert fun.qute_args == expected
|
assert fun.qute_args == expected
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user