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