From df0a20c14cd6ba9fec415f70d7a8cf5d88f3d074 Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 12:45:32 +0200 Subject: [PATCH 1/7] Change default of `suggest_on_error` to `True` --- Doc/library/argparse.rst | 32 ++++++++++++++++---------------- Lib/argparse.py | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index a7603ac272633d..0cf9beaf7b18b2 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -74,7 +74,7 @@ ArgumentParser objects prefix_chars='-', fromfile_prefix_chars=None, \ argument_default=None, conflict_handler='error', \ 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 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``) * 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``) @@ -134,6 +134,9 @@ ArgumentParser objects .. versionchanged:: 3.14 *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. @@ -596,13 +599,11 @@ suggest_on_error ^^^^^^^^^^^^^^^^ By default, when a user passes an invalid argument choice or subparser name, -:class:`ArgumentParser` will exit with error info and list the permissible -argument choices (if specified) or subparser names as part of the error message. - -If the user would like to enable suggestions for mistyped argument choices and -subparser names, the feature can be enabled by setting ``suggest_on_error`` to -``True``. Note that this only applies for arguments when the choices specified -are strings:: +:class:`ArgumentParser` will exit with error info and provide suggestions for +mistyped arguments. The error message will list the permissible argument +choices (if specified) or subparser names, along with a "maybe you meant" +suggestion if a close match is found. Note that this only applies for arguments +when the choices specified are strings:: >>> parser = argparse.ArgumentParser(description='Process some integers.', suggest_on_error=True) @@ -612,16 +613,15 @@ are strings:: >>> parser.parse_args(['--action', 'sumn', 1, 2, 3]) 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 -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:: +If you prefer the old behavior without suggestions, you can disable this feature +by setting ``suggest_on_error`` to ``False``:: - >>> parser = argparse.ArgumentParser(description='Process some integers.') - >>> parser.suggest_on_error = True + >>> parser = argparse.ArgumentParser(description='Process some integers.', + suggest_on_error=False) .. versionadded:: 3.14 - +.. versionchanged:: 3.15 + Changed default value of ``suggest_on_error`` from ``False`` to ``True``. color ^^^^^ diff --git a/Lib/argparse.py b/Lib/argparse.py index 1ddb7abbb35355..1f4413a9897eeb 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1857,7 +1857,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): - 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``) + and subparser names (default: ``True``) - color - Allow color output in help messages (default: ``False``) """ @@ -1876,7 +1876,7 @@ def __init__(self, allow_abbrev=True, exit_on_error=True, *, - suggest_on_error=False, + suggest_on_error=True, color=True, ): superinit = super(ArgumentParser, self).__init__ From d89cf4f6ba7c22b6d83f965d278275fc137a64cd Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 12:57:14 +0200 Subject: [PATCH 2/7] Add blurb --- .../next/Library/2025-10-22-12-56-57.gh-issue-140448.GsEkXD.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2025-10-22-12-56-57.gh-issue-140448.GsEkXD.rst diff --git a/Misc/NEWS.d/next/Library/2025-10-22-12-56-57.gh-issue-140448.GsEkXD.rst b/Misc/NEWS.d/next/Library/2025-10-22-12-56-57.gh-issue-140448.GsEkXD.rst new file mode 100644 index 00000000000000..db7f92e136d41b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-22-12-56-57.gh-issue-140448.GsEkXD.rst @@ -0,0 +1,2 @@ +Change the default of ``suggest_on_error`` to ``True`` in +``argparse.ArgumentParser``. From 220c9a9c710b9e446654682230860fb8fd2cd390 Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 13:46:28 +0200 Subject: [PATCH 3/7] Fix test relying on default --- Lib/test/test_argparse.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index e5d642cde662c2..e4b500a0b69d58 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2331,13 +2331,14 @@ def test_wrong_argument_subparsers_no_suggestions(self): excinfo.exception.stderr, ) - def test_wrong_argument_no_suggestion_implicit(self): + def test_wrong_argument_with_suggestion_implicit(self): parser = ErrorRaisingArgumentParser() parser.add_argument('foo', choices=['bar', 'baz']) with self.assertRaises(ArgumentParserError) as excinfo: parser.parse_args(('bazz',)) 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, ) From 77b5e59476531805ba2cfc6ce10392fddaede05b Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 16:56:19 +0200 Subject: [PATCH 4/7] Add myself to ACKS --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index 2dc513829a2218..6876380e0ba8d2 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1681,6 +1681,7 @@ David Scherer Wolfgang Scherer Felix Scherz Hynek Schlawack +Jakob Schluse Bob Schmertz Gregor Schmid Ralf Schmitt From ce77c7a27a97dd510a44c6cba05b61d5edd84bca Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 16:57:57 +0200 Subject: [PATCH 5/7] Improve formulation in documentation --- Doc/library/argparse.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 0cf9beaf7b18b2..418f514995df3a 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -613,8 +613,7 @@ when the choices specified are strings:: >>> parser.parse_args(['--action', 'sumn', 1, 2, 3]) tester.py: error: argument --action: invalid choice: 'sumn', maybe you meant 'sum'? (choose from 'sum', 'max') -If you prefer the old behavior without suggestions, you can disable this feature -by setting ``suggest_on_error`` to ``False``:: +You can disable suggestions by setting ``suggest_on_error`` to ``False``:: >>> parser = argparse.ArgumentParser(description='Process some integers.', suggest_on_error=False) From a8185af969d7f1be84510fcb5225c320c06df6ca Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 17:03:42 +0200 Subject: [PATCH 6/7] Make enabling suggest_on_error implicit in tests This is done as explicit enablement will be the least common pattern now. --- Lib/test/test_argparse.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index e4b500a0b69d58..d6c9c1ef2c81e8 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2287,7 +2287,7 @@ class TestArgumentAndSubparserSuggestions(TestCase): """Test error handling and suggestion when a user makes a typo""" def test_wrong_argument_error_with_suggestions(self): - parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser = ErrorRaisingArgumentParser() parser.add_argument('foo', choices=['bar', 'baz']) with self.assertRaises(ArgumentParserError) as excinfo: parser.parse_args(('bazz',)) @@ -2307,7 +2307,7 @@ def test_wrong_argument_error_no_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.add_parser('foo') subparsers.add_parser('bar') @@ -2331,8 +2331,8 @@ def test_wrong_argument_subparsers_no_suggestions(self): excinfo.exception.stderr, ) - def test_wrong_argument_with_suggestion_implicit(self): - parser = ErrorRaisingArgumentParser() + def test_wrong_argument_with_suggestion_explicit(self): + parser = ErrorRaisingArgumentParser(suggest_on_error=True) parser.add_argument('foo', choices=['bar', 'baz']) with self.assertRaises(ArgumentParserError) as excinfo: parser.parse_args(('bazz',)) @@ -2343,7 +2343,7 @@ def test_wrong_argument_with_suggestion_implicit(self): ) def test_suggestions_choices_empty(self): - parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser = ErrorRaisingArgumentParser() parser.add_argument('foo', choices=[]) with self.assertRaises(ArgumentParserError) as excinfo: parser.parse_args(('bazz',)) @@ -2353,7 +2353,7 @@ def test_suggestions_choices_empty(self): ) def test_suggestions_choices_int(self): - parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser = ErrorRaisingArgumentParser() parser.add_argument('foo', choices=[1, 2]) with self.assertRaises(ArgumentParserError) as excinfo: parser.parse_args(('3',)) @@ -2363,7 +2363,7 @@ def test_suggestions_choices_int(self): ) def test_suggestions_choices_mixed_types(self): - parser = ErrorRaisingArgumentParser(suggest_on_error=True) + parser = ErrorRaisingArgumentParser() parser.add_argument('foo', choices=[1, '2']) with self.assertRaises(ArgumentParserError) as excinfo: parser.parse_args(('3',)) From 55b4f0c81a6357fc167ddf5ce5c739863e61a228 Mon Sep 17 00:00:00 2001 From: HomerusJa Date: Wed, 22 Oct 2025 17:22:06 +0200 Subject: [PATCH 7/7] Add entry to What's new --- Doc/whatsnew/3.15.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 22e9cfde06f877..a9543bdd13e83f 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -317,6 +317,13 @@ New 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 --------