Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't require all the positional arguments if an optional argument is present

I have the following snippet:

parser = argparse.ArgumentParser()
parser.add_argument("a") # always required
parser.add_argument("x") # don't required in case -t option is chosen
parser.add_argument("y") # don't required in case -t option is chosen
parser.add_argument("z") # don't required in case -t option is chosen
parser.add_argument("-t", "--tt")
args = parser.parse_args()

The point is, I don't need the positional arguments x, y and z if the -t option is specified.

like image 816
xralf Avatar asked Nov 20 '16 21:11

xralf


1 Answers

You can achieve what you want I think using parse_known_args. Basically this means you can parse the args partially, once to see if you get -t or not, and then again to get the remaining args.

E.g:

test.py

import argparse

parser1 = argparse.ArgumentParser()
parser1.add_argument("a")  # always required
parser1.add_argument("-t", "--tt", default=False, action='store_true')
args1 = parser1.parse_known_args()

if args1[0].tt:
    print('got t')
else:
    parser2 = argparse.ArgumentParser()
    parser2.add_argument("x")
    parser2.add_argument("y")
    parser2.add_argument("z")
    args2 = parser2.parse_args(args1[1])
    print('got all args')

Call it:

$ python test.py a -t
got t
$ python test.py a
usage: test.py [-h] x y z
test.py: error: too few arguments
$ python test.py a b c d
got all args

You will probably want to modify the usage strings though to make sure you get something sane out. Like this you can build up very powerful CLIs, but with great power comes great responsibility to your users :-).

like image 75
daphtdazz Avatar answered Sep 21 '22 23:09

daphtdazz