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 AssertionError with add_mutually_exclusive_group and help=SUPPRESS #66559
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2016-01-29.03:30:00.386>created_at=<Date2014-09-08.11:46:27.076>labels= ['type-bug']
title='argparse AssertionError with add_mutually_exclusive_group and help=SUPPRESS'updated_at=<Date2016-01-29.03:30:00.384>user='https://bugs.python.org/mZarjk'
Executing the attached script causes an AssertionError.
Traceback (most recent call last):
File "bug.py", line 18, in <module>
parser.format_usage()
File "/usr/lib/python3.4/argparse.py", line 2318, in format_usagereturn formatter.format_help()
File "/usr/lib/python3.4/argparse.py", line 287, in format_helphelp=self._root_section.format_help()
File "/usr/lib/python3.4/argparse.py", line 217, in format_help
func(*args)
File "/usr/lib/python3.4/argparse.py", line 338, in _format_usageassert''.join(opt_parts) == opt_usage
AssertionError
The script was tested in a clean Python installation.
If any of the arguments are removed, there is no AssertionError exception.
If "help=SUPPRESS" is removed, there is no AssertionError exception.
This bug appears to have existed since Python 3.2, the first version that included argparse.
This assert statement is only reached when the usage line is long enough that it needs to be wrapped. Which is why the assertion does not happen when an argument is removed.
opt_usage is being compared to this string:
"[-h] [--arg2 ARG2] [--arg3 ARG3] [--arg4 ARG4] [--arg5 ARG5] [--arg6 ARG6]"
opt_usage in this case has the value:
"[-h] [--arg2 ARG2] [--arg3 ARG3] [--arg4 ARG4] [--arg5 ARG5] [--arg6 ARG6]"
There is an extra space after "[-h]". The value of opt_usage comes from _format_actions_usage. And that is where the bug is.
Just before _format_actions_usage returns, the usage string is:
"[-h] [ ] [--arg2 ARG2] [--arg3 ARG3] [--arg4 ARG4] [--arg5 ARG5] [--arg6 ARG6]"
The method uses this regexp:
"[ *]"
To remove the extra brackets. But that leaves the extra space after the brackets.
The attached patch changes the regexp to:
"[ *] ?"
So that the extra space is also removed.
The patch also adds a testcase based on the script that reproduces the
paulj3 commented on Sep 9, 2014
paulj3mannequin
Mannequin
More actions
This assertion has triggered several bug issues, either due to an empty group like this, or certain characters in the metavars.
I think this is a duplicate of 17890, though I'll have to look more closely at your patch to see what it adds.
For 11874 I proposed a major rewrite of the usage formatting. There I format each group and/or action separately, and keep the pieces in a list. That way it's easier to filter out empty pieces, and avoids the complex split that gives headaches when the usage is long enough to wrap.
mZarjk commented on Sep 9, 2014
mZarjkmannequin
MannequinAuthor
More actions
I've confirmed that this is a duplicate of bpo-17890.
In case anyone needs it, a workaround is to move the mutually exclusive group to the end of the arguments.
Activity
mZarjk commentedon Sep 8, 2014
Executing the attached script causes an AssertionError.
The script was tested in a clean Python installation.
If any of the arguments are removed, there is no AssertionError exception.
If "help=SUPPRESS" is removed, there is no AssertionError exception.
This bug appears to have existed since Python 3.2, the first version that included argparse.
mZarjk commentedon Sep 9, 2014
This assert statement is only reached when the usage line is long enough that it needs to be wrapped. Which is why the assertion does not happen when an argument is removed.
opt_usage is being compared to this string:
"[-h] [--arg2 ARG2] [--arg3 ARG3] [--arg4 ARG4] [--arg5 ARG5] [--arg6 ARG6]"
opt_usage in this case has the value:
"[-h] [--arg2 ARG2] [--arg3 ARG3] [--arg4 ARG4] [--arg5 ARG5] [--arg6 ARG6]"
There is an extra space after "[-h]". The value of opt_usage comes from _format_actions_usage. And that is where the bug is.
Just before _format_actions_usage returns, the usage string is:
"[-h] [ ] [--arg2 ARG2] [--arg3 ARG3] [--arg4 ARG4] [--arg5 ARG5] [--arg6 ARG6]"
The method uses this regexp:
"[ *]"
To remove the extra brackets. But that leaves the extra space after the brackets.
The attached patch changes the regexp to:
"[ *] ?"
So that the extra space is also removed.
The patch also adds a testcase based on the script that reproduces the
paulj3 commentedon Sep 9, 2014
This assertion has triggered several bug issues, either due to an empty group like this, or certain characters in the metavars.
http://bugs.python.org/issue17890
'argparse: mutually exclusive groups full of suppressed args can cause AssertionErrors'
http://bugs.python.org/issue11874
'argparse assertion failure with brackets in metavars'
http://bugs.python.org/issue16360
'argparse: comma in metavar causes assertion failure when formatting long usage message'
I think this is a duplicate of 17890, though I'll have to look more closely at your patch to see what it adds.
For 11874 I proposed a major rewrite of the usage formatting. There I format each group and/or action separately, and keep the pieces in a list. That way it's easier to filter out empty pieces, and avoids the complex split that gives headaches when the usage is long enough to wrap.
mZarjk commentedon Sep 9, 2014
I've confirmed that this is a duplicate of bpo-17890.
In case anyone needs it, a workaround is to move the mutually exclusive group to the end of the arguments.
vadmium commentedon Jan 29, 2016
I left one review comment, but it seems there is more discussion at bpo-17890, which also originally proposed a very similar fix.