| 1 | """ |
|---|
| 2 | :Author: M. Simionato |
|---|
| 3 | :Date: April 2004 |
|---|
| 4 | :Title: A much simplified interface to optparse. |
|---|
| 5 | |
|---|
| 6 | You should use optionparse in your scripts as follows. |
|---|
| 7 | First, write a module level docstring containing something like this |
|---|
| 8 | (this is just an example):: |
|---|
| 9 | |
|---|
| 10 | '''usage: %prog files [options] |
|---|
| 11 | -d, --delete: delete all files |
|---|
| 12 | -e, --erase = ERASE: erase the given file''' |
|---|
| 13 | |
|---|
| 14 | Then write a main program of this kind: |
|---|
| 15 | |
|---|
| 16 | # sketch of a script to delete files:: |
|---|
| 17 | |
|---|
| 18 | if __name__=='__main__': |
|---|
| 19 | import optionparse |
|---|
| 20 | option,args=optionparse.parse(__doc__) |
|---|
| 21 | if not args and not option: optionparse.exit() |
|---|
| 22 | elif option.delete: print "Delete all files" |
|---|
| 23 | elif option.erase: print "Delete the given file" |
|---|
| 24 | |
|---|
| 25 | Notice that ``optionparse`` parses the docstring by looking at the |
|---|
| 26 | characters ",", ":", "=", "\\n", so be careful in using them. If |
|---|
| 27 | the docstring is not correctly formatted you will get a SyntaxError |
|---|
| 28 | or worse, the script will not work as expected. |
|---|
| 29 | """ |
|---|
| 30 | |
|---|
| 31 | import optparse, re, sys, traceback |
|---|
| 32 | |
|---|
| 33 | USAGE = re.compile(r'(?s)\s*usage: (.*?)(\n[ \t]*\n|$)') |
|---|
| 34 | |
|---|
| 35 | def nonzero(self): # will become the nonzero method of optparse.Values |
|---|
| 36 | "True if options were given" |
|---|
| 37 | for v in self.__dict__.itervalues(): |
|---|
| 38 | if v is not None: return True |
|---|
| 39 | return False |
|---|
| 40 | |
|---|
| 41 | optparse.Values.__nonzero__ = nonzero # dynamically fix optparse.Values |
|---|
| 42 | |
|---|
| 43 | class ParsingError(Exception): pass |
|---|
| 44 | |
|---|
| 45 | optionstring="" |
|---|
| 46 | |
|---|
| 47 | def exception(msg=""): |
|---|
| 48 | print >> sys.stderr, "Exception while parsing command line:" |
|---|
| 49 | print >>sys.stderr, traceback.format_exc() |
|---|
| 50 | exit( msg ) |
|---|
| 51 | |
|---|
| 52 | def exit(msg=""): |
|---|
| 53 | raise SystemExit(msg or optionstring.replace("%prog",sys.argv[0])) |
|---|
| 54 | |
|---|
| 55 | def parse(docstring, arglist=None): |
|---|
| 56 | global optionstring |
|---|
| 57 | optionstring = docstring |
|---|
| 58 | match = USAGE.search(optionstring) |
|---|
| 59 | if not match: raise ParsingError("Cannot find the option string") |
|---|
| 60 | optlines = match.group(1).splitlines() |
|---|
| 61 | try: |
|---|
| 62 | p = optparse.OptionParser(optlines[0],conflict_handler="resolve") |
|---|
| 63 | for line in optlines[1:]: |
|---|
| 64 | opt, help=line.split(':')[:2] |
|---|
| 65 | # Make both short and long optional (but at least one) |
|---|
| 66 | ## Old: short,long=opt.split(',')[:2] |
|---|
| 67 | opt_strings = [] |
|---|
| 68 | action = "store_true" |
|---|
| 69 | for k in opt.split( ', ' ): |
|---|
| 70 | k = k.strip() |
|---|
| 71 | if k.startswith( "--" ) and "=" in k: |
|---|
| 72 | action = "store" |
|---|
| 73 | k = k.split( "=" )[0] |
|---|
| 74 | opt_strings.append( k ) |
|---|
| 75 | p.add_option( *opt_strings, **dict( action = action, help = help.strip() ) ) |
|---|
| 76 | helpstring = docstring.replace("%prog",sys.argv[0]) |
|---|
| 77 | # p.add_option( "-h", "--help", action="callback", callback=help_callback, callback_args=(helpstring,) ) |
|---|
| 78 | except (IndexError,ValueError): |
|---|
| 79 | raise ParsingError("Cannot parse the option string correctly") |
|---|
| 80 | return p.parse_args(arglist) |
|---|
| 81 | |
|---|
| 82 | def help_callback( option, opt, value, parser, help ): |
|---|
| 83 | print >> sys.stderr, help |
|---|
| 84 | sys.exit( 1 ) |
|---|
| 85 | |
|---|
| 86 | |
|---|