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