Argparse optional positional arguments?

323,902

Solution 1

Use nargs='?' (or nargs='*' if you need more than one dir)

parser.add_argument('dir', nargs='?', default=os.getcwd())

extended example:

>>> import os, argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-v', action='store_true')
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('dir', nargs='?', default=os.getcwd())
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]
positional arguments:
  dir
optional arguments:
  -h, --help  show this help message and exit
  -v

Solution 2

As an extension to @VinaySajip answer. There are additional nargs worth mentioning.

  1. parser.add_argument('dir', nargs=1, default=os.getcwd())

N (an integer). N arguments from the command line will be gathered together into a list

  1. parser.add_argument('dir', nargs='*', default=os.getcwd())

'*'. All command-line arguments present are gathered into a list. Note that it generally doesn't make much sense to have more than one positional argument with nargs='*', but multiple optional arguments with nargs='*' is possible.

  1. parser.add_argument('dir', nargs='+', default=os.getcwd())

'+'. Just like '*', all command-line args present are gathered into a list. Additionally, an error message will be generated if there wasn’t at least one command-line argument present.

  1. parser.add_argument('dir', nargs=argparse.REMAINDER, default=os.getcwd())

argparse.REMAINDER. All the remaining command-line arguments are gathered into a list. This is commonly useful for command line utilities that dispatch to other command line utilities

If the nargs keyword argument is not provided, the number of arguments consumed is determined by the action. Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced.

Edit (copied from a comment by @Acumenus) nargs='?' The docs say: '?'. One argument will be consumed from the command line if possible and produced as a single item. If no command-line argument is present, the value from default will be produced.

Share:
323,902
Waldo Bronchart
Author by

Waldo Bronchart

Updated on November 05, 2020

Comments

  • Waldo Bronchart
    Waldo Bronchart about 2 years

    I have a script which is meant to be used like this: usage: installer.py dir [-h] [-v]

    dir is a positional argument which is defined like this:

    parser.add_argument('dir', default=os.getcwd())
    

    I want the dir to be optional: when it's not specified it should just be cwd.

    Unfortunately when I don't specify the dir argument, I get Error: Too few arguments.

  • Dolan Antenucci
    Dolan Antenucci almost 10 years
    Do the ? and * mean the same thing they mean in regular expressions (i.e. ? requires 0 or 1, and * requiring 0 or more)? If so, does + work as well?
  • Vinay Sajip
    Vinay Sajip almost 10 years
    @dolan: Yes, + works, too. See docs.python.org/2/library/argparse.html#nargs for the details.
  • scagnetti
    scagnetti about 8 years
    is there some way to get dir to show up in optional arguments? or it seems that positional arguments should have a preceeding 'optional' qualifier. is it possible to register (as far as help is concerned) it as such?
  • Vinay Sajip
    Vinay Sajip about 8 years
    @ant From the above, you can see that dir is optional (that it appears in square brackets in argparse output indicates this).
  • Asclepius
    Asclepius about 6 years
    It should be noted however that nargs='?' does not produce a list.
  • Matas Vaitkevicius
    Matas Vaitkevicius about 6 years
    @A-B-B Last line of the answer Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced. Hope this helps...
  • Asclepius
    Asclepius about 6 years
    The quoted line refers to the case of not defining nargs, but nargs='?' is defining it. The docs say: '?'. One argument will be consumed from the command line if possible, and produced as a single item. If no command-line argument is present, the value from default will be produced.
  • Matas Vaitkevicius
    Matas Vaitkevicius about 6 years
    @A-B-B Just edit the answer if you feel that something is missing. Thanks.
  • SoloPilot
    SoloPilot almost 6 years
    OP was asking about positional params, not '--dir'. 'required' is an invalid argument for positionals. And 'false' was a typo, she meant 'False'. +1 for newbie, -1 for sloppiness.
  • ptim
    ptim almost 5 years
    Tx! Access dir from options.dir, not args.dir, as I was trying!
  • Admin
    Admin over 4 years
    What is the difference between nargs=argparse.REMAINDER and nargs='*', as it seems to me, they are identical in their effect (tested in Python 2.7.10 and Python 3.6.1)?
  • Gabriel Staples
    Gabriel Staples over 3 years
    Here's the updated (Python 3) documentation--a careful reading of it explains it all: docs.python.org/3/library/argparse.html#nargs. For anyone new to the argparse module, start with the tutorial: docs.python.org/3/howto/argparse.html
  • Joonho Park almost 3 years
    @dolan and Vinay, '+' does not work because it requires at least one argument at the command line.
  • Karthik Sunil
    Karthik Sunil over 2 years
    We can not use required for positional argument.
  • violet 12 months
    note also that default is required to make this work. without specifying a default value, executing the parsing command without a value in that position will complain that a value is required for that argument.