Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork34.1k
Comments
gh-99749: Add closest choice if exists in Argparser if wrong choice picked#99773
gh-99749: Add closest choice if exists in Argparser if wrong choice picked#99773abdulrafey38 wants to merge 24 commits intopython:mainfrom
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 to9965694Compare
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 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... |
sobolevn commentedNov 28, 2022
Please, don't create new PRs. |
abdulrafey38 commentedNov 28, 2022
Ok@sobolevn i will open this PR again... and close the new one |
abdulrafey38 commentedNov 28, 2022
@sobolevn reopened this PR again, please have a review |
sobolevn commentedNov 28, 2022
Quoting myself:
|
abdulrafey38 commentedNov 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 commentedNov 30, 2022
@sobolevn do we have any update here? |
rhettinger commentedDec 3, 2022
I'm still evaluating whether this should be done or not. Here are a few thoughts:
|
encukou commentedMar 19, 2024
How's the evaluation going?
|
abdulrafey38 commentedMar 19, 2024
@encukou i can work on it further like importing on errors only, what u say? |
encukou commentedMar 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 commentedSep 24, 2024
Yes you can pick it and if you need any help do let me know. Thanks |
savannahostrowski commentedSep 24, 2024
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
choicesargument #99749