Display help message with python argparse when script is called without any arguments

Posted on

Question :

Display help message with python argparse when script is called without any arguments

This might be a simple one. Assume I have a program that uses argparse to process command line arguments/options. The following will print the ‘help’ message:

./myprogram -h

or:

./myprogram --help

But, if I run the script without any arguments whatsoever, it doesn’t do anything. What I want it to do is to display the usage message when it is called with no arguments. How is that done?

Answer #1:

This answer comes from Steven Bethard on Google groups. I’m reposting it here to make it easier for people without a Google account to access.

You can override the default behavior of the error method:

import argparse
import sys

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %sn' % message)
        self.print_help()
        sys.exit(2)

parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()

Note that the above solution will print the help message whenever the error
method is triggered. For example, test.py --blah will print the help message
too if --blah isn’t a valid option.

If you want to print the help message only if no arguments are supplied on the
command line, then perhaps this is still the easiest way:

import argparse
import sys

parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
    parser.print_help(sys.stderr)
    sys.exit(1)
args=parser.parse_args()

Note that parser.print_help() prints to stdout by default. As init_js suggests, use parser.print_help(sys.stderr) to print to stderr.

Answered By: unutbu

Answer #2:

Instead of writing a class, a try/except can be used instead

try:
    options = parser.parse_args()
except:
    parser.print_help()
    sys.exit(0)

The upside is that the workflow is clearer and you don’t need a stub class. The downside is that the first ‘usage’ line is printed twice.

This will need at least one mandatory argument. With no mandatory arguments, providing zero args on the commandline is valid.

Answered By: vacri

Answer #3:

With argparse you could do:

parser.argparse.ArgumentParser()
#parser.add_args here

#sys.argv includes a list of elements starting with the program
if len(sys.argv) < 2:
    parser.print_usage()
    sys.exit(1)
Answered By: cgseller

Answer #4:

If you associate default functions for (sub)parsers, as is mentioned under add_subparsers, you can simply add it as the default action:

parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda x: parser.print_usage())
args = parser.parse_args()
args.func(args)

Add the try-except if you raise exceptions due to missing positional arguments.

Answered By: AManOfScience

Answer #5:

If you have arguments that must be specified for the script to run – use the required parameter for ArgumentParser as shown below:-

parser.add_argument('--foo', required=True)

parse_args() will report an error if the script is run without any arguments.

Answered By: pd321

Answer #6:

The cleanest solution will be to manually pass default argument if none were given on the command line:

parser.parse_args(args=None if sys.argv[1:] else ['--help'])

Complete example:

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost', help='Host to connect to')
# parse arguments
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])

# use your args
print("connecting to {}".format(args.host))

This will print complete help (not short usage) if called w/o arguments.

Answered By: Ievgen Popovych

Answer #7:

Throwing my version into the pile here:

import argparse

parser = argparse.ArgumentParser()
args = parser.parse_args()
if not vars(args):
    parser.print_help()
    parser.exit(1)

You may notice the parser.exit – I mainly do it like that because it saves an import line if that was the only reason for sys in the file…

Answered By: pauricthelodger

Answer #8:

There are a pair of one-liners with sys.argv[1:] (a very common Python’s idiom to refer the command line arguments, being sys.argv[0] the script’s name) that can do the job.

The first one is self-explanatory, clean and pythonic:

args = parser.parse_args(None if sys.argv[1:] else ['-h'])

The second one is a little hackier. Combining the previously evaluated fact that an empty list is False with the True == 1 and False == 0 equivalences you get this:

args = parser.parse_args([None, ['-h']][not sys.argv[1:]])

Maybe too many brackets, but pretty clear if a previous argument selection was made.

_, *av = sys.argv
args = parser.parse_args([None, ['-h']][not av])
Answered By: Nuno André

Leave a Reply

Your email address will not be published.