comparison corebio/utils/deoptparse.py @ 0:c55bdc2fb9fa

Uploaded
author davidmurphy
date Thu, 27 Oct 2011 12:09:09 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c55bdc2fb9fa
1 # Copyright (c) 2004 Gavin E. Crooks <gec@compbio.berkeley.edu>
2 #
3 # This software is distributed under the MIT Open Source License.
4 # <http://www.opensource.org/licenses/mit-license.html>
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 # and/or sell copies of the Software, and to permit persons to whom the
11 # Software is furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 # THE SOFTWARE.
23 #
24
25 """Custom extensions to OptionParse for parsing command line options."""
26 # FIXME: Docstring
27
28 # TODO: Add profiling option
29
30 # DeOptionParser :
31 #
32 # http://docs.python.org/lib/module-optparse.html
33 #
34 # Random_options :
35 # Set random generator and seed. Use options.random as
36 # source of random numbers
37 # Copyright :
38 # print copyright information
39
40 # Documentation :
41 # print extended document information
42 #
43 # Additional file_in and file_out types
44
45 import sys
46 from copy import copy
47 from optparse import Option
48 from optparse import OptionParser
49 from optparse import IndentedHelpFormatter
50 from optparse import OptionValueError
51 import random
52
53
54
55 def _copyright_callback(option, opt, value, parser):
56 if option or opt or value or parser: pass # Shut up lint checker
57 print parser.copyright
58 sys.exit()
59
60 def _doc_callback(option, opt, value, parser):
61 if option or opt or value or parser: pass # Shut up lint checker
62 print parser.long_description
63 sys.exit()
64
65
66 class DeHelpFormatter(IndentedHelpFormatter) :
67 def __init__ (self,
68 indent_increment=2,
69 max_help_position=32,
70 width=78,
71 short_first=1):
72 IndentedHelpFormatter.__init__(
73 self, indent_increment, max_help_position,
74 width, short_first)
75
76 def format_option_strings (self, option):
77 """Return a comma-separated list of option strings & metavariables."""
78 if option.takes_value():
79 metavar = option.metavar or option.dest.upper()
80 short_opts = option._short_opts
81 long_opts = [lopt + " " + metavar for lopt in option._long_opts]
82 else:
83 short_opts = option._short_opts
84 long_opts = option._long_opts
85
86 if not short_opts : short_opts = [" ",]
87
88 if self.short_first:
89 opts = short_opts + long_opts
90 else:
91 opts = long_opts + short_opts
92
93 return " ".join(opts)
94
95
96
97 def _check_file_in(option, opt, value):
98 if option or opt or value : pass # Shut up lint checker
99 try:
100 return file(value, "r")
101 except IOError:
102 raise OptionValueError(
103 "option %s: cannot open file: %s" % (opt, value) )
104
105 def _check_file_out(option, opt, value):
106 if option or opt or value : pass # Shut up lint checker
107 try:
108 return file(value, "w+")
109 except IOError:
110 raise OptionValueError(
111 "option %s: cannot open file: %s" % (opt, value) )
112
113 def _check_boolean(option, opt, value) :
114 if option or opt or value : pass # Shut up lint checker
115 v = value.lower()
116 choices = {'no': False, 'false':False, '0': False,
117 'yes': True, 'true': True, '1':True }
118 try:
119 return choices[v]
120 except KeyError:
121 raise OptionValueError(
122 "option %s: invalid choice: '%s' " \
123 "(choose from 'yes' or 'no', 'true' or 'false')" % (opt, value))
124
125 def _check_dict(option, opt, value) :
126 if option or opt or value : pass # Shut up lint checker
127 v = value.lower()
128 choices = option.choices
129 try:
130 return choices[v]
131 except KeyError:
132 raise OptionValueError(
133 "option %s: invalid choice: '%s' " \
134 "(choose from '%s')" % (opt, value, "', '".join(choices)))
135
136
137
138 class DeOption(Option):
139 TYPES = Option.TYPES + ("file_in","file_out", "boolean", "dict")
140 TYPE_CHECKER = copy(Option.TYPE_CHECKER)
141 TYPE_CHECKER["file_in"] = _check_file_in
142 TYPE_CHECKER["file_out"] = _check_file_out
143 TYPE_CHECKER["boolean"] = _check_boolean
144 TYPE_CHECKER["dict"] = _check_dict
145 choices = None
146
147 def _new_check_choice(self):
148 if self.type == "dict":
149 if self.choices is None:
150 raise OptionValueError(
151 "must supply a dictionary of choices for type 'dict'")
152 elif not isinstance(self.choices, dict):
153 raise OptionValueError(
154 "choices must be a dictinary ('%s' supplied)"
155 % str(type(self.choices)).split("'")[1])
156 return
157 self._check_choice()
158
159 # Have to override _check_choices so that we can parse
160 # a dict through to check_dict
161 CHECK_METHODS = Option.CHECK_METHODS
162 CHECK_METHODS[2] = _new_check_choice
163
164
165
166
167
168 class DeOptionParser(OptionParser) :
169 def __init__(self,
170 usage=None,
171 option_list=None,
172 option_class=DeOption,
173 version=None,
174 conflict_handler="error",
175 description=None,
176 long_description = None,
177 formatter=DeHelpFormatter(),
178 add_help_option=True,
179 prog=None,
180 copyright=None,
181 add_verbose_options=True,
182 add_random_options=False
183 ):
184
185 OptionParser.__init__(self,
186 usage,
187 option_list,
188 option_class,
189 version,
190 conflict_handler,
191 description,
192 formatter,
193 add_help_option,
194 prog )
195
196 if long_description :
197 self.long_description = long_description
198 self.add_option("--doc",
199 action="callback",
200 callback=_doc_callback,
201 help="Detailed documentation")
202
203 if copyright :
204 self.copyright = copyright
205 self.add_option("--copyright",
206 action="callback",
207 callback=_copyright_callback,
208 help="")
209
210 if add_verbose_options :
211 self.add_option("-q", "--quite",
212 action="store_false",
213 dest="verbose",
214 default=False,
215 help="Run quietly (default)")
216
217 self.add_option("-v", "--verbose",
218 action="store_true",
219 dest="verbose",
220 default=False,
221 help="Verbose output (Not quite)")
222
223 self.random_options = False
224 if add_random_options :
225 self.random_options = True
226 self.add_option("--seed",
227 action="store",
228 type = "int",
229 dest="random_seed",
230 help="Initial seed for pseudo-random number generator. (default: System time)",
231 metavar="INTEGER" )
232
233 self.add_option("--generator",
234 action="store",
235 dest="random_generator",
236 default="MersenneTwister",
237 help="Select MersenneTwister (default) or WichmannHill pseudo-random number generator",
238 metavar="TYPE" )
239
240 def parse_args(self,args, values=None) :
241 (options, args) = OptionParser.parse_args(self, args, values)
242
243 if self.random_options :
244 if options.random_generator is None or options.random_generator =="MersenneTwister" :
245 r = random.Random()
246 elif options.random_generator == "WichmannHill" :
247 r = random.WichmannHill()
248 else :
249 self.error("Acceptible generators are MersenneTwister (default) or WichmannHill")
250 if options.random_seed :
251 r.seed(options.random_seed)
252
253 options.__dict__["random"] = r
254
255
256 return (options, args)
257
258