New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArgumentParser inconsistent with parse_known_args #60346
Comments
When known and unknown options are given together in the same option string (e.g. -xy) then ArgumentParser behaves in a strange way:
This makes it impossible to use parse_known_args for its intended purpose because every single letter option might be interleaved with other unknown options. I attached a test script that demonstrates this. |
Looks like parse_known_args needs to be taught to not treat unknown text following an option as an argument if the option does not take an argument. That would be in keeping with its mission, I think :) There will still probably be ambiguous cases that will trip you up, but that should help. |
Yes that'd fix the known option before unknown but not the other way around. |
Right. I didn't read what you wrote carefully enough. Clearly parse_known_args is buggy here. |
Writing a patch now. Should be ready in a few hours. |
Make that a few days. I fixed the case where the known arg is first, but not the other one. Will get to it soon, hopefully. |
"- if the unknown option is given first then both options are treated as unknown and returned in the list of remaining arguments." |
parser = argparse.ArgumentParser()
parser.add_argument('-k','--known',action='store_true')
print(parser.parse_known_args(['-k','-u']))
print(parser.parse_known_args(['-ku']))
print(parser.parse_known_args(['-uk'])) I think you want these 3 cases to produce the same output:
With the attached patch, '-ku' produces the same result as '-k -u'. Instead of raising the "ignored explicit argument 'u'" error, if puts '-u' in the 'extras' list. 'parse_args' then raises a "error: unrecognized arguments: u" error. That's an easy change, and does not break anything in the 'test_argparse.py' file. But keep in mind that this test file mostly uses 'parse_args', and usually it ignores the failure messages. Getting '-uk' to work this way would be much harder. While it isn't obvious from the documentation, '-uk' is a valid option string, and '-u' is a valid abbreviation. Notice in 16.4.4.1. of the documentation, the difference between long and short options is based on the number of characters, not whether there it starts with '-' or '--'. So identifying what is wrong with '-uk' would require ambiguous reasoning. I wonder what optparse does. |
Correction: The patch I gave in the last message produces: >>> parser.parse_known_args(['-ku'])
(Namespace(known=False), ['u']) It doesn't take action on the '-k', and puts 'u' in extras, not '-u'. This new patch gets it right: >>> parser.parse_known_args(['-ku'])
(Namespace(known=True), ['-u']) We need more test cases, including ones that work as expected with optparse or other unix parsers. |
Hey this has been open for quite a while, is there anything that needs finishing off? |
The PR is ready for review. |
For |
I tested different corner cases, and neither proposed patches, nor PR #103197 handle them correctly. If
#114180 handles all these corner cases (and maybe more). It is much more complex than the original patch. |
…r.parse_known_args() (pythonGH-114180) (cherry picked from commit e47ecbd) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
…r.parse_known_args() (pythonGH-114180) (cherry picked from commit e47ecbd) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
…r.parse_known_args() (pythonGH-114180)
…r.parse_known_args() (pythonGH-114180)
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
The text was updated successfully, but these errors were encountered: