Closed
Description
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
- gh-96310: Fix a traceback in argparse when all options in a mutually exclusive group are suppressed #96311
- [3.12] gh-96310: Fix a traceback in argparse when all options in a mutually exclusive group are suppressed (GH-96311) #115767
- [3.11] gh-96310: Fix a traceback in argparse when all options in a mutually exclusive group are suppressed (GH-96311) #115768
Metadata
Metadata
Assignees
Projects
Status
Doc issues