pythonargumentsoptionparser

Set and require default Python script OptionParser


The following "parser.add_option" statements work but if the script is run without an option/arg it will not complain. If an option/argument are not specified I would like it to display help (-h / --help) as default.

usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
parser.add_option('-d', '--directory',
        action='store', dest='directory',
        default=None, help='specify directory')
parser.add_option('-f', '--file',
        action='store', dest='filename',
        default=None, help='specify file')
parser.add_option('-v', '--version',
                  action="store_true", dest="show_version",
                  default=False, help='displays the version number')
(options, args) = parser.parse_args()
#if len(args) < 1:
#    parser.error("incorrect number of arguments")

Secondly, if I enable the following snip than I get "error: incorrect number of arguments" even when specifying an option/arg.

if len(args) < 1:
parser.error("incorrect number of arguments")

Thanks.


Updated Code with Traceback error below

def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option('-d', '--directory',
            action='store', dest='directory',
            default=None, help='specify directory')
    parser.add_option('-f', '--file',
            action='store', dest='filename',
            default=None, help='specify file')
    parser.add_option('-v', '--version',
                      action="store_true", dest="show_version",
                      default=False, help='displays the version number')
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit()
    (options, args) = parser.parse_args()

#if options.show_version:
#    prog = os.path.basename(sys.argv[0])
#    version_str = "1.0"
#    print "version is: %s %s" % (prog, version_str)
#    sys.exit(0)

filenames_or_wildcards = []

# remove next line if you do not want allow to run the script without the -f -d
# option, but with arguments
filenames_or_wildcards = args # take all filenames passed in the command line

# if -f was specified add them (in current working directory)
if options.filename is not None:
    filenames_or_wildcards.append(options.filename)

Traceback

$ python boto-backup.py Traceback (most recent call last):   File "boto-backup.py", line 41, in <module>
    filenames_or_wildcards = args # take all filenames passed in the command line NameError: name 'args' is not defined

Solution

  • I would do something like this:

    from optparse import OptionParser
    import sys
    
    def main():
        usage = "usage: %prog [options] arg"
        parser = OptionParser(usage)
        parser.add_option('-d', '--directory',
                action='store', dest='directory',
                default=None, help='specify directory')
        parser.add_option('-f', '--file',
                action='store', dest='filename',
                default=None, help='specify file')
        parser.add_option('-v', '--version',
                          action="store_true", dest="show_version",
                          default=False, help='displays the version number')
        if len(sys.argv) == 1:
            parser.print_help()
            sys.exit()
        (options, args) = parser.parse_args()
        # rest of program...
    
    if __name__ == '__main__':
        main()
    

    So we set up the parser and options, and then check if there was any command-line input.
    If none, we print the help message and exit. Otherwise we proceed with program execution.

    When run with no command-line arguments the output is:

    Usage: your_script_name_here.py [options] arg
    
    Options:
      -h, --help            show this help message and exit
      -d DIRECTORY, --directory=DIRECTORY
                            specify directory
      -f FILENAME, --file=FILENAME
                            specify file
      -v, --version         displays the version number
    

    Edit (in response to updated code):
    Whitespace/indentation is important in Python.
    Make sure that the rest of your code is indented such that it belongs to the main() function.
    From filenames_or_wildcards = [] on, your code is outside of the scope of the main() function and thus doesn't have a variable named args.