Search code examples
pythonoptparse

Python optparse - option not being read as false


I am relatively new to Python and playing with optparse. I have the parser function as such:

def parse(argv):
    """Option parser, returns the options leave the args."""
    version = '0.1'
    usage = 'Usage: %prog [options] -f|--file <FILENAME>'
    parser = optparse.OptionParser(usage=usage,version="%prog: v.{}".format(version))
    parser.add_option("-m", "--mock",
            action="store_true", dest="fake", default=False,
            help="Mock the file and export to stdout")
    parser.add_option("-t", "--test",
            action="store_true", dest="test", default=False,
            help="Test the file against RocketAnalysis.m after completion")
    parser.add_option("-d", "--dir",
            dest="save_dir", default=os.getcwd(), metavar="DIR",
            help="Change save directory to DIR [Default: current dir]")
    parser.add_option("-f", "--file-name",
            dest="filename", default=None, metavar="FILENAME",
            help="FILENAME to create variables under [ REQUIRED ]")
    parser.add_option("-v", "--verbose",
            action="store_true", dest="verbose", default="False",
            help="Verbose prints enabled")
    parser.add_option("-q", "--quiet",
            action="store_true", dest="quiet", default="False",
            help="Turns on quiet mode with no prints or feedback except errors")
    parser.add_option("-c", "--clober",
            action="store_true", dest="clobber", default="False",
            help="Clobber FILENAME and re-write")
    (options, args) = parser.parse_args()
    return options

I am calling it from main (I have also included it in main in case that was the issue [it wasn't]) and then using the verbose option to list all the options and their values:

    options = parse(argv)
    file_path = "{}/{}".format(options.save_dir,options.filename)
    print("Is verbose? %s" % options.verbose)
    if options.verbose:
        opts_dic = vars(options)
        print("Options set:")
        for k, v in opts_dic.iteritems():
            print("\t{} : {}".format(k, v))
        print("\tFile path set to: {}".format(file_path))

The result:

./create_stage.py -f this.txt
Is verbose? False
Options set:
    verbose : False
    fake : False
    quiet : False
    clobber : False
    filename : this.txt
    save_dir : /home/silas/Documents/ksp/ksp-octave
    test : False
    File path set to: /home/silas/Documents/ksp/ksp-octave/this.txt

So, even though it knows verbose is false (print("Is verbose? %s" % options.verbose) showing false), it still runs the if block for verbose (if options.verbose:). Did I miss some step? As I said, it happens if I leave the parser in the main block as well, and argv is fed in as main(sys.argv). Would switching to argparse fix this mess, even though this SHOULD work in optparse? Any help would be nice. Running Python 2.7.5+


Solution

  • parser.add_option("-v", "--verbose",
            action="store_true", dest="verbose", default="False",
            help="Verbose prints enabled")
    

    The string "False" is truthy, being a non-zero length string. Try it: print(bool("False")). So your default value for verbose is truthy. Use the default value False, not "False".