Using mutually exclusive between groups

I am trying to create a mutually exclusive group between different groups: I have the arguments -a, -b, -c, and I want to have a conflict with -a and -b together, or -a and -c together. Help should show something like [-a | ([-b] [-c])].

The following code does not seem to have mutually exclusive options:

import argparse parser = argparse.ArgumentParser(description='My desc') main_group = parser.add_mutually_exclusive_group() mysub_group = main_group.add_argument_group() main_group.add_argument("-a", dest='a', action='store_true', default=False, help='a help') mysub_group.add_argument("-b", dest='b', action='store_true',default=False,help='b help') mysub_group.add_argument("-c", dest='c', action='store_true',default=False,help='c help') parser.parse_args() 

Analysis of various combinations - all pass:

 > python myscript.py -h usage: myscript.py [-h] [-a] [-b] [-c] My desc optional arguments: -h, --help show this help message and exit -aa help > python myscript.py -a -c > python myscript.py -a -b > python myscript.py -b -c 

I tried changing mysub_group to add_mutually_exclusive_group , turning everything into mutually exclusive:

 > python myscript.py -h usage: myscript.py [-h] [-a | -b | -c] My desc optional arguments: -h, --help show this help message and exit -aa help -bb help -cc help 

How to add arguments to [-a | ([-b] [-c])]?

+7
source share
2 answers

So this has been asked several times. The simple answer is "with argparse, you cannot." However, that is the simple answer. You can use subparameters, therefore:

 import argparse parser = argparse.ArgumentParser(description='My desc') sub_parsers = parser.add_subparsers() parser_a = sub_parsers.add_parser("a", help='a help') parser_b = sub_parsers.add_parser("b", help='b help') parser_b.add_argument("-c", dest='c', action='store_true',default=False,help='c help') parser.parse_args() 

Then you get:

 $ python parser -h usage: parser [-h] {a,b} ... My desc positional arguments: {a,b} aa help bb help optional arguments: -h, --help show this help message and exit 

and

 $ python parser b -h usage: parser b [-h] [-c] optional arguments: -h, --help show this help message and exit -cc help 

If you prefer your arguments as indicated in the question, look at docopt , it looks great and should exactly what you want.

+1
source

argument_groups does not affect parsing. They simply help format the help. Therefore, defining a group inside mutually_exclusive_group does not help this problem.

There is a proposed patch http://bugs.python.org/issue10984 , 'argparse add_mutually_exclusive_group should accept existing arguments to register conflicts' , which allows you to define two mutually_exclusive_groups , one [-a | -b] [-a | -b] and the other [-a | -c] [-a | -c] . Creating a second group containing the argument ( -a ) that is already defined is a trivial part of this patch. Creating a meaningful usage string is more complicated and requires overwriting several HelpFormatter methods.

 import argparse parser = argparse.ArgumentParser(description='My desc') group1 = parser.add_mutually_exclusive_group() action_a = group1.add_argument("-a", dest='a', action='store_true', default=False, help='a help') group1.add_argument("-b", dest='b', action='store_true',default=False,help='b help') group2 = parser.add_mutually_exclusive_group() group2.add_argument("-c", dest='c', action='store_true',default=False,help='c help') group2._group_actions.append(action_a) # THE KLUDGE print parser.format_usage() # usage: stack16769409.py [-h] [-a | -b] [-c] args = parser.parse_args() 

Usage does not display 2 groups correctly. But he accepts -b -c , but objects to -a -b and -a -c . But you can write a custom use string.

0
source

All Articles