Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.2k
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.
Changes fromall commits
ef8e4fc
7e8dcf8
8c754cd
4fb8ce6
2f197b3
940a66e
badc5ed
2588ef1
ee05c1e
4a36406
fe169bc
9fe0d95
d12e1c4
35f0961
087895c
6eeae5c
9965694
4ef218a
e63a01c
bfc9262
b3b4a9e
b8bc465
ade070f
3753a0d
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -84,7 +84,7 @@ | ||
'ZERO_OR_MORE', | ||
] | ||
import difflib as _difflib | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. | ||
import os as _os | ||
import re as _re | ||
import sys as _sys | ||
@@ -2541,11 +2541,29 @@ def _get_value(self, action, arg_string): | ||
return result | ||
def _check_value(self, action, value): | ||
if not action.choices and isinstance(action.choices, list): | ||
msg = 'Either add options in choices array or remove it' | ||
raise ArgumentError(action, msg) | ||
# converted value must be one of the choices (if specified) | ||
if action.choices is not None and value not in action.choices: | ||
try: | ||
closest_choice = _difflib.get_close_matches(value, action.choices, 1) | ||
except TypeError: | ||
closest_choice = [] | ||
args = { | ||
'value': value, | ||
'choices': ', '.join(map(repr, action.choices)), | ||
} | ||
if closest_choice: | ||
closest_choice = closest_choice[0] | ||
args['closest'] = closest_choice | ||
msg = _('invalid choice: %(value)r, maybe you meant %(closest)r? ' | ||
'(choose from %(choices)s)') | ||
else: | ||
msg = _('invalid choice: %(value)r (choose from %(choices)s)') | ||
raise ArgumentError(action, msg % args) | ||
# ======================= | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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.assertIn( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. We probably also want some additional test cases here. | ||
"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 commentThe 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. | ||
excinfo.exception.stderr, | ||
) | ||
def test_optional_subparsers(self): | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add closest choice if exists in Argparser if wrong choice picked. |