blob: 504368752ccd0aec7fe8e64dde9222405ce3c1b3 [file] [log] [blame]
Guido van Rossumb978d181997-12-09 16:56:41 +00001"""Configuration file parser.
2
3A setup file consists of sections, lead by a "[section]" header,
4and followed by "name: value" entries, with continuations and such in
Guido van Rossume03c0501998-08-12 02:38:11 +00005the style of RFC 822.
Guido van Rossumb978d181997-12-09 16:56:41 +00006
Guido van Rossume03c0501998-08-12 02:38:11 +00007The option values can contain format strings which refer to other values in
8the same section, or values in a special [DEFAULT] section.
9
Guido van Rossumb978d181997-12-09 16:56:41 +000010For example:
11
12 something: %(dir)s/whatever
13
14would resolve the "%(dir)s" to the value of dir. All reference
15expansions are done late, on demand.
16
17Intrinsic defaults can be specified by passing them into the
18ConfigParser constructor as a dictionary.
19
20class:
21
22ConfigParser -- responsible for for parsing a list of
23 configuration files, and managing the parsed database.
24
25 methods:
26
Guido van Rossum2e7840f1999-02-09 18:40:13 +000027 __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.
Guido van Rossumb978d181997-12-09 16:56:41 +000032
Guido van Rossum2e7840f1999-02-09 18:40:13 +000033 sections()
34 return all the configuration section names, sans DEFAULT
Guido van Rossumb978d181997-12-09 16:56:41 +000035
Guido van Rossumaad67612000-05-08 17:31:04 +000036 has_section(section)
37 return whether the given section exists
38
Guido van Rossum8d691c82000-09-01 19:25:51 +000039 has_option(section, option)
40 return whether the given option exists in the given section
41
Guido van Rossum2e7840f1999-02-09 18:40:13 +000042 options(section)
43 return list of configuration options for the named section
Guido van Rossumb978d181997-12-09 16:56:41 +000044
Guido van Rossumaad67612000-05-08 17:31:04 +000045 has_option(section, option)
46 return whether the given section has the given option
47
Guido van Rossum2e7840f1999-02-09 18:40:13 +000048 read(filenames)
Guido van Rossumaad67612000-05-08 17:31:04 +000049 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.
52
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).
Guido van Rossumb978d181997-12-09 16:56:41 +000057
Guido van Rossum2e7840f1999-02-09 18:40:13 +000058 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.
Guido van Rossumb978d181997-12-09 16:56:41 +000064
Guido van Rossum2e7840f1999-02-09 18:40:13 +000065 getint(section, options)
66 like get(), but convert value to an integer
Guido van Rossumb978d181997-12-09 16:56:41 +000067
Guido van Rossum2e7840f1999-02-09 18:40:13 +000068 getfloat(section, options)
69 like get(), but convert value to a float
Guido van Rossumb978d181997-12-09 16:56:41 +000070
Guido van Rossum2e7840f1999-02-09 18:40:13 +000071 getboolean(section, options)
72 like get(), but convert value to a boolean (currently defined as 0 or
73 1, only)
Guido van Rossum8d691c82000-09-01 19:25:51 +000074
75 remove_section(section)
76 remove the given file section and all its options
77
78 remove_option(section, option)
79 remove the given option from the given section
80
81 set(section, option, value)
82 set the given option
83
84 write(fp)
85 write the configuration state in .ini format
Guido van Rossumb978d181997-12-09 16:56:41 +000086"""
87
88import sys
89import string
Guido van Rossume03c0501998-08-12 02:38:11 +000090import re
Guido van Rossumb978d181997-12-09 16:56:41 +000091
92DEFAULTSECT = "DEFAULT"
93
Guido van Rossume8d2f552000-10-09 22:14:43 +000094MAX_INTERPOLATION_DEPTH = 10
95
Guido van Rossumb978d181997-12-09 16:56:41 +000096
97
98# exception classes
99class Error:
100 def __init__(self, msg=''):
Guido van Rossume03c0501998-08-12 02:38:11 +0000101 self._msg = msg
Guido van Rossumb978d181997-12-09 16:56:41 +0000102 def __repr__(self):
Guido van Rossume03c0501998-08-12 02:38:11 +0000103 return self._msg
Guido van Rossumb978d181997-12-09 16:56:41 +0000104
105class NoSectionError(Error):
106 def __init__(self, section):
Guido van Rossum548703a1998-03-26 22:14:20 +0000107 Error.__init__(self, 'No section: %s' % section)
108 self.section = section
Guido van Rossumb978d181997-12-09 16:56:41 +0000109
110class DuplicateSectionError(Error):
111 def __init__(self, section):
Guido van Rossum548703a1998-03-26 22:14:20 +0000112 Error.__init__(self, "Section %s already exists" % section)
113 self.section = section
Guido van Rossumb978d181997-12-09 16:56:41 +0000114
115class NoOptionError(Error):
116 def __init__(self, option, section):
Guido van Rossum548703a1998-03-26 22:14:20 +0000117 Error.__init__(self, "No option `%s' in section: %s" %
118 (option, section))
119 self.option = option
120 self.section = section
Guido van Rossumb978d181997-12-09 16:56:41 +0000121
122class InterpolationError(Error):
Guido van Rossume03c0501998-08-12 02:38:11 +0000123 def __init__(self, reference, option, section, rawval):
Guido van Rossum548703a1998-03-26 22:14:20 +0000124 Error.__init__(self,
Guido van Rossume03c0501998-08-12 02:38:11 +0000125 "Bad value substitution:\n"
126 "\tsection: [%s]\n"
127 "\toption : %s\n"
128 "\tkey : %s\n"
129 "\trawval : %s\n"
130 % (section, option, reference, rawval))
Guido van Rossum548703a1998-03-26 22:14:20 +0000131 self.reference = reference
132 self.option = option
133 self.section = section
Guido van Rossumb978d181997-12-09 16:56:41 +0000134
Guido van Rossume8d2f552000-10-09 22:14:43 +0000135class InterpolationDepthError(Error):
136 def __init__(self, option, section, rawval):
137 Error.__init__(self,
138 "Value interpolation too deeply recursive:\n"
139 "\tsection: [%s]\n"
140 "\toption : %s\n"
141 "\trawval : %s\n"
142 % (section, option, rawval))
143 self.option = option
144 self.section = section
Guido van Rossume03c0501998-08-12 02:38:11 +0000145
146class ParsingError(Error):
147 def __init__(self, filename):
148 Error.__init__(self, 'File contains parsing errors: %s' % filename)
149 self.filename = filename
150 self.errors = []
151
152 def append(self, lineno, line):
153 self.errors.append((lineno, line))
154 self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
155
Guido van Rossume8d2f552000-10-09 22:14:43 +0000156class MissingSectionHeaderError(ParsingError):
157 def __init__(self, filename, lineno, line):
158 Error.__init__(
159 self,
160 'File contains no section headers.\nfile: %s, line: %d\n%s' %
161 (filename, lineno, line))
162 self.filename = filename
163 self.lineno = lineno
164 self.line = line
165
Guido van Rossumb978d181997-12-09 16:56:41 +0000166
167
168class ConfigParser:
169 def __init__(self, defaults=None):
Guido van Rossum548703a1998-03-26 22:14:20 +0000170 self.__sections = {}
171 if defaults is None:
172 self.__defaults = {}
173 else:
174 self.__defaults = defaults
Guido van Rossumb978d181997-12-09 16:56:41 +0000175
176 def defaults(self):
Guido van Rossum548703a1998-03-26 22:14:20 +0000177 return self.__defaults
Guido van Rossumb978d181997-12-09 16:56:41 +0000178
179 def sections(self):
Guido van Rossum548703a1998-03-26 22:14:20 +0000180 """Return a list of section names, excluding [DEFAULT]"""
181 # self.__sections will never have [DEFAULT] in it
182 return self.__sections.keys()
Guido van Rossumb978d181997-12-09 16:56:41 +0000183
184 def add_section(self, section):
Guido van Rossum548703a1998-03-26 22:14:20 +0000185 """Create a new section in the configuration.
Guido van Rossumb978d181997-12-09 16:56:41 +0000186
Guido van Rossum548703a1998-03-26 22:14:20 +0000187 Raise DuplicateSectionError if a section by the specified name
188 already exists.
189 """
190 if self.__sections.has_key(section):
191 raise DuplicateSectionError(section)
192 self.__sections[section] = {}
Guido van Rossumb978d181997-12-09 16:56:41 +0000193
194 def has_section(self, section):
Guido van Rossum548703a1998-03-26 22:14:20 +0000195 """Indicate whether the named section is present in the configuration.
Guido van Rossumb978d181997-12-09 16:56:41 +0000196
Guido van Rossum548703a1998-03-26 22:14:20 +0000197 The DEFAULT section is not acknowledged.
198 """
Guido van Rossume8d2f552000-10-09 22:14:43 +0000199 return section in self.sections()
Guido van Rossumb978d181997-12-09 16:56:41 +0000200
201 def options(self, section):
Guido van Rossumaad67612000-05-08 17:31:04 +0000202 """Return a list of option names for the given section name."""
Guido van Rossum548703a1998-03-26 22:14:20 +0000203 try:
204 opts = self.__sections[section].copy()
205 except KeyError:
206 raise NoSectionError(section)
207 opts.update(self.__defaults)
Guido van Rossume8d2f552000-10-09 22:14:43 +0000208 if opts.has_key('__name__'):
209 del opts['__name__']
Guido van Rossum548703a1998-03-26 22:14:20 +0000210 return opts.keys()
Guido van Rossumb978d181997-12-09 16:56:41 +0000211
Guido van Rossumaad67612000-05-08 17:31:04 +0000212 def has_option(self, section, option):
213 """Return whether the given section has the given option."""
Guido van Rossume8d2f552000-10-09 22:14:43 +0000214 return option in self.options(section)
Guido van Rossumaad67612000-05-08 17:31:04 +0000215
Guido van Rossumb978d181997-12-09 16:56:41 +0000216 def read(self, filenames):
Guido van Rossumaad67612000-05-08 17:31:04 +0000217 """Read and parse a filename or a list of filenames.
218
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.
225 """
Guido van Rossum3e06ab12000-06-29 19:35:29 +0000226 if type(filenames) in [type(''), type(u'')]:
Guido van Rossum548703a1998-03-26 22:14:20 +0000227 filenames = [filenames]
Guido van Rossumaad67612000-05-08 17:31:04 +0000228 for filename in filenames:
Guido van Rossum548703a1998-03-26 22:14:20 +0000229 try:
Guido van Rossumaad67612000-05-08 17:31:04 +0000230 fp = open(filename)
Guido van Rossum548703a1998-03-26 22:14:20 +0000231 except IOError:
Guido van Rossumaad67612000-05-08 17:31:04 +0000232 continue
233 self.__read(fp, filename)
234 fp.close()
235
236 def readfp(self, fp, filename=None):
237 """Like read() but the argument must be a file-like object.
238
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.
243
244 """
245 if filename is None:
246 try:
247 filename = fp.name
248 except AttributeError:
249 filename = '<???>'
250 self.__read(fp, filename)
Guido van Rossumb978d181997-12-09 16:56:41 +0000251
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000252 def get(self, section, option, raw=0, vars=None):
Guido van Rossum548703a1998-03-26 22:14:20 +0000253 """Get an option value for a given section.
Guido van Rossumb978d181997-12-09 16:56:41 +0000254
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000255 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.
Guido van Rossumb978d181997-12-09 16:56:41 +0000260
Guido van Rossum548703a1998-03-26 22:14:20 +0000261 The section DEFAULT is special.
262 """
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)
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000272 # Update with the entry specific variables
273 if vars:
274 d.update(vars)
Guido van Rossumaad67612000-05-08 17:31:04 +0000275 option = self.optionxform(option)
Guido van Rossum548703a1998-03-26 22:14:20 +0000276 try:
277 rawval = d[option]
278 except KeyError:
279 raise NoOptionError(option, section)
Guido van Rossume8d2f552000-10-09 22:14:43 +0000280
Guido van Rossum548703a1998-03-26 22:14:20 +0000281 if raw:
282 return rawval
Guido van Rossumb978d181997-12-09 16:56:41 +0000283
Guido van Rossume8d2f552000-10-09 22:14:43 +0000284 # do the string interpolation
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000285 value = rawval # Make it a pretty variable name
Guido van Rossum5d856fc1999-02-16 20:05:35 +0000286 depth = 0
287 while depth < 10: # Loop through this until it's done
288 depth = depth + 1
Guido van Rossumaad67612000-05-08 17:31:04 +0000289 if string.find(value, "%(") >= 0:
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000290 try:
291 value = value % d
292 except KeyError, key:
293 raise InterpolationError(key, option, section, rawval)
294 else:
Guido van Rossume8d2f552000-10-09 22:14:43 +0000295 break
296 if value.find("%(") >= 0:
297 raise InterpolationDepthError(option, section, rawval)
298 return value
Guido van Rossum2e7840f1999-02-09 18:40:13 +0000299
Guido van Rossumb978d181997-12-09 16:56:41 +0000300 def __get(self, section, conv, option):
Guido van Rossum548703a1998-03-26 22:14:20 +0000301 return conv(self.get(section, option))
Guido van Rossumb978d181997-12-09 16:56:41 +0000302
303 def getint(self, section, option):
Guido van Rossum548703a1998-03-26 22:14:20 +0000304 return self.__get(section, string.atoi, option)
Guido van Rossumb978d181997-12-09 16:56:41 +0000305
306 def getfloat(self, section, option):
Guido van Rossum548703a1998-03-26 22:14:20 +0000307 return self.__get(section, string.atof, option)
Guido van Rossumb978d181997-12-09 16:56:41 +0000308
309 def getboolean(self, section, option):
Guido van Rossum548703a1998-03-26 22:14:20 +0000310 v = self.get(section, option)
311 val = string.atoi(v)
312 if val not in (0, 1):
313 raise ValueError, 'Not a boolean: %s' % v
314 return val
Guido van Rossumb978d181997-12-09 16:56:41 +0000315
Guido van Rossumaad67612000-05-08 17:31:04 +0000316 def optionxform(self, optionstr):
317 return string.lower(optionstr)
318
Guido van Rossum8d691c82000-09-01 19:25:51 +0000319 def has_option(self, section, option):
320 """Check for the existence of a given option in a given section."""
321 if not section or section == "DEFAULT":
322 return self.__defaults.has_key(option)
323 elif not self.has_section(section):
324 return 0
325 else:
326 return self.__sections[section].has_key(option)
327
328 def set(self, section, option, value):
329 """Set an option."""
330 if not section or section == "DEFAULT":
331 sectdict = self.__defaults
332 else:
333 try:
334 sectdict = self.__sections[section]
335 except KeyError:
336 raise NoSectionError(section)
337 sectdict[option] = value
338
339 def write(self, fp):
340 """Write an .ini-format representation of the configuration state."""
341 if self.__defaults:
342 fp.write("[DEFAULT]\n")
343 for (key, value) in self.__defaults.items():
344 fp.write("%s = %s\n" % (key, value))
345 fp.write("\n")
346 for section in self.sections():
347 fp.write("[" + section + "]\n")
348 sectdict = self.__sections[section]
349 for (key, value) in sectdict.items():
350 if key == "__name__":
351 continue
352 fp.write("%s = %s\n" % (key, value))
353 fp.write("\n")
354
355 def remove_option(self, section, option):
356 """Remove an option."""
357 if not section or section == "DEFAULT":
358 sectdict = self.__defaults
359 else:
360 try:
361 sectdict = self.__sections[section]
362 except KeyError:
363 raise NoSectionError(section)
364 existed = sectdict.has_key(key)
365 if existed:
366 del sectdict[key]
367 return existed
368
369 def remove_section(self, section):
370 """Remove a file section."""
371 if self.__sections.has_key(section):
372 del self.__sections[section]
373 return 1
374 else:
375 return 0
376
Guido van Rossume03c0501998-08-12 02:38:11 +0000377 #
378 # Regular expressions for parsing section headers and options. Note a
379 # slight semantic change from the previous version, because of the use
380 # of \w, _ is allowed in section header names.
Guido van Rossumaad67612000-05-08 17:31:04 +0000381 SECTCRE = re.compile(
Guido van Rossume03c0501998-08-12 02:38:11 +0000382 r'\[' # [
Guido van Rossume8d2f552000-10-09 22:14:43 +0000383 r'(?P<header>[-\w_.*,(){} ]+)' # a lot of stuff found by IvL
Guido van Rossume03c0501998-08-12 02:38:11 +0000384 r'\]' # ]
385 )
Guido van Rossumaad67612000-05-08 17:31:04 +0000386 OPTCRE = re.compile(
387 r'(?P<option>[-\w_.*,(){}]+)' # a lot of stuff found by IvL
388 r'[ \t]*(?P<vi>[:=])[ \t]*' # any number of space/tab,
Guido van Rossume03c0501998-08-12 02:38:11 +0000389 # followed by separator
390 # (either : or =), followed
391 # by any # space/tab
392 r'(?P<value>.*)$' # everything up to eol
393 )
394
Guido van Rossumaad67612000-05-08 17:31:04 +0000395 def __read(self, fp, fpname):
Guido van Rossum548703a1998-03-26 22:14:20 +0000396 """Parse a sectioned setup file.
Guido van Rossumb978d181997-12-09 16:56:41 +0000397
Guido van Rossum548703a1998-03-26 22:14:20 +0000398 The sections in setup file contains a title line at the top,
399 indicated by a name in square brackets (`[]'), plus key/value
400 options lines, indicated by `name: value' format lines.
401 Continuation are represented by an embedded newline then
402 leading whitespace. Blank lines, lines beginning with a '#',
403 and just about everything else is ignored.
404 """
Guido van Rossume03c0501998-08-12 02:38:11 +0000405 cursect = None # None, or a dictionary
Guido van Rossum548703a1998-03-26 22:14:20 +0000406 optname = None
407 lineno = 0
Guido van Rossume03c0501998-08-12 02:38:11 +0000408 e = None # None, or an exception
Guido van Rossum548703a1998-03-26 22:14:20 +0000409 while 1:
410 line = fp.readline()
411 if not line:
412 break
413 lineno = lineno + 1
414 # comment or blank line?
415 if string.strip(line) == '' or line[0] in '#;':
416 continue
417 if string.lower(string.split(line)[0]) == 'rem' \
Guido van Rossumaad67612000-05-08 17:31:04 +0000418 and line[0] in "rR": # no leading whitespace
Guido van Rossum548703a1998-03-26 22:14:20 +0000419 continue
420 # continuation line?
Guido van Rossume03c0501998-08-12 02:38:11 +0000421 if line[0] in ' \t' and cursect is not None and optname:
Guido van Rossum548703a1998-03-26 22:14:20 +0000422 value = string.strip(line)
423 if value:
Guido van Rossume03c0501998-08-12 02:38:11 +0000424 cursect[optname] = cursect[optname] + '\n ' + value
425 # a section header or option header?
Guido van Rossum548703a1998-03-26 22:14:20 +0000426 else:
Guido van Rossume03c0501998-08-12 02:38:11 +0000427 # is it a section header?
Guido van Rossumaad67612000-05-08 17:31:04 +0000428 mo = self.SECTCRE.match(line)
Guido van Rossume03c0501998-08-12 02:38:11 +0000429 if mo:
430 sectname = mo.group('header')
431 if self.__sections.has_key(sectname):
432 cursect = self.__sections[sectname]
433 elif sectname == DEFAULTSECT:
434 cursect = self.__defaults
435 else:
436 cursect = {'__name__': sectname}
437 self.__sections[sectname] = cursect
438 # So sections can't start with a continuation line
439 optname = None
440 # no section header in the file?
441 elif cursect is None:
Guido van Rossumaad67612000-05-08 17:31:04 +0000442 raise MissingSectionHeaderError(fpname, lineno, `line`)
Guido van Rossume03c0501998-08-12 02:38:11 +0000443 # an option line?
444 else:
Guido van Rossumaad67612000-05-08 17:31:04 +0000445 mo = self.OPTCRE.match(line)
Guido van Rossume03c0501998-08-12 02:38:11 +0000446 if mo:
Guido van Rossumaad67612000-05-08 17:31:04 +0000447 optname, vi, optval = mo.group('option', 'vi', 'value')
Guido van Rossumaad67612000-05-08 17:31:04 +0000448 if vi in ('=', ':') and ';' in optval:
449 # ';' is a comment delimiter only if it follows
450 # a spacing character
451 pos = string.find(optval, ';')
452 if pos and optval[pos-1] in string.whitespace:
453 optval = optval[:pos]
Guido van Rossume03c0501998-08-12 02:38:11 +0000454 optval = string.strip(optval)
455 # allow empty values
456 if optval == '""':
457 optval = ''
Jeremy Hyltond635b1d2000-09-26 17:32:27 +0000458 cursect[self.optionxform(optname)] = optval
Guido van Rossume03c0501998-08-12 02:38:11 +0000459 else:
460 # a non-fatal parsing error occurred. set up the
461 # exception but keep going. the exception will be
462 # raised at the end of the file and will contain a
463 # list of all bogus lines
464 if not e:
Guido van Rossumaad67612000-05-08 17:31:04 +0000465 e = ParsingError(fpname)
Guido van Rossume03c0501998-08-12 02:38:11 +0000466 e.append(lineno, `line`)
467 # if any parsing errors occurred, raise an exception
468 if e:
469 raise e