Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.1k
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 ourterms of service andprivacy 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
bedevere-bot commentedNov 25, 2022
Most changes to Pythonrequire a NEWS entry. Please add it using theblurb_it web app or theblurb command-line tool. |
ghost commentedNov 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
to9965694
CompareThere 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 ifaction.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 commentedNov 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... |
Please, don't create new PRs. |
Ok@sobolevn i will open this PR again... and close the new one |
@sobolevn reopened this PR again, please have a review |
Quoting myself:
|
@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 |
@sobolevn do we have any update here? |
I'm still evaluating whether this should be done or not. Here are a few thoughts:
|
How's the evaluation going?
|
@encukou i can work on it further like importing on errors only, what u say? |
That work might not be merged, so it's better to wait for the decision on whether this is a good idea. |
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!))
@@ -84,7 +84,7 @@ | |||
'ZERO_OR_MORE', | |||
] | |||
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.
@@ -2193,9 +2193,9 @@ def test_wrong_argument_subparsers_no_destination_error(self): | |||
subparsers.add_parser('bar') | |||
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.
@@ -2193,9 +2193,9 @@ def test_wrong_argument_subparsers_no_destination_error(self): | |||
subparsers.add_parser('bar') | |||
with self.assertRaises(ArgumentParserError) as excinfo: | |||
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.
Yes you can pick it and if you need any help do let me know. Thanks |
Carrying this forward in#124456 with@abdulrafey38's blessing. Thank you! |
Uh oh!
There was an error while loading.Please reload this page.
Description
Add closet choice if exists in Argparser if wrong choice picked
choices
argument #99749