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 | |
---|