]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-96310: Fix a traceback in argparse when all options in a mutually exclusive...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 21 Feb 2024 16:20:08 +0000 (17:20 +0100)
committerGitHub <noreply@github.com>
Wed, 21 Feb 2024 16:20:08 +0000 (18:20 +0200)
Reproducer depends on terminal size - the traceback occurs when there's
an option long enough so the usage line doesn't fit the terminal width.
Option order is also important for reproducibility.

Excluding empty groups (with all options suppressed) from inserts
fixes the problem.
(cherry picked from commit 5f7df88821347c5f44fc4e2c691e83a60a6c6cd5)

Co-authored-by: Daniel Mach <daniel.mach@suse.com>
Lib/argparse.py
Lib/test/test_argparse.py
Misc/NEWS.d/next/Library/2022-08-26-15-50-53.gh-issue-96310.0NssDh.rst [new file with mode: 0644]

index ffbdbc2075930d1cac6eba407e543256c876143a..57e6619a8c38d050a2b97d0ca42f39b2a0fa19ca 100644 (file)
@@ -414,6 +414,8 @@ class HelpFormatter(object):
                             suppressed_actions_count += 1
 
                     exposed_actions_count = group_action_count - suppressed_actions_count
+                    if not exposed_actions_count:
+                        continue
 
                     if not group.required:
                         if start in inserts:
index c67fca42228c9004ab9b52dc744d4ad6c5fad53a..790a4f8b808d166cbbfd88568eee17efb1dedffc 100644 (file)
@@ -2743,6 +2743,27 @@ class TestMutuallyExclusiveGroupErrors(TestCase):
               '''
         self.assertEqual(parser.format_help(), textwrap.dedent(expected))
 
+    def test_help_subparser_all_mutually_exclusive_group_members_suppressed(self):
+        self.maxDiff = None
+        parser = ErrorRaisingArgumentParser(prog='PROG')
+        commands = parser.add_subparsers(title="commands", dest="command")
+        cmd_foo = commands.add_parser("foo")
+        group = cmd_foo.add_mutually_exclusive_group()
+        group.add_argument('--verbose', action='store_true', help=argparse.SUPPRESS)
+        group.add_argument('--quiet', action='store_true', help=argparse.SUPPRESS)
+        longopt = '--' + 'long'*32
+        longmeta = 'LONG'*32
+        cmd_foo.add_argument(longopt)
+        expected = f'''\
+            usage: PROG foo [-h]
+                            [{longopt} {longmeta}]
+
+            options:
+              -h, --help            show this help message and exit
+              {longopt} {longmeta}
+              '''
+        self.assertEqual(cmd_foo.format_help(), textwrap.dedent(expected))
+
     def test_empty_group(self):
         # See issue 26952
         parser = argparse.ArgumentParser()
diff --git a/Misc/NEWS.d/next/Library/2022-08-26-15-50-53.gh-issue-96310.0NssDh.rst b/Misc/NEWS.d/next/Library/2022-08-26-15-50-53.gh-issue-96310.0NssDh.rst
new file mode 100644 (file)
index 0000000..f8efb00
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a traceback in :mod:`argparse` when all options in a mutually exclusive
+group are suppressed.