bpo-14074: argparse doesn't allow metavar to be a tuple#10847
bpo-14074: argparse doesn't allow metavar to be a tuple#10847cykerway wants to merge 2 commits intopython:mainfrom
Conversation
|
Hello, and thanks for your contribution! I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA). Unfortunately we couldn't find an account corresponding to your GitHub username on bugs.python.org (b.p.o) to verify you have signed the CLA (this might be simply due to a missing "GitHub Name" entry in your b.p.o account settings). This is necessary for legal reasons before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue. You can check yourself to see if the CLA has been received. Thanks again for your contribution, we look forward to reviewing it! |
|
Thanks for the PR. I can confirm that this fixes this (very old) bug... |
|
Consider restricting this to the case where nargs is an integer. It doesn't make much sense with |
Misc/NEWS.d/next/Library/2018-12-04-07-36-27.bpo-14074.fMLKCu.rst
Outdated
Show resolved
Hide resolved
Lib/argparse.py
Outdated
| if isinstance(argument.nargs, int) and \ | ||
| isinstance(argument.metavar, tuple): | ||
| return ' '.join(argument.metavar) |
There was a problem hiding this comment.
CPython follows PEP8, so I believe the style is to prefer open parentheses over \.
There was a problem hiding this comment.
There it is: c0204fd
Nothing else changed.
Currently argparse allows nargs>1 for positional arguments but doesn't
allow metavar to be a tuple:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('foo', nargs=2, metavar=('bar', 'baz'))
args = parser.parse_args()
The above code will raise exception both with and without '--help'.
This patch fixed some functions about metavar processing so the above
code will pass.
|
For: Wouldn't it be better to specify two separate arguments? Having two different meta variables implies that the arguments have different meanings. Collapsing them into a single argument seems like an anti-pattern to me. Both warrant their own error messages, possible type conversions, and possible default values. |
That's the matter of
If we assume |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
I wondered why TestHelpTupleMetavarPositional tests only argument with numerical value of nartgs, while TestHelpTupleMetavar tests with all nargs values. So I tried to change the test. It failed, but a simple change in _format_action_invocation() can fix this. I am nor sure that this is a best representation for nargs='*' and nargs='+', but this at least fixes failure.
The change in _get_action_name() is not tested. We need a test for it, and it should be generalized to support other nargs values.
| if isinstance( | ||
| argument.nargs, int) and isinstance(argument.metavar, tuple): | ||
| return ' '.join(argument.metavar) |
There was a problem hiding this comment.
This change is not covered by tests.
|
|
||
| parser_signature = Sig(prog='PROG') | ||
| argument_signatures = [ | ||
| Sig('foo', help='foo help', nargs=2, metavar=('bar', 'baz')) |
There was a problem hiding this comment.
| Sig('foo', help='foo help', nargs=2, metavar=('bar', 'baz')) | |
| Sig('w', help='w help', nargs='+', metavar=('W1', 'W2')), | |
| Sig('x', help='x help', nargs='*', metavar=('X1', 'X2')), | |
| Sig('y', help='y help', nargs=3, metavar=('Y1', 'Y2', 'Y3')), | |
| Sig('z', help='z help', nargs='?', metavar=('Z1', )), |
| ] | ||
| argument_group_signatures = [] | ||
| usage = '''\ | ||
| usage: PROG [-h] bar baz |
There was a problem hiding this comment.
| usage: PROG [-h] bar baz | |
| usage: PROG [-h] W1 [W2 ...] [X1 [X2 ...]] Y1 Y2 Y3 [Z1] |
| help = usage + '''\ | ||
|
|
||
| positional arguments: | ||
| bar baz foo help |
There was a problem hiding this comment.
| bar baz foo help | |
| W1 W2 w help | |
| X1 X2 x help | |
| Y1 Y2 Y3 y help | |
| Z1 z help |
| if isinstance(action.nargs, int): | ||
| return ' '.join(self._metavar_formatter(action, default)(1)) | ||
| metavar, = self._metavar_formatter(action, default)(1) | ||
| return metavar |
There was a problem hiding this comment.
| if isinstance(action.nargs, int): | |
| return ' '.join(self._metavar_formatter(action, default)(1)) | |
| metavar, = self._metavar_formatter(action, default)(1) | |
| return metavar | |
| return ' '.join(self._metavar_formatter(action, default)(1)) |
Currently argparse allows nargs>1 for positional arguments but doesn't
allow metavar to be a tuple:
The above code will raise exception both with and without '--help'.
This patch fixed some functions about metavar processing so the above
code will pass.
https://bugs.python.org/issue14074