From 74bfec5287600599b9cc75c08c586600975d8187 Mon Sep 17 00:00:00 2001 From: Pavel Ditenbir Date: Sun, 10 Jan 2021 01:18:57 +0700 Subject: [PATCH 01/15] bpo-42875: fix incorrect indent of long sub-commands 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 --- Lib/argparse.py | 7 +++---- Lib/test/test_argparse.py | 43 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Lib/argparse.py b/Lib/argparse.py index 7988c447d03584..7ab92cdb6f2165 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 138ff19e86acf4..77d2e9bc4c4fa7 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4958,6 +4958,49 @@ def custom_type(string): version = '' +class TestHelpUsageLongSubparserCommand(TestCase): + """Test that long command in subparser is displayed correctly in help + + The test was added for https://bugs.python.org/issue42875 + """ + + def setUp(self): + super().setUp() + self.main_program = os.path.basename(sys.argv[0]) + + def test_parent_help(self): + parent_parser = argparse.ArgumentParser( + add_help=False, formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=50)) + + main_parser = argparse.ArgumentParser( + formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=50)) + cmd_subparsers = main_parser.add_subparsers(title="commands", metavar='CMD', help='command to use') + + cmd_parser = cmd_subparsers.add_parser("add", help="add something", parents=[parent_parser]) + cmd_parser.add_subparsers(title="action", dest="action_command") + + cmd_parser2 = cmd_subparsers.add_parser("remove", help="remove something", parents=[parent_parser]) + cmd_parser2.add_subparsers(title="action", dest="action_command") + + cmd_subparsers.add_parser("a-very-long-command", help="command that does something", parents=[parent_parser]) + + parser_help = main_parser.format_help() + + progname = self.main_program + self.assertEqual(parser_help, textwrap.dedent('''\ + usage: {}{}[-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 + '''.format(progname, ' ' if progname else ''))) + + # ===================================== # Optional/Positional constructor tests # ===================================== From fef37a1dfb1e402d8a6157cbcdae0bc291de438c Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 15 Jan 2021 18:09:28 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst diff --git a/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst b/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst new file mode 100644 index 00000000000000..94a48a77be17f6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst @@ -0,0 +1 @@ +Fixed incorrect indentation in command line help generated by arggparse: in case of usage a long command along with max_help_position which is more than the length of the command, the command's help was incorrectly started on the new line. \ No newline at end of file From 4ad35eac07351fb698737ea2309b50de0e143ec3 Mon Sep 17 00:00:00 2001 From: Pavel Ditenbir Date: Sat, 16 Jan 2021 01:11:21 +0700 Subject: [PATCH 03/15] Update 2021-01-15-18-09-27.bpo-42875.puKGeU.rst --- .../next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst b/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst index 94a48a77be17f6..636c137c7d5855 100644 --- a/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst +++ b/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst @@ -1 +1 @@ -Fixed incorrect indentation in command line help generated by arggparse: in case of usage a long command along with max_help_position which is more than the length of the command, the command's help was incorrectly started on the new line. \ No newline at end of file +Fixed incorrect indentation in command line help generated by argparse: in case of usage a long command along with max_help_position which is more than the length of the command, the command's help was incorrectly started on the new line. From 8f8ef2021f1f6711665af2b92232b4109dc76e51 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Wed, 18 Sep 2024 20:30:13 -0700 Subject: [PATCH 04/15] Apply patch --- .../NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst diff --git a/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst b/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst deleted file mode 100644 index 636c137c7d5855..00000000000000 --- a/Misc/NEWS.d/next/Library/2021-01-15-18-09-27.bpo-42875.puKGeU.rst +++ /dev/null @@ -1 +0,0 @@ -Fixed incorrect indentation in command line help generated by argparse: in case of usage a long command along with max_help_position which is more than the length of the command, the command's help was incorrectly started on the new line. From 5a95302c82bf0a1e7d99d7574ba998ff55695ea7 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Wed, 18 Sep 2024 20:37:07 -0700 Subject: [PATCH 05/15] update docstring --- Lib/test/test_argparse.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 77d2e9bc4c4fa7..467e2d20dc521c 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4959,10 +4959,7 @@ def custom_type(string): class TestHelpUsageLongSubparserCommand(TestCase): - """Test that long command in subparser is displayed correctly in help - - The test was added for https://bugs.python.org/issue42875 - """ + """Test that subparser commands are formatted correctly in help""" def setUp(self): super().setUp() From c43a6e530f7a1e6d1e2753263e15c50dac1782b5 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Thu, 19 Sep 2024 03:47:00 +0000 Subject: [PATCH 06/15] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst 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..0ace27370951a3 --- /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 where lengthy subparser argument help is incorrectly indented. From 536a4655cde78b9c24e962e94f130a1a73982d55 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Thu, 19 Sep 2024 13:41:37 -0700 Subject: [PATCH 07/15] Update Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst Co-authored-by: Kirill Podoprigora --- .../next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 0ace27370951a3..4e6269b596cc21 100644 --- 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 @@ -1 +1 @@ -Fix a bug where lengthy subparser argument help is incorrectly indented. +Fix a bug in mod:`argparse` where lengthy subparser argument help is incorrectly indented. From f0ab099543756feb3cb5f7da7467e0fe5efd9163 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Thu, 19 Sep 2024 13:48:01 -0700 Subject: [PATCH 08/15] Update Misc/NEWS.d/next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst Co-authored-by: Kirill Podoprigora --- .../next/Library/2024-09-19-03-46-59.gh-issue-87041.9Ox7Bv.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 4e6269b596cc21..47a5f0c7ba520f 100644 --- 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 @@ -1 +1 @@ -Fix a bug in mod:`argparse` where lengthy subparser argument help is incorrectly indented. +Fix a bug in :mod:`argparse` where lengthy subparser argument help is incorrectly indented. From aef9d0584a7c2e4b5b4bebe19ff4dbf74dff916e Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sun, 22 Sep 2024 13:49:28 -0700 Subject: [PATCH 09/15] Address PR comments about tests --- Lib/test/test_argparse.py | 41 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 467e2d20dc521c..90ecabd7db3495 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4961,31 +4961,38 @@ def custom_type(string): class TestHelpUsageLongSubparserCommand(TestCase): """Test that subparser commands are formatted correctly in help""" - def setUp(self): - super().setUp() - self.main_program = os.path.basename(sys.argv[0]) - def test_parent_help(self): - parent_parser = argparse.ArgumentParser( - add_help=False, formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=50)) + def custom_formatter(prog): + return argparse.RawTextHelpFormatter(prog, max_help_position=50) + parent_parser = argparse.ArgumentParser( + prog='PROG', + add_help=False, + formatter_class=lambda prog: custom_formatter(prog) + ) main_parser = argparse.ArgumentParser( - formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, max_help_position=50)) - cmd_subparsers = main_parser.add_subparsers(title="commands", metavar='CMD', help='command to use') - - cmd_parser = cmd_subparsers.add_parser("add", help="add something", parents=[parent_parser]) + formatter_class=lambda prog: custom_formatter(prog)) + + cmd_subparsers = main_parser.add_subparsers(title="commands", + metavar='CMD', + help='command to use') + cmd_parser = cmd_subparsers.add_parser("add", + help="add something", + parents=[parent_parser]) cmd_parser.add_subparsers(title="action", dest="action_command") - - cmd_parser2 = cmd_subparsers.add_parser("remove", help="remove something", parents=[parent_parser]) + cmd_parser2 = cmd_subparsers.add_parser("remove", + help="remove something", + parents=[parent_parser]) + cmd_parser2.add_subparsers(title="action", dest="action_command") - cmd_subparsers.add_parser("a-very-long-command", help="command that does something", parents=[parent_parser]) + cmd_subparsers.add_parser("a-very-long-command", + help="command that does something", + parents=[parent_parser]) parser_help = main_parser.format_help() - - progname = self.main_program self.assertEqual(parser_help, textwrap.dedent('''\ - usage: {}{}[-h] CMD ... + usage: __main__.py [-h] CMD ... options: -h, --help show this help message and exit @@ -4995,7 +5002,7 @@ def test_parent_help(self): add add something remove remove something a-very-long-command command that does something - '''.format(progname, ' ' if progname else ''))) + ''')) # ===================================== From 2fcb5e067a7407923264389cfc2b6cb419001278 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sun, 22 Sep 2024 13:56:57 -0700 Subject: [PATCH 10/15] appease linter --- Lib/test/test_argparse.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 90ecabd7db3495..1e6b5fc7738455 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4967,26 +4967,26 @@ def custom_formatter(prog): parent_parser = argparse.ArgumentParser( prog='PROG', - add_help=False, + add_help=False, formatter_class=lambda prog: custom_formatter(prog) ) main_parser = argparse.ArgumentParser( formatter_class=lambda prog: custom_formatter(prog)) - - cmd_subparsers = main_parser.add_subparsers(title="commands", - metavar='CMD', + + cmd_subparsers = main_parser.add_subparsers(title="commands", + metavar='CMD', help='command to use') - cmd_parser = cmd_subparsers.add_parser("add", - help="add something", + cmd_parser = cmd_subparsers.add_parser("add", + help="add something", parents=[parent_parser]) cmd_parser.add_subparsers(title="action", dest="action_command") - cmd_parser2 = cmd_subparsers.add_parser("remove", + cmd_parser2 = cmd_subparsers.add_parser("remove", help="remove something", parents=[parent_parser]) - + cmd_parser2.add_subparsers(title="action", dest="action_command") - cmd_subparsers.add_parser("a-very-long-command", + cmd_subparsers.add_parser("a-very-long-command", help="command that does something", parents=[parent_parser]) From 5c322809f52a9951c693ccc050dfaa4872a016ee Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sun, 22 Sep 2024 14:13:16 -0700 Subject: [PATCH 11/15] Fix program name in output --- Lib/test/test_argparse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 1e6b5fc7738455..8ba23a1e1d168c 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4992,7 +4992,7 @@ def custom_formatter(prog): parser_help = main_parser.format_help() self.assertEqual(parser_help, textwrap.dedent('''\ - usage: __main__.py [-h] CMD ... + usage: {}{}[-h] CMD ... options: -h, --help show this help message and exit @@ -5002,7 +5002,7 @@ def custom_formatter(prog): add add something remove remove something a-very-long-command command that does something - ''')) + ''').format(main_parser.prog or '', ' ')) # ===================================== From c9b89c0332195068b80c22581f3864c4128a1177 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sun, 22 Sep 2024 15:16:36 -0700 Subject: [PATCH 12/15] Address comments --- Lib/test/test_argparse.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 8ba23a1e1d168c..a8af4e03cafb5a 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4968,10 +4968,10 @@ def custom_formatter(prog): parent_parser = argparse.ArgumentParser( prog='PROG', add_help=False, - formatter_class=lambda prog: custom_formatter(prog) + formatter_class=custom_formatter ) main_parser = argparse.ArgumentParser( - formatter_class=lambda prog: custom_formatter(prog)) + formatter_class=custom_formatter) cmd_subparsers = main_parser.add_subparsers(title="commands", metavar='CMD', @@ -4980,19 +4980,17 @@ def custom_formatter(prog): help="add something", parents=[parent_parser]) cmd_parser.add_subparsers(title="action", dest="action_command") - cmd_parser2 = cmd_subparsers.add_parser("remove", - help="remove something", - parents=[parent_parser]) - - cmd_parser2.add_subparsers(title="action", dest="action_command") + cmd_subparsers.add_parser("remove", + help="remove something", + parents=[parent_parser]) cmd_subparsers.add_parser("a-very-long-command", help="command that does something", parents=[parent_parser]) parser_help = main_parser.format_help() - self.assertEqual(parser_help, textwrap.dedent('''\ - usage: {}{}[-h] CMD ... + self.assertEqual(parser_help, textwrap.dedent(f'''\ + usage: {main_parser.prog or ' '} [-h] CMD ... options: -h, --help show this help message and exit @@ -5002,7 +5000,7 @@ def custom_formatter(prog): add add something remove remove something a-very-long-command command that does something - ''').format(main_parser.prog or '', ' ')) + ''')) # ===================================== From 96d2bd75821685201fbef0a5ef936e78fdea1cbb Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Sun, 22 Sep 2024 15:18:43 -0700 Subject: [PATCH 13/15] appease linter --- Lib/test/test_argparse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index a8af4e03cafb5a..bf135eb0051ca0 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4980,7 +4980,7 @@ def custom_formatter(prog): help="add something", parents=[parent_parser]) cmd_parser.add_subparsers(title="action", dest="action_command") - cmd_subparsers.add_parser("remove", + cmd_subparsers.add_parser("remove", help="remove something", parents=[parent_parser]) From 92c97ca1f738ad339e5fc9b3aabbcc66b79b1158 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 23 Sep 2024 11:22:42 -0700 Subject: [PATCH 14/15] simplify test --- Lib/test/test_argparse.py | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index bf135eb0051ca0..57a9b13e3dda5f 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4967,30 +4967,24 @@ def custom_formatter(prog): parent_parser = argparse.ArgumentParser( prog='PROG', - add_help=False, formatter_class=custom_formatter ) - main_parser = argparse.ArgumentParser( - formatter_class=custom_formatter) - - cmd_subparsers = main_parser.add_subparsers(title="commands", - metavar='CMD', - help='command to use') - cmd_parser = cmd_subparsers.add_parser("add", - help="add something", - parents=[parent_parser]) - cmd_parser.add_subparsers(title="action", dest="action_command") + + 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", - parents=[parent_parser]) + help="remove something") cmd_subparsers.add_parser("a-very-long-command", - help="command that does something", - parents=[parent_parser]) + help="command that does something") - parser_help = main_parser.format_help() - self.assertEqual(parser_help, textwrap.dedent(f'''\ - usage: {main_parser.prog or ' '} [-h] CMD ... + 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 From be9bdfa20543f3fb00b2a8fd70b414dba8bfb698 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Mon, 23 Sep 2024 12:01:55 -0700 Subject: [PATCH 15/15] Update Lib/test/test_argparse.py Co-authored-by: Serhiy Storchaka --- Lib/test/test_argparse.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 29149a8738d1f0..f51a690f7ddf1a 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4962,6 +4962,7 @@ def custom_type(string): class TestHelpUsageLongSubparserCommand(TestCase): """Test that subparser commands are formatted correctly in help""" + maxDiff = None def test_parent_help(self): def custom_formatter(prog):