[New-bugs-announce] [issue42973] argparse: mixing optional and positional arguments... not again

Tadek Kijkowski report at bugs.python.org
Tue Jan 19 17:21:34 EST 2021


New submission from Tadek Kijkowski <tkijkowski at gmail.com>:

I have following use case for argparse:

./prog --tracks=80 image1 --tracks=40 image2 --tracks=80 image3 ...

I expected that the following parser would be able process that command line:

parser = argparse.ArgumentParser()
add = parser.add_argument
add('--tracks', choices=['40', '80'])
add('image', nargs='*', action=_CustomAction)
parser.parse_args()

But it stops with 'unrecognized arguments: image2' error. It turns out that there is no way to prepare parser which could handle this command line.

There was a long discussion about this issue in #14191. There were two approaches proposed:
- Allow 'image' action to trigger multiple times with additional encountered parameters.
- Parse all optionals first and all positionals in second pass.

The first approach was represented by a patch by user guilherme-pg. This patch was slightly criticized (undeservedly IMO) and pretty much ignored.

The discussion then focused on the second approach which ended up with introduction of `parse_intermixed_args` into codebase.

The problem with `parse_intermixed_args` is that it defeats the purpose of having intermixed arguments. When the arguments are effectively reordered, there is no way to match "optionals" with "positionals" with they relate to.

In my option the Guilherme's approach was the correct way to go, I would say it was elegant. The only complaint against that patch is that it unnecessarily modified _StoreAction class - instead of that, the way to go is to use "extend" or custom action.

I allowed myself to simplify the changes a bit for readability. The patch doesn't change default functionality, for the cost of changing public API by adding new argument to ArgumentParser constructor.

With the changes applied, I can parse my command line with this code:

parser = argparse.ArgumentParser(greedy_star=True)
add = parser.add_argument
add('--tracks', choices=['40', '80'])
add('image', nargs='*', action=_CustomAction)
parser.parse_args()

----------
components: Library (Lib)
messages: 385301
nosy: monkeyman79
priority: normal
severity: normal
status: open
title: argparse: mixing optional and positional arguments... not again
type: enhancement
versions: Python 3.10

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue42973>
_______________________________________


More information about the New-bugs-announce mailing list