Skip to content

Commit 5f7df88

Browse files
authored
gh-96310: Fix a traceback in argparse when all options in a mutually exclusive group are suppressed (GH-96311)
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.
1 parent 4a9e649 commit 5f7df88

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

Lib/argparse.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ def _format_actions_usage(self, actions, groups):
413413
suppressed_actions_count += 1
414414

415415
exposed_actions_count = group_action_count - suppressed_actions_count
416+
if not exposed_actions_count:
417+
continue
416418

417419
if not group.required:
418420
if start in inserts:

Lib/test/test_argparse.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,6 +2864,27 @@ def test_help(self):
28642864
'''
28652865
self.assertEqual(parser.format_help(), textwrap.dedent(expected))
28662866

2867+
def test_help_subparser_all_mutually_exclusive_group_members_suppressed(self):
2868+
self.maxDiff = None
2869+
parser = ErrorRaisingArgumentParser(prog='PROG')
2870+
commands = parser.add_subparsers(title="commands", dest="command")
2871+
cmd_foo = commands.add_parser("foo")
2872+
group = cmd_foo.add_mutually_exclusive_group()
2873+
group.add_argument('--verbose', action='store_true', help=argparse.SUPPRESS)
2874+
group.add_argument('--quiet', action='store_true', help=argparse.SUPPRESS)
2875+
longopt = '--' + 'long'*32
2876+
longmeta = 'LONG'*32
2877+
cmd_foo.add_argument(longopt)
2878+
expected = f'''\
2879+
usage: PROG foo [-h]
2880+
[{longopt} {longmeta}]
2881+
2882+
options:
2883+
-h, --help show this help message and exit
2884+
{longopt} {longmeta}
2885+
'''
2886+
self.assertEqual(cmd_foo.format_help(), textwrap.dedent(expected))
2887+
28672888
def test_empty_group(self):
28682889
# See issue 26952
28692890
parser = argparse.ArgumentParser()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a traceback in :mod:`argparse` when all options in a mutually exclusive
2+
group are suppressed.

0 commit comments

Comments
 (0)