python / cpython

The Python programming language
https://www.python.org
Other
63.72k stars 30.53k forks source link

argparse option argument with `nargs=argparse.REMAINDER` is misplaced in usage line #92625

Open dhedde opened 2 years ago

dhedde commented 2 years ago

Bug report

When using an optional argument with nargs=argparse.REMAINDER, the argument appears within the list of optional arguments and before any positional arguments. I expected it to be placed last in usage line, which would better match the behavior since it consumes any following parameters. Not sure it is really bug...

The following scripts shows the issue:

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('foo')
parser.add_argument('--extra', nargs=argparse.REMAINDER)
parser.add_argument('--option')

args = parser.parse_args()

[--extra ...] is not at all last in the usage line:

$ ./test.py -h
usage: test.py [-h] [--extra ...] [--option OPTION] foo

positional arguments:
  foo

options:
  -h, --help       show this help message and exit
  --extra ...
  --option OPTION

Your environment

rhettinger commented 2 years ago

Not sure it is really bug...

We'll call it a feature request — nothing good can come from changing existing tools that were developed and tested with the current behavior.

I expected it to be placed last in usage line, which would better match the behavior since it consumes any following parameters.

That makes sense.

Still, I'm not sure this change should be made because REMAINDER is now an undocumented (soft-deprecated) feature because it had design flaws that weren't fixable without breaking existing code.

Also, the current code for _format_usage() is one of the few clean parts of argparse. It has loose coupling that only depends on prog and the notion of "positionals" vs "optionals". We would have to add tight-coupling to nargs=REMAINDER and introduce new special case code paths for every step along the way.

hpaulj commented 2 years ago

Currently usage shows the optionals first, and positionals last. There's no special provision for nargs values like this. Usage formatting is further complicated when it's long enough to split into multilines. Then positionals are placed on their own line. Overall usage formatting is quite brittle, easily messed up.

serhiy-storchaka commented 2 months ago

See also #105947.