Bump version number to 2.4.2 to pick up the latest minor bug fixes.
[python/dscho.git] / Lib / ConfigParser.py
blob842a576cef678118acbd538aa20e09b2486dc982
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 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 it's 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.
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=0, 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 0, and 1, true,
71 yes, on for 1). Returns 0 or 1.
73 items(section, raw=0, 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","ParsingError",
94 "MissingSectionHeaderError","ConfigParser",
95 "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"]
97 DEFAULTSECT = "DEFAULT"
99 MAX_INTERPOLATION_DEPTH = 10
103 # exception classes
104 class Error(Exception):
105 def __init__(self, msg=''):
106 self._msg = msg
107 Exception.__init__(self, msg)
108 def __repr__(self):
109 return self._msg
110 __str__ = __repr__
112 class NoSectionError(Error):
113 def __init__(self, section):
114 Error.__init__(self, 'No section: %s' % section)
115 self.section = section
117 class DuplicateSectionError(Error):
118 def __init__(self, section):
119 Error.__init__(self, "Section %s already exists" % section)
120 self.section = section
122 class NoOptionError(Error):
123 def __init__(self, option, section):
124 Error.__init__(self, "No option `%s' in section: %s" %
125 (option, section))
126 self.option = option
127 self.section = section
129 class InterpolationError(Error):
130 def __init__(self, reference, option, section, rawval):
131 Error.__init__(self,
132 "Bad value substitution:\n"
133 "\tsection: [%s]\n"
134 "\toption : %s\n"
135 "\tkey : %s\n"
136 "\trawval : %s\n"
137 % (section, option, reference, rawval))
138 self.reference = reference
139 self.option = option
140 self.section = section
142 class InterpolationDepthError(Error):
143 def __init__(self, option, section, rawval):
144 Error.__init__(self,
145 "Value interpolation too deeply recursive:\n"
146 "\tsection: [%s]\n"
147 "\toption : %s\n"
148 "\trawval : %s\n"
149 % (section, option, rawval))
150 self.option = option
151 self.section = section
153 class ParsingError(Error):
154 def __init__(self, filename):
155 Error.__init__(self, 'File contains parsing errors: %s' % filename)
156 self.filename = filename
157 self.errors = []
159 def append(self, lineno, line):
160 self.errors.append((lineno, line))
161 self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
163 class MissingSectionHeaderError(ParsingError):
164 def __init__(self, filename, lineno, line):
165 Error.__init__(
166 self,
167 'File contains no section headers.\nfile: %s, line: %d\n%s' %
168 (filename, lineno, line))
169 self.filename = filename
170 self.lineno = lineno
171 self.line = line
175 class ConfigParser:
176 def __init__(self, defaults=None):
177 self.__sections = {}
178 if defaults is None:
179 self.__defaults = {}
180 else:
181 self.__defaults = defaults
183 def defaults(self):
184 return self.__defaults
186 def sections(self):
187 """Return a list of section names, excluding [DEFAULT]"""
188 # self.__sections will never have [DEFAULT] in it
189 return self.__sections.keys()
191 def add_section(self, section):
192 """Create a new section in the configuration.
194 Raise DuplicateSectionError if a section by the specified name
195 already exists.
197 if section in self.__sections:
198 raise DuplicateSectionError(section)
199 self.__sections[section] = {}
201 def has_section(self, section):
202 """Indicate whether the named section is present in the configuration.
204 The DEFAULT section is not acknowledged.
206 return section in self.__sections
208 def options(self, section):
209 """Return a list of option names for the given section name."""
210 try:
211 opts = self.__sections[section].copy()
212 except KeyError:
213 raise NoSectionError(section)
214 opts.update(self.__defaults)
215 if '__name__' in opts:
216 del opts['__name__']
217 return opts.keys()
219 def read(self, filenames):
220 """Read and parse a filename or a list of filenames.
222 Files that cannot be opened are silently ignored; this is
223 designed so that you can specify a list of potential
224 configuration file locations (e.g. current directory, user's
225 home directory, systemwide directory), and all existing
226 configuration files in the list will be read. A single
227 filename may also be given.
229 if isinstance(filenames, basestring):
230 filenames = [filenames]
231 for filename in filenames:
232 try:
233 fp = open(filename)
234 except IOError:
235 continue
236 self.__read(fp, filename)
237 fp.close()
239 def readfp(self, fp, filename=None):
240 """Like read() but the argument must be a file-like object.
242 The `fp' argument must have a `readline' method. Optional
243 second argument is the `filename', which if not given, is
244 taken from fp.name. If fp has no `name' attribute, `<???>' is
245 used.
248 if filename is None:
249 try:
250 filename = fp.name
251 except AttributeError:
252 filename = '<???>'
253 self.__read(fp, filename)
255 def get(self, section, option, raw=0, vars=None):
256 """Get an option value for a given section.
258 All % interpolations are expanded in the return values, based on the
259 defaults passed into the constructor, unless the optional argument
260 `raw' is true. Additional substitutions may be provided using the
261 `vars' argument, which must be a dictionary whose contents overrides
262 any pre-existing defaults.
264 The section DEFAULT is special.
266 d = self.__defaults.copy()
267 try:
268 d.update(self.__sections[section])
269 except KeyError:
270 if section != DEFAULTSECT:
271 raise NoSectionError(section)
272 # Update with the entry specific variables
273 if vars is not None:
274 d.update(vars)
275 option = self.optionxform(option)
276 try:
277 value = d[option]
278 except KeyError:
279 raise NoOptionError(option, section)
281 if raw:
282 return value
283 return self._interpolate(section, option, value, d)
285 def items(self, section, raw=0, vars=None):
286 """Return a list of tuples with (name, value) for each option
287 in the section.
289 All % interpolations are expanded in the return values, based on the
290 defaults passed into the constructor, unless the optional argument
291 `raw' is true. Additional substitutions may be provided using the
292 `vars' argument, which must be a dictionary whose contents overrides
293 any pre-existing defaults.
295 The section DEFAULT is special.
297 d = self.__defaults.copy()
298 try:
299 d.update(self.__sections[section])
300 except KeyError:
301 if section != DEFAULTSECT:
302 raise NoSectionError(section)
303 # Update with the entry specific variables
304 if vars:
305 d.update(vars)
306 if raw:
307 for option in self.options(section):
308 yield (option, d[option])
309 else:
310 for option in self.options(section):
311 yield (option,
312 self._interpolate(section, option, d[option], d))
314 def _interpolate(self, section, option, rawval, vars):
315 # do the string interpolation
316 value = rawval
317 depth = MAX_INTERPOLATION_DEPTH
318 while depth: # Loop through this until it's done
319 depth -= 1
320 if value.find("%(") != -1:
321 try:
322 value = value % vars
323 except KeyError, key:
324 raise InterpolationError(key, option, section, rawval)
325 else:
326 break
327 if value.find("%(") != -1:
328 raise InterpolationDepthError(option, section, rawval)
329 return value
331 def __get(self, section, conv, option):
332 return conv(self.get(section, option))
334 def getint(self, section, option):
335 return self.__get(section, int, option)
337 def getfloat(self, section, option):
338 return self.__get(section, float, option)
340 _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
341 '0': False, 'no': False, 'false': False, 'off': False}
343 def getboolean(self, section, option):
344 v = self.get(section, option)
345 if v.lower() not in self._boolean_states:
346 raise ValueError, 'Not a boolean: %s' % v
347 return self._boolean_states[v.lower()]
349 def optionxform(self, optionstr):
350 return optionstr.lower()
352 def has_option(self, section, option):
353 """Check for the existence of a given option in a given section."""
354 if not section or section == DEFAULTSECT:
355 option = self.optionxform(option)
356 return option in self.__defaults
357 elif section not in self.__sections:
358 return 0
359 else:
360 option = self.optionxform(option)
361 return (option in self.__sections[section]
362 or option in self.__defaults)
364 def set(self, section, option, value):
365 """Set an option."""
366 if not section or section == DEFAULTSECT:
367 sectdict = self.__defaults
368 else:
369 try:
370 sectdict = self.__sections[section]
371 except KeyError:
372 raise NoSectionError(section)
373 sectdict[self.optionxform(option)] = value
375 def write(self, fp):
376 """Write an .ini-format representation of the configuration state."""
377 if self.__defaults:
378 fp.write("[%s]\n" % DEFAULTSECT)
379 for (key, value) in self.__defaults.items():
380 fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t')))
381 fp.write("\n")
382 for section in self.__sections:
383 fp.write("[%s]\n" % section)
384 for (key, value) in self.__sections[section].items():
385 if key != "__name__":
386 fp.write("%s = %s\n" %
387 (key, str(value).replace('\n', '\n\t')))
388 fp.write("\n")
390 def remove_option(self, section, option):
391 """Remove an option."""
392 if not section or section == DEFAULTSECT:
393 sectdict = self.__defaults
394 else:
395 try:
396 sectdict = self.__sections[section]
397 except KeyError:
398 raise NoSectionError(section)
399 option = self.optionxform(option)
400 existed = option in sectdict
401 if existed:
402 del sectdict[option]
403 return existed
405 def remove_section(self, section):
406 """Remove a file section."""
407 existed = section in self.__sections
408 if existed:
409 del self.__sections[section]
410 return existed
413 # Regular expressions for parsing section headers and options.
415 SECTCRE = re.compile(
416 r'\[' # [
417 r'(?P<header>[^]]+)' # very permissive!
418 r'\]' # ]
420 OPTCRE = re.compile(
421 r'(?P<option>[^:=\s][^:=]*)' # very permissive!
422 r'\s*(?P<vi>[:=])\s*' # any number of space/tab,
423 # followed by separator
424 # (either : or =), followed
425 # by any # space/tab
426 r'(?P<value>.*)$' # everything up to eol
429 def __read(self, fp, fpname):
430 """Parse a sectioned setup file.
432 The sections in setup file contains a title line at the top,
433 indicated by a name in square brackets (`[]'), plus key/value
434 options lines, indicated by `name: value' format lines.
435 Continuation are represented by an embedded newline then
436 leading whitespace. Blank lines, lines beginning with a '#',
437 and just about everything else is ignored.
439 cursect = None # None, or a dictionary
440 optname = None
441 lineno = 0
442 e = None # None, or an exception
443 while 1:
444 line = fp.readline()
445 if not line:
446 break
447 lineno = lineno + 1
448 # comment or blank line?
449 if line.strip() == '' or line[0] in '#;':
450 continue
451 if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
452 # no leading whitespace
453 continue
454 # continuation line?
455 if line[0].isspace() and cursect is not None and optname:
456 value = line.strip()
457 if value:
458 cursect[optname] = "%s\n%s" % (cursect[optname], value)
459 # a section header or option header?
460 else:
461 # is it a section header?
462 mo = self.SECTCRE.match(line)
463 if mo:
464 sectname = mo.group('header')
465 if sectname in self.__sections:
466 cursect = self.__sections[sectname]
467 elif sectname == DEFAULTSECT:
468 cursect = self.__defaults
469 else:
470 cursect = {'__name__': sectname}
471 self.__sections[sectname] = cursect
472 # So sections can't start with a continuation line
473 optname = None
474 # no section header in the file?
475 elif cursect is None:
476 raise MissingSectionHeaderError(fpname, lineno, `line`)
477 # an option line?
478 else:
479 mo = self.OPTCRE.match(line)
480 if mo:
481 optname, vi, optval = mo.group('option', 'vi', 'value')
482 if vi in ('=', ':') and ';' in optval:
483 # ';' is a comment delimiter only if it follows
484 # a spacing character
485 pos = optval.find(';')
486 if pos != -1 and optval[pos-1].isspace():
487 optval = optval[:pos]
488 optval = optval.strip()
489 # allow empty values
490 if optval == '""':
491 optval = ''
492 optname = self.optionxform(optname.rstrip())
493 cursect[optname] = optval
494 else:
495 # a non-fatal parsing error occurred. set up the
496 # exception but keep going. the exception will be
497 # raised at the end of the file and will contain a
498 # list of all bogus lines
499 if not e:
500 e = ParsingError(fpname)
501 e.append(lineno, `line`)
502 # if any parsing errors occurred, raise an exception
503 if e:
504 raise e