1

I have 2 group which are exclusive, you can define either arguments from group1 or group2 but group2 have to be exclusive within it's arguments too.

parser = argparse.ArgumentParser()
group_exclusive = parser.add_mutually_exclusive_group()
sub_exclusive_1 = group_exclusive.add_argument_group()
sub_exclusive_1.add_argument("-a")
sub_exclusive_1.add_argument("-b")
sub_exclusive_1.add_argument("-c")
sub_exclusive_1.add_argument("-d")

sub_exclusive_2 = group_exclusive.add_mutually_exclusive_group()
sub_exclusive_2.add_argument("-AA")
sub_exclusive_2.add_argument("-BB")

args = parser.parse_args()

The code have to terminate if [-a and -AA or -BB] or [-AA and -BB] have been defined but still have to work with [-a and/or -b],

The problem is that it's not terminating...

I found this thread and edited my code to

subparsers = parser.add_subparsers()
parser_a = subparsers.add_parser('command_1')
parser_a.add_argument("-a")
parser_a.add_argument("-b")
parser_a.add_argument("-c")
parser_a.add_argument("-d")

parser_b = subparsers.add_parser('command_2')
parser_b.add_argument("-AA")
parser_b.add_argument("-BB")

still does not work, traceback: main.py: error: too few arguments

What do i do wrong?

current workaround:

parser = argparse.ArgumentParser()
parser.add_argument("-a")
...
parser.add_argument("-AA")

args = parser.parse_args()
if (args.a or args.b or args.c or args.d) and (args.AA or args.BB) or (args.AA and args.BB):
    raise SystemExit()
Community
  • 1
  • 1
PYPL
  • 1,819
  • 1
  • 22
  • 45

1 Answers1

2

At the risk of repeating my answer from the earlier question, let's focus on your case

parser = argparse.ArgumentParser()
group_exclusive = parser.add_mutually_exclusive_group()
sub_exclusive_1 = group_exclusive.add_argument_group()
...

sub_exclusive_2 = group_exclusive.add_mutually_exclusive_group()
sub_exclusive_2.add_argument("-AA")
sub_exclusive_2.add_argument("-BB")

Despite similar names (and class nesting), the functionality of argument_groups and mutually_exclusive_groups is quite different. And the former does not nest meaningfully within the second.

An argument group is a tool to organize arguments in the help. It does not enter arguments 'as a group' into another group, and has NO effect on parsing or error checking.

If it did act as you want, what would the usage line look like?

With the subparser formulation the parser responds with:

prog command1 -a -b -c  # ok
prog command1 -a -AA    # error - not recognize -AA
prog command2 -AA -BB   # ok
prog command2 -a -AA    # error - -a not recognized
prog -AA                # error - too few arg

The subparser mechanism is similar to

parser.add_argument('cmd', choices=['command1','command2']

The 'command1' string tells it - parser the reset of the strings using the '-a -b ...' group of arguments. It has to know which group you expect it to use.

Short of using the bug/issue patch that I worked on a while back, you need to do your own 'mutually-exclusive' testing after parsing. As long as you use the default default None, it is is easy to test whether an argument has been used or now (args.AA is not None).

https://stackoverflow.com/a/30337890/901925 is a recent example of doing post-parsing testing.

Community
  • 1
  • 1
hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • the code must be able to work without specifing any argument, the line where you used `-AA` and `-BB` is not `ok` and the code have to terminate in that case too – PYPL May 21 '15 at 17:12
  • My focus is on what your code does. You could give `parser_b` a mutually exclusive group.. But with subparsers you can't get way with 0 arguments. If you don't like the subparser option, then doing your own post-parsing testing is the way to go. There are lots of SO about doing that. – hpaulj May 21 '15 at 19:11
  • i went with solution you have linked and just decided to check arguments with an condition which i added into my thread, works for my case – PYPL May 22 '15 at 13:51