see issue1006238, this merges in the following patch to ease cross
[python.git] / Lib / ConfigParser.py
blob14bfdb690f256312a12d12bcff311b9436377381
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 self._dict = dict_type
226 self._sections = self._dict()
227 self._defaults = self._dict()
228 if defaults:
229 for key, value in defaults.items():
230 self._defaults[self.optionxform(key)] = value
232 def defaults(self):
233 return self._defaults
235 def sections(self):
236 """Return a list of section names, excluding [DEFAULT]"""
237 # self._sections will never have [DEFAULT] in it
238 return self._sections.keys()
240 def add_section(self, section):
241 """Create a new section in the configuration.
243 Raise DuplicateSectionError if a section by the specified name
244 already exists. Raise ValueError if name is DEFAULT or any of it's
245 case-insensitive variants.
247 if section.lower() == "default":
248 raise ValueError, 'Invalid section name: %s' % section
250 if section in self._sections:
251 raise DuplicateSectionError(section)
252 self._sections[section] = self._dict()
254 def has_section(self, section):
255 """Indicate whether the named section is present in the configuration.
257 The DEFAULT section is not acknowledged.
259 return section in self._sections
261 def options(self, section):
262 """Return a list of option names for the given section name."""
263 try:
264 opts = self._sections[section].copy()
265 except KeyError:
266 raise NoSectionError(section)
267 opts.update(self._defaults)
268 if '__name__' in opts:
269 del opts['__name__']
270 return opts.keys()
272 def read(self, filenames):
273 """Read and parse a filename or a list of filenames.
275 Files that cannot be opened are silently ignored; this is
276 designed so that you can specify a list of potential
277 configuration file locations (e.g. current directory, user's
278 home directory, systemwide directory), and all existing
279 configuration files in the list will be read. A single
280 filename may also be given.
282 Return list of successfully read files.
284 if isinstance(filenames, basestring):
285 filenames = [filenames]
286 read_ok = []
287 for filename in filenames:
288 try:
289 fp = open(filename)
290 except IOError:
291 continue
292 self._read(fp, filename)
293 fp.close()
294 read_ok.append(filename)
295 return read_ok
297 def readfp(self, fp, filename=None):
298 """Like read() but the argument must be a file-like object.
300 The `fp' argument must have a `readline' method. Optional
301 second argument is the `filename', which if not given, is
302 taken from fp.name. If fp has no `name' attribute, `<???>' is
303 used.
306 if filename is None:
307 try:
308 filename = fp.name
309 except AttributeError:
310 filename = '<???>'
311 self._read(fp, filename)
313 def get(self, section, option):
314 opt = self.optionxform(option)
315 if section not in self._sections:
316 if section != DEFAULTSECT:
317 raise NoSectionError(section)
318 if opt in self._defaults:
319 return self._defaults[opt]
320 else:
321 raise NoOptionError(option, section)
322 elif opt in self._sections[section]:
323 return self._sections[section][opt]
324 elif opt in self._defaults:
325 return self._defaults[opt]
326 else:
327 raise NoOptionError(option, section)
329 def items(self, section):
330 try:
331 d2 = self._sections[section]
332 except KeyError:
333 if section != DEFAULTSECT:
334 raise NoSectionError(section)
335 d2 = self._dict()
336 d = self._defaults.copy()
337 d.update(d2)
338 if "__name__" in d:
339 del d["__name__"]
340 return d.items()
342 def _get(self, section, conv, option):
343 return conv(self.get(section, option))
345 def getint(self, section, option):
346 return self._get(section, int, option)
348 def getfloat(self, section, option):
349 return self._get(section, float, option)
351 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
352 '0': False, 'no': False, 'false': False, 'off': False}
354 def getboolean(self, section, option):
355 v = self.get(section, option)
356 if v.lower() not in self._boolean_states:
357 raise ValueError, 'Not a boolean: %s' % v
358 return self._boolean_states[v.lower()]
360 def optionxform(self, optionstr):
361 return optionstr.lower()
363 def has_option(self, section, option):
364 """Check for the existence of a given option in a given section."""
365 if not section or section == DEFAULTSECT:
366 option = self.optionxform(option)
367 return option in self._defaults
368 elif section not in self._sections:
369 return False
370 else:
371 option = self.optionxform(option)
372 return (option in self._sections[section]
373 or option in self._defaults)
375 def set(self, section, option, value):
376 """Set an option."""
377 if not section or section == DEFAULTSECT:
378 sectdict = self._defaults
379 else:
380 try:
381 sectdict = self._sections[section]
382 except KeyError:
383 raise NoSectionError(section)
384 sectdict[self.optionxform(option)] = value
386 def write(self, fp):
387 """Write an .ini-format representation of the configuration state."""
388 if self._defaults:
389 fp.write("[%s]\n" % DEFAULTSECT)
390 for (key, value) in self._defaults.items():
391 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
392 fp.write("\n")
393 for section in self._sections:
394 fp.write("[%s]\n" % section)
395 for (key, value) in self._sections[section].items():
396 if key != "__name__":
397 fp.write("%s = %s\n" %
398 (key, str(value).replace('\n', '\n\t')))
399 fp.write("\n")
401 def remove_option(self, section, option):
402 """Remove an option."""
403 if not section or section == DEFAULTSECT:
404 sectdict = self._defaults
405 else:
406 try:
407 sectdict = self._sections[section]
408 except KeyError:
409 raise NoSectionError(section)
410 option = self.optionxform(option)
411 existed = option in sectdict
412 if existed:
413 del sectdict[option]
414 return existed
416 def remove_section(self, section):
417 """Remove a file section."""
418 existed = section in self._sections
419 if existed:
420 del self._sections[section]
421 return existed
424 # Regular expressions for parsing section headers and options.
426 SECTCRE = re.compile(
427 r'\[' # [
428 r'(?P<header>[^]]+)' # very permissive!
429 r'\]' # ]
431 OPTCRE = re.compile(
432 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
433 r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
434 # followed by separator
435 # (either : or =), followed
436 # by any # space/tab
437 r'(?P<value>.*)$' # everything up to eol
440 def _read(self, fp, fpname):
441 """Parse a sectioned setup file.
443 The sections in setup file contains a title line at the top,
444 indicated by a name in square brackets (`[]'), plus key/value
445 options lines, indicated by `name: value' format lines.
446 Continuations are represented by an embedded newline then
447 leading whitespace. Blank lines, lines beginning with a '#',
448 and just about everything else are ignored.
450 cursect = None # None, or a dictionary
451 optname = None
452 lineno = 0
453 e = None # None, or an exception
454 while True:
455 line = fp.readline()
456 if not line:
457 break
458 lineno = lineno + 1
459 # comment or blank line?
460 if line.strip() == '' or line[0] in '#;':
461 continue
462 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
463 # no leading whitespace
464 continue
465 # continuation line?
466 if line[0].isspace() and cursect is not None and optname:
467 value = line.strip()
468 if value:
469 cursect[optname] = "%s\n%s" % (cursect[optname], value)
470 # a section header or option header?
471 else:
472 # is it a section header?
473 mo = self.SECTCRE.match(line)
474 if mo:
475 sectname = mo.group('header')
476 if sectname in self._sections:
477 cursect = self._sections[sectname]
478 elif sectname == DEFAULTSECT:
479 cursect = self._defaults
480 else:
481 cursect = self._dict()
482 cursect['__name__'] = sectname
483 self._sections[sectname] = cursect
484 # So sections can't start with a continuation line
485 optname = None
486 # no section header in the file?
487 elif cursect is None:
488 raise MissingSectionHeaderError(fpname, lineno, line)
489 # an option line?
490 else:
491 mo = self.OPTCRE.match(line)
492 if mo:
493 optname, vi, optval = mo.group('option', 'vi', 'value')
494 if vi in ('=', ':') and ';' in optval:
495 # ';' is a comment delimiter only if it follows
496 # a spacing character
497 pos = optval.find(';')
498 if pos != -1 and optval[pos-1].isspace():
499 optval = optval[:pos]
500 optval = optval.strip()
501 # allow empty values
502 if optval == '""':
503 optval = ''
504 optname = self.optionxform(optname.rstrip())
505 cursect[optname] = optval
506 else:
507 # a non-fatal parsing error occurred. set up the
508 # exception but keep going. the exception will be
509 # raised at the end of the file and will contain a
510 # list of all bogus lines
511 if not e:
512 e = ParsingError(fpname)
513 e.append(lineno, repr(line))
514 # if any parsing errors occurred, raise an exception
515 if e:
516 raise e
519 class ConfigParser(RawConfigParser):
521 def get(self, section, option, raw=False, vars=None):
522 """Get an option value for a given section.
524 All % interpolations are expanded in the return values, based on the
525 defaults passed into the constructor, unless the optional argument
526 `raw' is true. Additional substitutions may be provided using the
527 `vars' argument, which must be a dictionary whose contents overrides
528 any pre-existing defaults.
530 The section DEFAULT is special.
532 d = self._defaults.copy()
533 try:
534 d.update(self._sections[section])
535 except KeyError:
536 if section != DEFAULTSECT:
537 raise NoSectionError(section)
538 # Update with the entry specific variables
539 if vars:
540 for key, value in vars.items():
541 d[self.optionxform(key)] = value
542 option = self.optionxform(option)
543 try:
544 value = d[option]
545 except KeyError:
546 raise NoOptionError(option, section)
548 if raw:
549 return value
550 else:
551 return self._interpolate(section, option, value, d)
553 def items(self, section, raw=False, vars=None):
554 """Return a list of tuples with (name, value) for each option
555 in the section.
557 All % interpolations are expanded in the return values, based on the
558 defaults passed into the constructor, unless the optional argument
559 `raw' is true. Additional substitutions may be provided using the
560 `vars' argument, which must be a dictionary whose contents overrides
561 any pre-existing defaults.
563 The section DEFAULT is special.
565 d = self._defaults.copy()
566 try:
567 d.update(self._sections[section])
568 except KeyError:
569 if section != DEFAULTSECT:
570 raise NoSectionError(section)
571 # Update with the entry specific variables
572 if vars:
573 for key, value in vars.items():
574 d[self.optionxform(key)] = value
575 options = d.keys()
576 if "__name__" in options:
577 options.remove("__name__")
578 if raw:
579 return [(option, d[option])
580 for option in options]
581 else:
582 return [(option, self._interpolate(section, option, d[option], d))
583 for option in options]
585 def _interpolate(self, section, option, rawval, vars):
586 # do the string interpolation
587 value = rawval
588 depth = MAX_INTERPOLATION_DEPTH
589 while depth: # Loop through this until it's done
590 depth -= 1
591 if "%(" in value:
592 value = self._KEYCRE.sub(self._interpolation_replace, value)
593 try:
594 value = value % vars
595 except KeyError, e:
596 raise InterpolationMissingOptionError(
597 option, section, rawval, e.args[0])
598 else:
599 break
600 if "%(" in value:
601 raise InterpolationDepthError(option, section, rawval)
602 return value
604 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
606 def _interpolation_replace(self, match):
607 s = match.group(1)
608 if s is None:
609 return match.group()
610 else:
611 return "%%(%s)s" % self.optionxform(s)
614 class SafeConfigParser(ConfigParser):
616 def _interpolate(self, section, option, rawval, vars):
617 # do the string interpolation
618 L = []
619 self._interpolate_some(option, L, rawval, section, vars, 1)
620 return ''.join(L)
622 _interpvar_re = re.compile(r"%\(([^)]+)\)s")
624 def _interpolate_some(self, option, accum, rest, section, map, depth):
625 if depth > MAX_INTERPOLATION_DEPTH:
626 raise InterpolationDepthError(option, section, rest)
627 while rest:
628 p = rest.find("%")
629 if p < 0:
630 accum.append(rest)
631 return
632 if p > 0:
633 accum.append(rest[:p])
634 rest = rest[p:]
635 # p is no longer used
636 c = rest[1:2]
637 if c == "%":
638 accum.append("%")
639 rest = rest[2:]
640 elif c == "(":
641 m = self._interpvar_re.match(rest)
642 if m is None:
643 raise InterpolationSyntaxError(option, section,
644 "bad interpolation variable reference %r" % rest)
645 var = self.optionxform(m.group(1))
646 rest = rest[m.end():]
647 try:
648 v = map[var]
649 except KeyError:
650 raise InterpolationMissingOptionError(
651 option, section, rest, var)
652 if "%" in v:
653 self._interpolate_some(option, accum, v,
654 section, map, depth + 1)
655 else:
656 accum.append(v)
657 else:
658 raise InterpolationSyntaxError(
659 option, section,
660 "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
662 def set(self, section, option, value):
663 """Set an option. Extend ConfigParser.set: check for string values."""
664 if not isinstance(value, basestring):
665 raise TypeError("option values must be strings")
666 # check for bad percent signs:
667 # first, replace all "good" interpolations
668 tmp_value = value.replace('%%', '')
669 tmp_value = self._interpvar_re.sub('', tmp_value)
670 # then, check if there's a lone percent sign left
671 percent_index = tmp_value.find('%')
672 if percent_index != -1:
673 raise ValueError("invalid interpolation syntax in %r at "
674 "position %d" % (value, percent_index))
675 ConfigParser.set(self, section, option, value)