MayTheSchwartzBeWithYou
MayTheSchwartzBeWithYou

Reputation: 1177

How to handle optional and mandatory positional arguments with argparse(python)

I have been trying to execute my python script with some arguments passed. The way I want it to be is something like this:

python script.py filepath

but also to support this

python script.py filepath1 filepath2

My implementation has been:

parser = argparse.ArgumentParser()
mand = parser.add_argument_group("Mandatory arguments")
mand.add_argument("path1", help = "path1")
opt = parser.add_argument_group("Optional arguments")
opt.add_argument("path2", help = "path2")
args = parser.parse_args()

It seems to ask for both arguments. Does anyone have any suggestion as to what is the proper way to do this? One of my thoughts was to do two argument groups; one with the path1 and the other with both paths, but it still requested both.

Thanks guys and gals!

P.S. Python 2.7

Upvotes: 0

Views: 1187

Answers (2)

Jan Vlcinsky
Jan Vlcinsky

Reputation: 44142

Use nargs="?" (with argparse)

import argparse
parser = argparse.ArgumentParser()
mand = parser.add_argument_group("Mandatory arguments")
mand.add_argument("path1", help = "path1")
opt = parser.add_argument_group("Optional arguments")
opt.add_argument("path2", help = "path2", nargs="?")
args = parser.parse_args()
print args

See usage string:

$ python argscript.py 
usage: argscript.py [-h] path1 [path2]
argscript.py: error: too few arguments

Or with -h:

$ python argscript.py -h
usage: argscript.py [-h] path1 [path2]

optional arguments:
  -h, --help  show this help message and exit

Mandatory arguments:
  path1       path1

Optional arguments:
  path2       path2

and try it with one positional argument only:

$ python argscript.py alfa
Namespace(path1='alfa', path2=None)

And with two:

$ python argscript.py alfa beta
Namespace(path1='alfa', path2='beta')

Upvotes: 3

Jan Vlcinsky
Jan Vlcinsky

Reputation: 44142

Sorry for a bit off topic answer. I prefer using docopt so in case it would be of interest for you.

Using docopt

Install docopt first:

$ pip install docopt

and with the script:

"""script.py
Usage:
    script.py <fname>...
"""

if __name__ == "__main__":
    from docopt import docopt
    args = docopt(__doc__)
    print args

You can use it this way:

Asking for usage script:

$ python script.py 
Usage:
    script.py <fname>...

Calling with one file name:

$ python script.py alfa
{'<fname>': ['alfa']}

Using with two names:

$ python script.py alfa beta
{'<fname>': ['alfa', 'beta']}

Playing with alternative usage descriptions:

Following would allow one or two file names, but never three or more:

"""script.py
Usage:
    script.py <input> [<output>]
"""

if __name__ == "__main__":
    from docopt import docopt
    args = docopt(__doc__)
    print args

Upvotes: 1

Related Questions