attempt to test parse_subparser_arguments
This commit is contained in:
parent
f90d30e0e1
commit
6475345a8f
2 changed files with 51 additions and 26 deletions
|
@ -28,6 +28,37 @@ SUBPARSER_ALIASES = {
|
|||
}
|
||||
|
||||
|
||||
def parse_subparser_arguments(arguments, unparsed_arguments, subparsers):
|
||||
remaining_subparser_arguments = []
|
||||
|
||||
for subparser_name, subparser in reversed(subparsers.items()):
|
||||
if subparser_name not in arguments.keys():
|
||||
continue
|
||||
|
||||
subparser = subparsers[subparser_name]
|
||||
unused_parsed, remaining = subparser.parse_known_args(
|
||||
[argument for argument in unparsed_arguments if argument != subparser_name]
|
||||
)
|
||||
remaining_subparser_arguments.append(remaining)
|
||||
|
||||
# Determine the remaining arguments that no subparsers have consumed.
|
||||
if remaining_subparser_arguments:
|
||||
remaining_arguments = [
|
||||
argument
|
||||
for argument in dict.fromkeys(
|
||||
itertools.chain.from_iterable(remaining_subparser_arguments)
|
||||
).keys()
|
||||
if all(
|
||||
argument in subparser_arguments
|
||||
for subparser_arguments in remaining_subparser_arguments
|
||||
)
|
||||
]
|
||||
else:
|
||||
remaining_arguments = []
|
||||
|
||||
return remaining_arguments
|
||||
|
||||
|
||||
def parse_subparser_arguments(unparsed_arguments, subparsers):
|
||||
'''
|
||||
Given a sequence of arguments and a dict from subparser name to argparse.ArgumentParser
|
||||
|
@ -97,30 +128,7 @@ def parse_subparser_arguments(unparsed_arguments, subparsers):
|
|||
|
||||
# Now ask each subparser, one by one, to greedily consume arguments, from last to first. This
|
||||
# allows subparsers to consume arguments before their parent subparsers do.
|
||||
remaining_subparser_arguments = []
|
||||
|
||||
for subparser_name, subparser in reversed(subparsers.items()):
|
||||
if subparser_name not in arguments.keys():
|
||||
continue
|
||||
|
||||
subparser = subparsers[subparser_name]
|
||||
unused_parsed, remaining = subparser.parse_known_args(
|
||||
[argument for argument in unparsed_arguments if argument != subparser_name]
|
||||
)
|
||||
remaining_subparser_arguments.append(remaining)
|
||||
|
||||
# Determine the remaining arguments that no subparsers have consumed.
|
||||
if remaining_subparser_arguments:
|
||||
remaining_arguments = [
|
||||
argument
|
||||
for argument in dict.fromkeys(
|
||||
itertools.chain.from_iterable(remaining_subparser_arguments)
|
||||
).keys()
|
||||
if all(
|
||||
argument in subparser_arguments
|
||||
for subparser_arguments in remaining_subparser_arguments
|
||||
)
|
||||
]
|
||||
remaining_arguments = parse_subparser_arguments(arguments, unparsed_arguments, subparsers)
|
||||
|
||||
# Special case: If "borg" is present in the arguments, consume all arguments after (+1) the
|
||||
# "borg" action.
|
||||
|
@ -973,11 +981,9 @@ def make_parsers():
|
|||
|
||||
for name, subparser in subparsers.choices.items():
|
||||
merged_subparsers._name_parser_map[name] = subparser
|
||||
subparser._name_parser_map = merged_subparsers._name_parser_map
|
||||
|
||||
for name, subparser in config_subparsers.choices.items():
|
||||
merged_subparsers._name_parser_map[name] = subparser
|
||||
subparser._name_parser_map = merged_subparsers._name_parser_map
|
||||
|
||||
return top_level_parser, merged_subparsers
|
||||
|
||||
|
|
|
@ -175,3 +175,22 @@ def test_parse_subparser_arguments_raises_error_when_no_subparser_is_specified()
|
|||
|
||||
with pytest.raises(ValueError):
|
||||
module.parse_subparser_arguments(('config',), subparsers)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'arguments, unparsed_arguments, subparsers, expected_remaining_arguments',
|
||||
[
|
||||
(
|
||||
{'action': flexmock()},
|
||||
['--verbosity', 'lots'],
|
||||
{'action': flexmock(parse_known_args=lambda arguments: (flexmock(), ['--verbosity', 'lots']))},
|
||||
['--verbosity', 'lots'],
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_get_remaining_arguments_returns_expected_remaining_arguments(
|
||||
arguments, unparsed_arguments, subparsers, expected_remaining_arguments
|
||||
):
|
||||
remaining_arguments = module.get_remaining_arguments(arguments, unparsed_arguments, subparsers)
|
||||
|
||||
assert remaining_arguments == expected_remaining_arguments
|
Loading…
Reference in a new issue