Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34k
gh-99749: Add closest choice if exists in Argparser if wrong choice picked#99773
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
abdulrafey38 commented Nov 25, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
bedevere-bot commented Nov 25, 2022
Most changes to Python require a NEWS entry. Please add it using the blurb_it web app or the blurb command-line tool. |
ghost commented Nov 25, 2022 • edited by ghost
Loading Uh oh!
There was an error while loading. Please reload this page.
edited by ghost
Uh oh!
There was an error while loading. Please reload this page.
3416d13 to 9965694Compare
noamcohen97 left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great feature!
Maybe a way to opt out of this feature should be added?
Lib/argparse.py Outdated
| if closest_choice := closest_choice and closest_choice[0] or None: | ||
| args['closest'] = closest_choice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ifclosest_choice:=closest_choiceandclosest_choice[0] orNone: | |
| args['closest'] =closest_choice | |
| ifclosest_choice: | |
| args['closest'] =closest_choice[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not the above one liner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the one liner is less readable - at least to me
Lib/argparse.py Outdated
| args ={'value': value, | ||
| 'choices': ', '.join(map(repr, action.choices))} | ||
| msg = _('invalid choice: %(value)r (choose from %(choices)s)') | ||
| closest_choice = _difflib.get_close_matches(value, action.choices) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this might fail if action.choices are not strings
abdulrafey38Nov 26, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
argparser does not accept choices other than string, it will throw error even before reaching at this line
reference ==> https://stackoverflow.com/questions/49578928/typeerror-int-object-is-not-subscriptable-when-i-try-to-pass-three-arguments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The second example for the documentation (https://docs.python.org/3/library/argparse.html#choices)
parser=argparse.ArgumentParser(prog='doors.py') parser.add_argument('door', type=int, choices=range(1, 4)) print(parser.parse_args(['3']))Also - I would use
| closest_choice=_difflib.get_close_matches(value, action.choices) | |
| closest_choice=_difflib.get_close_matches(value, action.choices, 1) |
NIKDISSV-Forever left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, instead of just this
closet_choice=_difflib.get_close_matches(value, action.choices)Add
ifisinstance(value, Iterable) andall(isinstance(option, Sized) foroptioninaction.choices)): closet_choice=_difflib.get_close_matches(value, action.choices, 1) # also n=1 (default 3)else: closet_choice= []or this (better in my opinion)
try: closet_choice=_difflib.get_close_matches(value, action.choices, 1) exceptTypeError: closet_choice= []abdulrafey38 commented Nov 28, 2022 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Closing this pull request & opening a new one as this PR contains unwanted commits... |
sobolevn commented Nov 28, 2022
Please, don't create new PRs. |
abdulrafey38 commented Nov 28, 2022
Ok @sobolevn i will open this PR again... and close the new one |
abdulrafey38 commented Nov 28, 2022
@sobolevn reopened this PR again, please have a review |
sobolevn commented Nov 28, 2022
Quoting myself:
|
abdulrafey38 commented Nov 28, 2022
@sobolevn no this is not enough now, as we change argparser logic here ==> when we pass a choice which is not in choices array it now throws an exception with a different error message (this error message now includes closest suggestions too if available) & in the test case we are passing ['foo','bar'] in choices array and adding 'baz' in argparser. so instead of showing previous message which is (Isn't |
abdulrafey38 commented Nov 30, 2022
@sobolevn do we have any update here? |
rhettinger commented Dec 3, 2022
I'm still evaluating whether this should be done or not. Here are a few thoughts:
|
encukou commented Mar 19, 2024
How's the evaluation going?
|
abdulrafey38 commented Mar 19, 2024
@encukou i can work on it further like importing on errors only, what u say? |
encukou commented Mar 20, 2024
That work might not be merged, so it's better to wait for the decision on whether this is a good idea. |
savannahostrowski left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - thanks for the PR! I'm in the process of triaging existing PRs for argparse and noticed this was still open.
A couple of comments but, this still works as intended.
(If you haven't got the bandwidth, let me know and I'd also be happy to carry the PR forward (with credit to you, of course!))
| ] | ||
| import difflib as _difflib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'd probably want to move the import down into the case where the error is thrown, since this is probably not going to be used very often.
| with self.assertRaises(ArgumentParserError) as excinfo: | ||
| parser.parse_args(('baz',)) | ||
| self.assertRegex( | ||
| self.assertIn( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably also want some additional test cases here.
| parser.parse_args(('baz',)) | ||
| self.assertRegex( | ||
| self.assertIn( | ||
| "error: argument{foo,bar}: invalid choice: 'baz', maybe you meant 'bar'? (choose from 'foo', 'bar')", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be interested in others' opinions around the verbiage here. It seems like we are using both "Maybe you meant" and "Did you mean" verbiage in the codebase. Not sure if we have any principle around this.
abdulrafey38 commented Sep 24, 2024
Hi @savannahostrowski , Yes you can pick it and if you need any help do let me know. Thanks |
savannahostrowski commented Sep 24, 2024
Carrying this forward in #124456 with @abdulrafey38's blessing. Thank you! |
Description
Add closet choice if exists in Argparser if wrong choice picked
choicesargument #99749