1"""Configuration file parser. 2 3A setup file consists of sections, lead by a "[section]" header, 4and followed by "name: value" entries, with continuations and such in 5the style of RFC 822. 6 7The option values can contain format strings which refer to other values in 8the same section, or values in a special [DEFAULT] section. 9 10For example: 11 12 something: %(dir)s/whatever 13 14would resolve the "%(dir)s" to the value of dir. All reference 15expansions are done late, on demand. 16 17Intrinsic defaults can be specified by passing them into the 18ConfigParser constructor as a dictionary. 19 20class: 21 22ConfigParser -- responsible for parsing a list of 23 configuration files, and managing the parsed database. 24 25 methods: 26 27 __init__(defaults=None) 28 create the parser and specify a dictionary of intrinsic defaults. The 29 keys must be strings, the values must be appropriate for %()s string 30 interpolation. Note that `__name__' is always an intrinsic default; 31 its value is the section's name. 32 33 sections() 34 return all the configuration section names, sans DEFAULT 35 36 has_section(section) 37 return whether the given section exists 38 39 has_option(section, option) 40 return whether the given option exists in the given section 41 42 options(section) 43 return list of configuration options for the named section 44 45 read(filenames) 46 read and parse the list of named configuration files, given by 47 name. A single filename is also allowed. Non-existing files 48 are ignored. Return list of successfully read files. 49 50 readfp(fp, filename=None) 51 read and parse one configuration file, given as a file object. 52 The filename defaults to fp.name; it is only used in error 53 messages (if fp has no `name' attribute, the string `<???>' is used). 54 55 get(section, option, raw=False, vars=None) 56 return a string value for the named option. All % interpolations are 57 expanded in the return values, based on the defaults passed into the 58 constructor and the DEFAULT section. Additional substitutions may be 59 provided using the `vars' argument, which must be a dictionary whose 60 contents override any pre-existing defaults. 61 62 getint(section, options) 63 like get(), but convert value to an integer 64 65 getfloat(section, options) 66 like get(), but convert value to a float 67 68 getboolean(section, options) 69 like get(), but convert value to a boolean (currently case 70 insensitively defined as 0, false, no, off for False, and 1, true, 71 yes, on for True). Returns False or True. 72 73 items(section, raw=False, vars=None) 74 return a list of tuples with (name, value) for each option 75 in the section. 76 77 remove_section(section) 78 remove the given file section and all its options 79 80 remove_option(section, option) 81 remove the given option from the given section 82 83 set(section, option, value) 84 set the given option 85 86 write(fp) 87 write the configuration state in .ini format 88""" 89 90try: 91 from collections import OrderedDict as _default_dict 92except ImportError: 93 # fallback for setup.py which hasn't yet built _collections 94 _default_dict = dict 95 96import re 97 98__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError", 99 "InterpolationError", "InterpolationDepthError", 100 "InterpolationSyntaxError", "ParsingError", 101 "MissingSectionHeaderError", 102 "ConfigParser", "SafeConfigParser", "RawConfigParser", 103 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] 104 105DEFAULTSECT = "DEFAULT" 106 107MAX_INTERPOLATION_DEPTH = 10 108 109 110 111# exception classes 112class Error(Exception): 113 """Base class for ConfigParser exceptions.""" 114 115 def _get_message(self): 116 """Getter for 'message'; needed only to override deprecation in 117 BaseException.""" 118 return self.__message 119 120 def _set_message(self, value): 121 """Setter for 'message'; needed only to override deprecation in 122 BaseException.""" 123 self.__message = value 124 125 # BaseException.message has been deprecated since Python 2.6. To prevent 126 # DeprecationWarning from popping up over this pre-existing attribute, use 127 # a new property that takes lookup precedence. 128 message = property(_get_message, _set_message) 129 130 def __init__(self, msg=''): 131 self.message = msg 132 Exception.__init__(self, msg) 133 134 def __repr__(self): 135 return self.message 136 137 __str__ = __repr__ 138 139class NoSectionError(Error): 140 """Raised when no section matches a requested option.""" 141 142 def __init__(self, section): 143 Error.__init__(self, 'No section: %r' % (section,)) 144 self.section = section 145 146class DuplicateSectionError(Error): 147 """Raised when a section is multiply-created.""" 148 149 def __init__(self, section): 150 Error.__init__(self, "Section %r already exists" % section) 151 self.section = section 152 153class NoOptionError(Error): 154 """A requested option was not found.""" 155 156 def __init__(self, option, section): 157 Error.__init__(self, "No option %r in section: %r" % 158 (option, section)) 159 self.option = option 160 self.section = section 161 162class InterpolationError(Error): 163 """Base class for interpolation-related exceptions.""" 164 165 def __init__(self, option, section, msg): 166 Error.__init__(self, msg) 167 self.option = option 168 self.section = section 169 170class InterpolationMissingOptionError(InterpolationError): 171 """A string substitution required a setting which was not available.""" 172 173 def __init__(self, option, section, rawval, reference): 174 msg = ("Bad value substitution:\n" 175 "\tsection: [%s]\n" 176 "\toption : %s\n" 177 "\tkey : %s\n" 178 "\trawval : %s\n" 179 % (section, option, reference, rawval)) 180 InterpolationError.__init__(self, option, section, msg) 181 self.reference = reference 182 183class InterpolationSyntaxError(InterpolationError): 184 """Raised when the source text into which substitutions are made 185 does not conform to the required syntax.""" 186 187class InterpolationDepthError(InterpolationError): 188 """Raised when substitutions are nested too deeply.""" 189 190 def __init__(self, option, section, rawval): 191 msg = ("Value interpolation too deeply recursive:\n" 192 "\tsection: [%s]\n" 193 "\toption : %s\n" 194 "\trawval : %s\n" 195 % (section, option, rawval)) 196 InterpolationError.__init__(self, option, section, msg) 197 198class ParsingError(Error): 199 """Raised when a configuration file does not follow legal syntax.""" 200 201 def __init__(self, filename): 202 Error.__init__(self, 'File contains parsing errors: %s' % filename) 203 self.filename = filename 204 self.errors = [] 205 206 def append(self, lineno, line): 207 self.errors.append((lineno, line)) 208 self.message += '\n\t[line %2d]: %s' % (lineno, line) 209 210class MissingSectionHeaderError(ParsingError): 211 """Raised when a key-value pair is found before any section header.""" 212 213 def __init__(self, filename, lineno, line): 214 Error.__init__( 215 self, 216 'File contains no section headers.\nfile: %s, line: %d\n%r' % 217 (filename, lineno, line)) 218 self.filename = filename 219 self.lineno = lineno 220 self.line = line 221 222 223class RawConfigParser: 224 def __init__(self, defaults=None, dict_type=_default_dict, 225 allow_no_value=False): 226 self._dict = dict_type 227 self._sections = self._dict() 228 self._defaults = self._dict() 229 if allow_no_value: 230 self._optcre = self.OPTCRE_NV 231 else: 232 self._optcre = self.OPTCRE 233 if defaults: 234 for key, value in defaults.items(): 235 self._defaults[self.optionxform(key)] = value 236 237 def defaults(self): 238 return self._defaults 239 240 def sections(self): 241 """Return a list of section names, excluding [DEFAULT]""" 242 # self._sections will never have [DEFAULT] in it 243 return self._sections.keys() 244 245 def add_section(self, section): 246 """Create a new section in the configuration. 247 248 Raise DuplicateSectionError if a section by the specified name 249 already exists. Raise ValueError if name is DEFAULT or any of it's 250 case-insensitive variants. 251 """ 252 if section.lower() == "default": 253 raise ValueError, 'Invalid section name: %s' % section 254 255 if section in self._sections: 256 raise DuplicateSectionError(section) 257 self._sections[section] = self._dict() 258 259 def has_section(self, section): 260 """Indicate whether the named section is present in the configuration. 261 262 The DEFAULT section is not acknowledged. 263 """ 264 return section in self._sections 265 266 def options(self, section): 267 """Return a list of option names for the given section name.""" 268 try: 269 opts = self._sections[section].copy() 270 except KeyError: 271 raise NoSectionError(section) 272 opts.update(self._defaults) 273 if '__name__' in opts: 274 del opts['__name__'] 275 return opts.keys() 276 277 def read(self, filenames): 278 """Read and parse a filename or a list of filenames. 279 280 Files that cannot be opened are silently ignored; this is 281 designed so that you can specify a list of potential 282 configuration file locations (e.g. current directory, user's 283 home directory, systemwide directory), and all existing 284 configuration files in the list will be read. A single 285 filename may also be given. 286 287 Return list of successfully read files. 288 """ 289 if isinstance(filenames, basestring): 290 filenames = [filenames] 291 read_ok = [] 292 for filename in filenames: 293 try: 294 fp = open(filename) 295 except IOError: 296 continue 297 self._read(fp, filename) 298 fp.close() 299 read_ok.append(filename) 300 return read_ok 301 302 def readfp(self, fp, filename=None): 303 """Like read() but the argument must be a file-like object. 304 305 The `fp' argument must have a `readline' method. Optional 306 second argument is the `filename', which if not given, is 307 taken from fp.name. If fp has no `name' attribute, `<???>' is 308 used. 309 310 """ 311 if filename is None: 312 try: 313 filename = fp.name 314 except AttributeError: 315 filename = '<???>' 316 self._read(fp, filename) 317 318 def get(self, section, option): 319 opt = self.optionxform(option) 320 if section not in self._sections: 321 if section != DEFAULTSECT: 322 raise NoSectionError(section) 323 if opt in self._defaults: 324 return self._defaults[opt] 325 else: 326 raise NoOptionError(option, section) 327 elif opt in self._sections[section]: 328 return self._sections[section][opt] 329 elif opt in self._defaults: 330 return self._defaults[opt] 331 else: 332 raise NoOptionError(option, section) 333 334 def items(self, section): 335 try: 336 d2 = self._sections[section] 337 except KeyError: 338 if section != DEFAULTSECT: 339 raise NoSectionError(section) 340 d2 = self._dict() 341 d = self._defaults.copy() 342 d.update(d2) 343 if "__name__" in d: 344 del d["__name__"] 345 return d.items() 346 347 def _get(self, section, conv, option): 348 return conv(self.get(section, option)) 349 350 def getint(self, section, option): 351 return self._get(section, int, option) 352 353 def getfloat(self, section, option): 354 return self._get(section, float, option) 355 356 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True, 357 '0': False, 'no': False, 'false': False, 'off': False} 358 359 def getboolean(self, section, option): 360 v = self.get(section, option) 361 if v.lower() not in self._boolean_states: 362 raise ValueError, 'Not a boolean: %s' % v 363 return self._boolean_states[v.lower()] 364 365 def optionxform(self, optionstr): 366 return optionstr.lower() 367 368 def has_option(self, section, option): 369 """Check for the existence of a given option in a given section.""" 370 if not section or section == DEFAULTSECT: 371 option = self.optionxform(option) 372 return option in self._defaults 373 elif section not in self._sections: 374 return False 375 else: 376 option = self.optionxform(option) 377 return (option in self._sections[section] 378 or option in self._defaults) 379 380 def set(self, section, option, value=None): 381 """Set an option.""" 382 if not section or section == DEFAULTSECT: 383 sectdict = self._defaults 384 else: 385 try: 386 sectdict = self._sections[section] 387 except KeyError: 388 raise NoSectionError(section) 389 sectdict[self.optionxform(option)] = value 390 391 def write(self, fp): 392 """Write an .ini-format representation of the configuration state.""" 393 if self._defaults: 394 fp.write("[%s]\n" % DEFAULTSECT) 395 for (key, value) in self._defaults.items(): 396 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) 397 fp.write("\n") 398 for section in self._sections: 399 fp.write("[%s]\n" % section) 400 for (key, value) in self._sections[section].items(): 401 if key == "__name__": 402 continue 403 if (value is not None) or (self._optcre == self.OPTCRE): 404 key = " = ".join((key, str(value).replace('\n', '\n\t'))) 405 fp.write("%s\n" % (key)) 406 fp.write("\n") 407 408 def remove_option(self, section, option): 409 """Remove an option.""" 410 if not section or section == DEFAULTSECT: 411 sectdict = self._defaults 412 else: 413 try: 414 sectdict = self._sections[section] 415 except KeyError: 416 raise NoSectionError(section) 417 option = self.optionxform(option) 418 existed = option in sectdict 419 if existed: 420 del sectdict[option] 421 return existed 422 423 def remove_section(self, section): 424 """Remove a file section.""" 425 existed = section in self._sections 426 if existed: 427 del self._sections[section] 428 return existed 429 430 # 431 # Regular expressions for parsing section headers and options. 432 # 433 SECTCRE = re.compile( 434 r'\[' # [ 435 r'(?P<header>[^]]+)' # very permissive! 436 r'\]' # ] 437 ) 438 OPTCRE = re.compile( 439 r'(?P<option>[^:=\s][^:=]*)' # very permissive! 440 r'\s*(?P<vi>[:=])\s*' # any number of space/tab, 441 # followed by separator 442 # (either : or =), followed 443 # by any # space/tab 444 r'(?P<value>.*)$' # everything up to eol 445 ) 446 OPTCRE_NV = re.compile( 447 r'(?P<option>[^:=\s][^:=]*)' # very permissive! 448 r'\s*(?:' # any number of space/tab, 449 r'(?P<vi>[:=])\s*' # optionally followed by 450 # separator (either : or 451 # =), followed by any # 452 # space/tab 453 r'(?P<value>.*))?$' # everything up to eol 454 ) 455 456 def _read(self, fp, fpname): 457 """Parse a sectioned setup file. 458 459 The sections in setup file contains a title line at the top, 460 indicated by a name in square brackets (`[]'), plus key/value 461 options lines, indicated by `name: value' format lines. 462 Continuations are represented by an embedded newline then 463 leading whitespace. Blank lines, lines beginning with a '#', 464 and just about everything else are ignored. 465 """ 466 cursect = None # None, or a dictionary 467 optname = None 468 lineno = 0 469 e = None # None, or an exception 470 while True: 471 line = fp.readline() 472 if not line: 473 break 474 lineno = lineno + 1 475 # comment or blank line? 476 if line.strip() == '' or line[0] in '#;': 477 continue 478 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": 479 # no leading whitespace 480 continue 481 # continuation line? 482 if line[0].isspace() and cursect is not None and optname: 483 value = line.strip() 484 if value: 485 cursect[optname].append(value) 486 # a section header or option header? 487 else: 488 # is it a section header? 489 mo = self.SECTCRE.match(line) 490 if mo: 491 sectname = mo.group('header') 492 if sectname in self._sections: 493 cursect = self._sections[sectname] 494 elif sectname == DEFAULTSECT: 495 cursect = self._defaults 496 else: 497 cursect = self._dict() 498 cursect['__name__'] = sectname 499 self._sections[sectname] = cursect 500 # So sections can't start with a continuation line 501 optname = None 502 # no section header in the file? 503 elif cursect is None: 504 raise MissingSectionHeaderError(fpname, lineno, line) 505 # an option line? 506 else: 507 mo = self._optcre.match(line) 508 if mo: 509 optname, vi, optval = mo.group('option', 'vi', 'value') 510 optname = self.optionxform(optname.rstrip()) 511 # This check is fine because the OPTCRE cannot 512 # match if it would set optval to None 513 if optval is not None: 514 if vi in ('=', ':') and ';' in optval: 515 # ';' is a comment delimiter only if it follows 516 # a spacing character 517 pos = optval.find(';') 518 if pos != -1 and optval[pos-1].isspace(): 519 optval = optval[:pos] 520 optval = optval.strip() 521 # allow empty values 522 if optval == '""': 523 optval = '' 524 cursect[optname] = [optval] 525 else: 526 # valueless option handling 527 cursect[optname] = optval 528 else: 529 # a non-fatal parsing error occurred. set up the 530 # exception but keep going. the exception will be 531 # raised at the end of the file and will contain a 532 # list of all bogus lines 533 if not e: 534 e = ParsingError(fpname) 535 e.append(lineno, repr(line)) 536 # if any parsing errors occurred, raise an exception 537 if e: 538 raise e 539 540 # join the multi-line values collected while reading 541 all_sections = [self._defaults] 542 all_sections.extend(self._sections.values()) 543 for options in all_sections: 544 for name, val in options.items(): 545 if isinstance(val, list): 546 options[name] = '\n'.join(val) 547 548import UserDict as _UserDict 549 550class _Chainmap(_UserDict.DictMixin): 551 """Combine multiple mappings for successive lookups. 552 553 For example, to emulate Python's normal lookup sequence: 554 555 import __builtin__ 556 pylookup = _Chainmap(locals(), globals(), vars(__builtin__)) 557 """ 558 559 def __init__(self, *maps): 560 self._maps = maps 561 562 def __getitem__(self, key): 563 for mapping in self._maps: 564 try: 565 return mapping[key] 566 except KeyError: 567 pass 568 raise KeyError(key) 569 570 def keys(self): 571 result = [] 572 seen = set() 573 for mapping in self_maps: 574 for key in mapping: 575 if key not in seen: 576 result.append(key) 577 seen.add(key) 578 return result 579 580class ConfigParser(RawConfigParser): 581 582 def get(self, section, option, raw=False, vars=None): 583 """Get an option value for a given section. 584 585 If `vars' is provided, it must be a dictionary. The option is looked up 586 in `vars' (if provided), `section', and in `defaults' in that order. 587 588 All % interpolations are expanded in the return values, unless the 589 optional argument `raw' is true. Values for interpolation keys are 590 looked up in the same manner as the option. 591 592 The section DEFAULT is special. 593 """ 594 sectiondict = {} 595 try: 596 sectiondict = self._sections[section] 597 except KeyError: 598 if section != DEFAULTSECT: 599 raise NoSectionError(section) 600 # Update with the entry specific variables 601 vardict = {} 602 if vars: 603 for key, value in vars.items(): 604 vardict[self.optionxform(key)] = value 605 d = _Chainmap(vardict, sectiondict, self._defaults) 606 option = self.optionxform(option) 607 try: 608 value = d[option] 609 except KeyError: 610 raise NoOptionError(option, section) 611 612 if raw or value is None: 613 return value 614 else: 615 return self._interpolate(section, option, value, d) 616 617 def items(self, section, raw=False, vars=None): 618 """Return a list of tuples with (name, value) for each option 619 in the section. 620 621 All % interpolations are expanded in the return values, based on the 622 defaults passed into the constructor, unless the optional argument 623 `raw' is true. Additional substitutions may be provided using the 624 `vars' argument, which must be a dictionary whose contents overrides 625 any pre-existing defaults. 626 627 The section DEFAULT is special. 628 """ 629 d = self._defaults.copy() 630 try: 631 d.update(self._sections[section]) 632 except KeyError: 633 if section != DEFAULTSECT: 634 raise NoSectionError(section) 635 # Update with the entry specific variables 636 if vars: 637 for key, value in vars.items(): 638 d[self.optionxform(key)] = value 639 options = d.keys() 640 if "__name__" in options: 641 options.remove("__name__") 642 if raw: 643 return [(option, d[option]) 644 for option in options] 645 else: 646 return [(option, self._interpolate(section, option, d[option], d)) 647 for option in options] 648 649 def _interpolate(self, section, option, rawval, vars): 650 # do the string interpolation 651 value = rawval 652 depth = MAX_INTERPOLATION_DEPTH 653 while depth: # Loop through this until it's done 654 depth -= 1 655 if value and "%(" in value: 656 value = self._KEYCRE.sub(self._interpolation_replace, value) 657 try: 658 value = value % vars 659 except KeyError, e: 660 raise InterpolationMissingOptionError( 661 option, section, rawval, e.args[0]) 662 else: 663 break 664 if value and "%(" in value: 665 raise InterpolationDepthError(option, section, rawval) 666 return value 667 668 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") 669 670 def _interpolation_replace(self, match): 671 s = match.group(1) 672 if s is None: 673 return match.group() 674 else: 675 return "%%(%s)s" % self.optionxform(s) 676 677 678class SafeConfigParser(ConfigParser): 679 680 def _interpolate(self, section, option, rawval, vars): 681 # do the string interpolation 682 L = [] 683 self._interpolate_some(option, L, rawval, section, vars, 1) 684 return ''.join(L) 685 686 _interpvar_re = re.compile(r"%\(([^)]+)\)s") 687 688 def _interpolate_some(self, option, accum, rest, section, map, depth): 689 if depth > MAX_INTERPOLATION_DEPTH: 690 raise InterpolationDepthError(option, section, rest) 691 while rest: 692 p = rest.find("%") 693 if p < 0: 694 accum.append(rest) 695 return 696 if p > 0: 697 accum.append(rest[:p]) 698 rest = rest[p:] 699 # p is no longer used 700 c = rest[1:2] 701 if c == "%": 702 accum.append("%") 703 rest = rest[2:] 704 elif c == "(": 705 m = self._interpvar_re.match(rest) 706 if m is None: 707 raise InterpolationSyntaxError(option, section, 708 "bad interpolation variable reference %r" % rest) 709 var = self.optionxform(m.group(1)) 710 rest = rest[m.end():] 711 try: 712 v = map[var] 713 except KeyError: 714 raise InterpolationMissingOptionError( 715 option, section, rest, var) 716 if "%" in v: 717 self._interpolate_some(option, accum, v, 718 section, map, depth + 1) 719 else: 720 accum.append(v) 721 else: 722 raise InterpolationSyntaxError( 723 option, section, 724 "'%%' must be followed by '%%' or '(', found: %r" % (rest,)) 725 726 def set(self, section, option, value=None): 727 """Set an option. Extend ConfigParser.set: check for string values.""" 728 # The only legal non-string value if we allow valueless 729 # options is None, so we need to check if the value is a 730 # string if: 731 # - we do not allow valueless options, or 732 # - we allow valueless options but the value is not None 733 if self._optcre is self.OPTCRE or value: 734 if not isinstance(value, basestring): 735 raise TypeError("option values must be strings") 736 if value is not None: 737 # check for bad percent signs: 738 # first, replace all "good" interpolations 739 tmp_value = value.replace('%%', '') 740 tmp_value = self._interpvar_re.sub('', tmp_value) 741 # then, check if there's a lone percent sign left 742 if '%' in tmp_value: 743 raise ValueError("invalid interpolation syntax in %r at " 744 "position %d" % (value, tmp_value.find('%'))) 745 ConfigParser.set(self, section, option, value) 746