I had to read your description several times, but I think this is the problem:
prog -i id1 id2 cmd1 -foo 3 ....
and it gives some sort of warning about not finding {cmd1,cmd2,cmd3}
. The exact error may differ because in some versions subparsers
aren't actually required.
In any case, the arguments to -i
are ['id1','id2','cmd1']
, everything up to the next -
flag. To the main parser, the subparsers argument is just another positional
one (with choices
). When allocating strings to -i
it does not check whether the string matches one of the cmds
. It just looks at whether it starts with -
or not.
The only way you can use an nargs='+'
(or '*') in the context is to include some other flagged argument, e.g.
prog -i id1 id2 -x 3 cmd1 --foo ...
I realize that goes against your mutually_exclusive
group.
The basic point is non flag strings are allocated based on position, not value. For a variable nargs
you have to have some sort of explicit list terminator.
From the sidebar
Argparse nargs="+" is eating positional argument
It's similar except that your next positional is the subparsers cmd.
==============
A positional with '+' will work right before a subparsers cmd
usage: prog [-h] foo [foo ...] {cmd1,cmd2} ...
In [160]: p1.parse_args('1 22 3 cmd1'.split())
Out[160]: Namespace(cmd='cmd1', foo=['1', '22', '3'])
But that's because strings for foo
and cmd
are allocated with one regex
pattern test.
In
usage: prog [-h] [--bar BAR [BAR ...]] {cmd1,cmd2} ...
strings are allocated to bar
without reference to the needs of the following positional, cmd
. As shown in the suggested patches for http://bugs.python.org/issue9338, changing this behavior is not a trivial change. It requires an added look-ahead trial-and-error loop.