Skip to content

Commit dae7341

Browse files
[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 5f7df88) Co-authored-by: Daniel Mach <[email protected]>
1 parent 2ea2d25 commit dae7341

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
@@ -415,6 +415,8 @@ def _format_actions_usage(self, actions, groups):
415415
suppressed_actions_count += 1
416416

417417
exposed_actions_count = group_action_count - suppressed_actions_count
418+
if not exposed_actions_count:
419+
continue
418420

419421
if not group.required:
420422
if start in inserts:

Lib/test/test_argparse.py

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

2800+
def test_help_subparser_all_mutually_exclusive_group_members_suppressed(self):
2801+
self.maxDiff = None
2802+
parser = ErrorRaisingArgumentParser(prog='PROG')
2803+
commands = parser.add_subparsers(title="commands", dest="command")
2804+
cmd_foo = commands.add_parser("foo")
2805+
group = cmd_foo.add_mutually_exclusive_group()
2806+
group.add_argument('--verbose', action='store_true', help=argparse.SUPPRESS)
2807+
group.add_argument('--quiet', action='store_true', help=argparse.SUPPRESS)
2808+
longopt = '--' + 'long'*32
2809+
longmeta = 'LONG'*32
2810+
cmd_foo.add_argument(longopt)
2811+
expected = f'''\
2812+
usage: PROG foo [-h]
2813+
[{longopt} {longmeta}]
2814+
2815+
options:
2816+
-h, --help show this help message and exit
2817+
{longopt} {longmeta}
2818+
'''
2819+
self.assertEqual(cmd_foo.format_help(), textwrap.dedent(expected))
2820+
28002821
def test_empty_group(self):
28012822
# See issue 26952
28022823
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)