-
-
Notifications
You must be signed in to change notification settings - Fork 32k
bpo-14074: argparse doesn't allow metavar to be a tuple #10847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CPython follows PEP8, so I believe the style is to prefer open parentheses over \
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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