Fix choices validation with unannotated args

Something like:

    @cmdutils.argument('foo', choices=['one', 'two'])
    def func(foo):
        # ...

didn't actually validate the foo argument, since the inferred type of
the argument is None, and that skipped all conversion (and thus
validation).

Fixes #1871
See #1885
This commit is contained in:
Florian Bruhin 2016-08-23 22:01:21 +02:00
parent 8643f6f28d
commit 12061b8bb1
3 changed files with 16 additions and 4 deletions

View File

@ -119,7 +119,7 @@ def type_conv(param, typ, value, *, str_choices=None):
if utils.is_enum(typ):
_check_choices(param, value, [arg_name(e.name) for e in typ])
return typ[value.replace('-', '_')]
elif typ is str:
elif typ in [str, None]:
if str_choices is not None:
_check_choices(param, value, str_choices)
return value

View File

@ -422,11 +422,9 @@ class Command:
choices = self.get_arg_info(param).choices
value = argparser.multitype_conv(param, types, value,
str_choices=choices)
elif typ is str:
elif typ in [str, None]:
choices = self.get_arg_info(param).choices
value = argparser.type_conv(param, typ, value, str_choices=choices)
elif typ is None:
pass
elif typ is bool: # no type conversion for flags
assert isinstance(value, bool)
else:

View File

@ -295,6 +295,20 @@ class TestRegister:
else:
assert cmd._get_call_args(win_id=0) == ([expected], {})
def test_choices_no_annotation(self):
# https://github.com/The-Compiler/qutebrowser/issues/1871
@cmdutils.register()
@cmdutils.argument('arg', choices=['foo', 'bar'])
def fun(arg):
"""Blah."""
pass
cmd = cmdutils.cmd_dict['fun']
cmd.namespace = cmd.parser.parse_args(['fish'])
with pytest.raises(cmdexc.ArgumentTypeError):
cmd._get_call_args(win_id=0)
def test_pos_arg_info(self):
@cmdutils.register()
@cmdutils.argument('foo', choices=('a', 'b'))