Catch situations where currentframe() returns None. See SF patch #1447410, this is...
[python.git] / Lib / ConfigParser.py
blob6dc53b9e0d269c03d8fadc1b6cc3fe467a23f93a
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 import re
92 __all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError",
93 "InterpolationError", "InterpolationDepthError",
94 "InterpolationSyntaxError", "ParsingError",
95 "MissingSectionHeaderError",
96 "ConfigParser", "SafeConfigParser", "RawConfigParser",
97 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
99 DEFAULTSECT = "DEFAULT"
101 MAX_INTERPOLATION_DEPTH = 10
105 # exception classes
106 class Error(Exception):
107 """Base class for ConfigParser exceptions."""
109 def __init__(self, msg=''):
110 self.message = msg
111 Exception.__init__(self, msg)
113 def __repr__(self):
114 return self.message
116 __str__ = __repr__
118 class NoSectionError(Error):
119 """Raised when no section matches a requested option."""
121 def __init__(self, section):
122 Error.__init__(self, 'No section: %r' % (section,))
123 self.section = section
125 class DuplicateSectionError(Error):
126 """Raised when a section is multiply-created."""
128 def __init__(self, section):
129 Error.__init__(self, "Section %r already exists" % section)
130 self.section = section
132 class NoOptionError(Error):
133 """A requested option was not found."""
135 def __init__(self, option, section):
136 Error.__init__(self, "No option %r in section: %r" %
137 (option, section))
138 self.option = option
139 self.section = section
141 class InterpolationError(Error):
142 """Base class for interpolation-related exceptions."""
144 def __init__(self, option, section, msg):
145 Error.__init__(self, msg)
146 self.option = option
147 self.section = section
149 class InterpolationMissingOptionError(InterpolationError):
150 """A string substitution required a setting which was not available."""
152 def __init__(self, option, section, rawval, reference):
153 msg = ("Bad value substitution:\n"
154 "\tsection: [%s]\n"
155 "\toption : %s\n"
156 "\tkey : %s\n"
157 "\trawval : %s\n"
158 % (section, option, reference, rawval))
159 InterpolationError.__init__(self, option, section, msg)
160 self.reference = reference
162 class InterpolationSyntaxError(InterpolationError):
163 """Raised when the source text into which substitutions are made
164 does not conform to the required syntax."""
166 class InterpolationDepthError(InterpolationError):
167 """Raised when substitutions are nested too deeply."""
169 def __init__(self, option, section, rawval):
170 msg = ("Value interpolation too deeply recursive:\n"
171 "\tsection: [%s]\n"
172 "\toption : %s\n"
173 "\trawval : %s\n"
174 % (section, option, rawval))
175 InterpolationError.__init__(self, option, section, msg)
177 class ParsingError(Error):
178 """Raised when a configuration file does not follow legal syntax."""
180 def __init__(self, filename):
181 Error.__init__(self, 'File contains parsing errors: %s' % filename)
182 self.filename = filename
183 self.errors = []
185 def append(self, lineno, line):
186 self.errors.append((lineno, line))
187 self.message += '\n\t[line %2d]: %s' % (lineno, line)
189 class MissingSectionHeaderError(ParsingError):
190 """Raised when a key-value pair is found before any section header."""
192 def __init__(self, filename, lineno, line):
193 Error.__init__(
194 self,
195 'File contains no section headers.\nfile: %s, line: %d\n%r' %
196 (filename, lineno, line))
197 self.filename = filename
198 self.lineno = lineno
199 self.line = line
203 class RawConfigParser:
204 def __init__(self, defaults=None):
205 self._sections = {}
206 self._defaults = {}
207 if defaults:
208 for key, value in defaults.items():
209 self._defaults[self.optionxform(key)] = value
211 def defaults(self):
212 return self._defaults
214 def sections(self):
215 """Return a list of section names, excluding [DEFAULT]"""
216 # self._sections will never have [DEFAULT] in it
217 return self._sections.keys()
219 def add_section(self, section):
220 """Create a new section in the configuration.
222 Raise DuplicateSectionError if a section by the specified name
223 already exists.
225 if section in self._sections:
226 raise DuplicateSectionError(section)
227 self._sections[section] = {}
229 def has_section(self, section):
230 """Indicate whether the named section is present in the configuration.
232 The DEFAULT section is not acknowledged.
234 return section in self._sections
236 def options(self, section):
237 """Return a list of option names for the given section name."""
238 try:
239 opts = self._sections[section].copy()
240 except KeyError:
241 raise NoSectionError(section)
242 opts.update(self._defaults)
243 if '__name__' in opts:
244 del opts['__name__']
245 return opts.keys()
247 def read(self, filenames):
248 """Read and parse a filename or a list of filenames.
250 Files that cannot be opened are silently ignored; this is
251 designed so that you can specify a list of potential
252 configuration file locations (e.g. current directory, user's
253 home directory, systemwide directory), and all existing
254 configuration files in the list will be read. A single
255 filename may also be given.
257 Return list of successfully read files.
259 if isinstance(filenames, basestring):
260 filenames = [filenames]
261 read_ok = []
262 for filename in filenames:
263 try:
264 fp = open(filename)
265 except IOError:
266 continue
267 self._read(fp, filename)
268 fp.close()
269 read_ok.append(filename)
270 return read_ok
272 def readfp(self, fp, filename=None):
273 """Like read() but the argument must be a file-like object.
275 The `fp' argument must have a `readline' method. Optional
276 second argument is the `filename', which if not given, is
277 taken from fp.name. If fp has no `name' attribute, `<???>' is
278 used.
281 if filename is None:
282 try:
283 filename = fp.name
284 except AttributeError:
285 filename = '<???>'
286 self._read(fp, filename)
288 def get(self, section, option):
289 opt = self.optionxform(option)
290 if section not in self._sections:
291 if section != DEFAULTSECT:
292 raise NoSectionError(section)
293 if opt in self._defaults:
294 return self._defaults[opt]
295 else:
296 raise NoOptionError(option, section)
297 elif opt in self._sections[section]:
298 return self._sections[section][opt]
299 elif opt in self._defaults:
300 return self._defaults[opt]
301 else:
302 raise NoOptionError(option, section)
304 def items(self, section):
305 try:
306 d2 = self._sections[section]
307 except KeyError:
308 if section != DEFAULTSECT:
309 raise NoSectionError(section)
310 d2 = {}
311 d = self._defaults.copy()
312 d.update(d2)
313 if "__name__" in d:
314 del d["__name__"]
315 return d.items()
317 def _get(self, section, conv, option):
318 return conv(self.get(section, option))
320 def getint(self, section, option):
321 return self._get(section, int, option)
323 def getfloat(self, section, option):
324 return self._get(section, float, option)
326 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
327 '0': False, 'no': False, 'false': False, 'off': False}
329 def getboolean(self, section, option):
330 v = self.get(section, option)
331 if v.lower() not in self._boolean_states:
332 raise ValueError, 'Not a boolean: %s' % v
333 return self._boolean_states[v.lower()]
335 def optionxform(self, optionstr):
336 return optionstr.lower()
338 def has_option(self, section, option):
339 """Check for the existence of a given option in a given section."""
340 if not section or section == DEFAULTSECT:
341 option = self.optionxform(option)
342 return option in self._defaults
343 elif section not in self._sections:
344 return False
345 else:
346 option = self.optionxform(option)
347 return (option in self._sections[section]
348 or option in self._defaults)
350 def set(self, section, option, value):
351 """Set an option."""
352 if not section or section == DEFAULTSECT:
353 sectdict = self._defaults
354 else:
355 try:
356 sectdict = self._sections[section]
357 except KeyError:
358 raise NoSectionError(section)
359 sectdict[self.optionxform(option)] = value
361 def write(self, fp):
362 """Write an .ini-format representation of the configuration state."""
363 if self._defaults:
364 fp.write("[%s]\n" % DEFAULTSECT)
365 for (key, value) in self._defaults.items():
366 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
367 fp.write("\n")
368 for section in self._sections:
369 fp.write("[%s]\n" % section)
370 for (key, value) in self._sections[section].items():
371 if key != "__name__":
372 fp.write("%s = %s\n" %
373 (key, str(value).replace('\n', '\n\t')))
374 fp.write("\n")
376 def remove_option(self, section, option):
377 """Remove an option."""
378 if not section or section == DEFAULTSECT:
379 sectdict = self._defaults
380 else:
381 try:
382 sectdict = self._sections[section]
383 except KeyError:
384 raise NoSectionError(section)
385 option = self.optionxform(option)
386 existed = option in sectdict
387 if existed:
388 del sectdict[option]
389 return existed
391 def remove_section(self, section):
392 """Remove a file section."""
393 existed = section in self._sections
394 if existed:
395 del self._sections[section]
396 return existed
399 # Regular expressions for parsing section headers and options.
401 SECTCRE = re.compile(
402 r'\[' # [
403 r'(?P<header>[^]]+)' # very permissive!
404 r'\]' # ]
406 OPTCRE = re.compile(
407 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
408 r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
409 # followed by separator
410 # (either : or =), followed
411 # by any # space/tab
412 r'(?P<value>.*)$' # everything up to eol
415 def _read(self, fp, fpname):
416 """Parse a sectioned setup file.
418 The sections in setup file contains a title line at the top,
419 indicated by a name in square brackets (`[]'), plus key/value
420 options lines, indicated by `name: value' format lines.
421 Continuations are represented by an embedded newline then
422 leading whitespace. Blank lines, lines beginning with a '#',
423 and just about everything else are ignored.
425 cursect = None # None, or a dictionary
426 optname = None
427 lineno = 0
428 e = None # None, or an exception
429 while True:
430 line = fp.readline()
431 if not line:
432 break
433 lineno = lineno + 1
434 # comment or blank line?
435 if line.strip() == '' or line[0] in '#;':
436 continue
437 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
438 # no leading whitespace
439 continue
440 # continuation line?
441 if line[0].isspace() and cursect is not None and optname:
442 value = line.strip()
443 if value:
444 cursect[optname] = "%s\n%s" % (cursect[optname], value)
445 # a section header or option header?
446 else:
447 # is it a section header?
448 mo = self.SECTCRE.match(line)
449 if mo:
450 sectname = mo.group('header')
451 if sectname in self._sections:
452 cursect = self._sections[sectname]
453 elif sectname == DEFAULTSECT:
454 cursect = self._defaults
455 else:
456 cursect = {'__name__': sectname}
457 self._sections[sectname] = cursect
458 # So sections can't start with a continuation line
459 optname = None
460 # no section header in the file?
461 elif cursect is None:
462 raise MissingSectionHeaderError(fpname, lineno, line)
463 # an option line?
464 else:
465 mo = self.OPTCRE.match(line)
466 if mo:
467 optname, vi, optval = mo.group('option', 'vi', 'value')
468 if vi in ('=', ':') and ';' in optval:
469 # ';' is a comment delimiter only if it follows
470 # a spacing character
471 pos = optval.find(';')
472 if pos != -1 and optval[pos-1].isspace():
473 optval = optval[:pos]
474 optval = optval.strip()
475 # allow empty values
476 if optval == '""':
477 optval = ''
478 optname = self.optionxform(optname.rstrip())
479 cursect[optname] = optval
480 else:
481 # a non-fatal parsing error occurred. set up the
482 # exception but keep going. the exception will be
483 # raised at the end of the file and will contain a
484 # list of all bogus lines
485 if not e:
486 e = ParsingError(fpname)
487 e.append(lineno, repr(line))
488 # if any parsing errors occurred, raise an exception
489 if e:
490 raise e
493 class ConfigParser(RawConfigParser):
495 def get(self, section, option, raw=False, vars=None):
496 """Get an option value for a given section.
498 All % interpolations are expanded in the return values, based on the
499 defaults passed into the constructor, unless the optional argument
500 `raw' is true. Additional substitutions may be provided using the
501 `vars' argument, which must be a dictionary whose contents overrides
502 any pre-existing defaults.
504 The section DEFAULT is special.
506 d = self._defaults.copy()
507 try:
508 d.update(self._sections[section])
509 except KeyError:
510 if section != DEFAULTSECT:
511 raise NoSectionError(section)
512 # Update with the entry specific variables
513 if vars:
514 for key, value in vars.items():
515 d[self.optionxform(key)] = value
516 option = self.optionxform(option)
517 try:
518 value = d[option]
519 except KeyError:
520 raise NoOptionError(option, section)
522 if raw:
523 return value
524 else:
525 return self._interpolate(section, option, value, d)
527 def items(self, section, raw=False, vars=None):
528 """Return a list of tuples with (name, value) for each option
529 in the section.
531 All % interpolations are expanded in the return values, based on the
532 defaults passed into the constructor, unless the optional argument
533 `raw' is true. Additional substitutions may be provided using the
534 `vars' argument, which must be a dictionary whose contents overrides
535 any pre-existing defaults.
537 The section DEFAULT is special.
539 d = self._defaults.copy()
540 try:
541 d.update(self._sections[section])
542 except KeyError:
543 if section != DEFAULTSECT:
544 raise NoSectionError(section)
545 # Update with the entry specific variables
546 if vars:
547 for key, value in vars.items():
548 d[self.optionxform(key)] = value
549 options = d.keys()
550 if "__name__" in options:
551 options.remove("__name__")
552 if raw:
553 return [(option, d[option])
554 for option in options]
555 else:
556 return [(option, self._interpolate(section, option, d[option], d))
557 for option in options]
559 def _interpolate(self, section, option, rawval, vars):
560 # do the string interpolation
561 value = rawval
562 depth = MAX_INTERPOLATION_DEPTH
563 while depth: # Loop through this until it's done
564 depth -= 1
565 if "%(" in value:
566 value = self._KEYCRE.sub(self._interpolation_replace, value)
567 try:
568 value = value % vars
569 except KeyError, e:
570 raise InterpolationMissingOptionError(
571 option, section, rawval, e[0])
572 else:
573 break
574 if "%(" in value:
575 raise InterpolationDepthError(option, section, rawval)
576 return value
578 _KEYCRE = re.compile(r"%\(([^)]*)\)s|.")
580 def _interpolation_replace(self, match):
581 s = match.group(1)
582 if s is None:
583 return match.group()
584 else:
585 return "%%(%s)s" % self.optionxform(s)
588 class SafeConfigParser(ConfigParser):
590 def _interpolate(self, section, option, rawval, vars):
591 # do the string interpolation
592 L = []
593 self._interpolate_some(option, L, rawval, section, vars, 1)
594 return ''.join(L)
596 _interpvar_match = re.compile(r"%\(([^)]+)\)s").match
598 def _interpolate_some(self, option, accum, rest, section, map, depth):
599 if depth > MAX_INTERPOLATION_DEPTH:
600 raise InterpolationDepthError(option, section, rest)
601 while rest:
602 p = rest.find("%")
603 if p < 0:
604 accum.append(rest)
605 return
606 if p > 0:
607 accum.append(rest[:p])
608 rest = rest[p:]
609 # p is no longer used
610 c = rest[1:2]
611 if c == "%":
612 accum.append("%")
613 rest = rest[2:]
614 elif c == "(":
615 m = self._interpvar_match(rest)
616 if m is None:
617 raise InterpolationSyntaxError(option, section,
618 "bad interpolation variable reference %r" % rest)
619 var = self.optionxform(m.group(1))
620 rest = rest[m.end():]
621 try:
622 v = map[var]
623 except KeyError:
624 raise InterpolationMissingOptionError(
625 option, section, rest, var)
626 if "%" in v:
627 self._interpolate_some(option, accum, v,
628 section, map, depth + 1)
629 else:
630 accum.append(v)
631 else:
632 raise InterpolationSyntaxError(
633 option, section,
634 "'%%' must be followed by '%%' or '(', found: %r" % (rest,))
636 def set(self, section, option, value):
637 """Set an option. Extend ConfigParser.set: check for string values."""
638 if not isinstance(value, basestring):
639 raise TypeError("option values must be strings")
640 ConfigParser.set(self, section, option, value)