https://github.com/python/cpython/commit/dae7341da27a6004d985f1fd696f755f634bf61e
commit: dae7341da27a6004d985f1fd696f755f634bf61e
branch: 3.12
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-02-21T18:20:29+02:00
summary:

[3.12] gh-96310: Fix a traceback in argparse when all options in a mutually 
exclusive group are suppressed (GH-96311) (GH-115767)

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 <[email protected]>

files:
A Misc/NEWS.d/next/Library/2022-08-26-15-50-53.gh-issue-96310.0NssDh.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Lib/argparse.py b/Lib/argparse.py
index 462cf2cdc7f6bb..4d6b31aaef6452 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -415,6 +415,8 @@ def _format_actions_usage(self, actions, groups):
                             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:
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 5a953088e66518..940c93bcb02a3b 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -2797,6 +2797,27 @@ def test_help(self):
               '''
         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
index 00000000000000..f8efb0002e104a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-08-26-15-50-53.gh-issue-96310.0NssDh.rst
@@ -0,0 +1,2 @@
+Fix a traceback in :mod:`argparse` when all options in a mutually exclusive
+group are suppressed.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to