]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-96310: Fix a traceback in argparse when all options in a mutually exclusive group...
authorDaniel Mach <daniel.mach@suse.com>
Wed, 21 Feb 2024 13:58:04 +0000 (14:58 +0100)
committerGitHub <noreply@github.com>
Wed, 21 Feb 2024 13:58:04 +0000 (13:58 +0000)
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.

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 ea39d26687b931419a3a0611ee966202cb76ef12..f86658baf7f2bac8294ed415b8c20be66badc51d 100644 (file)
@@ -413,6 +413,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 65fd9cf1a4a567a4edf19d0ddf25ff59ef5a0255..617b1721f3dbb1c6677543c94982831666dedaa6 100644 (file)
@@ -2864,6 +2864,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.