mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-140448: Default suggest_on_error to True in argparse.ArgumentParser (#140450)
This commit is contained in:
parent
d51be28876
commit
d2f3cfd384
6 changed files with 36 additions and 26 deletions
|
|
@ -74,7 +74,7 @@ ArgumentParser objects
|
||||||
prefix_chars='-', fromfile_prefix_chars=None, \
|
prefix_chars='-', fromfile_prefix_chars=None, \
|
||||||
argument_default=None, conflict_handler='error', \
|
argument_default=None, conflict_handler='error', \
|
||||||
add_help=True, allow_abbrev=True, exit_on_error=True, \
|
add_help=True, allow_abbrev=True, exit_on_error=True, \
|
||||||
*, suggest_on_error=False, color=True)
|
*, suggest_on_error=True, color=True)
|
||||||
|
|
||||||
Create a new :class:`ArgumentParser` object. All parameters should be passed
|
Create a new :class:`ArgumentParser` object. All parameters should be passed
|
||||||
as keyword arguments. Each parameter has its own more detailed description
|
as keyword arguments. Each parameter has its own more detailed description
|
||||||
|
|
@ -117,7 +117,7 @@ ArgumentParser objects
|
||||||
error info when an error occurs. (default: ``True``)
|
error info when an error occurs. (default: ``True``)
|
||||||
|
|
||||||
* suggest_on_error_ - Enables suggestions for mistyped argument choices
|
* suggest_on_error_ - Enables suggestions for mistyped argument choices
|
||||||
and subparser names (default: ``False``)
|
and subparser names (default: ``True``)
|
||||||
|
|
||||||
* color_ - Allow color output (default: ``True``)
|
* color_ - Allow color output (default: ``True``)
|
||||||
|
|
||||||
|
|
@ -134,6 +134,9 @@ ArgumentParser objects
|
||||||
.. versionchanged:: 3.14
|
.. versionchanged:: 3.14
|
||||||
*suggest_on_error* and *color* parameters were added.
|
*suggest_on_error* and *color* parameters were added.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.15
|
||||||
|
*suggest_on_error* default changed to ``True``.
|
||||||
|
|
||||||
The following sections describe how each of these are used.
|
The following sections describe how each of these are used.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -596,13 +599,11 @@ suggest_on_error
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
By default, when a user passes an invalid argument choice or subparser name,
|
By default, when a user passes an invalid argument choice or subparser name,
|
||||||
:class:`ArgumentParser` will exit with error info and list the permissible
|
:class:`ArgumentParser` will exit with error info and provide suggestions for
|
||||||
argument choices (if specified) or subparser names as part of the error message.
|
mistyped arguments. The error message will list the permissible argument
|
||||||
|
choices (if specified) or subparser names, along with a "maybe you meant"
|
||||||
If the user would like to enable suggestions for mistyped argument choices and
|
suggestion if a close match is found. Note that this only applies for arguments
|
||||||
subparser names, the feature can be enabled by setting ``suggest_on_error`` to
|
when the choices specified are strings::
|
||||||
``True``. Note that this only applies for arguments when the choices specified
|
|
||||||
are strings::
|
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser(description='Process some integers.',
|
>>> parser = argparse.ArgumentParser(description='Process some integers.',
|
||||||
suggest_on_error=True)
|
suggest_on_error=True)
|
||||||
|
|
@ -612,16 +613,14 @@ are strings::
|
||||||
>>> parser.parse_args(['--action', 'sumn', 1, 2, 3])
|
>>> parser.parse_args(['--action', 'sumn', 1, 2, 3])
|
||||||
tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max')
|
tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max')
|
||||||
|
|
||||||
If you're writing code that needs to be compatible with older Python versions
|
You can disable suggestions by setting ``suggest_on_error`` to ``False``::
|
||||||
and want to opportunistically use ``suggest_on_error`` when it's available, you
|
|
||||||
can set it as an attribute after initializing the parser instead of using the
|
|
||||||
keyword argument::
|
|
||||||
|
|
||||||
>>> parser = argparse.ArgumentParser(description='Process some integers.')
|
>>> parser = argparse.ArgumentParser(description='Process some integers.',
|
||||||
>>> parser.suggest_on_error = True
|
suggest_on_error=False)
|
||||||
|
|
||||||
.. versionadded:: 3.14
|
.. versionadded:: 3.14
|
||||||
|
.. versionchanged:: 3.15
|
||||||
|
Changed default value of ``suggest_on_error`` from ``False`` to ``True``.
|
||||||
|
|
||||||
color
|
color
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,13 @@ New modules
|
||||||
Improved modules
|
Improved modules
|
||||||
================
|
================
|
||||||
|
|
||||||
|
argparse
|
||||||
|
--------
|
||||||
|
|
||||||
|
* Changed the *suggest_on_error* parameter of :class:`argparse.ArgumentParser` to
|
||||||
|
default to ``True``. This enables suggestions for mistyped arguments by default.
|
||||||
|
(Contributed by Jakob Schluse in :gh:`140450`.)
|
||||||
|
|
||||||
calendar
|
calendar
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1857,7 +1857,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
|
||||||
- exit_on_error -- Determines whether or not ArgumentParser exits with
|
- exit_on_error -- Determines whether or not ArgumentParser exits with
|
||||||
error info when an error occurs
|
error info when an error occurs
|
||||||
- suggest_on_error - Enables suggestions for mistyped argument choices
|
- suggest_on_error - Enables suggestions for mistyped argument choices
|
||||||
and subparser names (default: ``False``)
|
and subparser names (default: ``True``)
|
||||||
- color - Allow color output in help messages (default: ``False``)
|
- color - Allow color output in help messages (default: ``False``)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -1876,7 +1876,7 @@ def __init__(self,
|
||||||
allow_abbrev=True,
|
allow_abbrev=True,
|
||||||
exit_on_error=True,
|
exit_on_error=True,
|
||||||
*,
|
*,
|
||||||
suggest_on_error=False,
|
suggest_on_error=True,
|
||||||
color=True,
|
color=True,
|
||||||
):
|
):
|
||||||
superinit = super(ArgumentParser, self).__init__
|
superinit = super(ArgumentParser, self).__init__
|
||||||
|
|
|
||||||
|
|
@ -2287,7 +2287,7 @@ class TestArgumentAndSubparserSuggestions(TestCase):
|
||||||
"""Test error handling and suggestion when a user makes a typo"""
|
"""Test error handling and suggestion when a user makes a typo"""
|
||||||
|
|
||||||
def test_wrong_argument_error_with_suggestions(self):
|
def test_wrong_argument_error_with_suggestions(self):
|
||||||
parser = ErrorRaisingArgumentParser(suggest_on_error=True)
|
parser = ErrorRaisingArgumentParser()
|
||||||
parser.add_argument('foo', choices=['bar', 'baz'])
|
parser.add_argument('foo', choices=['bar', 'baz'])
|
||||||
with self.assertRaises(ArgumentParserError) as excinfo:
|
with self.assertRaises(ArgumentParserError) as excinfo:
|
||||||
parser.parse_args(('bazz',))
|
parser.parse_args(('bazz',))
|
||||||
|
|
@ -2307,7 +2307,7 @@ def test_wrong_argument_error_no_suggestions(self):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_wrong_argument_subparsers_with_suggestions(self):
|
def test_wrong_argument_subparsers_with_suggestions(self):
|
||||||
parser = ErrorRaisingArgumentParser(suggest_on_error=True)
|
parser = ErrorRaisingArgumentParser()
|
||||||
subparsers = parser.add_subparsers(required=True)
|
subparsers = parser.add_subparsers(required=True)
|
||||||
subparsers.add_parser('foo')
|
subparsers.add_parser('foo')
|
||||||
subparsers.add_parser('bar')
|
subparsers.add_parser('bar')
|
||||||
|
|
@ -2331,18 +2331,19 @@ def test_wrong_argument_subparsers_no_suggestions(self):
|
||||||
excinfo.exception.stderr,
|
excinfo.exception.stderr,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_wrong_argument_no_suggestion_implicit(self):
|
def test_wrong_argument_with_suggestion_explicit(self):
|
||||||
parser = ErrorRaisingArgumentParser()
|
parser = ErrorRaisingArgumentParser(suggest_on_error=True)
|
||||||
parser.add_argument('foo', choices=['bar', 'baz'])
|
parser.add_argument('foo', choices=['bar', 'baz'])
|
||||||
with self.assertRaises(ArgumentParserError) as excinfo:
|
with self.assertRaises(ArgumentParserError) as excinfo:
|
||||||
parser.parse_args(('bazz',))
|
parser.parse_args(('bazz',))
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
"error: argument foo: invalid choice: 'bazz' (choose from bar, baz)",
|
"error: argument foo: invalid choice: 'bazz', maybe you meant"
|
||||||
|
" 'baz'? (choose from bar, baz)",
|
||||||
excinfo.exception.stderr,
|
excinfo.exception.stderr,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_suggestions_choices_empty(self):
|
def test_suggestions_choices_empty(self):
|
||||||
parser = ErrorRaisingArgumentParser(suggest_on_error=True)
|
parser = ErrorRaisingArgumentParser()
|
||||||
parser.add_argument('foo', choices=[])
|
parser.add_argument('foo', choices=[])
|
||||||
with self.assertRaises(ArgumentParserError) as excinfo:
|
with self.assertRaises(ArgumentParserError) as excinfo:
|
||||||
parser.parse_args(('bazz',))
|
parser.parse_args(('bazz',))
|
||||||
|
|
@ -2352,7 +2353,7 @@ def test_suggestions_choices_empty(self):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_suggestions_choices_int(self):
|
def test_suggestions_choices_int(self):
|
||||||
parser = ErrorRaisingArgumentParser(suggest_on_error=True)
|
parser = ErrorRaisingArgumentParser()
|
||||||
parser.add_argument('foo', choices=[1, 2])
|
parser.add_argument('foo', choices=[1, 2])
|
||||||
with self.assertRaises(ArgumentParserError) as excinfo:
|
with self.assertRaises(ArgumentParserError) as excinfo:
|
||||||
parser.parse_args(('3',))
|
parser.parse_args(('3',))
|
||||||
|
|
@ -2362,7 +2363,7 @@ def test_suggestions_choices_int(self):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_suggestions_choices_mixed_types(self):
|
def test_suggestions_choices_mixed_types(self):
|
||||||
parser = ErrorRaisingArgumentParser(suggest_on_error=True)
|
parser = ErrorRaisingArgumentParser()
|
||||||
parser.add_argument('foo', choices=[1, '2'])
|
parser.add_argument('foo', choices=[1, '2'])
|
||||||
with self.assertRaises(ArgumentParserError) as excinfo:
|
with self.assertRaises(ArgumentParserError) as excinfo:
|
||||||
parser.parse_args(('3',))
|
parser.parse_args(('3',))
|
||||||
|
|
|
||||||
|
|
@ -1681,6 +1681,7 @@ David Scherer
|
||||||
Wolfgang Scherer
|
Wolfgang Scherer
|
||||||
Felix Scherz
|
Felix Scherz
|
||||||
Hynek Schlawack
|
Hynek Schlawack
|
||||||
|
Jakob Schluse
|
||||||
Bob Schmertz
|
Bob Schmertz
|
||||||
Gregor Schmid
|
Gregor Schmid
|
||||||
Ralf Schmitt
|
Ralf Schmitt
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Change the default of ``suggest_on_error`` to ``True`` in
|
||||||
|
``argparse.ArgumentParser``.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue