Python argparse: Mutually exclusive required group with a required option
14,690
You have already achieved it! Argparse only prints the first error it finds, so while it may look like it's only checking -k, it actually recuires -n/-t too. You can see this by actually giving it the -k argument.
If you provide the -k argument, the error message will change from test.py: error: argument -k/--kick_start is required
to test.py: error: one of the arguments -n/--name -t/--template is required
.
Related videos on Youtube
Author by
Abhinav
Updated on June 03, 2022Comments
-
Abhinav almost 2 years
I am trying to have a required mutually exclusive group with one required parameter. Below is the code which I have put
#!/usr/bin/python import argparse import sys # Check for the option provided as part of arguments def parseArgv(): parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group() group.add_argument("-v", "--verbose", choices=[1,2,3,4], help = "Increase verbosity") group.add_argument("-q", "--quiet", action="store_true", help = "Run quietly") name = parser.add_mutually_exclusive_group(required=True) name.add_argument("-n", "--name", help = "Name of the virtual machine") name.add_argument("-t", "--template", help = "Name of the template to use \ for creating vm. If path is not provided then it will be looked \ under template directory.") parser.add_argument("-s", "--save", help = "Save the machine template. If \ path is not provided then it will be saved under template directory."); #parser.add_argument("-k", "--kick_start", required = True, help = "Name of the \ # kick start file. If path is not provided then it will be look into http \ # directory.") if len(sys.argv) == 1: parser.print_help() args = parser.parse_args() if __name__ == '__main__': parseArgv()
Now the output of this program as follow
$ python test.py usage: test.py [-h] [-v {1,2,3,4} | -q] (-n NAME | -t TEMPLATE) [-s SAVE] optional arguments: -h, --help show this help message and exit -v {1,2,3,4}, --verbose {1,2,3,4} Increase verbosity -q, --quiet Run quietly -n NAME, --name NAME Name of the virtual machine -t TEMPLATE, --template TEMPLATE Name of the template to use for creating vm. If path is not provided then it will be looked under template directory. -s SAVE, --save SAVE Save the machine template. If path is not provided then it will be saved under template directory. usage: test.py [-h] [-v {1,2,3,4} | -q] (-n NAME | -t TEMPLATE) [-s SAVE] test.py: error: one of the arguments -n/--name -t/--template is required
But if I un-comment the from line 20 - 22 then the output change as below
$ python test.py usage: test.py [-h] [-v {1,2,3,4} | -q] (-n NAME | -t TEMPLATE) [-s SAVE] -k KICK_START optional arguments: -h, --help show this help message and exit -v {1,2,3,4}, --verbose {1,2,3,4} Increase verbosity -q, --quiet Run quietly -n NAME, --name NAME Name of the virtual machine -t TEMPLATE, --template TEMPLATE Name of the template to use for creating vm. If path is not provided then it will be looked under template directory. -s SAVE, --save SAVE Save the machine template. If path is not provided then it will be saved under template directory. -k KICK_START, --kick_start KICK_START Name of the kick start file. If path is not provided then it will be look into http directory. usage: test.py [-h] [-v {1,2,3,4} | -q] (-n NAME | -t TEMPLATE) [-s SAVE] -k KICK_START test.py: error: argument -k/--kick_start is required
But I want that either -n / -t along with -k become mandatory. How to achieve the same.
-
Abhinav almost 10 yearsThanks, I was not knowing it as I am learning Python :). One more thing how to check if argument has some value. Is there some empty(C++) like function.
-
Aleksi Torhamo almost 10 yearsYou should really ask a separate question if it isn't related (after checking it hasn't been asked already, of course), but... It depends on what exactly you want to do. Python has a concept of "truthiness", so you can just use the variable directly in an if-clause or whatever, eg.
if variable:
orif not variable:
. Aside from that, you can use eg.len(variable) == 0
on containers orvariable is None
to check that it is None specifically. Or just compare to the empty value for the type in question. -
hpaulj almost 10 yearsThe default value for your
argparse
arguments isNone
. Thusprint args.name is None
will printTrue
. Default forargs.quiet
isFalse
.