From 0d6958cdff657fc4965251695a5fa766f18dafee Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Fri, 26 Aug 2022 15:05:08 +0200 Subject: [PATCH] gh-96310: Fix a traceback when all options in a mutually exclusive group are suppressed 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 | 2 ++ Lib/test/test_argparse.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Lib/argparse.py b/Lib/argparse.py index fe48f8670fa20a4..808e1401dba4949 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -405,6 +405,8 @@ def _format_actions_usage(self, actions, groups): else: end = start + len(group._group_actions) if actions[start:end] == group._group_actions: + if all((action.help is SUPPRESS for action in group._group_actions)): + continue for action in group._group_actions: group_actions.add(action) if not group.required: diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 2b7f008d38564bc..f2a625a972b4e10 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2695,6 +2695,25 @@ 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) + cmd_foo.add_argument("--longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong") + expected = '''\ + usage: PROG foo [-h] + [--longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong LONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONG] + + options: + -h, --help show this help message and exit + --longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong LONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONG + ''' + self.assertEqual(cmd_foo.format_help(), textwrap.dedent(expected)) + def test_empty_group(self): # See issue 26952 parser = argparse.ArgumentParser()