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.

Author vvas
Recipients vvas
Date 2014年05月30日.22:01:36
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1401487300.75.0.673087061626.issue21616@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2014年05月30日 22:01:41vvassetrecipients: + vvas
2014年05月30日 22:01:40vvassetmessageid: <1401487300.75.0.673087061626.issue21616@psf.upfronthosting.co.za>
2014年05月30日 22:01:40vvaslinkissue21616 messages
2014年05月30日 22:01:36vvascreate

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