From 7ee99217345af3010bf05b1f5241c661a5e0ea9b Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 23 Sep 2024 12:45:36 -0700 Subject: [PATCH] GH-87041: Fix incorrect indentation in argparse help (GH-124230) In case of usage a long command along with max_help_position more than the length of the command, the command's help was incorrectly started on the new line. Co-authored-by: Pavel Ditenbir --- Lib/argparse.py | 7 ++-- Lib/test/test_argparse.py | 40 +++++++++++++++++++ ...4-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst | 1 + 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst diff --git a/Lib/argparse.py b/Lib/argparse.py index b77da29417b920..98d65312417ab8 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -261,13 +261,12 @@ def add_argument(self, action): # find all invocations get_invocation = self._format_action_invocation - invocations = [get_invocation(action)] + invocation_lengths = [len(get_invocation(action)) + self._current_indent] for subaction in self._iter_indented_subactions(action): - invocations.append(get_invocation(subaction)) + invocation_lengths.append(len(get_invocation(subaction)) + self._current_indent) # update the maximum item length - invocation_length = max(map(len, invocations)) - action_length = invocation_length + self._current_indent + action_length = max(invocation_lengths) self._action_max_length = max(self._action_max_length, action_length) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 37d07968b22543..f51a690f7ddf1a 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4960,6 +4960,46 @@ def custom_type(string): version = '' +class TestHelpUsageLongSubparserCommand(TestCase): + """Test that subparser commands are formatted correctly in help""" + maxDiff = None + + def test_parent_help(self): + def custom_formatter(prog): + return argparse.RawTextHelpFormatter(prog, max_help_position=50) + + parent_parser = argparse.ArgumentParser( + prog='PROG', + formatter_class=custom_formatter + ) + + cmd_subparsers = parent_parser.add_subparsers(title="commands", + metavar='CMD', + help='command to use') + cmd_subparsers.add_parser("add", + help="add something") + + cmd_subparsers.add_parser("remove", + help="remove something") + + cmd_subparsers.add_parser("a-very-long-command", + help="command that does something") + + parser_help = parent_parser.format_help() + self.assertEqual(parser_help, textwrap.dedent('''\ + usage: PROG [-h] CMD ... + + options: + -h, --help show this help message and exit + + commands: + CMD command to use + add add something + remove remove something + a-very-long-command command that does something + ''')) + + # ===================================== # Optional/Positional constructor tests # ===================================== diff --git a/Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst b/Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst new file mode 100644 index 00000000000000..47a5f0c7ba520f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst @@ -0,0 +1 @@ +Fix a bug in :mod:`argparse` where lengthy subparser argument help is incorrectly indented.