1 """Configuration file parser.
3 A setup file consists of sections, lead by a "[section]" header,
4 and followed by "name: value" entries, with continuations and such in
7 The option values can contain format strings which refer to other values in
8 the same section, or values in a special [DEFAULT] section.
12 something: %(dir)s/whatever
14 would resolve the "%(dir)s" to the value of dir. All reference
15 expansions are done late, on demand.
17 Intrinsic defaults can be specified by passing them into the
18 ConfigParser constructor as a dictionary.
22 ConfigParser -- responsible for parsing a list of
23 configuration files, and managing the parsed database.
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.
34 return all the configuration section names, sans DEFAULT
37 return whether the given section exists
39 has_option(section, option)
40 return whether the given option exists in the given section
43 return list of configuration options for the named section
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.
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).
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.
62 getint(section, options)
63 like get(), but convert value to an integer
65 getfloat(section, options)
66 like get(), but convert value to a float
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.
73 items(section, raw=False, vars=None)
74 return a list of tuples with (name, value) for each option
77 remove_section(section)
78 remove the given file section and all its options
80 remove_option(section, option)
81 remove the given option from the given section
83 set(section, option, value)
87 write the configuration state in .ini format
91 from collections import OrderedDict as _default_dict
93 # fallback for setup.py which hasn't yet built _collections
98 __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
99 "InterpolationError", "InterpolationDepthError",
100 "InterpolationSyntaxError", "ParsingError",
101 "MissingSectionHeaderError",
102 "ConfigParser", "SafeConfigParser", "RawConfigParser",
103 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
105 DEFAULTSECT = "DEFAULT"
107 MAX_INTERPOLATION_DEPTH = 10
112 class Error(Exception):
113 """Base class for ConfigParser exceptions."""
115 def _get_message(self):
116 """Getter for 'message'; needed only to override deprecation in
118 return self.__message
120 def _set_message(self, value):
121 """Setter for 'message'; needed only to override deprecation in
123 self.__message = value
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)
130 def __init__(self, msg=''):
132 Exception.__init__(self, msg)
139 class NoSectionError(Error):
140 """Raised when no section matches a requested option."""
142 def __init__(self, section):
143 Error.__init__(self, 'No section: %r' % (section,))
144 self.section = section
145 self.args = (section, )
147 class DuplicateSectionError(Error):
148 """Raised when a section is multiply-created."""
150 def __init__(self, section):
151 Error.__init__(self, "Section %r already exists" % section)
152 self.section = section
153 self.args = (section, )
155 class NoOptionError(Error):
156 """A requested option was not found."""
158 def __init__(self, option, section):
159 Error.__init__(self, "No option %r in section: %r" %
162 self.section = section
163 self.args = (option, section)
165 class InterpolationError(Error):
166 """Base class for interpolation-related exceptions."""
168 def __init__(self, option, section, msg):
169 Error.__init__(self, msg)
171 self.section = section
172 self.args = (option, section, msg)
174 class InterpolationMissingOptionError(InterpolationError):
175 """A string substitution required a setting which was not available."""
177 def __init__(self, option, section, rawval, reference):
178 msg = ("Bad value substitution:\n"
183 % (section, option, reference, rawval))
184 InterpolationError.__init__(self, option, section, msg)
185 self.reference = reference
186 self.args = (option, section, rawval, reference)
188 class InterpolationSyntaxError(InterpolationError):
189 """Raised when the source text into which substitutions are made
190 does not conform to the required syntax."""
192 class InterpolationDepthError(InterpolationError):
193 """Raised when substitutions are nested too deeply."""
195 def __init__(self, option, section, rawval):
196 msg = ("Value interpolation too deeply recursive:\n"
200 % (section, option, rawval))
201 InterpolationError.__init__(self, option, section, msg)
202 self.args = (option, section, rawval)
204 class ParsingError(Error):
205 """Raised when a configuration file does not follow legal syntax."""
207 def __init__(self, filename):
208 Error.__init__(self, 'File contains parsing errors: %s' % filename)
209 self.filename = filename
211 self.args = (filename, )
213 def append(self, lineno, line):
214 self.errors.append((lineno, line))
215 self.message += '\n\t[line %2d]: %s' % (lineno, line)
217 class MissingSectionHeaderError(ParsingError):
218 """Raised when a key-value pair is found before any section header."""
220 def __init__(self, filename, lineno, line):
223 'File contains no section headers.\nfile: %s, line: %d\n%r' %
224 (filename, lineno, line))
225 self.filename = filename
228 self.args = (filename, lineno, line)
231 class RawConfigParser:
232 def __init__(self, defaults=None, dict_type=_default_dict,
233 allow_no_value=False):
234 self._dict = dict_type
235 self._sections = self._dict()
236 self._defaults = self._dict()
238 self._optcre = self.OPTCRE_NV
240 self._optcre = self.OPTCRE
242 for key, value in defaults.items():
243 self._defaults[self.optionxform(key)] = value
246 return self._defaults
249 """Return a list of section names, excluding [DEFAULT]"""
250 # self._sections will never have [DEFAULT] in it
251 return self._sections.keys()
253 def add_section(self, section):
254 """Create a new section in the configuration.
256 Raise DuplicateSectionError if a section by the specified name
257 already exists. Raise ValueError if name is DEFAULT or any of it's
258 case-insensitive variants.
260 if section.lower() == "default":
261 raise ValueError, 'Invalid section name: %s' % section
263 if section in self._sections:
264 raise DuplicateSectionError(section)
265 self._sections[section] = self._dict()
267 def has_section(self, section):
268 """Indicate whether the named section is present in the configuration.
270 The DEFAULT section is not acknowledged.
272 return section in self._sections
274 def options(self, section):
275 """Return a list of option names for the given section name."""
277 opts = self._sections[section].copy()
279 raise NoSectionError(section)
280 opts.update(self._defaults)
281 if '__name__' in opts:
285 def read(self, filenames):
286 """Read and parse a filename or a list of filenames.
288 Files that cannot be opened are silently ignored; this is
289 designed so that you can specify a list of potential
290 configuration file locations (e.g. current directory, user's
291 home directory, systemwide directory), and all existing
292 configuration files in the list will be read. A single
293 filename may also be given.
295 Return list of successfully read files.
297 if isinstance(filenames, basestring):
298 filenames = [filenames]
300 for filename in filenames:
305 self._read(fp, filename)
307 read_ok.append(filename)
310 def readfp(self, fp, filename=None):
311 """Like read() but the argument must be a file-like object.
313 The `fp' argument must have a `readline' method. Optional
314 second argument is the `filename', which if not given, is
315 taken from fp.name. If fp has no `name' attribute, `<???>' is
322 except AttributeError:
324 self._read(fp, filename)
326 def get(self, section, option):
327 opt = self.optionxform(option)
328 if section not in self._sections:
329 if section != DEFAULTSECT:
330 raise NoSectionError(section)
331 if opt in self._defaults:
332 return self._defaults[opt]
334 raise NoOptionError(option, section)
335 elif opt in self._sections[section]:
336 return self._sections[section][opt]
337 elif opt in self._defaults:
338 return self._defaults[opt]
340 raise NoOptionError(option, section)
342 def items(self, section):
344 d2 = self._sections[section]
346 if section != DEFAULTSECT:
347 raise NoSectionError(section)
349 d = self._defaults.copy()
355 def _get(self, section, conv, option):
356 return conv(self.get(section, option))
358 def getint(self, section, option):
359 return self._get(section, int, option)
361 def getfloat(self, section, option):
362 return self._get(section, float, option)
364 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
365 '0': False, 'no': False, 'false': False, 'off': False}
367 def getboolean(self, section, option):
368 v = self.get(section, option)
369 if v.lower() not in self._boolean_states:
370 raise ValueError, 'Not a boolean: %s' % v
371 return self._boolean_states[v.lower()]
373 def optionxform(self, optionstr):
374 return optionstr.lower()
376 def has_option(self, section, option):
377 """Check for the existence of a given option in a given section."""
378 if not section or section == DEFAULTSECT:
379 option = self.optionxform(option)
380 return option in self._defaults
381 elif section not in self._sections:
384 option = self.optionxform(option)
385 return (option in self._sections[section]
386 or option in self._defaults)
388 def set(self, section, option, value=None):
390 if not section or section == DEFAULTSECT:
391 sectdict = self._defaults
394 sectdict = self._sections[section]
396 raise NoSectionError(section)
397 sectdict[self.optionxform(option)] = value
400 """Write an .ini-format representation of the configuration state."""
402 fp.write("[%s]\n" % DEFAULTSECT)
403 for (key, value) in self._defaults.items():
404 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
406 for section in self._sections:
407 fp.write("[%s]\n" % section)
408 for (key, value) in self._sections[section].items():
409 if key == "__name__":
411 if (value is not None) or (self._optcre == self.OPTCRE):
412 key = " = ".join((key, str(value).replace('\n', '\n\t')))
413 fp.write("%s\n" % (key))
416 def remove_option(self, section, option):
417 """Remove an option."""
418 if not section or section == DEFAULTSECT:
419 sectdict = self._defaults
422 sectdict = self._sections[section]
424 raise NoSectionError(section)
425 option = self.optionxform(option)
426 existed = option in sectdict
431 def remove_section(self, section):
432 """Remove a file section."""
433 existed = section in self._sections
435 del self._sections[section]
439 # Regular expressions for parsing section headers and options.
441 SECTCRE = re.compile(
443 r'(?P<header>[^]]+)' # very permissive!
447 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
448 r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
449 # followed by separator
450 # (either : or =), followed
452 r'(?P<value>.*)$' # everything up to eol
454 OPTCRE_NV = re.compile(
455 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
456 r'\s*(?:' # any number of space/tab,
457 r'(?P<vi>[:=])\s*' # optionally followed by
458 # separator (either : or
459 # =), followed by any #
461 r'(?P<value>.*))?$' # everything up to eol
464 def _read(self, fp, fpname):
465 """Parse a sectioned setup file.
467 The sections in setup file contains a title line at the top,
468 indicated by a name in square brackets (`[]'), plus key/value
469 options lines, indicated by `name: value' format lines.
470 Continuations are represented by an embedded newline then
471 leading whitespace. Blank lines, lines beginning with a '#',
472 and just about everything else are ignored.
474 cursect = None # None, or a dictionary
477 e = None # None, or an exception
483 # comment or blank line?
484 if line.strip() == '' or line[0] in '#;':
486 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
487 # no leading whitespace
490 if line[0].isspace() and cursect is not None and optname:
493 cursect[optname].append(value)
494 # a section header or option header?
496 # is it a section header?
497 mo = self.SECTCRE.match(line)
499 sectname = mo.group('header')
500 if sectname in self._sections:
501 cursect = self._sections[sectname]
502 elif sectname == DEFAULTSECT:
503 cursect = self._defaults
505 cursect = self._dict()
506 cursect['__name__'] = sectname
507 self._sections[sectname] = cursect
508 # So sections can't start with a continuation line
510 # no section header in the file?
511 elif cursect is None:
512 raise MissingSectionHeaderError(fpname, lineno, line)
515 mo = self._optcre.match(line)
517 optname, vi, optval = mo.group('option', 'vi', 'value')
518 optname = self.optionxform(optname.rstrip())
519 # This check is fine because the OPTCRE cannot
520 # match if it would set optval to None
521 if optval is not None:
522 if vi in ('=', ':') and ';' in optval:
523 # ';' is a comment delimiter only if it follows
524 # a spacing character
525 pos = optval.find(';')
526 if pos != -1 and optval[pos-1].isspace():
527 optval = optval[:pos]
528 optval = optval.strip()
532 cursect[optname] = [optval]
534 # valueless option handling
535 cursect[optname] = optval
537 # a non-fatal parsing error occurred. set up the
538 # exception but keep going. the exception will be
539 # raised at the end of the file and will contain a
540 # list of all bogus lines
542 e = ParsingError(fpname)
543 e.append(lineno, repr(line))
544 # if any parsing errors occurred, raise an exception
548 # join the multi-line values collected while reading
549 all_sections = [self._defaults]
550 all_sections.extend(self._sections.values())
551 for options in all_sections:
552 for name, val in options.items():
553 if isinstance(val, list):
554 options[name] = '\n'.join(val)
556 import UserDict as _UserDict
558 class _Chainmap(_UserDict.DictMixin):
559 """Combine multiple mappings for successive lookups.
561 For example, to emulate Python's normal lookup sequence:
564 pylookup = _Chainmap(locals(), globals(), vars(__builtin__))
567 def __init__(self, *maps):
570 def __getitem__(self, key):
571 for mapping in self._maps:
581 for mapping in self._maps:
588 class ConfigParser(RawConfigParser):
590 def get(self, section, option, raw=False, vars=None):
591 """Get an option value for a given section.
593 If `vars' is provided, it must be a dictionary. The option is looked up
594 in `vars' (if provided), `section', and in `defaults' in that order.
596 All % interpolations are expanded in the return values, unless the
597 optional argument `raw' is true. Values for interpolation keys are
598 looked up in the same manner as the option.
600 The section DEFAULT is special.
604 sectiondict = self._sections[section]
606 if section != DEFAULTSECT:
607 raise NoSectionError(section)
608 # Update with the entry specific variables
611 for key, value in vars.items():
612 vardict[self.optionxform(key)] = value
613 d = _Chainmap(vardict, sectiondict, self._defaults)
614 option = self.optionxform(option)
618 raise NoOptionError(option, section)
620 if raw or value is None:
623 return self._interpolate(section, option, value, d)
625 def items(self, section, raw=False, vars=None):
626 """Return a list of tuples with (name, value) for each option
629 All % interpolations are expanded in the return values, based on the
630 defaults passed into the constructor, unless the optional argument
631 `raw' is true. Additional substitutions may be provided using the
632 `vars' argument, which must be a dictionary whose contents overrides
633 any pre-existing defaults.
635 The section DEFAULT is special.
637 d = self._defaults.copy()
639 d.update(self._sections[section])
641 if section != DEFAULTSECT:
642 raise NoSectionError(section)
643 # Update with the entry specific variables
645 for key, value in vars.items():
646 d[self.optionxform(key)] = value
648 if "__name__" in options:
649 options.remove("__name__")
651 return [(option, d[option])
652 for option in options]
654 return [(option, self._interpolate(section, option, d[option], d))
655 for option in options]
657 def _interpolate(self, section, option, rawval, vars):
658 # do the string interpolation
660 depth = MAX_INTERPOLATION_DEPTH
661 while depth: # Loop through this until it's done
663 if value and "%(" in value:
664 value = self._KEYCRE.sub(self._interpolation_replace, value)
668 raise InterpolationMissingOptionError(
669 option, section, rawval, e.args[0])
672 if value and "%(" in value:
673 raise InterpolationDepthError(option, section, rawval)
676 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
678 def _interpolation_replace(self, match):
683 return "%%(%s)s" % self.optionxform(s)
686 class SafeConfigParser(ConfigParser):
688 def _interpolate(self, section, option, rawval, vars):
689 # do the string interpolation
691 self._interpolate_some(option, L, rawval, section, vars, 1)
694 _interpvar_re = re.compile(r"%\(([^)]+)\)s")
696 def _interpolate_some(self, option, accum, rest, section, map, depth):
697 if depth > MAX_INTERPOLATION_DEPTH:
698 raise InterpolationDepthError(option, section, rest)
705 accum.append(rest[:p])
707 # p is no longer used
713 m = self._interpvar_re.match(rest)
715 raise InterpolationSyntaxError(option, section,
716 "bad interpolation variable reference %r" % rest)
717 var = self.optionxform(m.group(1))
718 rest = rest[m.end():]
722 raise InterpolationMissingOptionError(
723 option, section, rest, var)
725 self._interpolate_some(option, accum, v,
726 section, map, depth + 1)
730 raise InterpolationSyntaxError(
732 "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
734 def set(self, section, option, value=None):
735 """Set an option. Extend ConfigParser.set: check for string values."""
736 # The only legal non-string value if we allow valueless
737 # options is None, so we need to check if the value is a
739 # - we do not allow valueless options, or
740 # - we allow valueless options but the value is not None
741 if self._optcre is self.OPTCRE or value:
742 if not isinstance(value, basestring):
743 raise TypeError("option values must be strings")
744 if value is not None:
745 # check for bad percent signs:
746 # first, replace all "good" interpolations
747 tmp_value = value.replace('%%', '')
748 tmp_value = self._interpvar_re.sub('', tmp_value)
749 # then, check if there's a lone percent sign left
751 raise ValueError("invalid interpolation syntax in %r at "
752 "position %d" % (value, tmp_value.find('%')))
753 ConfigParser.set(self, section, option, value)