If I have the arguments '-a', '-b', '-c', '-d'
, with the add_mutually_exclusive_group()
function my program will have to use just one of them. Is there a way to combine that, so that the program will accept only either '-a 999 -b 999'
or '-c 999 -d 999'
?
Edit: adding a simple program for more clarity:
>>> parser = argparse.ArgumentParser() >>> group = parser.add_mutually_exclusive_group() >>> group.add_argument('-a') >>> group.add_argument('-b') >>> group.add_argument('-c') >>> group.add_argument('-d')
Then only ./app.py -a | ./app.py -b | ./app.py -c | ./app.py -d
can be called. Is it possible to have argparse group the exclusion groups, so that only ./app.py -a .. -b .. | ./app.py -c .. -d ..
be called?
Python's argparse standard library module is a tool that helps you write command-line interfaces (CLI) over your Python code. You may already be familiar with CLIs: programs like git , ls , grep , and find all expose command-line interfaces that allow you to call an underlying program with specific inputs and options.
The argparse is a standard module; we do not need to install it. A parser is created with ArgumentParser and a new parameter is added with add_argument . Arguments can be optional, required, or positional.
EDIT: Never mind. Because argparse
makes the horrible choice of having to create an option when invoking group.add_argument
. That wouldn't be my design choice. If you're desperate for this feature, you can try doing it with ConflictsOptionParser:
# exclusivegroups.py import conflictsparse parser = conflictsparse.ConflictsOptionParser() a_opt = parser.add_option('-a') b_opt = parser.add_option('-b') c_opt = parser.add_option('-c') d_opt = parser.add_option('-d') import itertools compatible_opts1 = (a_opt, b_opt) compatible_opts2 = (c_opt, d_opt) exclusives = itertools.product(compatible_opts1, compatible_opts2) for exclusive_grp in exclusives: parser.register_conflict(exclusive_grp) opts, args = parser.parse_args() print "opts: ", opts print "args: ", args
Thus when we invoke it, we can see we get the desired effect.
$ python exclusivegroups.py -a 1 -b 2 opts: {'a': '1', 'c': None, 'b': '2', 'd': None} args: [] $ python exclusivegroups.py -c 3 -d 2 opts: {'a': None, 'c': '3', 'b': None, 'd': '2'} args: [] $ python exclusivegroups.py -a 1 -b 2 -c 3 Usage: exclusivegroups.py [options] exclusivegroups.py: error: -b, -c are incompatible options.
The warning message doesn't inform you that both '-a'
and '-b'
are incompatible with '-c'
, however a more appropriate error message could be crafted. Older, wrong answer below.
OLDER EDIT: [This edit is wrong, although wouldn't it be just a perfect world if argparse
worked this way?] My previous answer actually was incorrect, you should be able to do this with argparse
by specifying one group per mutually exclusive options. We can even use itertools
to generalize the process. And make it so we don't have to type out all the combinations explicitly:
import itertools compatible_opts1 = ('-a', '-b') compatible_opts2 = ('-c', '-d') exclusives = itertools.product(compatible_opts1, compatible_opts2) for exclusive_grp in exclusives: group = parser.add_mutually_exclusive_group() group.add_argument(exclusive_grp[0]) group.add_argument(exclusive_grp[1])
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