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)
...
1

1 Answer 1

5

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
Sign up to request clarification or add additional context in comments.

4 Comments

OP stated "At least one", which sounds like mutually exclusive is not what he wants.
@MaxNow, yes you are correct. Updated the answer to include at least one.
@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.
nargs="?' makes the argument optional. It's best used with both default and const parameters. See the docs.

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.