New submission from Vasilis Vasaitis:
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