Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Negative boolean options --no-whatever in optparse?

With optparse, is there a simple way to define negative options, e.g., --no-cleanup?

I did it this way, but it's cumbersome and bug-prone, especially due to the None check which is easy to forget and leave out:

#!/bin/env python

from __future__ import print_function
import sys
import optparse

def main(argv):
    parser = optparse.OptionParser("usage: %prog [options]")
    parser.add_option("--no-cleanup",
                      dest = "cleanup",
                      action = "store_false",
                      help = "do cleanup at end?")

    (opts, args) = parser.parse_args()

    if opts.cleanup == None:
        opts.cleanup = True

    # do stuff ...

    if opts.cleanup:
        print("Cleaning up!", file = sys.stderr)
    else:
        print("Not cleaning up", file = sys.stderr)

if __name__ == "__main__":
    main(sys.argv[1:])

Ideally I'd like to do something like Getoptions::Long in Perl, where I can define an option cleanup as boolean and then it will automatically provide --cleanup and --no-cleanup and set my boolean variable accordingly.

like image 699
Frank Avatar asked Mar 29 '12 22:03

Frank


1 Answers

If I was to do this using optparse (or argparse for that matter -- assuming you want to add a --cleanup and --no-cleanup flag in one command), I would just subclass the option parser class... Something like:

from optparse import OptionParser
class MyOptParse(OptionParser):
      def boolean(self,dest,**kwargs):
          self.add_option('--%s'%dest,dest=dest,action='store_true',**kwargs)
          self.add_option('--no-%s'%dest,dest=dest,action='store_false',**kwargs)

Of course, this is a complete hack, but I think it's pretty obvious where I'm going with it...You can make boolean behave however you want it to (reformatting help, accepting a default value so that either '--blah' or '--no-blah' is set as the default, etc...)

I think that

parser=MyOptParse()
parser.boolean('cleanup',default=True,help="Do/Do Not do cleanup")

should work and get rid of the if options.cleanup is None line while it's at it since the default is set, although the help message will be repeated (with the code I provided)

If you just want to add defaults for a particular flag (to get rid of the check for None), you can use the default keyword to add_option, OR, according to the optparse documentation ...

A clearer way to specify default values is the set_defaults() method of OptionParser, which you can call at any time before calling parse_args(): e.g. parser.set_defaults(verbose=True)

like image 196
mgilson Avatar answered Sep 23 '22 13:09

mgilson