Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: third_party/logilab/common/configuration.py

Issue 707353002: pylint: upgrade to 1.3.1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 1 # copyright 2003-2012 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 #
11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT 11 # logilab-common is distributed in the hope that it will be useful, but WITHOUT
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 [MY CONFIG] 89 [MY CONFIG]
90 90
91 dothis=no 91 dothis=no
92 92
93 value=bacon 93 value=bacon
94 94
95 # you can also document the option 95 # you can also document the option
96 multiple=4,5,6 96 multiple=4,5,6
97 97
98 number=3 98 number=3
99 >>> 99
100 Note : starting with Python 2.7 ConfigParser is able to take into
101 account the order of occurrences of the options into a file (by
102 using an OrderedDict). If you have two options changing some common
103 state, like a 'disable-all-stuff' and a 'enable-some-stuff-a', their
104 order of appearance will be significant : the last specified in the
105 file wins. For earlier version of python and logilab.common newer
106 than 0.61 the behaviour is unspecified.
107
100 """ 108 """
109
110 from __future__ import print_function
111
101 __docformat__ = "restructuredtext en" 112 __docformat__ = "restructuredtext en"
102 113
103 __all__ = ('OptionsManagerMixIn', 'OptionsProviderMixIn', 114 __all__ = ('OptionsManagerMixIn', 'OptionsProviderMixIn',
104 'ConfigurationMixIn', 'Configuration', 115 'ConfigurationMixIn', 'Configuration',
105 'OptionsManager2ConfigurationAdapter') 116 'OptionsManager2ConfigurationAdapter')
106 117
107 import os 118 import os
108 import sys 119 import sys
109 import re 120 import re
110 from os.path import exists, expanduser 121 from os.path import exists, expanduser
111 from copy import copy 122 from copy import copy
112 from ConfigParser import ConfigParser, NoOptionError, NoSectionError, \
113 DuplicateSectionError
114 from warnings import warn 123 from warnings import warn
115 124
116 from logilab.common.compat import callable, raw_input, str_encode as _encode 125 from six import string_types
126 from six.moves import range, configparser as cp, input
117 127
128 from logilab.common.compat import str_encode as _encode
129 from logilab.common.deprecation import deprecated
118 from logilab.common.textutils import normalize_text, unquote 130 from logilab.common.textutils import normalize_text, unquote
119 from logilab.common import optik_ext as optparse 131 from logilab.common import optik_ext
120 132
121 OptionError = optparse.OptionError 133 OptionError = optik_ext.OptionError
122 134
123 REQUIRED = [] 135 REQUIRED = []
124 136
125 class UnsupportedAction(Exception): 137 class UnsupportedAction(Exception):
126 """raised by set_option when it doesn't know what to do for an action""" 138 """raised by set_option when it doesn't know what to do for an action"""
127 139
128 140
129 def _get_encoding(encoding, stream): 141 def _get_encoding(encoding, stream):
130 encoding = encoding or getattr(stream, 'encoding', None) 142 encoding = encoding or getattr(stream, 'encoding', None)
131 if not encoding: 143 if not encoding:
132 import locale 144 import locale
133 encoding = locale.getpreferredencoding() 145 encoding = locale.getpreferredencoding()
134 return encoding 146 return encoding
135 147
136 148
137 # validation functions ######################################################## 149 # validation functions ########################################################
138 150
151 # validators will return the validated value or raise optparse.OptionValueError
152 # XXX add to documentation
153
139 def choice_validator(optdict, name, value): 154 def choice_validator(optdict, name, value):
140 """validate and return a converted value for option of type 'choice' 155 """validate and return a converted value for option of type 'choice'
141 """ 156 """
142 if not value in optdict['choices']: 157 if not value in optdict['choices']:
143 msg = "option %s: invalid value: %r, should be in %s" 158 msg = "option %s: invalid value: %r, should be in %s"
144 raise optparse.OptionValueError(msg % (name, value, optdict['choices'])) 159 raise optik_ext.OptionValueError(msg % (name, value, optdict['choices']) )
145 return value 160 return value
146 161
147 def multiple_choice_validator(optdict, name, value): 162 def multiple_choice_validator(optdict, name, value):
148 """validate and return a converted value for option of type 'choice' 163 """validate and return a converted value for option of type 'choice'
149 """ 164 """
150 choices = optdict['choices'] 165 choices = optdict['choices']
151 values = optparse.check_csv(None, name, value) 166 values = optik_ext.check_csv(None, name, value)
152 for value in values: 167 for value in values:
153 if not value in choices: 168 if not value in choices:
154 msg = "option %s: invalid value: %r, should be in %s" 169 msg = "option %s: invalid value: %r, should be in %s"
155 raise optparse.OptionValueError(msg % (name, value, choices)) 170 raise optik_ext.OptionValueError(msg % (name, value, choices))
156 return values 171 return values
157 172
158 def csv_validator(optdict, name, value): 173 def csv_validator(optdict, name, value):
159 """validate and return a converted value for option of type 'csv' 174 """validate and return a converted value for option of type 'csv'
160 """ 175 """
161 return optparse.check_csv(None, name, value) 176 return optik_ext.check_csv(None, name, value)
162 177
163 def yn_validator(optdict, name, value): 178 def yn_validator(optdict, name, value):
164 """validate and return a converted value for option of type 'yn' 179 """validate and return a converted value for option of type 'yn'
165 """ 180 """
166 return optparse.check_yn(None, name, value) 181 return optik_ext.check_yn(None, name, value)
167 182
168 def named_validator(optdict, name, value): 183 def named_validator(optdict, name, value):
169 """validate and return a converted value for option of type 'named' 184 """validate and return a converted value for option of type 'named'
170 """ 185 """
171 return optparse.check_named(None, name, value) 186 return optik_ext.check_named(None, name, value)
172 187
173 def file_validator(optdict, name, value): 188 def file_validator(optdict, name, value):
174 """validate and return a filepath for option of type 'file'""" 189 """validate and return a filepath for option of type 'file'"""
175 return optparse.check_file(None, name, value) 190 return optik_ext.check_file(None, name, value)
176 191
177 def color_validator(optdict, name, value): 192 def color_validator(optdict, name, value):
178 """validate and return a valid color for option of type 'color'""" 193 """validate and return a valid color for option of type 'color'"""
179 return optparse.check_color(None, name, value) 194 return optik_ext.check_color(None, name, value)
180 195
181 def password_validator(optdict, name, value): 196 def password_validator(optdict, name, value):
182 """validate and return a string for option of type 'password'""" 197 """validate and return a string for option of type 'password'"""
183 return optparse.check_password(None, name, value) 198 return optik_ext.check_password(None, name, value)
184 199
185 def date_validator(optdict, name, value): 200 def date_validator(optdict, name, value):
186 """validate and return a mx DateTime object for option of type 'date'""" 201 """validate and return a mx DateTime object for option of type 'date'"""
187 return optparse.check_date(None, name, value) 202 return optik_ext.check_date(None, name, value)
188 203
189 def time_validator(optdict, name, value): 204 def time_validator(optdict, name, value):
190 """validate and return a time object for option of type 'time'""" 205 """validate and return a time object for option of type 'time'"""
191 return optparse.check_time(None, name, value) 206 return optik_ext.check_time(None, name, value)
192 207
193 def bytes_validator(optdict, name, value): 208 def bytes_validator(optdict, name, value):
194 """validate and return an integer for option of type 'bytes'""" 209 """validate and return an integer for option of type 'bytes'"""
195 return optparse.check_bytes(None, name, value) 210 return optik_ext.check_bytes(None, name, value)
196 211
197 212
198 VALIDATORS = {'string': unquote, 213 VALIDATORS = {'string': unquote,
199 'int': int, 214 'int': int,
200 'float': float, 215 'float': float,
201 'file': file_validator, 216 'file': file_validator,
202 'font': unquote, 217 'font': unquote,
203 'color': color_validator, 218 'color': color_validator,
204 'regexp': re.compile, 219 'regexp': re.compile,
205 'csv': csv_validator, 220 'csv': csv_validator,
206 'yn': yn_validator, 221 'yn': yn_validator,
207 'bool': yn_validator, 222 'bool': yn_validator,
208 'named': named_validator, 223 'named': named_validator,
209 'password': password_validator, 224 'password': password_validator,
210 'date': date_validator, 225 'date': date_validator,
211 'time': time_validator, 226 'time': time_validator,
212 'bytes': bytes_validator, 227 'bytes': bytes_validator,
213 'choice': choice_validator, 228 'choice': choice_validator,
214 'multiple_choice': multiple_choice_validator, 229 'multiple_choice': multiple_choice_validator,
215 } 230 }
216 231
217 def _call_validator(opttype, optdict, option, value): 232 def _call_validator(opttype, optdict, option, value):
218 if opttype not in VALIDATORS: 233 if opttype not in VALIDATORS:
219 raise Exception('Unsupported type "%s"' % opttype) 234 raise Exception('Unsupported type "%s"' % opttype)
220 try: 235 try:
221 return VALIDATORS[opttype](optdict, option, value) 236 return VALIDATORS[opttype](optdict, option, value)
222 except TypeError: 237 except TypeError:
223 try: 238 try:
224 return VALIDATORS[opttype](value) 239 return VALIDATORS[opttype](value)
225 except optparse.OptionValueError: 240 except optik_ext.OptionValueError:
226 raise 241 raise
227 except: 242 except:
228 raise optparse.OptionValueError('%s value (%r) should be of type %s' % 243 raise optik_ext.OptionValueError('%s value (%r) should be of type %s ' %
229 (option, value, opttype)) 244 (option, value, opttype))
230 245
231 # user input functions ######################################################## 246 # user input functions ########################################################
232 247
248 # user input functions will ask the user for input on stdin then validate
249 # the result and return the validated value or raise optparse.OptionValueError
250 # XXX add to documentation
251
233 def input_password(optdict, question='password:'): 252 def input_password(optdict, question='password:'):
234 from getpass import getpass 253 from getpass import getpass
235 while True: 254 while True:
236 value = getpass(question) 255 value = getpass(question)
237 value2 = getpass('confirm: ') 256 value2 = getpass('confirm: ')
238 if value == value2: 257 if value == value2:
239 return value 258 return value
240 print 'password mismatch, try again' 259 print('password mismatch, try again')
241 260
242 def input_string(optdict, question): 261 def input_string(optdict, question):
243 value = raw_input(question).strip() 262 value = input(question).strip()
244 return value or None 263 return value or None
245 264
246 def _make_input_function(opttype): 265 def _make_input_function(opttype):
247 def input_validator(optdict, question): 266 def input_validator(optdict, question):
248 while True: 267 while True:
249 value = raw_input(question) 268 value = input(question)
250 if not value.strip(): 269 if not value.strip():
251 return None 270 return None
252 try: 271 try:
253 return _call_validator(opttype, optdict, None, value) 272 return _call_validator(opttype, optdict, None, value)
254 except optparse.OptionValueError, ex: 273 except optik_ext.OptionValueError as ex:
255 msg = str(ex).split(':', 1)[-1].strip() 274 msg = str(ex).split(':', 1)[-1].strip()
256 print 'bad value: %s' % msg 275 print('bad value: %s' % msg)
257 return input_validator 276 return input_validator
258 277
259 INPUT_FUNCTIONS = { 278 INPUT_FUNCTIONS = {
260 'string': input_string, 279 'string': input_string,
261 'password': input_password, 280 'password': input_password,
262 } 281 }
263 282
264 for opttype in VALIDATORS.keys(): 283 for opttype in VALIDATORS.keys():
265 INPUT_FUNCTIONS.setdefault(opttype, _make_input_function(opttype)) 284 INPUT_FUNCTIONS.setdefault(opttype, _make_input_function(opttype))
266 285
286 # utility functions ############################################################
287
267 def expand_default(self, option): 288 def expand_default(self, option):
268 """monkey patch OptionParser.expand_default since we have a particular 289 """monkey patch OptionParser.expand_default since we have a particular
269 way to handle defaults to avoid overriding values in the configuration 290 way to handle defaults to avoid overriding values in the configuration
270 file 291 file
271 """ 292 """
272 if self.parser is None or not self.default_tag: 293 if self.parser is None or not self.default_tag:
273 return option.help 294 return option.help
274 optname = option._long_opts[0][2:] 295 optname = option._long_opts[0][2:]
275 try: 296 try:
276 provider = self.parser.options_manager._all_options[optname] 297 provider = self.parser.options_manager._all_options[optname]
277 except KeyError: 298 except KeyError:
278 value = None 299 value = None
279 else: 300 else:
280 optdict = provider.get_option_def(optname) 301 optdict = provider.get_option_def(optname)
281 optname = provider.option_name(optname, optdict) 302 optname = provider.option_attrname(optname, optdict)
282 value = getattr(provider.config, optname, optdict) 303 value = getattr(provider.config, optname, optdict)
283 value = format_option_value(optdict, value) 304 value = format_option_value(optdict, value)
284 if value is optparse.NO_DEFAULT or not value: 305 if value is optik_ext.NO_DEFAULT or not value:
285 value = self.NO_DEFAULT_VALUE 306 value = self.NO_DEFAULT_VALUE
286 return option.help.replace(self.default_tag, str(value)) 307 return option.help.replace(self.default_tag, str(value))
287 308
288 309
289 def convert(value, optdict, name=''): 310 def _validate(value, optdict, name=''):
290 """return a validated value for an option according to its type 311 """return a validated value for an option according to its type
291 312
292 optional argument name is only used for error message formatting 313 optional argument name is only used for error message formatting
293 """ 314 """
294 try: 315 try:
295 _type = optdict['type'] 316 _type = optdict['type']
296 except KeyError: 317 except KeyError:
297 # FIXME 318 # FIXME
298 return value 319 return value
299 return _call_validator(_type, optdict, name, value) 320 return _call_validator(_type, optdict, name, value)
321 convert = deprecated('[0.60] convert() was renamed _validate()')(_validate)
322
323 # format and output functions ##################################################
300 324
301 def comment(string): 325 def comment(string):
302 """return string as a comment""" 326 """return string as a comment"""
303 lines = [line.strip() for line in string.splitlines()] 327 lines = [line.strip() for line in string.splitlines()]
304 return '# ' + ('%s# ' % os.linesep).join(lines) 328 return '# ' + ('%s# ' % os.linesep).join(lines)
305 329
306 def format_time(value): 330 def format_time(value):
307 if not value: 331 if not value:
308 return '0' 332 return '0'
309 if value != int(value): 333 if value != int(value):
(...skipping 29 matching lines...) Expand all
339 """return the user input's value from a 'compiled' value""" 363 """return the user input's value from a 'compiled' value"""
340 if isinstance(value, (list, tuple)): 364 if isinstance(value, (list, tuple)):
341 value = ','.join(value) 365 value = ','.join(value)
342 elif isinstance(value, dict): 366 elif isinstance(value, dict):
343 value = ','.join(['%s:%s' % (k, v) for k, v in value.items()]) 367 value = ','.join(['%s:%s' % (k, v) for k, v in value.items()])
344 elif hasattr(value, 'match'): # optdict.get('type') == 'regexp' 368 elif hasattr(value, 'match'): # optdict.get('type') == 'regexp'
345 # compiled regexp 369 # compiled regexp
346 value = value.pattern 370 value = value.pattern
347 elif optdict.get('type') == 'yn': 371 elif optdict.get('type') == 'yn':
348 value = value and 'yes' or 'no' 372 value = value and 'yes' or 'no'
349 elif isinstance(value, (str, unicode)) and value.isspace(): 373 elif isinstance(value, string_types) and value.isspace():
350 value = "'%s'" % value 374 value = "'%s'" % value
351 elif optdict.get('type') == 'time' and isinstance(value, (float, int, long)) : 375 elif optdict.get('type') == 'time' and isinstance(value, (float, int, long)) :
352 value = format_time(value) 376 value = format_time(value)
353 elif optdict.get('type') == 'bytes' and hasattr(value, '__int__'): 377 elif optdict.get('type') == 'bytes' and hasattr(value, '__int__'):
354 value = format_bytes(value) 378 value = format_bytes(value)
355 return value 379 return value
356 380
357 def ini_format_section(stream, section, options, encoding=None, doc=None): 381 def ini_format_section(stream, section, options, encoding=None, doc=None):
358 """format an options section using the INI format""" 382 """format an options section using the INI format"""
359 encoding = _get_encoding(encoding, stream) 383 encoding = _get_encoding(encoding, stream)
360 if doc: 384 if doc:
361 print >> stream, _encode(comment(doc), encoding) 385 print(_encode(comment(doc), encoding), file=stream)
362 print >> stream, '[%s]' % section 386 print('[%s]' % section, file=stream)
363 ini_format(stream, options, encoding) 387 ini_format(stream, options, encoding)
364 388
365 def ini_format(stream, options, encoding): 389 def ini_format(stream, options, encoding):
366 """format options using the INI format""" 390 """format options using the INI format"""
367 for optname, optdict, value in options: 391 for optname, optdict, value in options:
368 value = format_option_value(optdict, value) 392 value = format_option_value(optdict, value)
369 help = optdict.get('help') 393 help = optdict.get('help')
370 if help: 394 if help:
371 help = normalize_text(help, line_len=79, indent='# ') 395 help = normalize_text(help, line_len=79, indent='# ')
372 print >> stream 396 print(file=stream)
373 print >> stream, _encode(help, encoding) 397 print(_encode(help, encoding), file=stream)
374 else: 398 else:
375 print >> stream 399 print(file=stream)
376 if value is None: 400 if value is None:
377 print >> stream, '#%s=' % optname 401 print('#%s=' % optname, file=stream)
378 else: 402 else:
379 value = _encode(value, encoding).strip() 403 value = _encode(value, encoding).strip()
380 print >> stream, '%s=%s' % (optname, value) 404 print('%s=%s' % (optname, value), file=stream)
381 405
382 format_section = ini_format_section 406 format_section = ini_format_section
383 407
384 def rest_format_section(stream, section, options, encoding=None, doc=None): 408 def rest_format_section(stream, section, options, encoding=None, doc=None):
385 """format an options section using the INI format""" 409 """format an options section using as ReST formatted output"""
386 encoding = _get_encoding(encoding, stream) 410 encoding = _get_encoding(encoding, stream)
387 if section: 411 if section:
388 print >> stream, '%s\n%s' % (section, "'"*len(section)) 412 print >> stream, '%s\n%s' % (section, "'"*len(section))
389 if doc: 413 if doc:
390 print >> stream, _encode(normalize_text(doc, line_len=79, indent=''), 414 print >> stream, _encode(normalize_text(doc, line_len=79, indent=''),
391 encoding) 415 encoding)
392 print >> stream 416 print >> stream
393 for optname, optdict, value in options: 417 for optname, optdict, value in options:
394 help = optdict.get('help') 418 help = optdict.get('help')
395 print >> stream, ':%s:' % optname 419 print >> stream, ':%s:' % optname
396 if help: 420 if help:
397 help = normalize_text(help, line_len=79, indent=' ') 421 help = normalize_text(help, line_len=79, indent=' ')
398 print >> stream, _encode(help, encoding) 422 print >> stream, _encode(help, encoding)
399 if value: 423 if value:
400 value = _encode(format_option_value(optdict, value), encoding) 424 value = _encode(format_option_value(optdict, value), encoding)
401 print >> stream, '' 425 print >> stream, ''
402 print >> stream, ' Default: ``%s``' % value.replace("`` ", "```` `` ") 426 print >> stream, ' Default: ``%s``' % value.replace("`` ", "```` `` ")
403 427
428 # Options Manager ##############################################################
404 429
405 class OptionsManagerMixIn(object): 430 class OptionsManagerMixIn(object):
406 """MixIn to handle a configuration from both a configuration file and 431 """MixIn to handle a configuration from both a configuration file and
407 command line options 432 command line options
408 """ 433 """
409 434
410 def __init__(self, usage, config_file=None, version=None, quiet=0): 435 def __init__(self, usage, config_file=None, version=None, quiet=0):
411 self.config_file = config_file 436 self.config_file = config_file
412 self.reset_parsers(usage, version=version) 437 self.reset_parsers(usage, version=version)
413 # list of registered options providers 438 # list of registered options providers
414 self.options_providers = [] 439 self.options_providers = []
415 # dictionary associating option name to checker 440 # dictionary associating option name to checker
416 self._all_options = {} 441 self._all_options = {}
417 self._short_options = {} 442 self._short_options = {}
418 self._nocallback_options = {} 443 self._nocallback_options = {}
419 self._mygroups = dict() 444 self._mygroups = dict()
420 # verbosity 445 # verbosity
421 self.quiet = quiet 446 self.quiet = quiet
422 self._maxlevel = 0 447 self._maxlevel = 0
423 448
424 def reset_parsers(self, usage='', version=None): 449 def reset_parsers(self, usage='', version=None):
425 # configuration file parser 450 # configuration file parser
426 self.cfgfile_parser = ConfigParser() 451 self.cfgfile_parser = cp.ConfigParser()
427 # command line parser 452 # command line parser
428 self.cmdline_parser = optparse.OptionParser(usage=usage, version=version ) 453 self.cmdline_parser = optik_ext.OptionParser(usage=usage, version=versio n)
429 self.cmdline_parser.options_manager = self 454 self.cmdline_parser.options_manager = self
430 self._optik_option_attrs = set(self.cmdline_parser.option_class.ATTRS) 455 self._optik_option_attrs = set(self.cmdline_parser.option_class.ATTRS)
431 456
432 def register_options_provider(self, provider, own_group=True): 457 def register_options_provider(self, provider, own_group=True):
433 """register an options provider""" 458 """register an options provider"""
434 assert provider.priority <= 0, "provider's priority can't be >= 0" 459 assert provider.priority <= 0, "provider's priority can't be >= 0"
435 for i in range(len(self.options_providers)): 460 for i in range(len(self.options_providers)):
436 if provider.priority > self.options_providers[i].priority: 461 if provider.priority > self.options_providers[i].priority:
437 self.options_providers.insert(i, provider) 462 self.options_providers.insert(i, provider)
438 break 463 break
(...skipping 15 matching lines...) Expand all
454 self.add_option_group(gname, gdoc, goptions, provider) 479 self.add_option_group(gname, gdoc, goptions, provider)
455 480
456 def add_option_group(self, group_name, doc, options, provider): 481 def add_option_group(self, group_name, doc, options, provider):
457 """add an option group including the listed options 482 """add an option group including the listed options
458 """ 483 """
459 assert options 484 assert options
460 # add option group to the command line parser 485 # add option group to the command line parser
461 if group_name in self._mygroups: 486 if group_name in self._mygroups:
462 group = self._mygroups[group_name] 487 group = self._mygroups[group_name]
463 else: 488 else:
464 group = optparse.OptionGroup(self.cmdline_parser, 489 group = optik_ext.OptionGroup(self.cmdline_parser,
465 title=group_name.capitalize()) 490 title=group_name.capitalize())
466 self.cmdline_parser.add_option_group(group) 491 self.cmdline_parser.add_option_group(group)
467 group.level = provider.level 492 group.level = provider.level
468 self._mygroups[group_name] = group 493 self._mygroups[group_name] = group
469 # add section to the config file 494 # add section to the config file
470 if group_name != "DEFAULT": 495 if group_name != "DEFAULT":
471 self.cfgfile_parser.add_section(group_name) 496 self.cfgfile_parser.add_section(group_name)
472 # add provider's specific options 497 # add provider's specific options
473 for opt, optdict in options: 498 for opt, optdict in options:
474 self.add_optik_option(provider, group, opt, optdict) 499 self.add_optik_option(provider, group, opt, optdict)
(...skipping 15 matching lines...) Expand all
490 optdict = copy(optdict) 515 optdict = copy(optdict)
491 others = {} 516 others = {}
492 if 'action' in optdict: 517 if 'action' in optdict:
493 self._nocallback_options[provider] = opt 518 self._nocallback_options[provider] = opt
494 else: 519 else:
495 optdict['action'] = 'callback' 520 optdict['action'] = 'callback'
496 optdict['callback'] = self.cb_set_provider_option 521 optdict['callback'] = self.cb_set_provider_option
497 # default is handled here and *must not* be given to optik if you 522 # default is handled here and *must not* be given to optik if you
498 # want the whole machinery to work 523 # want the whole machinery to work
499 if 'default' in optdict: 524 if 'default' in optdict:
500 if (optparse.OPTPARSE_FORMAT_DEFAULT and 'help' in optdict and 525 if ('help' in optdict
501 optdict.get('default') is not None and 526 and optdict.get('default') is not None
502 not optdict['action'] in ('store_true', 'store_false')): 527 and not optdict['action'] in ('store_true', 'store_false')):
503 optdict['help'] += ' [current: %default]' 528 optdict['help'] += ' [current: %default]'
504 del optdict['default'] 529 del optdict['default']
505 args = ['--' + str(opt)] 530 args = ['--' + str(opt)]
506 if 'short' in optdict: 531 if 'short' in optdict:
507 self._short_options[optdict['short']] = opt 532 self._short_options[optdict['short']] = opt
508 args.append('-' + optdict['short']) 533 args.append('-' + optdict['short'])
509 del optdict['short'] 534 del optdict['short']
510 # cleanup option definition dict before giving it to optik 535 # cleanup option definition dict before giving it to optik
511 for key in optdict.keys(): 536 for key in list(optdict.keys()):
512 if not key in self._optik_option_attrs: 537 if not key in self._optik_option_attrs:
513 optdict.pop(key) 538 optdict.pop(key)
514 return args, optdict 539 return args, optdict
515 540
516 def cb_set_provider_option(self, option, opt, value, parser): 541 def cb_set_provider_option(self, option, opt, value, parser):
517 """optik callback for option setting""" 542 """optik callback for option setting"""
518 if opt.startswith('--'): 543 if opt.startswith('--'):
519 # remove -- on long option 544 # remove -- on long option
520 opt = opt[2:] 545 opt = opt[2:]
521 else: 546 else:
(...skipping 26 matching lines...) Expand all
548 continue 573 continue
549 if not section in sections: 574 if not section in sections:
550 sections.append(section) 575 sections.append(section)
551 alloptions = options_by_section.setdefault(section, []) 576 alloptions = options_by_section.setdefault(section, [])
552 alloptions += options 577 alloptions += options
553 stream = stream or sys.stdout 578 stream = stream or sys.stdout
554 encoding = _get_encoding(encoding, stream) 579 encoding = _get_encoding(encoding, stream)
555 printed = False 580 printed = False
556 for section in sections: 581 for section in sections:
557 if printed: 582 if printed:
558 print >> stream, '\n' 583 print('\n', file=stream)
559 format_section(stream, section.upper(), options_by_section[section], 584 format_section(stream, section.upper(), options_by_section[section],
560 encoding) 585 encoding)
561 printed = True 586 printed = True
562 587
563 def generate_manpage(self, pkginfo, section=1, stream=None): 588 def generate_manpage(self, pkginfo, section=1, stream=None):
564 """write a man page for the current configuration into the given 589 """write a man page for the current configuration into the given
565 stream or stdout 590 stream or stdout
566 """ 591 """
567 self._monkeypatch_expand_default() 592 self._monkeypatch_expand_default()
568 try: 593 try:
569 optparse.generate_manpage(self.cmdline_parser, pkginfo, 594 optik_ext.generate_manpage(self.cmdline_parser, pkginfo,
570 section, stream=stream or sys.stdout, 595 section, stream=stream or sys.stdout,
571 level=self._maxlevel) 596 level=self._maxlevel)
572 finally: 597 finally:
573 self._unmonkeypatch_expand_default() 598 self._unmonkeypatch_expand_default()
574 599
575 # initialization methods ################################################## 600 # initialization methods ##################################################
576 601
577 def load_provider_defaults(self): 602 def load_provider_defaults(self):
578 """initialize configuration using default values""" 603 """initialize configuration using default values"""
579 for provider in self.options_providers: 604 for provider in self.options_providers:
580 provider.load_defaults() 605 provider.load_defaults()
581 606
582 def load_file_configuration(self, config_file=None): 607 def load_file_configuration(self, config_file=None):
583 """load the configuration from file""" 608 """load the configuration from file"""
584 self.read_config_file(config_file) 609 self.read_config_file(config_file)
585 self.load_config_file() 610 self.load_config_file()
586 611
587 def read_config_file(self, config_file=None): 612 def read_config_file(self, config_file=None):
588 """read the configuration file but do not load it (i.e. dispatching 613 """read the configuration file but do not load it (i.e. dispatching
589 values to each options provider) 614 values to each options provider)
590 """ 615 """
591 helplevel = 1 616 helplevel = 1
592 while helplevel <= self._maxlevel: 617 while helplevel <= self._maxlevel:
593 opt = '-'.join(['long'] * helplevel) + '-help' 618 opt = '-'.join(['long'] * helplevel) + '-help'
594 if opt in self._all_options: 619 if opt in self._all_options:
595 break # already processed 620 break # already processed
596 def helpfunc(option, opt, val, p, level=helplevel): 621 def helpfunc(option, opt, val, p, level=helplevel):
597 print self.help(level) 622 print(self.help(level))
598 sys.exit(0) 623 sys.exit(0)
599 helpmsg = '%s verbose help.' % ' '.join(['more'] * helplevel) 624 helpmsg = '%s verbose help.' % ' '.join(['more'] * helplevel)
600 optdict = {'action' : 'callback', 'callback' : helpfunc, 625 optdict = {'action' : 'callback', 'callback' : helpfunc,
601 'help' : helpmsg} 626 'help' : helpmsg}
602 provider = self.options_providers[0] 627 provider = self.options_providers[0]
603 self.add_optik_option(provider, self.cmdline_parser, opt, optdict) 628 self.add_optik_option(provider, self.cmdline_parser, opt, optdict)
604 provider.options += ( (opt, optdict), ) 629 provider.options += ( (opt, optdict), )
605 helplevel += 1 630 helplevel += 1
606 if config_file is None: 631 if config_file is None:
607 config_file = self.config_file 632 config_file = self.config_file
608 if config_file is not None: 633 if config_file is not None:
609 config_file = expanduser(config_file) 634 config_file = expanduser(config_file)
610 if config_file and exists(config_file): 635 if config_file and exists(config_file):
611 parser = self.cfgfile_parser 636 parser = self.cfgfile_parser
612 parser.read([config_file]) 637 parser.read([config_file])
613 # normalize sections'title 638 # normalize sections'title
614 for sect, values in parser._sections.items(): 639 for sect, values in parser._sections.items():
615 if not sect.isupper() and values: 640 if not sect.isupper() and values:
616 parser._sections[sect.upper()] = values 641 parser._sections[sect.upper()] = values
617 elif not self.quiet: 642 elif not self.quiet:
618 msg = 'No config file found, using default configuration' 643 msg = 'No config file found, using default configuration'
619 print >> sys.stderr, msg 644 print(msg, file=sys.stderr)
620 return 645 return
621 646
622 def input_config(self, onlysection=None, inputlevel=0, stream=None): 647 def input_config(self, onlysection=None, inputlevel=0, stream=None):
623 """interactively get configuration values by asking to the user and gene rate 648 """interactively get configuration values by asking to the user and gene rate
624 a configuration file 649 a configuration file
625 """ 650 """
626 if onlysection is not None: 651 if onlysection is not None:
627 onlysection = onlysection.upper() 652 onlysection = onlysection.upper()
628 for provider in self.options_providers: 653 for provider in self.options_providers:
629 for section, option, optdict in provider.all_options(): 654 for section, option, optdict in provider.all_options():
630 if onlysection is not None and section != onlysection: 655 if onlysection is not None and section != onlysection:
631 continue 656 continue
632 if not 'type' in optdict: 657 if not 'type' in optdict:
633 # ignore action without type (callback, store_true...) 658 # ignore action without type (callback, store_true...)
634 continue 659 continue
635 provider.input_option(option, optdict, inputlevel) 660 provider.input_option(option, optdict, inputlevel)
636 # now we can generate the configuration file 661 # now we can generate the configuration file
637 if stream is not None: 662 if stream is not None:
638 self.generate_config(stream) 663 self.generate_config(stream)
639 664
640 def load_config_file(self): 665 def load_config_file(self):
641 """dispatch values previously read from a configuration file to each 666 """dispatch values previously read from a configuration file to each
642 options provider) 667 options provider)
643 """ 668 """
644 parser = self.cfgfile_parser 669 parser = self.cfgfile_parser
645 for provider in self.options_providers: 670 for section in parser.sections():
646 for section, option, optdict in provider.all_options(): 671 for option, value in parser.items(section):
647 try: 672 try:
648 value = parser.get(section, option) 673 self.global_set_option(option, value)
649 provider.set_option(option, value, optdict=optdict) 674 except (KeyError, OptionError):
650 except (NoSectionError, NoOptionError), ex: 675 # TODO handle here undeclared options appearing in the co nfig file
651 continue 676 continue
652 677
653 def load_configuration(self, **kwargs): 678 def load_configuration(self, **kwargs):
654 """override configuration according to given parameters 679 """override configuration according to given parameters
655 """ 680 """
656 for opt, opt_value in kwargs.items(): 681 for opt, opt_value in kwargs.items():
657 opt = opt.replace('_', '-') 682 opt = opt.replace('_', '-')
658 provider = self._all_options[opt] 683 provider = self._all_options[opt]
659 provider.set_option(opt, opt_value) 684 provider.set_option(opt, opt_value)
660 685
661 def load_command_line_configuration(self, args=None): 686 def load_command_line_configuration(self, args=None):
(...skipping 17 matching lines...) Expand all
679 setattr(config, attr, value) 704 setattr(config, attr, value)
680 return args 705 return args
681 finally: 706 finally:
682 self._unmonkeypatch_expand_default() 707 self._unmonkeypatch_expand_default()
683 708
684 709
685 # help methods ############################################################ 710 # help methods ############################################################
686 711
687 def add_help_section(self, title, description, level=0): 712 def add_help_section(self, title, description, level=0):
688 """add a dummy option section for help purpose """ 713 """add a dummy option section for help purpose """
689 group = optparse.OptionGroup(self.cmdline_parser, 714 group = optik_ext.OptionGroup(self.cmdline_parser,
690 title=title.capitalize(), 715 title=title.capitalize(),
691 description=description) 716 description=description)
692 group.level = level 717 group.level = level
693 self._maxlevel = max(self._maxlevel, level) 718 self._maxlevel = max(self._maxlevel, level)
694 self.cmdline_parser.add_option_group(group) 719 self.cmdline_parser.add_option_group(group)
695 720
696 def _monkeypatch_expand_default(self): 721 def _monkeypatch_expand_default(self):
697 # monkey patch optparse to deal with our default values 722 # monkey patch optik_ext to deal with our default values
698 try: 723 try:
699 self.__expand_default_backup = optparse.HelpFormatter.expand_default 724 self.__expand_default_backup = optik_ext.HelpFormatter.expand_defaul t
700 optparse.HelpFormatter.expand_default = expand_default 725 optik_ext.HelpFormatter.expand_default = expand_default
701 except AttributeError: 726 except AttributeError:
702 # python < 2.4: nothing to be done 727 # python < 2.4: nothing to be done
703 pass 728 pass
704 def _unmonkeypatch_expand_default(self): 729 def _unmonkeypatch_expand_default(self):
705 # remove monkey patch 730 # remove monkey patch
706 if hasattr(optparse.HelpFormatter, 'expand_default'): 731 if hasattr(optik_ext.HelpFormatter, 'expand_default'):
707 # unpatch optparse to avoid side effects 732 # unpatch optik_ext to avoid side effects
708 optparse.HelpFormatter.expand_default = self.__expand_default_backup 733 optik_ext.HelpFormatter.expand_default = self.__expand_default_backu p
709 734
710 def help(self, level=0): 735 def help(self, level=0):
711 """return the usage string for available options """ 736 """return the usage string for available options """
712 self.cmdline_parser.formatter.output_level = level 737 self.cmdline_parser.formatter.output_level = level
713 self._monkeypatch_expand_default() 738 self._monkeypatch_expand_default()
714 try: 739 try:
715 return self.cmdline_parser.format_help() 740 return self.cmdline_parser.format_help()
716 finally: 741 finally:
717 self._unmonkeypatch_expand_default() 742 self._unmonkeypatch_expand_default()
718 743
719 744
720 class Method(object): 745 class Method(object):
721 """used to ease late binding of default method (so you can define options 746 """used to ease late binding of default method (so you can define options
722 on the class using default methods on the configuration instance) 747 on the class using default methods on the configuration instance)
723 """ 748 """
724 def __init__(self, methname): 749 def __init__(self, methname):
725 self.method = methname 750 self.method = methname
726 self._inst = None 751 self._inst = None
727 752
728 def bind(self, instance): 753 def bind(self, instance):
729 """bind the method to its instance""" 754 """bind the method to its instance"""
730 if self._inst is None: 755 if self._inst is None:
731 self._inst = instance 756 self._inst = instance
732 757
733 def __call__(self, *args, **kwargs): 758 def __call__(self, *args, **kwargs):
734 assert self._inst, 'unbound method' 759 assert self._inst, 'unbound method'
735 return getattr(self._inst, self.method)(*args, **kwargs) 760 return getattr(self._inst, self.method)(*args, **kwargs)
736 761
762 # Options Provider #############################################################
737 763
738 class OptionsProviderMixIn(object): 764 class OptionsProviderMixIn(object):
739 """Mixin to provide options to an OptionsManager""" 765 """Mixin to provide options to an OptionsManager"""
740 766
741 # those attributes should be overridden 767 # those attributes should be overridden
742 priority = -1 768 priority = -1
743 name = 'default' 769 name = 'default'
744 options = () 770 options = ()
745 level = 0 771 level = 0
746 772
747 def __init__(self): 773 def __init__(self):
748 self.config = optparse.Values() 774 self.config = optik_ext.Values()
749 for option in self.options: 775 for option in self.options:
750 try: 776 try:
751 option, optdict = option 777 option, optdict = option
752 except ValueError: 778 except ValueError:
753 raise Exception('Bad option: %r' % option) 779 raise Exception('Bad option: %r' % option)
754 if isinstance(optdict.get('default'), Method): 780 if isinstance(optdict.get('default'), Method):
755 optdict['default'].bind(self) 781 optdict['default'].bind(self)
756 elif isinstance(optdict.get('callback'), Method): 782 elif isinstance(optdict.get('callback'), Method):
757 optdict['callback'].bind(self) 783 optdict['callback'].bind(self)
758 self.load_defaults() 784 self.load_defaults()
(...skipping 11 matching lines...) Expand all
770 796
771 def option_default(self, opt, optdict=None): 797 def option_default(self, opt, optdict=None):
772 """return the default value for an option""" 798 """return the default value for an option"""
773 if optdict is None: 799 if optdict is None:
774 optdict = self.get_option_def(opt) 800 optdict = self.get_option_def(opt)
775 default = optdict.get('default') 801 default = optdict.get('default')
776 if callable(default): 802 if callable(default):
777 default = default() 803 default = default()
778 return default 804 return default
779 805
780 def option_name(self, opt, optdict=None): 806 def option_attrname(self, opt, optdict=None):
781 """get the config attribute corresponding to opt 807 """get the config attribute corresponding to opt
782 """ 808 """
783 if optdict is None: 809 if optdict is None:
784 optdict = self.get_option_def(opt) 810 optdict = self.get_option_def(opt)
785 return optdict.get('dest', opt.replace('-', '_')) 811 return optdict.get('dest', opt.replace('-', '_'))
812 option_name = deprecated('[0.60] OptionsProviderMixIn.option_name() was rena med to option_attrname()')(option_attrname)
786 813
787 def option_value(self, opt): 814 def option_value(self, opt):
788 """get the current value for the given option""" 815 """get the current value for the given option"""
789 return getattr(self.config, self.option_name(opt), None) 816 return getattr(self.config, self.option_attrname(opt), None)
790 817
791 def set_option(self, opt, value, action=None, optdict=None): 818 def set_option(self, opt, value, action=None, optdict=None):
792 """method called to set an option (registered in the options list) 819 """method called to set an option (registered in the options list)
793 """ 820 """
794 # print "************ setting option", opt," to value", value
795 if optdict is None: 821 if optdict is None:
796 optdict = self.get_option_def(opt) 822 optdict = self.get_option_def(opt)
797 if value is not None: 823 if value is not None:
798 value = convert(value, optdict, opt) 824 value = _validate(value, optdict, opt)
799 if action is None: 825 if action is None:
800 action = optdict.get('action', 'store') 826 action = optdict.get('action', 'store')
801 if optdict.get('type') == 'named': # XXX need specific handling 827 if optdict.get('type') == 'named': # XXX need specific handling
802 optname = self.option_name(opt, optdict) 828 optname = self.option_attrname(opt, optdict)
803 currentvalue = getattr(self.config, optname, None) 829 currentvalue = getattr(self.config, optname, None)
804 if currentvalue: 830 if currentvalue:
805 currentvalue.update(value) 831 currentvalue.update(value)
806 value = currentvalue 832 value = currentvalue
807 if action == 'store': 833 if action == 'store':
808 setattr(self.config, self.option_name(opt, optdict), value) 834 setattr(self.config, self.option_attrname(opt, optdict), value)
809 elif action in ('store_true', 'count'): 835 elif action in ('store_true', 'count'):
810 setattr(self.config, self.option_name(opt, optdict), 0) 836 setattr(self.config, self.option_attrname(opt, optdict), 0)
811 elif action == 'store_false': 837 elif action == 'store_false':
812 setattr(self.config, self.option_name(opt, optdict), 1) 838 setattr(self.config, self.option_attrname(opt, optdict), 1)
813 elif action == 'append': 839 elif action == 'append':
814 opt = self.option_name(opt, optdict) 840 opt = self.option_attrname(opt, optdict)
815 _list = getattr(self.config, opt, None) 841 _list = getattr(self.config, opt, None)
816 if _list is None: 842 if _list is None:
817 if isinstance(value, (list, tuple)): 843 if isinstance(value, (list, tuple)):
818 _list = value 844 _list = value
819 elif value is not None: 845 elif value is not None:
820 _list = [] 846 _list = []
821 _list.append(value) 847 _list.append(value)
822 setattr(self.config, opt, _list) 848 setattr(self.config, opt, _list)
823 elif isinstance(_list, tuple): 849 elif isinstance(_list, tuple):
824 setattr(self.config, opt, _list + (value,)) 850 setattr(self.config, opt, _list + (value,))
825 else: 851 else:
826 _list.append(value) 852 _list.append(value)
827 elif action == 'callback': 853 elif action == 'callback':
828 optdict['callback'](None, opt, value, None) 854 optdict['callback'](None, opt, value, None)
829 else: 855 else:
830 raise UnsupportedAction(action) 856 raise UnsupportedAction(action)
831 857
832 def input_option(self, option, optdict, inputlevel=99): 858 def input_option(self, option, optdict, inputlevel=99):
833 default = self.option_default(option, optdict) 859 default = self.option_default(option, optdict)
834 if default is REQUIRED: 860 if default is REQUIRED:
835 defaultstr = '(required): ' 861 defaultstr = '(required): '
836 elif optdict.get('level', 0) > inputlevel: 862 elif optdict.get('level', 0) > inputlevel:
837 return 863 return
838 elif optdict['type'] == 'password' or default is None: 864 elif optdict['type'] == 'password' or default is None:
839 defaultstr = ': ' 865 defaultstr = ': '
840 else: 866 else:
841 defaultstr = '(default: %s): ' % format_option_value(optdict, defaul t) 867 defaultstr = '(default: %s): ' % format_option_value(optdict, defaul t)
842 print ':%s:' % option 868 print(':%s:' % option)
843 print optdict.get('help') or option 869 print(optdict.get('help') or option)
844 inputfunc = INPUT_FUNCTIONS[optdict['type']] 870 inputfunc = INPUT_FUNCTIONS[optdict['type']]
845 value = inputfunc(optdict, defaultstr) 871 value = inputfunc(optdict, defaultstr)
846 while default is REQUIRED and not value: 872 while default is REQUIRED and not value:
847 print 'please specify a value' 873 print('please specify a value')
848 value = inputfunc(optdict, '%s: ' % option) 874 value = inputfunc(optdict, '%s: ' % option)
849 if value is None and default is not None: 875 if value is None and default is not None:
850 value = default 876 value = default
851 self.set_option(option, value, optdict=optdict) 877 self.set_option(option, value, optdict=optdict)
852 878
853 def get_option_def(self, opt): 879 def get_option_def(self, opt):
854 """return the dictionary defining an option given it's name""" 880 """return the dictionary defining an option given it's name"""
855 assert self.options 881 assert self.options
856 for option in self.options: 882 for option in self.options:
857 if option[0] == opt: 883 if option[0] == opt:
(...skipping 28 matching lines...) Expand all
886 yield None, sections.pop(None) 912 yield None, sections.pop(None)
887 for section, options in sections.items(): 913 for section, options in sections.items():
888 yield section.upper(), options 914 yield section.upper(), options
889 915
890 def options_and_values(self, options=None): 916 def options_and_values(self, options=None):
891 if options is None: 917 if options is None:
892 options = self.options 918 options = self.options
893 for optname, optdict in options: 919 for optname, optdict in options:
894 yield (optname, optdict, self.option_value(optname)) 920 yield (optname, optdict, self.option_value(optname))
895 921
922 # configuration ################################################################
896 923
897 class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn): 924 class ConfigurationMixIn(OptionsManagerMixIn, OptionsProviderMixIn):
898 """basic mixin for simple configurations which don't need the 925 """basic mixin for simple configurations which don't need the
899 manager / providers model 926 manager / providers model
900 """ 927 """
901 def __init__(self, *args, **kwargs): 928 def __init__(self, *args, **kwargs):
902 if not args: 929 if not args:
903 kwargs.setdefault('usage', '') 930 kwargs.setdefault('usage', '')
904 kwargs.setdefault('quiet', 1) 931 kwargs.setdefault('quiet', 1)
905 OptionsManagerMixIn.__init__(self, *args, **kwargs) 932 OptionsManagerMixIn.__init__(self, *args, **kwargs)
906 OptionsProviderMixIn.__init__(self) 933 OptionsProviderMixIn.__init__(self)
907 if not getattr(self, 'option_groups', None): 934 if not getattr(self, 'option_groups', None):
908 self.option_groups = [] 935 self.option_groups = []
909 for option, optdict in self.options: 936 for option, optdict in self.options:
910 try: 937 try:
911 gdef = (optdict['group'].upper(), '') 938 gdef = (optdict['group'].upper(), '')
912 except KeyError: 939 except KeyError:
913 continue 940 continue
914 if not gdef in self.option_groups: 941 if not gdef in self.option_groups:
915 self.option_groups.append(gdef) 942 self.option_groups.append(gdef)
916 self.register_options_provider(self, own_group=0) 943 self.register_options_provider(self, own_group=False)
917 944
918 def register_options(self, options): 945 def register_options(self, options):
919 """add some options to the configuration""" 946 """add some options to the configuration"""
920 options_by_group = {} 947 options_by_group = {}
921 for optname, optdict in options: 948 for optname, optdict in options:
922 options_by_group.setdefault(optdict.get('group', self.name.upper()), []).append((optname, optdict)) 949 options_by_group.setdefault(optdict.get('group', self.name.upper()), []).append((optname, optdict))
923 for group, options in options_by_group.items(): 950 for group, options in options_by_group.items():
924 self.add_option_group(group, None, options, self) 951 self.add_option_group(group, None, options, self)
925 self.options += tuple(options) 952 self.options += tuple(options)
926 953
927 def load_defaults(self): 954 def load_defaults(self):
928 OptionsProviderMixIn.load_defaults(self) 955 OptionsProviderMixIn.load_defaults(self)
929 956
930 def __iter__(self): 957 def __iter__(self):
931 return iter(self.config.__dict__.iteritems()) 958 return iter(self.config.__dict__.iteritems())
932 959
933 def __getitem__(self, key): 960 def __getitem__(self, key):
934 try: 961 try:
935 return getattr(self.config, self.option_name(key)) 962 return getattr(self.config, self.option_attrname(key))
936 except (optparse.OptionValueError, AttributeError): 963 except (optik_ext.OptionValueError, AttributeError):
937 raise KeyError(key) 964 raise KeyError(key)
938 965
939 def __setitem__(self, key, value): 966 def __setitem__(self, key, value):
940 self.set_option(key, value) 967 self.set_option(key, value)
941 968
942 def get(self, key, default=None): 969 def get(self, key, default=None):
943 try: 970 try:
944 return getattr(self.config, self.option_name(key)) 971 return getattr(self.config, self.option_attrname(key))
945 except (OptionError, AttributeError): 972 except (OptionError, AttributeError):
946 return default 973 return default
947 974
948 975
949 class Configuration(ConfigurationMixIn): 976 class Configuration(ConfigurationMixIn):
950 """class for simple configurations which don't need the 977 """class for simple configurations which don't need the
951 manager / providers model and prefer delegation to inheritance 978 manager / providers model and prefer delegation to inheritance
952 979
953 configuration values are accessible through a dict like interface 980 configuration values are accessible through a dict like interface
954 """ 981 """
(...skipping 15 matching lines...) Expand all
970 """ 997 """
971 def __init__(self, provider): 998 def __init__(self, provider):
972 self.config = provider 999 self.config = provider
973 1000
974 def __getattr__(self, key): 1001 def __getattr__(self, key):
975 return getattr(self.config, key) 1002 return getattr(self.config, key)
976 1003
977 def __getitem__(self, key): 1004 def __getitem__(self, key):
978 provider = self.config._all_options[key] 1005 provider = self.config._all_options[key]
979 try: 1006 try:
980 return getattr(provider.config, provider.option_name(key)) 1007 return getattr(provider.config, provider.option_attrname(key))
981 except AttributeError: 1008 except AttributeError:
982 raise KeyError(key) 1009 raise KeyError(key)
983 1010
984 def __setitem__(self, key, value): 1011 def __setitem__(self, key, value):
985 self.config.global_set_option(self.config.option_name(key), value) 1012 self.config.global_set_option(self.config.option_attrname(key), value)
986 1013
987 def get(self, key, default=None): 1014 def get(self, key, default=None):
988 provider = self.config._all_options[key] 1015 provider = self.config._all_options[key]
989 try: 1016 try:
990 return getattr(provider.config, provider.option_name(key)) 1017 return getattr(provider.config, provider.option_attrname(key))
991 except AttributeError: 1018 except AttributeError:
992 return default 1019 return default
993 1020
1021 # other functions ##############################################################
994 1022
995 def read_old_config(newconfig, changes, configfile): 1023 def read_old_config(newconfig, changes, configfile):
996 """initialize newconfig from a deprecated configuration file 1024 """initialize newconfig from a deprecated configuration file
997 1025
998 possible changes: 1026 possible changes:
999 * ('renamed', oldname, newname) 1027 * ('renamed', oldname, newname)
1000 * ('moved', option, oldgroup, newgroup) 1028 * ('moved', option, oldgroup, newgroup)
1001 * ('typechanged', option, oldtype, newvalue) 1029 * ('typechanged', option, oldtype, newvalue)
1002 """ 1030 """
1003 # build an index of changes 1031 # build an index of changes
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 done.add(newname) 1076 done.add(newname)
1049 elif action[0] == 'typechanged': 1077 elif action[0] == 'typechanged':
1050 optname, oldtype, newvalue = action[1:] 1078 optname, oldtype, newvalue = action[1:]
1051 newconfig[optname] = newvalue 1079 newconfig[optname] = newvalue
1052 done.add(optname) 1080 done.add(optname)
1053 for optname, optdef in newconfig.options: 1081 for optname, optdef in newconfig.options:
1054 if optdef.get('type') and not optname in done: 1082 if optdef.get('type') and not optname in done:
1055 newconfig.set_option(optname, oldconfig[optname], optdict=optdef) 1083 newconfig.set_option(optname, oldconfig[optname], optdict=optdef)
1056 1084
1057 1085
1058 def merge_options(options): 1086 def merge_options(options, optgroup=None):
1059 """preprocess options to remove duplicate""" 1087 """preprocess a list of options and remove duplicates, returning a new list
1088 (tuple actually) of options.
1089
1090 Options dictionaries are copied to avoid later side-effect. Also, if
1091 `otpgroup` argument is specified, ensure all options are in the given group.
1092 """
1060 alloptions = {} 1093 alloptions = {}
1061 options = list(options) 1094 options = list(options)
1062 for i in range(len(options)-1, -1, -1): 1095 for i in range(len(options)-1, -1, -1):
1063 optname, optdict = options[i] 1096 optname, optdict = options[i]
1064 if optname in alloptions: 1097 if optname in alloptions:
1065 options.pop(i) 1098 options.pop(i)
1066 alloptions[optname].update(optdict) 1099 alloptions[optname].update(optdict)
1067 else: 1100 else:
1101 optdict = optdict.copy()
1102 options[i] = (optname, optdict)
1068 alloptions[optname] = optdict 1103 alloptions[optname] = optdict
1104 if optgroup is not None:
1105 alloptions[optname]['group'] = optgroup
1069 return tuple(options) 1106 return tuple(options)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698