Skip to content

argparse sometimes tracebacks when all options in a mutually exclusive group are suppressed #96310

@dmach

Description

@dmach

Bug report

When a subparser contains a mutually exclusive group and the all options in the group are suppressed,
it sometimes errors out with a traceback. The crash depends on other options (their ordering and length) and terminal size.

Reproducer:

#!/usr/bin/python3 import argparse parser = argparse.ArgumentParser() 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") parser.parse_args() 
$ python3.11 reproducer.py foo --help Traceback (most recent call last): File ".../reproducer.py", line 13, in <module> parser.parse_args() File "/usr/lib64/python3.11/argparse.py", line 1862, in parse_args args, argv = self.parse_known_args(args, namespace) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 1895, in parse_known_args namespace, args = self._parse_known_args(args, namespace) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 2085, in _parse_known_args positionals_end_index = consume_positionals(start_index) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 2062, in consume_positionals take_action(action, args) File "/usr/lib64/python3.11/argparse.py", line 1971, in take_action action(self, namespace, argument_values, option_string) File "/usr/lib64/python3.11/argparse.py", line 1234, in __call__ subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 1895, in parse_known_args namespace, args = self._parse_known_args(args, namespace) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 2103, in _parse_known_args start_index = consume_optional(start_index) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 2043, in consume_optional take_action(action, args, option_string) File "/usr/lib64/python3.11/argparse.py", line 1971, in take_action action(self, namespace, argument_values, option_string) File "/usr/lib64/python3.11/argparse.py", line 1112, in __call__ parser.print_help() File "/usr/lib64/python3.11/argparse.py", line 2590, in print_help self._print_message(self.format_help(), file) ^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 2574, in format_help return formatter.format_help() ^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 286, in format_help help = self._root_section.format_help() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 217, in format_help item_help = join([func(*args) for func, args in self.items]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 217, in <listcomp> item_help = join([func(*args) for func, args in self.items]) ^^^^^^^^^^^ File "/usr/lib64/python3.11/argparse.py", line 341, in _format_usage assert ' '.join(opt_parts) == opt_usage AssertionError 

Please note that setting COLUMNS to a high number doesn't trigger the traceback:

COLUMNS=1000 python3.11 reproducer.py foo --help usage: reproducer.py foo [-h] [--longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong LONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONG] options: -h, --help show this help message and exit --longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong LONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONGLONG 

Your environment

  • CPython versions tested on: 3.8.13, 3.10.6, 3.11.0b5
  • openSUSE Tumbleweed 20220823

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Doc issues

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions