This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author monkeyman79
Recipients monkeyman79
Date 2021-01-19.22:21:34
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1611094894.69.0.476759327253.issue42973@roundup.psfhosted.org>
In-reply-to
Content
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()
History
Date User Action Args
2021-01-19 22:21:34monkeyman79setrecipients: + monkeyman79
2021-01-19 22:21:34monkeyman79setmessageid: <1611094894.69.0.476759327253.issue42973@roundup.psfhosted.org>
2021-01-19 22:21:34monkeyman79linkissue42973 messages
2021-01-19 22:21:34monkeyman79create