Let\'s say I have two groups of arguments. You can use any number of arguments from each group but you cannot mix arguments between the groups.
Is there a way to cus
I've proposed a patch (or rather patches) that would let you test for general logical combinations of arguments. http://bugs.python.org/issue11588.
The core of my ideas there is to add a hook just inside parse_args that lets the user test for all logical combinations of arguments. At that it point it has access to a list seen arguments. This list is not available to you outside parse_args (hence the need for a hook). But with appropriate defaults, you can write your own tests that use the args Namespace.
The difficulties with implementing a general argparse version include:
a) implementing some sort of nesting groups (in your case several any groups nesting within a xor group)
b) displaying those groups in a meaningful usage line
For now your best bet is either implement your problem with subparsers (if it fits), or do your own testing after parsing. And write your own usage.
Here's a sketch of a generalizable test that could be applied to the args namespace after parsing
def present(a):
# test whether an argument is 'present' or not
# simple case, just check whether it is the default None or not
if a is not None:
return True
else:
return False
# sample namespace from parser
args = argparse.Namespace(x1='one',x2=None,y1=None,y2=3)
# a nested list defining the argument groups that need to be tested
groups=[[args.x1,args.x2],[args.y1,args.y2]]
# a test that applies 'any' test to the inner group
# and returns the number of groups that are 'present'
[any(present(a) for a in g) for g in groups].count(True)
If the count is 0, no groups are found, if 1 one group has been found, etc. The hook that I mentioned in the bug issue does the same sort of testing, just using a different present test.
The normal mutually exclusive test would object if count >1. A required group would object to 0, etc. You could also do something like
if (present(args.x1) or present(args.x2)) and
(present(args.y1) or present(args.y2)):
parser.error('too many groups')
ie. some combination of any,all,and,or. But count is a nice way of handling the xor condition.