1

from the advice by the accepted answer of my previous question, and from this question, I tried to do:

parser = argparse.ArgumentParser(description="output parser")
line_parser = argparse.ArgumentParser(add_help=False)
line_parser.add_argument("-N", help="Showing first N line",
 metavar='integer', type=int)
line_parser.add_argument("-n", help="Showing last n line",
 metavar='integer', type=int)
parser.add_argument("opt", help="grep string from file",
 nargs=2, metavar=("str", "file"))
subp = parser.add_subparsers()
pscf = subp.add_parser("scf", help="show convergence", parents=[line_parser])#,
pkp = subp.add_parser("kpoint", help="show kpoints")
pnb = subp.add_parser("nband", help="show number of bands")
pmd = subp.add_parser("md", help="Create xyz file for each ionic step for"
 " visualization")#, action='store_true')
pfrc = subp.add_parser("force", help="See which atom has maximum force")
# parser.add_argument("--xsf", help="Create xsf file for md(default is xyz)"
 # " visualization", action='store_true')
args = parser.parse_args()

This is giving error:

python3 vasp.py --help
Traceback (most recent call last):
 File "vasp.py", line 27, in <module>
 args = parser.parse_args()
 File "/usr/lib64/python3.4/argparse.py", line 1728, in parse_args
 args, argv = self.parse_known_args(args, namespace)
 File "/usr/lib64/python3.4/argparse.py", line 1760, in parse_known_args
 namespace, args = self._parse_known_args(args, namespace)
 File "/usr/lib64/python3.4/argparse.py", line 1966, in _parse_known_args
 start_index = consume_optional(start_index)
 File "/usr/lib64/python3.4/argparse.py", line 1906, in consume_optional
 take_action(action, args, option_string)
 File "/usr/lib64/python3.4/argparse.py", line 1834, in take_action
 action(self, namespace, argument_values, option_string)
 File "/usr/lib64/python3.4/argparse.py", line 1016, in __call__
 parser.print_help()
 File "/usr/lib64/python3.4/argparse.py", line 2359, in print_help
 self._print_message(self.format_help(), file)
 File "/usr/lib64/python3.4/argparse.py", line 2336, in format_help
 formatter.add_arguments(action_group._group_actions)
 File "/usr/lib64/python3.4/argparse.py", line 272, in add_arguments
 self.add_argument(action)
 File "/usr/lib64/python3.4/argparse.py", line 257, in add_argument
 invocations = [get_invocation(action)]
 File "/usr/lib64/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)

If I remove all of line_parser, then it works fine. But I need them, as -N and -n will be used in multiple options, though not shown here.

I have read this but haven't managed to assimilate.

asked Mar 18, 2016 at 22:52

2 Answers 2

0

The exception is not related to line_parser, but parameter 'metavar' in line 8. Change tuple to list will make your code work.

parser.add_argument("opt", help="grep string from file",
 nargs=2, metavar=["str", "file"])
answered Mar 19, 2016 at 0:53
Sign up to request clarification or add additional context in comments.

1 Comment

Changing to a list does let it run. The help line looks right, but the usage line has ['str', 'file'] ['str', 'file'], which isn't what BaRud intends. Something looks buggy. I'll have to dig into the code.
0

I agree, it isn't a parents or subparser issue, but a nargs and metavar issue. There is a relevant Python bug/issue

http://bugs.python.org/issue14074; argparse allows nargs>1 for positional arguments but doesn't allow metavar to be a tuple

I suggested a patch a couple of years ago, but there's a big backlog of argparse issues, so no action has been taken.


If opt is changed to --opt:

parser.add_argument("--opt", help="grep string from file",
 nargs=2, metavar=("str", "file"))

then the help is:

1949:~/mypy$ python stack36095543.py -h
usage: stack36095543.py [-h] [--opt str file] {scf,kpoint,nband,md,force} ...
output parser
positional arguments:
 {scf,kpoint,nband,md,force}
 scf show convergence
 ...
optional arguments:
 -h, --help show this help message and exit
 --opt str file grep string from file

I think that's what is intended.

Changing the metavar to a list produces

usage: stack36095543.py [-h] [--opt ['str', 'file'] ['str', 'file']]
 {scf,kpoint,nband,md,force} ...

which I don't think is the intended usage.

According to the docs:

Providing a tuple to metavar specifies a different display for each of the arguments:

I would suggest going with the --opt argument. One, it gets this metavar display right. Two, positionals don't play that nicely with subparsers. A subparser is a positional argument as well (in disguise). I think it is safer to define the other main parser arguments as 'optionals'

Note, if I make --opt required=True, the usage like is:

usage: stack36095543.py [-h] --opt str file {scf,kpoint,nband,md,force} ...

In that case it's a bit hard to distinguish between flag and argument. argparse uses upper case for the default optionals metavars. It is clear if get use:

 usage: stack36095543.py [-h] --opt STR FILE {scf,kpoint,nband,md,force} ...

Another possibility is to replace the nargs=2 argument with 2 positionals

parser.add_argument("grep",metavar='STR')
parser.add_argument("file",metavar='FILE')

producing:

usage: stack36095543.py [-h] STR FILE {scf,kpoint,nband,md,force} ...

A positional with nargs=2 (or *,+) is best reserved for cases where all values are the same kind of thing - values in a list. Where they represent different things, it makes more sense to use separate arguments.


On further testing I find that your code handles the usage just fine. parser.print_usage() produces:

usage: stack36095543.py [-h] str file {scf,kpoint,nband,md,force} ...

the error is produced when formatting the help line. A line that should look like:

str file grep string from file

And according to my posts on the bug/issue, a metavar like this also has problems when displaying an error message.

answered Mar 19, 2016 at 2:57

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.