OLD | NEW |
1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. | 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr | 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
3 # | 3 # |
4 # This file is part of logilab-common. | 4 # This file is part of logilab-common. |
5 # | 5 # |
6 # logilab-common is free software: you can redistribute it and/or modify it unde
r | 6 # logilab-common is free software: you can redistribute it and/or modify it unde
r |
7 # the terms of the GNU Lesser General Public License as published by the Free | 7 # the terms of the GNU Lesser General Public License as published by the Free |
8 # Software Foundation, either version 2.1 of the License, or (at your option) an
y | 8 # Software Foundation, either version 2.1 of the License, or (at your option) an
y |
9 # later version. | 9 # later version. |
10 # | 10 # |
(...skipping 28 matching lines...) Expand all Loading... |
39 * color | 39 * color |
40 argument of this type wont be converted but checked its either a | 40 argument of this type wont be converted but checked its either a |
41 named color or a color specified using hexadecimal notation (preceded by a #
) | 41 named color or a color specified using hexadecimal notation (preceded by a #
) |
42 * time | 42 * time |
43 argument of this type will be converted to a float value in seconds | 43 argument of this type will be converted to a float value in seconds |
44 according to time units (ms, s, min, h, d) | 44 according to time units (ms, s, min, h, d) |
45 * bytes | 45 * bytes |
46 argument of this type will be converted to a float value in bytes | 46 argument of this type will be converted to a float value in bytes |
47 according to byte units (b, kb, mb, gb, tb) | 47 according to byte units (b, kb, mb, gb, tb) |
48 """ | 48 """ |
| 49 from __future__ import print_function |
| 50 |
49 __docformat__ = "restructuredtext en" | 51 __docformat__ = "restructuredtext en" |
50 | 52 |
51 import re | 53 import re |
52 import sys | 54 import sys |
53 import time | 55 import time |
54 from copy import copy | 56 from copy import copy |
55 from os.path import exists | 57 from os.path import exists |
56 | 58 |
57 # python >= 2.3 | 59 # python >= 2.3 |
58 from optparse import OptionParser as BaseParser, Option as BaseOption, \ | 60 from optparse import OptionParser as BaseParser, Option as BaseOption, \ |
59 OptionGroup, OptionContainer, OptionValueError, OptionError, \ | 61 OptionGroup, OptionContainer, OptionValueError, OptionError, \ |
60 Values, HelpFormatter, NO_DEFAULT, SUPPRESS_HELP | 62 Values, HelpFormatter, NO_DEFAULT, SUPPRESS_HELP |
61 | 63 |
62 try: | 64 try: |
63 from mx import DateTime | 65 from mx import DateTime |
64 HAS_MX_DATETIME = True | 66 HAS_MX_DATETIME = True |
65 except ImportError: | 67 except ImportError: |
66 HAS_MX_DATETIME = False | 68 HAS_MX_DATETIME = False |
67 | 69 |
| 70 from logilab.common.textutils import splitstrip, TIME_UNITS, BYTE_UNITS, \ |
| 71 apply_units |
68 | 72 |
69 OPTPARSE_FORMAT_DEFAULT = sys.version_info >= (2, 4) | |
70 | |
71 from logilab.common.textutils import splitstrip | |
72 | 73 |
73 def check_regexp(option, opt, value): | 74 def check_regexp(option, opt, value): |
74 """check a regexp value by trying to compile it | 75 """check a regexp value by trying to compile it |
75 return the compiled regexp | 76 return the compiled regexp |
76 """ | 77 """ |
77 if hasattr(value, 'pattern'): | 78 if hasattr(value, 'pattern'): |
78 return value | 79 return value |
79 try: | 80 try: |
80 return re.compile(value) | 81 return re.compile(value) |
81 except ValueError: | 82 except ValueError: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 return value | 162 return value |
162 # Case (2) : only accepts hexadecimal forms | 163 # Case (2) : only accepts hexadecimal forms |
163 if re.match('#[a-f0-9]{6}', value, re.I): | 164 if re.match('#[a-f0-9]{6}', value, re.I): |
164 return value | 165 return value |
165 # Else : not a color label neither a valid hexadecimal form => error | 166 # Else : not a color label neither a valid hexadecimal form => error |
166 msg = "option %s: invalid color : %r, should be either hexadecimal \ | 167 msg = "option %s: invalid color : %r, should be either hexadecimal \ |
167 value or predefined color" | 168 value or predefined color" |
168 raise OptionValueError(msg % (opt, value)) | 169 raise OptionValueError(msg % (opt, value)) |
169 | 170 |
170 def check_time(option, opt, value): | 171 def check_time(option, opt, value): |
171 from logilab.common.textutils import TIME_UNITS, apply_units | |
172 if isinstance(value, (int, long, float)): | 172 if isinstance(value, (int, long, float)): |
173 return value | 173 return value |
174 return apply_units(value, TIME_UNITS) | 174 return apply_units(value, TIME_UNITS) |
175 | 175 |
176 def check_bytes(option, opt, value): | 176 def check_bytes(option, opt, value): |
177 from logilab.common.textutils import BYTE_UNITS, apply_units | |
178 if hasattr(value, '__int__'): | 177 if hasattr(value, '__int__'): |
179 return value | 178 return value |
180 return apply_units(value, BYTE_UNITS) | 179 return apply_units(value, BYTE_UNITS) |
181 | 180 |
182 import types | |
183 | 181 |
184 class Option(BaseOption): | 182 class Option(BaseOption): |
185 """override optik.Option to add some new option types | 183 """override optik.Option to add some new option types |
186 """ | 184 """ |
187 TYPES = BaseOption.TYPES + ('regexp', 'csv', 'yn', 'named', 'password', | 185 TYPES = BaseOption.TYPES + ('regexp', 'csv', 'yn', 'named', 'password', |
188 'multiple_choice', 'file', 'color', | 186 'multiple_choice', 'file', 'color', |
189 'time', 'bytes') | 187 'time', 'bytes') |
190 ATTRS = BaseOption.ATTRS + ['hide', 'level'] | 188 ATTRS = BaseOption.ATTRS + ['hide', 'level'] |
191 TYPE_CHECKER = copy(BaseOption.TYPE_CHECKER) | 189 TYPE_CHECKER = copy(BaseOption.TYPE_CHECKER) |
192 TYPE_CHECKER['regexp'] = check_regexp | 190 TYPE_CHECKER['regexp'] = check_regexp |
(...skipping 14 matching lines...) Expand all Loading... |
207 BaseOption.__init__(self, *opts, **attrs) | 205 BaseOption.__init__(self, *opts, **attrs) |
208 if hasattr(self, "hide") and self.hide: | 206 if hasattr(self, "hide") and self.hide: |
209 self.help = SUPPRESS_HELP | 207 self.help = SUPPRESS_HELP |
210 | 208 |
211 def _check_choice(self): | 209 def _check_choice(self): |
212 """FIXME: need to override this due to optik misdesign""" | 210 """FIXME: need to override this due to optik misdesign""" |
213 if self.type in ("choice", "multiple_choice"): | 211 if self.type in ("choice", "multiple_choice"): |
214 if self.choices is None: | 212 if self.choices is None: |
215 raise OptionError( | 213 raise OptionError( |
216 "must supply a list of choices for type 'choice'", self) | 214 "must supply a list of choices for type 'choice'", self) |
217 elif type(self.choices) not in (types.TupleType, types.ListType): | 215 elif not isinstance(self.choices, (tuple, list)): |
218 raise OptionError( | 216 raise OptionError( |
219 "choices must be a list of strings ('%s' supplied)" | 217 "choices must be a list of strings ('%s' supplied)" |
220 % str(type(self.choices)).split("'")[1], self) | 218 % str(type(self.choices)).split("'")[1], self) |
221 elif self.choices is not None: | 219 elif self.choices is not None: |
222 raise OptionError( | 220 raise OptionError( |
223 "must not supply choices for type %r" % self.type, self) | 221 "must not supply choices for type %r" % self.type, self) |
224 BaseOption.CHECK_METHODS[2] = _check_choice | 222 BaseOption.CHECK_METHODS[2] = _check_choice |
225 | 223 |
226 | 224 |
227 def process(self, opt, value, values, parser): | 225 def process(self, opt, value, values, parser): |
228 # First, convert the value(s) to the right type. Howl if any | 226 # First, convert the value(s) to the right type. Howl if any |
229 # value(s) are bogus. | 227 # value(s) are bogus. |
230 try: | 228 value = self.convert_value(opt, value) |
231 value = self.convert_value(opt, value) | |
232 except AttributeError: # py < 2.4 | |
233 value = self.check_value(opt, value) | |
234 if self.type == 'named': | 229 if self.type == 'named': |
235 existant = getattr(values, self.dest) | 230 existant = getattr(values, self.dest) |
236 if existant: | 231 if existant: |
237 existant.update(value) | 232 existant.update(value) |
238 value = existant | 233 value = existant |
239 # And then take whatever action is expected of us. | 234 # And then take whatever action is expected of us. |
240 # This is a separate method to make life easier for | 235 # This is a separate method to make life easier for |
241 # subclasses to add new actions. | 236 # subclasses to add new actions. |
242 return self.take_action( | 237 return self.take_action( |
243 self.action, self.dest, opt, value, values, parser) | 238 self.action, self.dest, opt, value, values, parser) |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 %s | 376 %s |
382 ''' % pkginfo.copyright | 377 ''' % pkginfo.copyright |
383 | 378 |
384 return tail | 379 return tail |
385 | 380 |
386 def generate_manpage(optparser, pkginfo, section=1, stream=sys.stdout, level=0): | 381 def generate_manpage(optparser, pkginfo, section=1, stream=sys.stdout, level=0): |
387 """generate a man page from an optik parser""" | 382 """generate a man page from an optik parser""" |
388 formatter = ManHelpFormatter() | 383 formatter = ManHelpFormatter() |
389 formatter.output_level = level | 384 formatter.output_level = level |
390 formatter.parser = optparser | 385 formatter.parser = optparser |
391 print >> stream, formatter.format_head(optparser, pkginfo, section) | 386 print(formatter.format_head(optparser, pkginfo, section), file=stream) |
392 print >> stream, optparser.format_option_help(formatter) | 387 print(optparser.format_option_help(formatter), file=stream) |
393 print >> stream, formatter.format_tail(pkginfo) | 388 print(formatter.format_tail(pkginfo), file=stream) |
394 | 389 |
395 | 390 |
396 __all__ = ('OptionParser', 'Option', 'OptionGroup', 'OptionValueError', | 391 __all__ = ('OptionParser', 'Option', 'OptionGroup', 'OptionValueError', |
397 'Values') | 392 'Values') |
OLD | NEW |