0

I am trying to configure argparse so that only the following argument combinations are valid:

--flagA --argument1 val1 --argument2 val2 --argument3 val3
--flagB --argument1 val1

So far, I have written the following piece of code however it doesn't do the trick as both --argument2 and --argument3 are optional:

required_args = arg_parser.add_argument_group()
required_args.add_argument('--argument1', required=True)

# Optional arguments
optional_args = arg_parser.add_argument_group()
optional_args.add_argument('--argument2', required=False)
optional_args.add_argument('--argument3', required=False)

# Flags
flag_group = arg_parser.add_mutually_exclusive_group(required=True)
flag_group.add_argument('--flagA', dest='flag', action='store_const', const="flagA")
flag_group.add_argument('--flagB', dest='flag', action='store_const', const="flagB")

args = vars(arg_parser.parse_args())

With this setting, --flagA --argument1 val1 is also but it shouldn't be.

I know that I can process the Namespace generated after calling .parse_args() and check whether --argument2 and --argument3 are provided when --flagA is passed however I am looking for a more natural way to achieve this.

Essentially, the definition should look like the one below:

[-h] --argument1 ARGUMENT1 (--flagA --argument2 ARGUMENT2 --argument3 ARGUMENT3 | --flagB)
1
  • 1
    Mutually Exclusive Groups is the only co-occurrence tool in argparse. It's a simple xor. If that doesn't work for you, use the post-parsing testing. There's nothing 'natural' about trying to use argparse for everything. Commented Nov 7, 2019 at 18:57

1 Answer 1

2

Have you considered using a subparser for the two flags?

something along the lines of

arg_parser = argparse.ArgumentParser()

subparser = arg_parser.add_subparsers(dest="flag", required=True)

flag_a = subparser.add_parser('flagA')
flag_a.add_argument('--argument1', required=True)
flag_a.add_argument('--argument2', required=True)
flag_a.add_argument('--argument3', required=True)

flag_b = subparser.add_parser('flagB')
flag_b.add_argument('--argument1', required=True)

Hope this helps

Sign up to request clarification or add additional context in comments.

3 Comments

This does not work properly. Even python myscript.py --flagB --argument1 val1 does not pass.
flagA and flagB aren't options any more: python myscript.py flagB --argument val1.
This version works, but the flags don't have the "--" prefix when you call them since that prefix causes the arg parser to identify the argument as a new argument rather than the input for the subcommand. looking for a workaround now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.