You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
argparse assertion failure with multiline metavars #77048
Traceback (most recent call last):
File "tmp.py", line 7, in <module>
p.parse_args()
File "/usr/lib/python3.6/argparse.py", line 1730, in parse_args
args, argv =self.parse_known_args(args, namespace)
File "/usr/lib/python3.6/argparse.py", line 1762, in parse_known_args
namespace, args =self._parse_known_args(args, namespace)
File "/usr/lib/python3.6/argparse.py", line 1968, in _parse_known_args
start_index = consume_optional(start_index)
File "/usr/lib/python3.6/argparse.py", line 1908, in consume_optional
take_action(action, args, option_string)
File "/usr/lib/python3.6/argparse.py", line 1836, in take_action
action(self, namespace, argument_values, option_string)
File "/usr/lib/python3.6/argparse.py", line 1020, in __call__
parser.print_help()
File "/usr/lib/python3.6/argparse.py", line 2362, in print_helpself._print_message(self.format_help(), file)
File "/usr/lib/python3.6/argparse.py", line 2346, in format_helpreturn formatter.format_help()
File "/usr/lib/python3.6/argparse.py", line 282, in format_helphelp=self._root_section.format_help()
File "/usr/lib/python3.6/argparse.py", line 213, in format_help
item_help = join([func(*args) for func, args inself.items])
File "/usr/lib/python3.6/argparse.py", line 213, in <listcomp>
item_help = join([func(*args) for func, args inself.items])
File "/usr/lib/python3.6/argparse.py", line 334, in _format_usageassert''.join(pos_parts) == pos_usage
AssertionError
-----8<
```------------------
If newlines are not permitted in metavars, the user should see
ValueError: newline not permitted in metavar
paulj3 commented on Mar 18, 2018
paulj3mannequin
Mannequin
More actions
I haven't seen anyone try to use \n in a metavar before, but other special characters like [] and () produce this assertion error. At this point the code is trying split the usage into 2 or more lines, because it's too long for one. It creates a usage for optionals and positionals separately.
In a clumsy way, it formats the whole usage string, and tries to split it into pieces so it can decide to split long lines. The 'assert' is used to make sure it has split the line into meaningful blocks. It splits with
r'\(.*?\)+|\[.*?\]+|\S+'
basically white space (including nl) and [] and () which are used to mark optional arguments and groups. So including any of these characters in text via metavar will screwup this split.
We could try to refine this splitting expression, but that feels like a never ending task as users become more inventive.
I suggested a major rewrite of this section, one that keeps the pieces a list, and joins them after deciding how many can fit on a line.
No one has, to my knowledge, come up with a comprehensive list of characters that will cause problems here.
argparse does provide a backup - a user provided usage string. That's not as nice as a automatically generated one, but if you have to have something special, that's the way to go. In the long run there's only so much that general purpose parser can do to accommodate special needs.
Activity
MaT1g3R commentedon Feb 18, 2018
If I run this script with -h
-----8<------------------
I get an error:
---------8<--------------------
terryjreedy commentedon Feb 23, 2018
I don't understand the -h (display help part) but pasting code into repository 3.8 IDLE editor and running, I get same traceback.
Never having used argparse, I don't know if a multiline metavar is expected to work. Assuming so, can you suggest a fix?
vadmium commentedon Feb 24, 2018
This looks like the same assertion failure as described in bpo-16360. Paul pointed to a patch in bpo-11874, so that may also be relevant.
However I agree that embedding newlines in a metavar doesn’t make much sense. What’s the use case?
MaT1g3R commentedon Feb 24, 2018
I tried to include line breaks for listing options for a positional argument.
The default metavar for that is something like {opt1, opt2, op3},
however I wanted it to display the options on separate lines.
terryjreedy commentedon Feb 24, 2018
If newlines are not permitted in metavars, the user should see
ValueError: newline not permitted in metavar
paulj3 commentedon Mar 18, 2018
I haven't seen anyone try to use \n in a metavar before, but other special characters like [] and () produce this assertion error. At this point the code is trying split the usage into 2 or more lines, because it's too long for one. It creates a usage for optionals and positionals separately.
In a clumsy way, it formats the whole usage string, and tries to split it into pieces so it can decide to split long lines. The 'assert' is used to make sure it has split the line into meaningful blocks. It splits with
basically white space (including nl) and [] and () which are used to mark optional arguments and groups. So including any of these characters in text via metavar will screwup this split.
We could try to refine this splitting expression, but that feels like a never ending task as users become more inventive.
I suggested a major rewrite of this section, one that keeps the pieces a list, and joins them after deciding how many can fit on a line.
No one has, to my knowledge, come up with a comprehensive list of characters that will cause problems here.
argparse does provide a backup - a user provided usage string. That's not as nice as a automatically generated one, but if you have to have something special, that's the way to go. In the long run there's only so much that general purpose parser can do to accommodate special needs.
iritkatriel commentedon Dec 15, 2021
It works for me on 3.11:
% ./python.exe b.py -h
usage: 11111111111111 [-h] [-v] 123456
12345
12345
123 [123456
12345
12345
123 ...]
positional arguments:
123456
12345
12345
123
installation targets
options:
-h, --help show this help message and exit
-v, --verbose verbose mode
Simplify argparse usage formatting
gh-62090: Simplify argparse usage formatting (GH-105039)
encukou commentedon May 7, 2024
This was fixed some time between Python 3.7.17 and 3.8.19.
pythongh-62090: Simplify argparse usage formatting (pythonGH-105039)