Skip to content Skip to sidebar Skip to footer

Argparse.remainder Changes The Behavior Of Positional Arguments

Without argparse.REMAINDER, optional arguments can be in front of or after positional arguments: import argparse parser = argparse.ArgumentParser() parser.add_argument('-a') parse

Solution 1:

To add to kabanus's answer, it may help to know a bit about how arguments are parsed.

It iterates over the arguments, first looking for positionals, then optionals, then positionals, ...,

At the positionals step it tries to match as many as it can, using the nargs as a primary factor. The default is one string (your 'b'); '*' will match up to the next optional (the -a); but a REMAINDER ignores that constraint and matches to the end. So a 'positionals' evaluation is greedy, and one with REMAINDER is especially greedy.

So in the '2 -a 1 3' case, the initial '2' can match 'b', and the rest can match 'c'. Just one 'positionals' evaluation consumes the whole list, including the '-a', and it is done.

The documentation example shows this:

>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')

The '--foo' is handled as optional, but the '--arg1' is part of the REMAINDER. 'args' is filled immediately after 'command'.

If you want to retain control over when the REMAINDER is used, make it an optional, add_argument('-c',nargs='...'). Otherwise you are at the mercy of this positionals/optionals loop.

By the way, subparsers are implemented with a narg=argarse.PARSER, which is the name for '+...'. It's like REMAINDER but requires at least one string (the subparser name). It too consumes everything in its path.

Instead of REMAINDER you might want to use '*' and use '--' to trigger the 'consume everything else' action.

Solution 2:

From the documentation:

argparse.REMAINDER. All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities:

this means using remainder by definition cannot have (any) other arguments after the argument accepting this, as they are part of the remainder, and would go into this argument.

Post a Comment for "Argparse.remainder Changes The Behavior Of Positional Arguments"