add release date
[python/dscho.git] / Lib / ConfigParser.py
blobcee6b2aec5f4c1ec2e61cd40aa5b456027648890
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
5 the style of RFC 822.
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.
10 For example:
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.
20 class:
22 ConfigParser -- responsible for parsing a list of
23 configuration files, and managing the parsed database.
25 methods:
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.
33 sections()
34 return all the configuration section names, sans DEFAULT
36 has_section(section)
37 return whether the given section exists
39 has_option(section, option)
40 return whether the given option exists in the given section
42 options(section)
43 return list of configuration options for the named section
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.
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
75 in the section.
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)
84 set the given option
86 write(fp)
87 write the configuration state in .ini format
88 """
90 try:
91 from collections import OrderedDict as _default_dict
92 except ImportError:
93 # fallback for setup.py which hasn't yet built _collections
94 _default_dict = dict
96 import re
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
111 # exception classes
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
117 BaseException."""
118 return self.__message
120 def _set_message(self, value):
121 """Setter for 'message'; needed only to override deprecation in
122 BaseException."""
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=''):
131 self.message = msg
132 Exception.__init__(self, msg)
134 def __repr__(self):
135 return self.message
137 __str__ = __repr__
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
146 class DuplicateSectionError(Error):
147 """Raised when a section is multiply-created."""
149 def __init__(self, section):
150 Error.__init__(self, "Section %r already exists" % section)
151 self.section = section
153 class NoOptionError(Error):
154 """A requested option was not found."""
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
162 class InterpolationError(Error):
163 """Base class for interpolation-related exceptions."""
165 def __init__(self, option, section, msg):
166 Error.__init__(self, msg)
167 self.option = option
168 self.section = section
170 class InterpolationMissingOptionError(InterpolationError):
171 """A string substitution required a setting which was not available."""
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
183 class InterpolationSyntaxError(InterpolationError):
184 """Raised when the source text into which substitutions are made
185 does not conform to the required syntax."""
187 class InterpolationDepthError(InterpolationError):
188 """Raised when substitutions are nested too deeply."""
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)
198 class ParsingError(Error):
199 """Raised when a configuration file does not follow legal syntax."""
201 def __init__(self, filename):
202 Error.__init__(self, 'File contains parsing errors: %s' % filename)
203 self.filename = filename
204 self.errors = []
206 def append(self, lineno, line):
207 self.errors.append((lineno, line))
208 self.message += '\n\t[line %2d]: %s' % (lineno, line)
210 class MissingSectionHeaderError(ParsingError):
211 """Raised when a key-value pair is found before any section header."""
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
223 class 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
237 def defaults(self):
238 return self._defaults
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()
245 def add_section(self, section):
246 """Create a new section in the configuration.
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.
252 if section.lower() == "default":
253 raise ValueError, 'Invalid section name: %s' % section
255 if section in self._sections:
256 raise DuplicateSectionError(section)
257 self._sections[section] = self._dict()
259 def has_section(self, section):
260 """Indicate whether the named section is present in the configuration.
262 The DEFAULT section is not acknowledged.
264 return section in self._sections
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()
277 def read(self, filenames):
278 """Read and parse a filename or a list of filenames.
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.
287 Return list of successfully read files.
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
302 def readfp(self, fp, filename=None):
303 """Like read() but the argument must be a file-like object.
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.
311 if filename is None:
312 try:
313 filename = fp.name
314 except AttributeError:
315 filename = '<???>'
316 self._read(fp, filename)
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)
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()
347 def _get(self, section, conv, option):
348 return conv(self.get(section, option))
350 def getint(self, section, option):
351 return self._get(section, int, option)
353 def getfloat(self, section, option):
354 return self._get(section, float, option)
356 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
357 '0': False, 'no': False, 'false': False, 'off': False}
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()]
365 def optionxform(self, optionstr):
366 return optionstr.lower()
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)
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
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 if value is None:
403 fp.write("%s\n" % (key))
404 else:
405 fp.write("%s = %s\n" %
406 (key, str(value).replace('\n', '\n\t')))
407 fp.write("\n")
409 def remove_option(self, section, option):
410 """Remove an option."""
411 if not section or section == DEFAULTSECT:
412 sectdict = self._defaults
413 else:
414 try:
415 sectdict = self._sections[section]
416 except KeyError:
417 raise NoSectionError(section)
418 option = self.optionxform(option)
419 existed = option in sectdict
420 if existed:
421 del sectdict[option]
422 return existed
424 def remove_section(self, section):
425 """Remove a file section."""
426 existed = section in self._sections
427 if existed:
428 del self._sections[section]
429 return existed
432 # Regular expressions for parsing section headers and options.
434 SECTCRE = re.compile(
435 r'\[' # [
436 r'(?P<header>[^]]+)' # very permissive!
437 r'\]' # ]
439 OPTCRE = re.compile(
440 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
441 r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
442 # followed by separator
443 # (either : or =), followed
444 # by any # space/tab
445 r'(?P<value>.*)$' # everything up to eol
447 OPTCRE_NV = re.compile(
448 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
449 r'\s*(?:' # any number of space/tab,
450 r'(?P<vi>[:=])\s*' # optionally followed by
451 # separator (either : or
452 # =), followed by any #
453 # space/tab
454 r'(?P<value>.*))?$' # everything up to eol
457 def _read(self, fp, fpname):
458 """Parse a sectioned setup file.
460 The sections in setup file contains a title line at the top,
461 indicated by a name in square brackets (`[]'), plus key/value
462 options lines, indicated by `name: value' format lines.
463 Continuations are represented by an embedded newline then
464 leading whitespace. Blank lines, lines beginning with a '#',
465 and just about everything else are ignored.
467 cursect = None # None, or a dictionary
468 optname = None
469 lineno = 0
470 e = None # None, or an exception
471 while True:
472 line = fp.readline()
473 if not line:
474 break
475 lineno = lineno + 1
476 # comment or blank line?
477 if line.strip() == '' or line[0] in '#;':
478 continue
479 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
480 # no leading whitespace
481 continue
482 # continuation line?
483 if line[0].isspace() and cursect is not None and optname:
484 value = line.strip()
485 if value:
486 cursect[optname] = "%s\n%s" % (cursect[optname], value)
487 # a section header or option header?
488 else:
489 # is it a section header?
490 mo = self.SECTCRE.match(line)
491 if mo:
492 sectname = mo.group('header')
493 if sectname in self._sections:
494 cursect = self._sections[sectname]
495 elif sectname == DEFAULTSECT:
496 cursect = self._defaults
497 else:
498 cursect = self._dict()
499 cursect['__name__'] = sectname
500 self._sections[sectname] = cursect
501 # So sections can't start with a continuation line
502 optname = None
503 # no section header in the file?
504 elif cursect is None:
505 raise MissingSectionHeaderError(fpname, lineno, line)
506 # an option line?
507 else:
508 mo = self._optcre.match(line)
509 if mo:
510 optname, vi, optval = mo.group('option', 'vi', 'value')
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 optname = self.optionxform(optname.rstrip())
525 cursect[optname] = optval
526 else:
527 # a non-fatal parsing error occurred. set up the
528 # exception but keep going. the exception will be
529 # raised at the end of the file and will contain a
530 # list of all bogus lines
531 if not e:
532 e = ParsingError(fpname)
533 e.append(lineno, repr(line))
534 # if any parsing errors occurred, raise an exception
535 if e:
536 raise e
539 class ConfigParser(RawConfigParser):
541 def get(self, section, option, raw=False, vars=None):
542 """Get an option value for a given section.
544 All % interpolations are expanded in the return values, based on the
545 defaults passed into the constructor, unless the optional argument
546 `raw' is true. Additional substitutions may be provided using the
547 `vars' argument, which must be a dictionary whose contents overrides
548 any pre-existing defaults.
550 The section DEFAULT is special.
552 d = self._defaults.copy()
553 try:
554 d.update(self._sections[section])
555 except KeyError:
556 if section != DEFAULTSECT:
557 raise NoSectionError(section)
558 # Update with the entry specific variables
559 if vars:
560 for key, value in vars.items():
561 d[self.optionxform(key)] = value
562 option = self.optionxform(option)
563 try:
564 value = d[option]
565 except KeyError:
566 raise NoOptionError(option, section)
568 if raw or value is None:
569 return value
570 else:
571 return self._interpolate(section, option, value, d)
573 def items(self, section, raw=False, vars=None):
574 """Return a list of tuples with (name, value) for each option
575 in the section.
577 All % interpolations are expanded in the return values, based on the
578 defaults passed into the constructor, unless the optional argument
579 `raw' is true. Additional substitutions may be provided using the
580 `vars' argument, which must be a dictionary whose contents overrides
581 any pre-existing defaults.
583 The section DEFAULT is special.
585 d = self._defaults.copy()
586 try:
587 d.update(self._sections[section])
588 except KeyError:
589 if section != DEFAULTSECT:
590 raise NoSectionError(section)
591 # Update with the entry specific variables
592 if vars:
593 for key, value in vars.items():
594 d[self.optionxform(key)] = value
595 options = d.keys()
596 if "__name__" in options:
597 options.remove("__name__")
598 if raw:
599 return [(option, d[option])
600 for option in options]
601 else:
602 return [(option, self._interpolate(section, option, d[option], d))
603 for option in options]
605 def _interpolate(self, section, option, rawval, vars):
606 # do the string interpolation
607 value = rawval
608 depth = MAX_INTERPOLATION_DEPTH
609 while depth: # Loop through this until it's done
610 depth -= 1
611 if value and "%(" in value:
612 value = self._KEYCRE.sub(self._interpolation_replace, value)
613 try:
614 value = value % vars
615 except KeyError, e:
616 raise InterpolationMissingOptionError(
617 option, section, rawval, e.args[0])
618 else:
619 break
620 if value and "%(" in value:
621 raise InterpolationDepthError(option, section, rawval)
622 return value
624 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
626 def _interpolation_replace(self, match):
627 s = match.group(1)
628 if s is None:
629 return match.group()
630 else:
631 return "%%(%s)s" % self.optionxform(s)
634 class SafeConfigParser(ConfigParser):
636 def _interpolate(self, section, option, rawval, vars):
637 # do the string interpolation
638 L = []
639 self._interpolate_some(option, L, rawval, section, vars, 1)
640 return ''.join(L)
642 _interpvar_re = re.compile(r"%\(([^)]+)\)s")
644 def _interpolate_some(self, option, accum, rest, section, map, depth):
645 if depth > MAX_INTERPOLATION_DEPTH:
646 raise InterpolationDepthError(option, section, rest)
647 while rest:
648 p = rest.find("%")
649 if p < 0:
650 accum.append(rest)
651 return
652 if p > 0:
653 accum.append(rest[:p])
654 rest = rest[p:]
655 # p is no longer used
656 c = rest[1:2]
657 if c == "%":
658 accum.append("%")
659 rest = rest[2:]
660 elif c == "(":
661 m = self._interpvar_re.match(rest)
662 if m is None:
663 raise InterpolationSyntaxError(option, section,
664 "bad interpolation variable reference %r" % rest)
665 var = self.optionxform(m.group(1))
666 rest = rest[m.end():]
667 try:
668 v = map[var]
669 except KeyError:
670 raise InterpolationMissingOptionError(
671 option, section, rest, var)
672 if "%" in v:
673 self._interpolate_some(option, accum, v,
674 section, map, depth + 1)
675 else:
676 accum.append(v)
677 else:
678 raise InterpolationSyntaxError(
679 option, section,
680 "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
682 def set(self, section, option, value=None):
683 """Set an option. Extend ConfigParser.set: check for string values."""
684 # The only legal non-string value if we allow valueless
685 # options is None, so we need to check if the value is a
686 # string if:
687 # - we do not allow valueless options, or
688 # - we allow valueless options but the value is not None
689 if self._optcre is self.OPTCRE or value:
690 if not isinstance(value, basestring):
691 raise TypeError("option values must be strings")
692 # check for bad percent signs:
693 # first, replace all "good" interpolations
694 tmp_value = value.replace('%%', '')
695 tmp_value = self._interpvar_re.sub('', tmp_value)
696 # then, check if there's a lone percent sign left
697 percent_index = tmp_value.find('%')
698 if percent_index != -1:
699 raise ValueError("invalid interpolation syntax in %r at "
700 "position %d" % (value, percent_index))
701 ConfigParser.set(self, section, option, value)