summaryrefslogtreecommitdiffstats
path: root/Lib/argparse.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/argparse.py')
-rw-r--r--Lib/argparse.py35
1 files changed, 26 insertions, 9 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py
index fa9f521..ece6f2e 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -1773,6 +1773,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
- allow_abbrev -- Allow long options to be abbreviated unambiguously
- exit_on_error -- Determines whether or not ArgumentParser exits with
error info when an error occurs
+ - suggest_on_error - Enables suggestions for mistyped argument choices
+ and subparser names. (default: ``False``)
"""
def __init__(self,
@@ -1788,7 +1790,8 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
conflict_handler='error',
add_help=True,
allow_abbrev=True,
- exit_on_error=True):
+ exit_on_error=True,
+ suggest_on_error=False):
superinit = super(ArgumentParser, self).__init__
superinit(description=description,
@@ -1804,6 +1807,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
self.add_help = add_help
self.allow_abbrev = allow_abbrev
self.exit_on_error = exit_on_error
+ self.suggest_on_error = suggest_on_error
add_group = self.add_argument_group
self._positionals = add_group(_('positional arguments'))
@@ -2601,14 +2605,27 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
def _check_value(self, action, value):
# converted value must be one of the choices (if specified)
choices = action.choices
- if choices is not None:
- if isinstance(choices, str):
- choices = iter(choices)
- if value not in choices:
- args = {'value': str(value),
- 'choices': ', '.join(map(str, action.choices))}
- msg = _('invalid choice: %(value)r (choose from %(choices)s)')
- raise ArgumentError(action, msg % args)
+ if choices is None:
+ return
+
+ if isinstance(choices, str):
+ choices = iter(choices)
+
+ if value not in choices:
+ args = {'value': str(value),
+ 'choices': ', '.join(map(str, action.choices))}
+ msg = _('invalid choice: %(value)r (choose from %(choices)s)')
+
+ if self.suggest_on_error and isinstance(value, str):
+ if all(isinstance(choice, str) for choice in action.choices):
+ import difflib
+ suggestions = difflib.get_close_matches(value, action.choices, 1)
+ if suggestions:
+ args['closest'] = suggestions[0]
+ msg = _('invalid choice: %(value)r, maybe you meant %(closest)r? '
+ '(choose from %(choices)s)')
+
+ raise ArgumentError(action, msg % args)
# =======================
# Help-formatting methods