blob: 4dbe606b033552b3e7f32c14515c3e8d660390d9 [file] [log] [blame]
Guido van Rossum3d209861997-12-09 16:10:31 +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
Barry Warsawbfa3f6b1998-07-01 20:41:12 +00005the style of RFC 822.
Guido van Rossum3d209861997-12-09 16:10:31 +00006
Barry Warsawbfa3f6b1998-07-01 20:41:12 +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 Rossum3d209861997-12-09 16:10:31 +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
Barry Warsawf09f6a51999-01-26 22:01:37 +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 Rossum3d209861997-12-09 16:10:31 +000032
Barry Warsawf09f6a51999-01-26 22:01:37 +000033 sections()
34 return all the configuration section names, sans DEFAULT
Guido van Rossum3d209861997-12-09 16:10:31 +000035
Barry Warsawf09f6a51999-01-26 22:01:37 +000036 options(section)
37 return list of configuration options for the named section
Guido van Rossum3d209861997-12-09 16:10:31 +000038
Guido van Rossumc0780ac1999-01-30 04:35:47 +000039 read(filenames)
Barry Warsawf09f6a51999-01-26 22:01:37 +000040 read and parse the list of named configuration files
Guido van Rossum3d209861997-12-09 16:10:31 +000041
Barry Warsawf09f6a51999-01-26 22:01:37 +000042 get(section, option, raw=0, vars=None)
43 return a string value for the named option. All % interpolations are
44 expanded in the return values, based on the defaults passed into the
45 constructor and the DEFAULT section. Additional substitutions may be
46 provided using the `vars' argument, which must be a dictionary whose
47 contents override any pre-existing defaults.
Guido van Rossum3d209861997-12-09 16:10:31 +000048
Barry Warsawf09f6a51999-01-26 22:01:37 +000049 getint(section, options)
50 like get(), but convert value to an integer
Guido van Rossum3d209861997-12-09 16:10:31 +000051
Barry Warsawf09f6a51999-01-26 22:01:37 +000052 getfloat(section, options)
53 like get(), but convert value to a float
Guido van Rossum3d209861997-12-09 16:10:31 +000054
Barry Warsawf09f6a51999-01-26 22:01:37 +000055 getboolean(section, options)
56 like get(), but convert value to a boolean (currently defined as 0 or
57 1, only)
Guido van Rossum3d209861997-12-09 16:10:31 +000058"""
59
60import sys
61import string
Barry Warsawbfa3f6b1998-07-01 20:41:12 +000062import re
Guido van Rossum3d209861997-12-09 16:10:31 +000063
64DEFAULTSECT = "DEFAULT"
65
66
67
68# exception classes
69class Error:
70 def __init__(self, msg=''):
Barry Warsawbfa3f6b1998-07-01 20:41:12 +000071 self._msg = msg
Guido van Rossum3d209861997-12-09 16:10:31 +000072 def __repr__(self):
Barry Warsawbfa3f6b1998-07-01 20:41:12 +000073 return self._msg
Guido van Rossum3d209861997-12-09 16:10:31 +000074
75class NoSectionError(Error):
76 def __init__(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000077 Error.__init__(self, 'No section: %s' % section)
78 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +000079
80class DuplicateSectionError(Error):
81 def __init__(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000082 Error.__init__(self, "Section %s already exists" % section)
83 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +000084
85class NoOptionError(Error):
86 def __init__(self, option, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000087 Error.__init__(self, "No option `%s' in section: %s" %
88 (option, section))
89 self.option = option
90 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +000091
92class InterpolationError(Error):
Barry Warsaw64462121998-08-06 18:48:41 +000093 def __init__(self, reference, option, section, rawval):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000094 Error.__init__(self,
Barry Warsaw64462121998-08-06 18:48:41 +000095 "Bad value substitution:\n"
96 "\tsection: [%s]\n"
97 "\toption : %s\n"
98 "\tkey : %s\n"
99 "\trawval : %s\n"
100 % (section, option, reference, rawval))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000101 self.reference = reference
102 self.option = option
103 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +0000104
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000105class MissingSectionHeaderError(Error):
106 def __init__(self, filename, lineno, line):
107 Error.__init__(
108 self,
109 'File contains no section headers.\nfile: %s, line: %d\n%s' %
110 (filename, lineno, line))
111 self.filename = filename
112 self.lineno = lineno
113 self.line = line
114
115class ParsingError(Error):
116 def __init__(self, filename):
117 Error.__init__(self, 'File contains parsing errors: %s' % filename)
118 self.filename = filename
119 self.errors = []
120
121 def append(self, lineno, line):
122 self.errors.append((lineno, line))
123 self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
124
Guido van Rossum3d209861997-12-09 16:10:31 +0000125
126
127class ConfigParser:
128 def __init__(self, defaults=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000129 self.__sections = {}
130 if defaults is None:
131 self.__defaults = {}
132 else:
133 self.__defaults = defaults
Guido van Rossum3d209861997-12-09 16:10:31 +0000134
135 def defaults(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000136 return self.__defaults
Guido van Rossum3d209861997-12-09 16:10:31 +0000137
138 def sections(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000139 """Return a list of section names, excluding [DEFAULT]"""
140 # self.__sections will never have [DEFAULT] in it
141 return self.__sections.keys()
Guido van Rossum3d209861997-12-09 16:10:31 +0000142
143 def add_section(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000144 """Create a new section in the configuration.
Guido van Rossum3d209861997-12-09 16:10:31 +0000145
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000146 Raise DuplicateSectionError if a section by the specified name
147 already exists.
148 """
149 if self.__sections.has_key(section):
150 raise DuplicateSectionError(section)
151 self.__sections[section] = {}
Guido van Rossum3d209861997-12-09 16:10:31 +0000152
153 def has_section(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000154 """Indicate whether the named section is present in the configuration.
Guido van Rossum3d209861997-12-09 16:10:31 +0000155
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000156 The DEFAULT section is not acknowledged.
157 """
158 return self.__sections.has_key(section)
Guido van Rossum3d209861997-12-09 16:10:31 +0000159
160 def options(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000161 try:
162 opts = self.__sections[section].copy()
163 except KeyError:
164 raise NoSectionError(section)
165 opts.update(self.__defaults)
166 return opts.keys()
Guido van Rossum3d209861997-12-09 16:10:31 +0000167
168 def read(self, filenames):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000169 """Read and parse a list of filenames."""
170 if type(filenames) is type(''):
171 filenames = [filenames]
172 for file in filenames:
173 try:
174 fp = open(file, 'r')
175 self.__read(fp)
176 except IOError:
177 pass
Guido van Rossum3d209861997-12-09 16:10:31 +0000178
Guido van Rossume6506e71999-01-26 19:29:25 +0000179 def get(self, section, option, raw=0, vars=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000180 """Get an option value for a given section.
Guido van Rossum3d209861997-12-09 16:10:31 +0000181
Barry Warsawf09f6a51999-01-26 22:01:37 +0000182 All % interpolations are expanded in the return values, based on the
183 defaults passed into the constructor, unless the optional argument
184 `raw' is true. Additional substitutions may be provided using the
185 `vars' argument, which must be a dictionary whose contents overrides
186 any pre-existing defaults.
Guido van Rossum3d209861997-12-09 16:10:31 +0000187
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000188 The section DEFAULT is special.
189 """
190 try:
191 sectdict = self.__sections[section].copy()
192 except KeyError:
193 if section == DEFAULTSECT:
194 sectdict = {}
195 else:
196 raise NoSectionError(section)
197 d = self.__defaults.copy()
198 d.update(sectdict)
Guido van Rossume6506e71999-01-26 19:29:25 +0000199 # Update with the entry specific variables
200 if vars:
201 d.update(vars)
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000202 option = self.optionxform(option)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000203 try:
204 rawval = d[option]
205 except KeyError:
206 raise NoOptionError(option, section)
207 # do the string interpolation
208 if raw:
209 return rawval
Guido van Rossum3d209861997-12-09 16:10:31 +0000210
Guido van Rossume6506e71999-01-26 19:29:25 +0000211 value = rawval # Make it a pretty variable name
Guido van Rossum72ce8581999-02-12 14:13:10 +0000212 depth = 0
213 while depth < 10: # Loop through this until it's done
214 depth = depth + 1
Guido van Rossume6506e71999-01-26 19:29:25 +0000215 if not string.find(value, "%("):
216 try:
217 value = value % d
218 except KeyError, key:
219 raise InterpolationError(key, option, section, rawval)
220 else:
221 return value
222
Guido van Rossum3d209861997-12-09 16:10:31 +0000223 def __get(self, section, conv, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000224 return conv(self.get(section, option))
Guido van Rossum3d209861997-12-09 16:10:31 +0000225
226 def getint(self, section, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000227 return self.__get(section, string.atoi, option)
Guido van Rossum3d209861997-12-09 16:10:31 +0000228
229 def getfloat(self, section, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000230 return self.__get(section, string.atof, option)
Guido van Rossum3d209861997-12-09 16:10:31 +0000231
232 def getboolean(self, section, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000233 v = self.get(section, option)
234 val = string.atoi(v)
235 if val not in (0, 1):
236 raise ValueError, 'Not a boolean: %s' % v
237 return val
Guido van Rossum3d209861997-12-09 16:10:31 +0000238
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000239 def optionxform(self, optionstr):
240 return string.lower(optionstr)
241
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000242 #
243 # Regular expressions for parsing section headers and options. Note a
244 # slight semantic change from the previous version, because of the use
245 # of \w, _ is allowed in section header names.
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000246 SECTCRE = re.compile(
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000247 r'\[' # [
248 r'(?P<header>[-\w]+)' # `-', `_' or any alphanum
249 r'\]' # ]
250 )
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000251 OPTCRE = re.compile(
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000252 r'(?P<option>[-.\w]+)' # - . _ alphanum
253 r'[ \t]*[:=][ \t]*' # any number of space/tab,
254 # followed by separator
255 # (either : or =), followed
256 # by any # space/tab
257 r'(?P<value>.*)$' # everything up to eol
258 )
259
Guido van Rossum3d209861997-12-09 16:10:31 +0000260 def __read(self, fp):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000261 """Parse a sectioned setup file.
Guido van Rossum3d209861997-12-09 16:10:31 +0000262
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000263 The sections in setup file contains a title line at the top,
264 indicated by a name in square brackets (`[]'), plus key/value
265 options lines, indicated by `name: value' format lines.
266 Continuation are represented by an embedded newline then
267 leading whitespace. Blank lines, lines beginning with a '#',
268 and just about everything else is ignored.
269 """
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000270 cursect = None # None, or a dictionary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000271 optname = None
272 lineno = 0
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000273 e = None # None, or an exception
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000274 while 1:
275 line = fp.readline()
276 if not line:
277 break
278 lineno = lineno + 1
279 # comment or blank line?
280 if string.strip(line) == '' or line[0] in '#;':
281 continue
282 if string.lower(string.split(line)[0]) == 'rem' \
283 and line[0] == "r": # no leading whitespace
284 continue
285 # continuation line?
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000286 if line[0] in ' \t' and cursect is not None and optname:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000287 value = string.strip(line)
288 if value:
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000289 cursect[optname] = cursect[optname] + '\n ' + value
290 # a section header or option header?
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000291 else:
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000292 # is it a section header?
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000293 mo = self.SECTCRE.match(line)
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000294 if mo:
295 sectname = mo.group('header')
296 if self.__sections.has_key(sectname):
297 cursect = self.__sections[sectname]
298 elif sectname == DEFAULTSECT:
299 cursect = self.__defaults
300 else:
Barry Warsaw64462121998-08-06 18:48:41 +0000301 cursect = {'__name__': sectname}
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000302 self.__sections[sectname] = cursect
303 # So sections can't start with a continuation line
304 optname = None
305 # no section header in the file?
306 elif cursect is None:
307 raise MissingSectionHeaderError(fp.name, lineno, `line`)
308 # an option line?
309 else:
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000310 mo = self.OPTCRE.match(line)
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000311 if mo:
312 optname, optval = mo.group('option', 'value')
313 optname = string.lower(optname)
314 optval = string.strip(optval)
315 # allow empty values
316 if optval == '""':
317 optval = ''
318 cursect[optname] = optval
319 else:
320 # a non-fatal parsing error occurred. set up the
321 # exception but keep going. the exception will be
322 # raised at the end of the file and will contain a
323 # list of all bogus lines
324 if not e:
325 e = ParsingError(fp.name)
326 e.append(lineno, `line`)
327 # if any parsing errors occurred, raise an exception
328 if e:
329 raise e