I have test scenario where I need to take action based on arguments passed to python script. The requirement is as follows:
test.py -a a1 -b b1 [[[-c c1] [-d d1]] | [-e e1 -f f1]]
- The user has to pass mandatory arguments '-a' and '-b'.
- The arguments '-c' and '-d' are optional arguments which could be passed individually.
- The arguments '-e' and '-f' are optional arguments that has to be passed together along with mandatory arguments.
- If any of '-c' or '-d' are passed along with '-e' and '-f', then script should give error for arguments '-c' or '-d'.
- If '-e' and '-f' are passed along with '-c' or '-d', then script should give error for arguments '-e' and '-d'.
The error could be generic error for all the optional arguments.
Till now, I'm trying to do it using parents=
option of argparse.ArgumentParser
but it is giving error when I try to read the passed arguments.
import argparse
parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-a', type=str, required=True)
parent_parser.add_argument('-b', type=str, required=True)
one_parser = argparse.ArgumentParser(parents=[parent_parser])
one_parser.add_argument('-c', type=str, default="test")
one_parser.add_argument('-d', type=str, default="Default")
multi_parser = argparse.ArgumentParser(parents=[parent_parser])
multi_parser.add_argument('-e', type=str)
multi_parser.add_argument('-f', type=str)
if str(one_parser.parse_args().c):
print(one_parser.parse_args())
elif str(multi_parser.parse_args().e):
print(multi_parser.parse_args())
When I run the script as :
test.py -a a1 -b b1 -e e1 -f f1
I'm getting the error :
usage: test.py [-h] -a A -b B [-c C] [-d D]
test.py: error: unrecognized arguments: -e e1 -f f1
Process finished with exit code 2
Any pointers are highly appreciated. Thank you.
Answer: The solution is hack but it worked for me.
import argparse
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-a', type=str, required=True)
parser.add_argument('-b', type=str, required=True)
parser.add_argument('-c', type=str)
parser.add_argument('-d', type=str)
parser.add_argument('-e', type=str)
parser.add_argument('-f', type=str)
args = parser.parse_args()
a = str(args.a)
b = str(args.b)
c = str(args.c)
d = str(args.d)
e = str(args.e)
f = str(args.f)
if (e != "None" and f == "None") or (e == "None" and f != "None"):
if c == "None" and d == "None":
raise argparse.ArgumentTypeError("Both e and f arguments are required")
elif c != "None" or d != "None":
raise argparse.ArgumentTypeError("e and f are not supported with c or d")
if (c != "None" or d != "None") and (e != "None" or f != "None"):
raise argparse.ArgumentTypeError("c and d are not supported with e and f")
if e == "None" and f == "None":
if c == "None":
c = "test"
if d == "None":
d = "Default"
IMO, argparser should handle argument dependency more efficiently. Maybe someone will contribute and help us all.. :)