Uh oh!
There was an error while loading. Please reload this page.
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 into
Conversation
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. |
3416d13 to
9965694Compare
noamcohen97
left a comment
There was a problem hiding this comment.
Great feature!
Maybe a way to opt out of this feature should be added?
| if closest_choice := closest_choice and closest_choice[0] or None: | ||
| args['closest'] = closest_choice |
There was a problem hiding this comment.
| 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.
the one liner is less readable - at least to me
| 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.
this might fail if action.choices are not strings
There was a problem hiding this comment.
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.
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) |
ndenissov
left a comment
There was a problem hiding this comment.
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= []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.
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.
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.
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.
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