65

I want to specify a required argument called inputdir but I also would like to have a shorthand version of it called i. I don't see a concise solution to do this without making both optional arguments and then doing my own check. Is there a preferred practice for this that I'm not seeing or the only way is to make both optional and do my own error-handling?

Here is my code:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("inputdir", help="Specify the input directory")
parser.parse_args()
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user3621633
  • 1,681
  • 3
  • 32
  • 46

2 Answers2

88

For flags (options starting with - or --) pass in options with the flags. You can specify multiple options:

parser.add_argument('-i', '--inputdir', help="Specify the input directory")

See the name or flags option documentation:

The add_argument() method must know whether an optional argument, like -f or --foo, or a positional argument, like a list of filenames, is expected. The first arguments passed to add_argument() must therefore be either a series of flags, or a simple argument name.

Demo:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-i', '--inputdir', help="Specify the input directory")
_StoreAction(option_strings=['-i', '--inputdir'], dest='inputdir', nargs=None, const=None, default=None, type=None, choices=None, help='Specify the input directory', metavar=None)
>>> parser.print_help()
usage: [-h] [-i INPUTDIR]

optional arguments:
  -h, --help            show this help message and exit
  -i INPUTDIR, --inputdir INPUTDIR
                        Specify the input directory
>>> parser.parse_args(['-i', '/some/dir'])
Namespace(inputdir='/some/dir')
>>> parser.parse_args(['--inputdir', '/some/dir'])
Namespace(inputdir='/some/dir')

However, the first element for required arguments is just a placeholder. - and -- options are always optional (that's the command line convention), required arguments are never specified with such switches. Instead the command-line help will show where to put required arguments with a placeholder based on the first argument passed to add_argument(), which is to be passed in without dashes.

If you have to break with that convention and use an argument starting with - or -- that is required anyway, you'll have to do your own checking:

args = parser.parse_args()
if not args.inputdir:
    parser.error('Please specify an inputdir with the -i or --inputdir option')

Here the parser.error() method will print the help information together with your error message, then exit.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 2
    The thing that I don't like, is that when it prints out the usage, it doesn't print out `-i` and `--inputdir`. I would want the usage to be something like `usage: [-h] [-i|--inputdir INPUTDIR]`; something to that effect. Probably one way to do it is to use `add_mutually_exclusive_group()`, but that seems a little hacky to me. I'm wondering if there's a better way. – searchengine27 Oct 21 '16 at 18:58
  • 1
    @searchengine27: you'd have to customise the [help formatter class](https://docs.python.org/2/library/argparse.html#formatter-class), I fear. – Martijn Pieters Oct 21 '16 at 21:21
0

https://docs.python.org/3/library/argparse.html#required

required=True should support making the argument required

ess enn
  • 11