ConfigParser.py (15922B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\ConfigParser.py 2 try: 3 from collections import OrderedDict as _default_dict 4 except ImportError: 5 _default_dict = dict 6 7 import re 8 __all__ = ['NoSectionError', 9 'DuplicateSectionError', 10 'NoOptionError', 11 'InterpolationError', 12 'InterpolationDepthError', 13 'InterpolationSyntaxError', 14 'ParsingError', 15 'MissingSectionHeaderError', 16 'ConfigParser', 17 'SafeConfigParser', 18 'RawConfigParser', 19 'DEFAULTSECT', 20 'MAX_INTERPOLATION_DEPTH'] 21 DEFAULTSECT = 'DEFAULT' 22 MAX_INTERPOLATION_DEPTH = 10 23 24 class Error(Exception): 25 26 def _get_message(self): 27 return self.__message 28 29 def _set_message(self, value): 30 self.__message = value 31 32 message = property(_get_message, _set_message) 33 34 def __init__(self, msg = ''): 35 self.message = msg 36 Exception.__init__(self, msg) 37 38 def __repr__(self): 39 return self.message 40 41 __str__ = __repr__ 42 43 44 class NoSectionError(Error): 45 46 def __init__(self, section): 47 Error.__init__(self, 'No section: %r' % (section,)) 48 self.section = section 49 50 51 class DuplicateSectionError(Error): 52 53 def __init__(self, section): 54 Error.__init__(self, 'Section %r already exists' % section) 55 self.section = section 56 57 58 class NoOptionError(Error): 59 60 def __init__(self, option, section): 61 Error.__init__(self, 'No option %r in section: %r' % (option, section)) 62 self.option = option 63 self.section = section 64 65 66 class InterpolationError(Error): 67 68 def __init__(self, option, section, msg): 69 Error.__init__(self, msg) 70 self.option = option 71 self.section = section 72 73 74 class InterpolationMissingOptionError(InterpolationError): 75 76 def __init__(self, option, section, rawval, reference): 77 msg = 'Bad value substitution:\n\tsection: [%s]\n\toption : %s\n\tkey : %s\n\trawval : %s\n' % (section, 78 option, 79 reference, 80 rawval) 81 InterpolationError.__init__(self, option, section, msg) 82 self.reference = reference 83 84 85 class InterpolationSyntaxError(InterpolationError): 86 pass 87 88 89 class InterpolationDepthError(InterpolationError): 90 91 def __init__(self, option, section, rawval): 92 msg = 'Value interpolation too deeply recursive:\n\tsection: [%s]\n\toption : %s\n\trawval : %s\n' % (section, option, rawval) 93 InterpolationError.__init__(self, option, section, msg) 94 95 96 class ParsingError(Error): 97 98 def __init__(self, filename): 99 Error.__init__(self, 'File contains parsing errors: %s' % filename) 100 self.filename = filename 101 self.errors = [] 102 103 def append(self, lineno, line): 104 self.errors.append((lineno, line)) 105 self.message += '\n\t[line %2d]: %s' % (lineno, line) 106 107 108 class MissingSectionHeaderError(ParsingError): 109 110 def __init__(self, filename, lineno, line): 111 Error.__init__(self, 'File contains no section headers.\nfile: %s, line: %d\n%r' % (filename, lineno, line)) 112 self.filename = filename 113 self.lineno = lineno 114 self.line = line 115 116 117 class RawConfigParser(): 118 119 def __init__(self, defaults = None, dict_type = _default_dict, allow_no_value = False): 120 self._dict = dict_type 121 self._sections = self._dict() 122 self._defaults = self._dict() 123 if allow_no_value: 124 self._optcre = self.OPTCRE_NV 125 else: 126 self._optcre = self.OPTCRE 127 if defaults: 128 for key, value in defaults.items(): 129 self._defaults[self.optionxform(key)] = value 130 131 def defaults(self): 132 return self._defaults 133 134 def sections(self): 135 return self._sections.keys() 136 137 def add_section(self, section): 138 if section.lower() == 'default': 139 raise ValueError, 'Invalid section name: %s' % section 140 if section in self._sections: 141 raise DuplicateSectionError(section) 142 self._sections[section] = self._dict() 143 144 def has_section(self, section): 145 return section in self._sections 146 147 def options(self, section): 148 try: 149 opts = self._sections[section].copy() 150 except KeyError: 151 raise NoSectionError(section) 152 153 opts.update(self._defaults) 154 if '__name__' in opts: 155 del opts['__name__'] 156 return opts.keys() 157 158 def read(self, filenames): 159 if isinstance(filenames, basestring): 160 filenames = [filenames] 161 read_ok = [] 162 for filename in filenames: 163 try: 164 fp = open(filename) 165 except IOError: 166 continue 167 168 self._read(fp, filename) 169 fp.close() 170 read_ok.append(filename) 171 172 return read_ok 173 174 def readfp(self, fp, filename = None): 175 if filename is None: 176 try: 177 filename = fp.name 178 except AttributeError: 179 filename = '<???>' 180 181 self._read(fp, filename) 182 183 def get(self, section, option): 184 opt = self.optionxform(option) 185 if section not in self._sections: 186 if section != DEFAULTSECT: 187 raise NoSectionError(section) 188 if opt in self._defaults: 189 return self._defaults[opt] 190 raise NoOptionError(option, section) 191 else: 192 if opt in self._sections[section]: 193 return self._sections[section][opt] 194 if opt in self._defaults: 195 return self._defaults[opt] 196 raise NoOptionError(option, section) 197 198 def items(self, section): 199 try: 200 d2 = self._sections[section] 201 except KeyError: 202 if section != DEFAULTSECT: 203 raise NoSectionError(section) 204 d2 = self._dict() 205 206 d = self._defaults.copy() 207 d.update(d2) 208 if '__name__' in d: 209 del d['__name__'] 210 return d.items() 211 212 def _get(self, section, conv, option): 213 return conv(self.get(section, option)) 214 215 def getint(self, section, option): 216 return self._get(section, int, option) 217 218 def getfloat(self, section, option): 219 return self._get(section, float, option) 220 221 _boolean_states = {'1': True, 222 'yes': True, 223 'true': True, 224 'on': True, 225 '0': False, 226 'no': False, 227 'false': False, 228 'off': False} 229 230 def getboolean(self, section, option): 231 v = self.get(section, option) 232 if v.lower() not in self._boolean_states: 233 raise ValueError, 'Not a boolean: %s' % v 234 return self._boolean_states[v.lower()] 235 236 def optionxform(self, optionstr): 237 return optionstr.lower() 238 239 def has_option(self, section, option): 240 if not section or section == DEFAULTSECT: 241 option = self.optionxform(option) 242 return option in self._defaults 243 elif section not in self._sections: 244 return False 245 else: 246 option = self.optionxform(option) 247 return option in self._sections[section] or option in self._defaults 248 249 def set(self, section, option, value = None): 250 if not section or section == DEFAULTSECT: 251 sectdict = self._defaults 252 else: 253 try: 254 sectdict = self._sections[section] 255 except KeyError: 256 raise NoSectionError(section) 257 258 sectdict[self.optionxform(option)] = value 259 260 def write(self, fp): 261 if self._defaults: 262 fp.write('[%s]\n' % DEFAULTSECT) 263 for key, value in self._defaults.items(): 264 fp.write('%s = %s\n' % (key, str(value).replace('\n', '\n\t'))) 265 266 fp.write('\n') 267 for section in self._sections: 268 fp.write('[%s]\n' % section) 269 for key, value in self._sections[section].items(): 270 if key == '__name__': 271 continue 272 if value is not None or self._optcre == self.OPTCRE: 273 key = ' = '.join((key, str(value).replace('\n', '\n\t'))) 274 fp.write('%s\n' % key) 275 276 fp.write('\n') 277 278 def remove_option(self, section, option): 279 if not section or section == DEFAULTSECT: 280 sectdict = self._defaults 281 else: 282 try: 283 sectdict = self._sections[section] 284 except KeyError: 285 raise NoSectionError(section) 286 287 option = self.optionxform(option) 288 existed = option in sectdict 289 if existed: 290 del sectdict[option] 291 return existed 292 293 def remove_section(self, section): 294 existed = section in self._sections 295 if existed: 296 del self._sections[section] 297 return existed 298 299 SECTCRE = re.compile('\\[(?P<header>[^]]+)\\]') 300 OPTCRE = re.compile('(?P<option>[^:=\\s][^:=]*)\\s*(?P<vi>[:=])\\s*(?P<value>.*)$') 301 OPTCRE_NV = re.compile('(?P<option>[^:=\\s][^:=]*)\\s*(?:(?P<vi>[:=])\\s*(?P<value>.*))?$') 302 303 def _read(self, fp, fpname): 304 cursect = None 305 optname = None 306 lineno = 0 307 e = None 308 while True: 309 line = fp.readline() 310 if not line: 311 break 312 lineno = lineno + 1 313 if line.strip() == '' or line[0] in '#;': 314 continue 315 if line.split(None, 1)[0].lower() == 'rem' and line[0] in 'rR': 316 continue 317 if line[0].isspace() and cursect is not None and optname: 318 value = line.strip() 319 if value: 320 cursect[optname].append(value) 321 else: 322 mo = self.SECTCRE.match(line) 323 if mo: 324 sectname = mo.group('header') 325 if sectname in self._sections: 326 cursect = self._sections[sectname] 327 elif sectname == DEFAULTSECT: 328 cursect = self._defaults 329 else: 330 cursect = self._dict() 331 cursect['__name__'] = sectname 332 self._sections[sectname] = cursect 333 optname = None 334 elif cursect is None: 335 raise MissingSectionHeaderError(fpname, lineno, line) 336 else: 337 mo = self._optcre.match(line) 338 if mo: 339 optname, vi, optval = mo.group('option', 'vi', 'value') 340 optname = self.optionxform(optname.rstrip()) 341 if optval is not None: 342 if vi in ('=', ':') and ';' in optval: 343 pos = optval.find(';') 344 if pos != -1 and optval[pos - 1].isspace(): 345 optval = optval[:pos] 346 optval = optval.strip() 347 if optval == '""': 348 optval = '' 349 cursect[optname] = [optval] 350 else: 351 cursect[optname] = optval 352 else: 353 if not e: 354 e = ParsingError(fpname) 355 e.append(lineno, repr(line)) 356 357 if e: 358 raise e 359 all_sections = [self._defaults] 360 all_sections.extend(self._sections.values()) 361 for options in all_sections: 362 for name, val in options.items(): 363 if isinstance(val, list): 364 options[name] = '\n'.join(val) 365 366 367 class ConfigParser(RawConfigParser): 368 369 def get(self, section, option, raw = False, vars = None): 370 d = self._defaults.copy() 371 try: 372 d.update(self._sections[section]) 373 except KeyError: 374 if section != DEFAULTSECT: 375 raise NoSectionError(section) 376 377 if vars: 378 for key, value in vars.items(): 379 d[self.optionxform(key)] = value 380 381 option = self.optionxform(option) 382 try: 383 value = d[option] 384 except KeyError: 385 raise NoOptionError(option, section) 386 387 if raw or value is None: 388 return value 389 else: 390 return self._interpolate(section, option, value, d) 391 392 def items(self, section, raw = False, vars = None): 393 d = self._defaults.copy() 394 try: 395 d.update(self._sections[section]) 396 except KeyError: 397 if section != DEFAULTSECT: 398 raise NoSectionError(section) 399 400 if vars: 401 for key, value in vars.items(): 402 d[self.optionxform(key)] = value 403 404 options = d.keys() 405 if '__name__' in options: 406 options.remove('__name__') 407 if raw: 408 return [ (option, d[option]) for option in options ] 409 else: 410 return [ (option, self._interpolate(section, option, d[option], d)) for option in options ] 411 412 def _interpolate(self, section, option, rawval, vars): 413 value = rawval 414 depth = MAX_INTERPOLATION_DEPTH 415 while depth: 416 depth -= 1 417 if value and '%(' in value: 418 value = self._KEYCRE.sub(self._interpolation_replace, value) 419 try: 420 value = value % vars 421 except KeyError as e: 422 raise InterpolationMissingOptionError(option, section, rawval, e.args[0]) 423 424 else: 425 break 426 427 if value and '%(' in value: 428 raise InterpolationDepthError(option, section, rawval) 429 return value 430 431 _KEYCRE = re.compile('%\\(([^)]*)\\)s|.') 432 433 def _interpolation_replace(self, match): 434 s = match.group(1) 435 if s is None: 436 return match.group() 437 else: 438 return '%%(%s)s' % self.optionxform(s) 439 440 441 class SafeConfigParser(ConfigParser): 442 443 def _interpolate(self, section, option, rawval, vars): 444 L = [] 445 self._interpolate_some(option, L, rawval, section, vars, 1) 446 return ''.join(L) 447 448 _interpvar_re = re.compile('%\\(([^)]+)\\)s') 449 450 def _interpolate_some(self, option, accum, rest, section, map, depth): 451 if depth > MAX_INTERPOLATION_DEPTH: 452 raise InterpolationDepthError(option, section, rest) 453 while rest: 454 p = rest.find('%') 455 if p < 0: 456 accum.append(rest) 457 return 458 if p > 0: 459 accum.append(rest[:p]) 460 rest = rest[p:] 461 c = rest[1:2] 462 if c == '%': 463 accum.append('%') 464 rest = rest[2:] 465 elif c == '(': 466 m = self._interpvar_re.match(rest) 467 if m is None: 468 raise InterpolationSyntaxError(option, section, 'bad interpolation variable reference %r' % rest) 469 var = self.optionxform(m.group(1)) 470 rest = rest[m.end():] 471 try: 472 v = map[var] 473 except KeyError: 474 raise InterpolationMissingOptionError(option, section, rest, var) 475 476 if '%' in v: 477 self._interpolate_some(option, accum, v, section, map, depth + 1) 478 else: 479 accum.append(v) 480 else: 481 raise InterpolationSyntaxError(option, section, "'%%' must be followed by '%%' or '(', found: %r" % (rest,)) 482 483 def set(self, section, option, value = None): 484 if self._optcre is self.OPTCRE or value: 485 if not isinstance(value, basestring): 486 raise TypeError('option values must be strings') 487 if value is not None: 488 tmp_value = value.replace('%%', '') 489 tmp_value = self._interpvar_re.sub('', tmp_value) 490 if '%' in tmp_value: 491 raise ValueError('invalid interpolation syntax in %r at position %d' % (value, tmp_value.find('%'))) 492 ConfigParser.set(self, section, option, value)