homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: argparse explodes with nargs='*' and a tuple metavar
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.4, Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: argparse allows nargs>1 for positional arguments but doesn't allow metavar to be a tuple
View: 14074
Assigned To: Nosy List: paul.j3, vvas
Priority: normal Keywords:

Created on 2014年05月30日 22:01 by vvas, last changed 2022年04月11日 14:58 by admin. This issue is now closed.

Messages (3)
msg219429 - (view) Author: Vasilis Vasaitis (vvas) Date: 2014年05月30日 22:01
The title says it all really, but to demostrate: Let's say I'm building a program which takes another command as its argument(s) on the command line, to execute it in a special way or whatever. The natural way to do this then would be something like the following:
 import argparse
 parser = argparse.ArgumentParser()
 parser.add_argument('cmd', nargs='*')
 parser.parse_args()
Which gives the following output with -h:
 usage: nargs.py [-h] [cmd [cmd ...]]
 positional arguments:
 cmd
 optional arguments:
 -h, --help show this help message and exit
Now, let's say I want to have 'command' printed in the help output, but still write the shorter 'cmd' in the code. Naturally I would make use of the metavar feature:
 import argparse
 parser = argparse.ArgumentParser()
 parser.add_argument('cmd', nargs='*', metavar='command')
 parser.parse_args()
So now the help output is:
 usage: nargs.py [-h] [command [command ...]]
 positional arguments:
 command
 optional arguments:
 -h, --help show this help message and exit
That's better, but I don't really want it to say 'command' twice there, it's more like a command and then its arguments. So what about a tuple instead?
 import argparse
 parser = argparse.ArgumentParser()
 parser.add_argument('cmd', nargs='*', metavar=('command', 'arguments'))
 parser.parse_args()
So let's see what happens now with -h:
 Traceback (most recent call last):
 File "/Users/Vasilis/Sources/Tests/nargs.py", line 6, in <module>
 parser.parse_args()
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1717, in parse_args
 args, argv = self.parse_known_args(args, namespace)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1749, in parse_known_args
 namespace, args = self._parse_known_args(args, namespace)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1955, in _parse_known_args
 start_index = consume_optional(start_index)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1895, in consume_optional
 take_action(action, args, option_string)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1823, in take_action
 action(self, namespace, argument_values, option_string)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1016, in __call__
 parser.print_help()
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 2348, in print_help
 self._print_message(self.format_help(), file)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 2325, in format_help
 formatter.add_arguments(action_group._group_actions)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 272, in add_arguments
 self.add_argument(action)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 257, in add_argument
 invocations = [get_invocation(action)]
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 535, in _format_action_invocation
 metavar, = self._metavar_formatter(action, default)(1)
 ValueError: too many values to unpack (expected 1)
Hm, that didn't go very well. Perhaps I can try with a single element in the tuple, as the exception seems to suggest:
 import argparse
 parser = argparse.ArgumentParser()
 parser.add_argument('cmd', nargs='*', metavar=('command',))
 parser.parse_args()
Any better?
 Traceback (most recent call last):
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1334, in add_argument
 self._get_formatter()._format_args(action, None)
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 579, in _format_args
 result = '[%s [%s ...]]' % get_metavar(2)
 TypeError: not enough arguments for format string
 During handling of the above exception, another exception occurred:
 Traceback (most recent call last):
 File "/Users/Vasilis/Sources/Tests/nargs.py", line 5, in <module>
 parser.add_argument('cmd', nargs='*', metavar=('command',))
 File "/usr/local/Cellar/python3/3.4.0/Frameworks/Python.framework/Versions/3.4/lib/python3.4/argparse.py", line 1336, in add_argument
 raise ValueError("length of metavar tuple does not match nargs")
 ValueError: length of metavar tuple does not match nargs
No, not really.
So there you have it. I think the two-element-tuple example should do the right thing (print "[command [arguments ...]]"). But if not, at least *some* kind of tuple should work without raising an exception.
Apart from 3.4, I see precisely the same behaviour with Python 2.7 too. I haven't tested with any other version I'm afraid.
msg219646 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2014年06月02日 22:21
I think is issue was already raised in
http://bugs.python.org/issue14074
argparse allows nargs>1 for positional arguments but doesn't allow metavar to be a tuple
msg220072 - (view) Author: Vasilis Vasaitis (vvas) Date: 2014年06月09日 00:05
Ah, I did come across that issue when I was searching for prior reports, but somehow it didn't register in my head as being the same thing. Does the fix for that address the behaviour I'm seeing too? If so, feel free to close as a duplicate. Additionally, if that fix is indeed relevant, is there an ETA for it?
History
Date User Action Args
2022年04月11日 14:58:04adminsetgithub: 65815
2021年11月26日 23:42:24iritkatrielsetstatus: open -> closed
superseder: argparse allows nargs>1 for positional arguments but doesn't allow metavar to be a tuple
resolution: duplicate
stage: resolved
2014年06月09日 00:05:42vvassetmessages: + msg220072
2014年06月02日 22:21:46paul.j3setnosy: + paul.j3
messages: + msg219646
2014年05月30日 22:02:30vvassetversions: + Python 2.7
2014年05月30日 22:01:40vvascreate

AltStyle によって変換されたページ (->オリジナル) /