I am writing a wrapper script using argparse
which accepts a list of arguments that are going to be passed to another program, and some options that are specific to my wrapper. To avoid confusion regarding which options go where, I want any appearance of a non-option argument to suppress processing further arguments as options, as if a --
argument appeared just before it. In other words, something similar to what xterm -e
does.
parse_known_args
is obviously wrong, because it will ignore unknown options, and pick up options appearing after a non-option.
What is the best way to accomplish this in Python? I would prefer to keep using argparse
over parsing the command line manually.
Use nargs=argparse.REMAINDER
or nargs=argparse.PARSER
. The latter differs in that it makes the remaining arguments required.
Neither is particularly well documented as of April 2023: REMAINDER
is barely mentioned twice in the manual (with no explanation what it does), while PARSER
is not present in the manual at all, so it looks even more like an implementation detail; perhaps it is not so wise to actually use it. Beware.
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('argv', nargs=argparse.REMAINDER)
>>> parser.add_argument('--foo', action='store_const', const=True)
>>> print(parser.parse_args(['--foo', 'a', '--foo', 'b']))
Namespace(argv=['a', '--foo', 'b'], foo=True)
>>> print(parser.parse_args(['--foo']))
Namespace(argv=[], foo=True)
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('argv', nargs=argparse.PARSER)
>>> parser.add_argument('--foo', action='store_const', const=True)
>>> print(parser.parse_args(['--foo', 'a', '--foo', 'b']))
Namespace(argv=['a', '--foo', 'b'], foo=True)
>>> print(parser.parse_args(['--foo']))
usage: [-h] [--foo] argv ...
: error: the following arguments are required: argv