Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python argparse conditional requirements

How do I set up argparse as follows:

if -2 is on the command line, no other arguments are required
if -2 is not on the command line, -3 and -4 arguments are required

For example,

-2 [good]
-3 a -4 b [good]
-3 a [not good, -4 required]
-2 -5 c [good]
-2 -3 a [good]

There are a number of similar questions here, but either they don't address this situation or I don't understand.

Python 2.7 if that matters.

like image 586
foosion Avatar asked Aug 02 '13 20:08

foosion


People also ask

What is required in Argparse?

The argparse module provides a convenient interface to handle command-line arguments. It displays the generic usage of the program, help, and errors. required is a parameter of the ArugmentParser object's function add_argument() . By default, the arguments of type -f or --foo are optional and can be omitted.

How do you add an optional argument in Argparse?

To add an optional argument, simply omit the required parameter in add_argument() . args = parser. parse_args()if args.

What is Store_true in Python?

The store_true option automatically creates a default value of False. Likewise, store_false will default to True when the command-line argument is not present.

What is ArgumentParser in Python?

argparse — parse the arguments. Using argparse is how you let the user of your program provide values for variables at runtime. It's a means of communication between the writer of a program and the user. That user might be your future self.


2 Answers

A subparser (as suggested in comments) might work.

Another alternative (since mutually_exclusive_group can't quite do this) is just to code it manually, as it were:

import argparse

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('-2', dest='two', action='store_true')
    parser.add_argument('-3', dest='three')
    parser.add_argument('-4', dest='four')
    parser.add_argument('-5', dest='five')

    args = parser.parse_args()

    if not args.two:
        if args.three is None or args.four is None:
            parser.error('without -2, *both* -3 <a> *and* -4 <b> are required')

    print args
    return 0

Adding a little driver to this:

import sys
sys.exit(main())

and run with your examples, it seems to do the right thing; here are two runs:

$ python mxgroup.py -2; echo $?
Namespace(five=None, four=None, three=None, two=True)
0
$ python mxgroup.py -3 a; echo $?
usage: mxgroup.py [-h] [-2] [-3 THREE] [-4 FOUR] [-5 FIVE]
mxgroup.py: error: without -2, *both* -3 <a> *and* -4 <b> are required
2
$ 
like image 132
torek Avatar answered Oct 19 '22 18:10

torek


I think it is pretty hard to achieve that (including a nice help message) while only using the standard argparse functions. You can however easily test it yourself after parsing the arguments. You can describe the extra requirements in the epilogue or so. Note that it is unusual to use numbers as options, I had to use dest='two', since args.2 is not valid syntax.

#!/usr/bin/env python

import argparse

parser = argparse.ArgumentParser(
   description='bla bla',
   epilog='Note: arguments -3 and -4 are required when -2 is missing')

parser.add_argument('-2', dest='two', action='store_true')
parser.add_argument('-3', dest='three')
parser.add_argument('-4', dest='four')
parser.add_argument('-5', dest='five')

args = parser.parse_args()

if not args.two and (args.three is None or args.four is None):
    parser.error('arguments -3 and -4 are required when -2 is missing')

print 'Good:', args

With these results:

[~]: ./test.py -h
usage: test.py [-h] [-2] [-3 THREE] [-4 FOUR] [-5 FIVE]

bla bla

optional arguments:
  -h, --help  show this help message and exit
  -2
  -3 THREE
  -4 FOUR
  -5 FIVE

Note: arguments -3 and -4 are required when -2 is missing

[~]: ./test.py -2
Good: Namespace(five=None, four=None, three=None, two=True)
[~]: ./test.py -3 a -4 b
Good: Namespace(five=None, four='b', three='a', two=False)
[~]: ./test.py -3 a
usage: test.py [-h] [-2] [-3 THREE] [-4 FOUR] [-5 FIVE]
test.py: error: arguments -3 and -4 are required when -2 is missing
[~]: ./test.py -2 -5 c
Good: Namespace(five='c', four=None, three=None, two=True)
[~]: ./test.py -2 -3 a
Good: Namespace(five=None, four=None, three='a', two=True)
like image 3
Bas Swinckels Avatar answered Oct 19 '22 19:10

Bas Swinckels