From b1c0c60a4b7e11abed82bdbb060faad65dcff218 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 8 May 2025 16:28:16 +0300 Subject: [PATCH 1/3] Fix subclassing HelpFormatter --- Lib/argparse.py | 6 ++--- Lib/test/test_argparse.py | 24 +++++++++++++++++++ ...-05-08-16-28-05.gh-issue-133653.7cxHXN.rst | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index f13ac82dbc50b3..aa15cc6d0525d9 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2723,15 +2723,13 @@ def format_help(self): return formatter.format_help() def _get_formatter(self): - if isinstance(self.formatter_class, type) and issubclass( - self.formatter_class, HelpFormatter - ): + try: return self.formatter_class( prog=self.prog, prefix_chars=self.prefix_chars, color=self.color, ) - else: + except TypeError: return self.formatter_class(prog=self.prog) # ===================== diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 5a6be1180c1a3e..d9bb58c1c8f322 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -5176,6 +5176,30 @@ class TestHelpTupleMetavarPositional(HelpTestCase): version = '' +class TestHelpFormatter(HelpTestCase): + """Test the HelpFormatter""" + + # Test subclassing the help formatter + class MyFormatter(argparse.HelpFormatter): + def __init__(self, prog) -> None: + super().__init__(prog) + + parser_signature = Sig( + prog="PROG", + formatter_class=MyFormatter, + description="Test with subclassing the help formatter", + ) + usage = '''\ + usage: PROG [-h] + ''' + help = usage + '''\ + + Test with subclassing the help formatter + + options: + -h, --help show this help message and exit + ''' + class TestHelpRawText(HelpTestCase): """Test the RawTextHelpFormatter""" diff --git a/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst b/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst new file mode 100644 index 00000000000000..0883c9448b5102 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst @@ -0,0 +1 @@ +Fix subclassing :meth:`argparse.HelpFormatter`. Patch by Hugo van Kemenade. From fa4d044195bb9be4d7a51282926dbdfaa6367833 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 8 May 2025 16:51:43 +0300 Subject: [PATCH 2/3] Fix Sphinx warning --- .../next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst b/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst index 0883c9448b5102..d49de56cee719d 100644 --- a/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst +++ b/Misc/NEWS.d/next/Library/2025-05-08-16-28-05.gh-issue-133653.7cxHXN.rst @@ -1 +1 @@ -Fix subclassing :meth:`argparse.HelpFormatter`. Patch by Hugo van Kemenade. +Fix subclassing :meth:`!argparse.HelpFormatter`. Patch by Hugo van Kemenade. From 91c1f4fe19dc69075b28f2ea2e8e4a662e5e5370 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Thu, 8 May 2025 18:33:35 +0300 Subject: [PATCH 3/3] Big if --- Lib/argparse.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Lib/argparse.py b/Lib/argparse.py index aa15cc6d0525d9..06d8e6cc1f1ca2 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2723,13 +2723,23 @@ def format_help(self): return formatter.format_help() def _get_formatter(self): - try: + import inspect + if len( + [v.kind for (k, v) in + inspect.signature(self.formatter_class).parameters.items() + if k in ('prefix_chars', 'color') + and v.kind in ( + inspect._ParameterKind.POSITIONAL_OR_KEYWORD, + inspect._ParameterKind.KEYWORD_ONLY, + ) + ] + ) == 2: return self.formatter_class( prog=self.prog, prefix_chars=self.prefix_chars, color=self.color, ) - except TypeError: + else: return self.formatter_class(prog=self.prog) # =====================