From 1adb17b1a26e1547d14ca15f915e605cfdda3edd Mon Sep 17 00:00:00 2001 From: Fabian Henze <32638720+henzef@users.noreply.github.com> Date: Tue, 9 Dec 2025 17:48:35 +0100 Subject: [PATCH] gh-112527: Fix help text for required options in argparse (GH-112528) For optional arguments with required=True, the ArgumentDefaultsHelpFormatter would always add a " (default: None)" to the end of the help text. Since that's a bit misleading, it is removed with this commit. --- Lib/argparse.py | 27 ++++++++++--------- Lib/test/test_argparse.py | 6 +++-- ...-12-09-14-40-45.gh-issue-112527.Tvf5Zk.rst | 2 ++ 3 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-12-09-14-40-45.gh-issue-112527.Tvf5Zk.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index 1d550264ae42..ed98aa9e974b 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -738,18 +738,21 @@ class ArgumentDefaultsHelpFormatter(HelpFormatter): if help is None: help = '' - if '%(default)' not in help: - if action.default is not SUPPRESS: - defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] - if action.option_strings or action.nargs in defaulting_nargs: - t = self._theme - default_str = _(" (default: %(default)s)") - prefix, suffix = default_str.split("%(default)s") - help += ( - f" {t.default}{prefix.lstrip()}" - f"{t.default_value}%(default)s" - f"{t.default}{suffix}{t.reset}" - ) + if ( + '%(default)' not in help + and action.default is not SUPPRESS + and not action.required + ): + defaulting_nargs = (OPTIONAL, ZERO_OR_MORE) + if action.option_strings or action.nargs in defaulting_nargs: + t = self._theme + default_str = _(" (default: %(default)s)") + prefix, suffix = default_str.split("%(default)s") + help += ( + f" {t.default}{prefix.lstrip()}" + f"{t.default_value}%(default)s" + f"{t.default}{suffix}{t.reset}" + ) return help diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index ab5382e41e78..24e8ab1c5cac 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5419,6 +5419,7 @@ class TestHelpArgumentDefaults(HelpTestCase): argument_signatures = [ Sig('--foo', help='foo help - oh and by the way, %(default)s'), Sig('--bar', action='store_true', help='bar help'), + Sig('--required', required=True, help='some help'), Sig('--taz', action=argparse.BooleanOptionalAction, help='Whether to taz it', default=True), Sig('--corge', action=argparse.BooleanOptionalAction, @@ -5432,8 +5433,8 @@ class TestHelpArgumentDefaults(HelpTestCase): [Sig('--baz', type=int, default=42, help='baz help')]), ] usage = '''\ - usage: PROG [-h] [--foo FOO] [--bar] [--taz | --no-taz] [--corge | --no-corge] - [--quux QUUX] [--baz BAZ] + usage: PROG [-h] [--foo FOO] [--bar] --required REQUIRED [--taz | --no-taz] + [--corge | --no-corge] [--quux QUUX] [--baz BAZ] spam [badger] ''' help = usage + '''\ @@ -5448,6 +5449,7 @@ class TestHelpArgumentDefaults(HelpTestCase): -h, --help show this help message and exit --foo FOO foo help - oh and by the way, None --bar bar help (default: False) + --required REQUIRED some help --taz, --no-taz Whether to taz it (default: True) --corge, --no-corge Whether to corge it --quux QUUX Set the quux (default: 42) diff --git a/Misc/NEWS.d/next/Library/2025-12-09-14-40-45.gh-issue-112527.Tvf5Zk.rst b/Misc/NEWS.d/next/Library/2025-12-09-14-40-45.gh-issue-112527.Tvf5Zk.rst new file mode 100644 index 000000000000..70447bc64376 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-09-14-40-45.gh-issue-112527.Tvf5Zk.rst @@ -0,0 +1,2 @@ +The help text for required options in :mod:`argparse` no +longer extended with " (default: None)". -- 2.47.3