Merged release21-maint changes.
[python/dscho.git] / Lib / ConfigParser.py
blob699803d84a5a117ca825afedda35ed8ce463d89b
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 has_option(section, option)
46 return whether the given section has the given option
48 read(filenames)
49 read and parse the list of named configuration files, given by
50 name. A single filename is also allowed. Non-existing files
51 are ignored.
53 readfp(fp, filename=None)
54 read and parse one configuration file, given as a file object.
55 The filename defaults to fp.name; it is only used in error
56 messages (if fp has no `name' attribute, the string `<???>' is used).
58 get(section, option, raw=0, vars=None)
59 return a string value for the named option. All % interpolations are
60 expanded in the return values, based on the defaults passed into the
61 constructor and the DEFAULT section. Additional substitutions may be
62 provided using the `vars' argument, which must be a dictionary whose
63 contents override any pre-existing defaults.
65 getint(section, options)
66 like get(), but convert value to an integer
68 getfloat(section, options)
69 like get(), but convert value to a float
71 getboolean(section, options)
72 like get(), but convert value to a boolean (currently defined as 0 or
73 1, only)
75 remove_section(section)
76 remove the given file section and all its options
78 remove_option(section, option)
79 remove the given option from the given section
81 set(section, option, value)
82 set the given option
84 write(fp)
85 write the configuration state in .ini format
86 """
88 import string
89 import re
91 __all__ = ["NoSectionError","DuplicateSectionError","NoOptionError",
92 "InterpolationError","InterpolationDepthError","ParsingError",
93 "MissingSectionHeaderError","ConfigParser",
94 "MAX_INTERPOLATION_DEPTH"]
96 DEFAULTSECT = "DEFAULT"
98 MAX_INTERPOLATION_DEPTH = 10
102 # exception classes
103 class Error(Exception):
104 def __init__(self, msg=''):
105 self._msg = msg
106 Exception.__init__(self, msg)
107 def __repr__(self):
108 return self._msg
109 __str__ = __repr__
111 class NoSectionError(Error):
112 def __init__(self, section):
113 Error.__init__(self, 'No section: %s' % section)
114 self.section = section
116 class DuplicateSectionError(Error):
117 def __init__(self, section):
118 Error.__init__(self, "Section %s already exists" % section)
119 self.section = section
121 class NoOptionError(Error):
122 def __init__(self, option, section):
123 Error.__init__(self, "No option `%s' in section: %s" %
124 (option, section))
125 self.option = option
126 self.section = section
128 class InterpolationError(Error):
129 def __init__(self, reference, option, section, rawval):
130 Error.__init__(self,
131 "Bad value substitution:\n"
132 "\tsection: [%s]\n"
133 "\toption : %s\n"
134 "\tkey : %s\n"
135 "\trawval : %s\n"
136 % (section, option, reference, rawval))
137 self.reference = reference
138 self.option = option
139 self.section = section
141 class InterpolationDepthError(Error):
142 def __init__(self, option, section, rawval):
143 Error.__init__(self,
144 "Value interpolation too deeply recursive:\n"
145 "\tsection: [%s]\n"
146 "\toption : %s\n"
147 "\trawval : %s\n"
148 % (section, option, rawval))
149 self.option = option
150 self.section = section
152 class ParsingError(Error):
153 def __init__(self, filename):
154 Error.__init__(self, 'File contains parsing errors: %s' % filename)
155 self.filename = filename
156 self.errors = []
158 def append(self, lineno, line):
159 self.errors.append((lineno, line))
160 self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
162 class MissingSectionHeaderError(ParsingError):
163 def __init__(self, filename, lineno, line):
164 Error.__init__(
165 self,
166 'File contains no section headers.\nfile: %s, line: %d\n%s' %
167 (filename, lineno, line))
168 self.filename = filename
169 self.lineno = lineno
170 self.line = line
174 class ConfigParser:
175 def __init__(self, defaults=None):
176 self.__sections = {}
177 if defaults is None:
178 self.__defaults = {}
179 else:
180 self.__defaults = defaults
182 def defaults(self):
183 return self.__defaults
185 def sections(self):
186 """Return a list of section names, excluding [DEFAULT]"""
187 # self.__sections will never have [DEFAULT] in it
188 return self.__sections.keys()
190 def add_section(self, section):
191 """Create a new section in the configuration.
193 Raise DuplicateSectionError if a section by the specified name
194 already exists.
196 if self.__sections.has_key(section):
197 raise DuplicateSectionError(section)
198 self.__sections[section] = {}
200 def has_section(self, section):
201 """Indicate whether the named section is present in the configuration.
203 The DEFAULT section is not acknowledged.
205 return section in self.sections()
207 def options(self, section):
208 """Return a list of option names for the given section name."""
209 try:
210 opts = self.__sections[section].copy()
211 except KeyError:
212 raise NoSectionError(section)
213 opts.update(self.__defaults)
214 if opts.has_key('__name__'):
215 del opts['__name__']
216 return opts.keys()
218 def has_option(self, section, option):
219 """Return whether the given section has the given option."""
220 return option in self.options(section)
222 def read(self, filenames):
223 """Read and parse a filename or a list of filenames.
225 Files that cannot be opened are silently ignored; this is
226 designed so that you can specify a list of potential
227 configuration file locations (e.g. current directory, user's
228 home directory, systemwide directory), and all existing
229 configuration files in the list will be read. A single
230 filename may also be given.
232 if type(filenames) in [type(''), type(u'')]:
233 filenames = [filenames]
234 for filename in filenames:
235 try:
236 fp = open(filename)
237 except IOError:
238 continue
239 self.__read(fp, filename)
240 fp.close()
242 def readfp(self, fp, filename=None):
243 """Like read() but the argument must be a file-like object.
245 The `fp' argument must have a `readline' method. Optional
246 second argument is the `filename', which if not given, is
247 taken from fp.name. If fp has no `name' attribute, `<???>' is
248 used.
251 if filename is None:
252 try:
253 filename = fp.name
254 except AttributeError:
255 filename = '<???>'
256 self.__read(fp, filename)
258 def get(self, section, option, raw=0, vars=None):
259 """Get an option value for a given section.
261 All % interpolations are expanded in the return values, based on the
262 defaults passed into the constructor, unless the optional argument
263 `raw' is true. Additional substitutions may be provided using the
264 `vars' argument, which must be a dictionary whose contents overrides
265 any pre-existing defaults.
267 The section DEFAULT is special.
269 try:
270 sectdict = self.__sections[section].copy()
271 except KeyError:
272 if section == DEFAULTSECT:
273 sectdict = {}
274 else:
275 raise NoSectionError(section)
276 d = self.__defaults.copy()
277 d.update(sectdict)
278 # Update with the entry specific variables
279 if vars:
280 d.update(vars)
281 option = self.optionxform(option)
282 try:
283 rawval = d[option]
284 except KeyError:
285 raise NoOptionError(option, section)
287 if raw:
288 return rawval
290 # do the string interpolation
291 value = rawval # Make it a pretty variable name
292 depth = 0
293 while depth < 10: # Loop through this until it's done
294 depth = depth + 1
295 if value.find("%(") >= 0:
296 try:
297 value = value % d
298 except KeyError, key:
299 raise InterpolationError(key, option, section, rawval)
300 else:
301 break
302 if value.find("%(") >= 0:
303 raise InterpolationDepthError(option, section, rawval)
304 return value
306 def __get(self, section, conv, option):
307 return conv(self.get(section, option))
309 def getint(self, section, option):
310 return self.__get(section, string.atoi, option)
312 def getfloat(self, section, option):
313 return self.__get(section, string.atof, option)
315 def getboolean(self, section, option):
316 v = self.get(section, option)
317 val = int(v)
318 if val not in (0, 1):
319 raise ValueError, 'Not a boolean: %s' % v
320 return val
322 def optionxform(self, optionstr):
323 return optionstr.lower()
325 def has_option(self, section, option):
326 """Check for the existence of a given option in a given section."""
327 if not section or section == "DEFAULT":
328 return self.__defaults.has_key(option)
329 elif not self.has_section(section):
330 return 0
331 else:
332 option = self.optionxform(option)
333 return self.__sections[section].has_key(option)
335 def set(self, section, option, value):
336 """Set an option."""
337 if not section or section == "DEFAULT":
338 sectdict = self.__defaults
339 else:
340 try:
341 sectdict = self.__sections[section]
342 except KeyError:
343 raise NoSectionError(section)
344 option = self.optionxform(option)
345 sectdict[option] = value
347 def write(self, fp):
348 """Write an .ini-format representation of the configuration state."""
349 if self.__defaults:
350 fp.write("[DEFAULT]\n")
351 for (key, value) in self.__defaults.items():
352 fp.write("%s = %s\n" % (key, value))
353 fp.write("\n")
354 for section in self.sections():
355 fp.write("[" + section + "]\n")
356 sectdict = self.__sections[section]
357 for (key, value) in sectdict.items():
358 if key == "__name__":
359 continue
360 fp.write("%s = %s\n" % (key, value))
361 fp.write("\n")
363 def remove_option(self, section, option):
364 """Remove an option."""
365 if not section or section == "DEFAULT":
366 sectdict = self.__defaults
367 else:
368 try:
369 sectdict = self.__sections[section]
370 except KeyError:
371 raise NoSectionError(section)
372 option = self.optionxform(option)
373 existed = sectdict.has_key(option)
374 if existed:
375 del sectdict[option]
376 return existed
378 def remove_section(self, section):
379 """Remove a file section."""
380 if self.__sections.has_key(section):
381 del self.__sections[section]
382 return 1
383 else:
384 return 0
387 # Regular expressions for parsing section headers and options. Note a
388 # slight semantic change from the previous version, because of the use
389 # of \w, _ is allowed in section header names.
390 SECTCRE = re.compile(
391 r'\[' # [
392 r'(?P<header>[^]]+)' # very permissive!
393 r'\]' # ]
395 OPTCRE = re.compile(
396 r'(?P<option>[]\-[\w_.*,(){}]+)' # a lot of stuff found by IvL
397 r'[ \t]*(?P<vi>[:=])[ \t]*' # any number of space/tab,
398 # followed by separator
399 # (either : or =), followed
400 # by any # space/tab
401 r'(?P<value>.*)$' # everything up to eol
404 def __read(self, fp, fpname):
405 """Parse a sectioned setup file.
407 The sections in setup file contains a title line at the top,
408 indicated by a name in square brackets (`[]'), plus key/value
409 options lines, indicated by `name: value' format lines.
410 Continuation are represented by an embedded newline then
411 leading whitespace. Blank lines, lines beginning with a '#',
412 and just about everything else is ignored.
414 cursect = None # None, or a dictionary
415 optname = None
416 lineno = 0
417 e = None # None, or an exception
418 while 1:
419 line = fp.readline()
420 if not line:
421 break
422 lineno = lineno + 1
423 # comment or blank line?
424 if line.strip() == '' or line[0] in '#;':
425 continue
426 if line.split()[0].lower() == 'rem' \
427 and line[0] in "rR": # no leading whitespace
428 continue
429 # continuation line?
430 if line[0] in ' \t' and cursect is not None and optname:
431 value = line.strip()
432 if value:
433 k = self.optionxform(optname)
434 cursect[k] = "%s\n%s" % (cursect[k], value)
435 # a section header or option header?
436 else:
437 # is it a section header?
438 mo = self.SECTCRE.match(line)
439 if mo:
440 sectname = mo.group('header')
441 if self.__sections.has_key(sectname):
442 cursect = self.__sections[sectname]
443 elif sectname == DEFAULTSECT:
444 cursect = self.__defaults
445 else:
446 cursect = {'__name__': sectname}
447 self.__sections[sectname] = cursect
448 # So sections can't start with a continuation line
449 optname = None
450 # no section header in the file?
451 elif cursect is None:
452 raise MissingSectionHeaderError(fpname, lineno, `line`)
453 # an option line?
454 else:
455 mo = self.OPTCRE.match(line)
456 if mo:
457 optname, vi, optval = mo.group('option', 'vi', 'value')
458 if vi in ('=', ':') and ';' in optval:
459 # ';' is a comment delimiter only if it follows
460 # a spacing character
461 pos = optval.find(';')
462 if pos and optval[pos-1] in string.whitespace:
463 optval = optval[:pos]
464 optval = optval.strip()
465 # allow empty values
466 if optval == '""':
467 optval = ''
468 cursect[self.optionxform(optname)] = optval
469 else:
470 # a non-fatal parsing error occurred. set up the
471 # exception but keep going. the exception will be
472 # raised at the end of the file and will contain a
473 # list of all bogus lines
474 if not e:
475 e = ParsingError(fpname)
476 e.append(lineno, `line`)
477 # if any parsing errors occurred, raise an exception
478 if e:
479 raise e