I've been searching through a lot of the subparser examples on here and in general but can't seem to figure this seemingly simple thing out.
I have two var types of which one has constraints so thought subparser was the way to go. e.g. -t allows for either "A" or "B". If the user passes "A" then they are further required to also specify if it is either "a1" or "a2". If they pass just "B" then nothing.
Can I do this and have argparse return me what type of "A" was passed or if it was just "B"?
The below seems to work but for some reason breaks when passing anything after the subparse.
e.g. from a linux terminal
>> python test01.py -t A a1 -v 61
errors with...
usage: test01.py a1 [-h] test01.py a1: error: unrecognized arguments: -v
Hopefully that makes sense.
The code:
import argparse parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(help='types of A') parser.add_argument("-t", choices = ["A", "B"], dest = "type", required=True, action='store', help="Some help blah blah") cam_parser = subparsers.add_parser('a1', help='Default') cam_parser.set_defaults(which='a1') cam_parser = subparsers.add_parser('a2', help='parse this instead of default') cam_parser.set_defaults(which='a2') parser.add_argument("-v", nargs = '+', required=True, dest = "version", type=int, action='store', help="some version help blah blah") argument = parser.parse_args() print argument.type print argument.version
A “subparser” is an argument parser bound to a namespace. In other words, it works with everything after a certain positional argument. Argh implements commands by creating a subparser for every function.
To add an optional argument, simply omit the required parameter in add_argument() . args = parser. parse_args()if args.
Subparsers are invoked based on the value of the first positional argument, so your call would look like
python test01.py A a1 -v 61
The "A" triggers the appropriate subparser, which would be defined to allow a positional argument and the -v
option.
Because argparse
does not otherwise impose any restrictions on the order in which arguments and options may appear, and there is no simple way to modify what arguments/options may appear once parsing has begun (something involving custom actions that modify the parser instance might work), you should consider replacing -t
itself:
import argparse parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(help='types of A') parser.add_argument("-v", ...) a_parser = subparsers.add_parser("A") b_parser = subparsers.add_parser("B") a_parser.add_argument("something", choices=['a1', 'a2'])
Since -v
is defined for the main parser, it must be specified before the argument that specifies which subparser is used for the remaining arguments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With