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