Skip to content

Commit a13076e

Browse files
committed
Keep the original input during _check_value
This will allow better error messages.
1 parent f54bc0e commit a13076e

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

Lib/argparse.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,7 +2528,7 @@ def _get_values(self, action, arg_strings):
25282528
elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
25292529
arg_string, = arg_strings
25302530
value = self._get_value(action, arg_string)
2531-
self._check_value(action, value)
2531+
self._check_value(action, value, arg_string)
25322532

25332533
# REMAINDER arguments convert all values, checking none
25342534
elif action.nargs == REMAINDER:
@@ -2537,7 +2537,7 @@ def _get_values(self, action, arg_strings):
25372537
# PARSER arguments convert all values, but check only the first
25382538
elif action.nargs == PARSER:
25392539
value = [self._get_value(action, v) for v in arg_strings]
2540-
self._check_value(action, value[0])
2540+
self._check_value(action, value[0], arg_strings[0])
25412541

25422542
# SUPPRESS argument does not put anything in the namespace
25432543
elif action.nargs == SUPPRESS:
@@ -2546,8 +2546,8 @@ def _get_values(self, action, arg_strings):
25462546
# all other types of nargs produce a list
25472547
else:
25482548
value = [self._get_value(action, v) for v in arg_strings]
2549-
for v in value:
2550-
self._check_value(action, v)
2549+
for v, s in zip(value, arg_strings):
2550+
self._check_value(action, v, s)
25512551

25522552
# return the converted value
25532553
return value
@@ -2576,34 +2576,38 @@ def _get_value(self, action, arg_string):
25762576
# return the converted value
25772577
return result
25782578

2579-
def _check_value(self, action, value):
2579+
def _check_value(self, action, value, arg_string=None):
25802580
# converted value must be one of the choices (if specified)
25812581
choices = action.choices
25822582
if choices is None:
25832583
return
25842584

2585+
if arg_string is None:
2586+
arg_string = value
2587+
25852588
if isinstance(choices, str):
25862589
choices = iter(choices)
25872590

25882591
typed_choices = []
25892592
if (self.convert_choices and
2590-
self.type and
2591-
isinstance(self.choices[0], str)):
2593+
action.type and
2594+
all(isinstance(choice, str) for choice in choices)
2595+
):
25922596
try:
2593-
typed_choices = [acton.type[v] for v in choices]
2597+
typed_choices = [action.type(v) for v in choices]
25942598
except Exception:
25952599
# We use a blanket catch here, because type is user provided.
25962600
pass
25972601

25982602
if value not in choices and value not in typed_choices:
2599-
args = {'value': str(value),
2603+
args = {'value': arg_string,
26002604
'choices': ', '.join(map(str, action.choices))}
26012605
msg = _('invalid choice: %(value)r (choose from %(choices)s)')
26022606

2603-
if self.suggest_on_error and isinstance(value, str):
2607+
if self.suggest_on_error:
26042608
if all(isinstance(choice, str) for choice in action.choices):
26052609
import difflib
2606-
suggestions = difflib.get_close_matches(value, action.choices, 1)
2610+
suggestions = difflib.get_close_matches(arg_string, action.choices, 1)
26072611
if suggestions:
26082612
args['closest'] = suggestions[0]
26092613
msg = _('invalid choice: %(value)r, maybe you meant %(closest)r? '

0 commit comments

Comments
 (0)