3

I'd like to implement arguments parsing.

./app.py -E [optional arg] -T [optional arg]

The script requires at least one of parameters: -E or -T

What should I pass in parser.add_argument to have such functionality?

UPDATE For some reason(s) the suggested solution with add_mutually_exclusive_group didn't work, when I added nargs='?' and const= attributes:

parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-F', '--foo', nargs='?', const='/tmp')
group.add_argument('-B', '--bar', nargs='?', const='/tmp')
parser.parse_args([])

Running as script.py -F still throws error:

PROG: error: one of the arguments -F/--foo -B/--bar is required

However, the following workaround helped me:

parser = argparse.ArgumentParser(prog='PROG')
parser.add_argument('-F', '--foo', nargs='?', const='/tmp')
parser.add_argument('-B', '--bar', nargs='?', const='/tmp')
args = parser.parse_args()

if (not args.foo and not args.bar) or (args.foo and args.bar):
   print('Must specify one of -F/-B options.')
   sys.exit(1)

if args.foo:
   foo_func(arg.foo)
elif args.bar:
   bar_func(args.bar)
...
Mark
  • 6,052
  • 8
  • 61
  • 129
  • Does this answer your question? [Require either of two arguments using argparse](https://stackoverflow.com/questions/11154946/require-either-of-two-arguments-using-argparse) – wwii Jan 17 '20 at 16:13

1 Answers1

3

You can make them both optional and check in your code if they are set.

parser = argparse.ArgumentParser()
parser.add_argument('--foo')
parser.add_argument('--bar')

args = parser.parse_args()

if args.foo is None and args.bar is None:
   parser.error("please specify at least one of --foo or --bar")

If you want only one of the two arguments to be present, see [add_mutually_exclusive_group] (https://docs.python.org/2/library/argparse.html#mutual-exclusion) with required=True

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> group = parser.add_mutually_exclusive_group(required=True)
>>> group.add_argument('--foo', action='store_true')
>>> group.add_argument('--bar', action='store_false')
>>> parser.parse_args([])
usage: PROG [-h] (--foo | --bar)
PROG: error: one of the arguments --foo --bar is required
Shashank V
  • 10,007
  • 2
  • 25
  • 41
  • OP stated "At least one", which sounds like mutually exclusive is not what he wants. – MaxNoe Jan 17 '20 at 16:13
  • @MaxNow, yes you are correct. Updated the answer to include at least one. – Shashank V Jan 17 '20 at 16:19
  • @ShashankV, thanks for your answer. Does `argparse` support checking optional parameters following the argument? For example, `script.py --foo FOO_BAR` and FOO_BAR is optional. – Mark Jan 17 '20 at 16:29
  • 1
    `nargs="?'` makes the argument optional. It's best used with both `default` and `const` parameters. See the docs. – hpaulj Jan 17 '20 at 17:59