pythoncommand-lineargparse

Suppressing option processing after a non-option command-line argument


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.


Solution

  • Use nargs=argparse.REMAINDER or nargs=argparse.PARSER. The latter differs in that it makes the remaining arguments required.

    Neither is documented as of June 2025: argparse.REMAINDER used to be documented in Python 3.8, but was quietly reduced to a passing mention in 3.9 with no explanation what it does, and excised entirely in 3.11. Meanwhile argparse.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 either. 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