1

I'm using the argparse module.

My script need four arguments: arg1, arg2, group_arg1, group_arg2. arg1 and arg2 are required. group_arg1 and group_arg2 are grouped and the group is optional.

My code:

parser = argparse.ArgumentParser(description='Test.')
parser.add_argument('--arg1', type=str, required=True)
parser.add_argument('--arg2', type=str, required=True)
test_group = parser.add_argument_group(title='Grouped Arguments')  # Need to be optional
test_group.add_argument('--group_arg1', type=str, required=True)
test_group.add_argument('--group_arg2', type=str, required=True)

How to set a group optional which contains several required arguments?

For example:

Users must pass in --arg1 xx --arg2 xx or --arg1 xx --arg2 xx --group_arg1 xx --group_arg2 xx

Case --arg1 xx --arg2 xx --group_arg1 xx is not allowed.

Ann Lin
  • 41
  • 3
  • An argument_group is just used for the `help`. It does nothing to the parsing logic. Also make sure that your requirements are easily explained. `argparse` docs has plenty of examples of usage lines. – hpaulj May 27 '22 at 06:23
  • @hpaulj I see. Is there any other ways to implement my case? – Ann Lin May 27 '22 at 06:25
  • If your use case is just two strings why not just do `--group_args value1 value2`? Set `nargs=2` and the flag itself would be optional – MYousefi May 27 '22 at 06:28
  • The links and comments this other recent SO may be relevant, https://stackoverflow.com/questions/72399131/argparse-argument-can-only-be-used-alone-no-other-arguments – hpaulj May 29 '22 at 21:22

1 Answers1

0

You could define a custom function to evaluate if the arguments are required instead of just setting the boolean yourself

import argparse
import sys

def need_optionals():
    return bool(len(set(sys.argv).intersection(('--group_arg1', '--group_arg2'))))

parser = argparse.ArgumentParser(description='Test.')
parser.add_argument('--arg1', type=str, required=True)
parser.add_argument('--arg2', type=str, required=True)
# Need to be optional
test_group = parser.add_argument_group(title='Grouped Arguments')
test_group.add_argument('--group_arg1', type=str, required=need_optionals())
test_group.add_argument('--group_arg2', type=str, required=need_optionals())
print(parser.parse_args())
Tzane
  • 2,752
  • 1
  • 10
  • 21
  • Actually I want to add six argument to the group. So the validation function will have a deep nested `if-else` block. I'm wondering if the example in my use case is a common example. – Ann Lin May 27 '22 at 06:49
  • And maybe I need more than one groups and they are not mutually exclusive – Ann Lin May 27 '22 at 06:53
  • @AnnLin Maybe in that case the easier way would be to go with MYousefi's suggestion of giving 2 arguments with the same key. – Tzane May 27 '22 at 07:11