blob: 2f60742ddbbb0912fb638f0ffe5ccf386bb539fa [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
Guido van Rossuma5a24b71999-10-04 19:58:22 +000036 has_section(section)
37 return whether the given section exists
38
Eric S. Raymond649685a2000-07-14 14:28:22 +000039 has_option(section, option)
40 return whether the given option exists in the given section
41
Barry Warsawf09f6a51999-01-26 22:01:37 +000042 options(section)
43 return list of configuration options for the named section
Guido van Rossum3d209861997-12-09 16:10:31 +000044
Guido van Rossuma5a24b71999-10-04 19:58:22 +000045 has_option(section, option)
46 return whether the given section has the given option
47
Guido van Rossumc0780ac1999-01-30 04:35:47 +000048 read(filenames)
Guido van Rossum6a8d84b1999-10-04 18:57:27 +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
Barry Warsaw25394511999-10-12 16:12:48 +000056 messages (if fp has no `name' attribute, the string `<???>' is used).
Guido van Rossum3d209861997-12-09 16:10:31 +000057
Barry Warsawf09f6a51999-01-26 22:01:37 +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 Rossum3d209861997-12-09 16:10:31 +000064
Barry Warsawf09f6a51999-01-26 22:01:37 +000065 getint(section, options)
66 like get(), but convert value to an integer
Guido van Rossum3d209861997-12-09 16:10:31 +000067
Barry Warsawf09f6a51999-01-26 22:01:37 +000068 getfloat(section, options)
69 like get(), but convert value to a float
Guido van Rossum3d209861997-12-09 16:10:31 +000070
Barry Warsawf09f6a51999-01-26 22:01:37 +000071 getboolean(section, options)
72 like get(), but convert value to a boolean (currently defined as 0 or
73 1, only)
Eric S. Raymond649685a2000-07-14 14:28:22 +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 Rossum3d209861997-12-09 16:10:31 +000086"""
87
88import sys
89import string
Barry Warsawbfa3f6b1998-07-01 20:41:12 +000090import re
Guido van Rossum3d209861997-12-09 16:10:31 +000091
92DEFAULTSECT = "DEFAULT"
93
Fred Drake2a37f9f2000-09-27 22:43:54 +000094MAX_INTERPOLATION_DEPTH = 10
95
Guido van Rossum3d209861997-12-09 16:10:31 +000096
97
98# exception classes
Fred Drake7c1e5ad2000-12-11 18:13:19 +000099class Error(Exception):
Guido van Rossum3d209861997-12-09 16:10:31 +0000100 def __init__(self, msg=''):
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000101 self._msg = msg
Fred Drake7c1e5ad2000-12-11 18:13:19 +0000102 Exception.__init__(self, msg)
Guido van Rossum3d209861997-12-09 16:10:31 +0000103 def __repr__(self):
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000104 return self._msg
Fred Drake7c1e5ad2000-12-11 18:13:19 +0000105 __str__ = __repr__
Guido van Rossum3d209861997-12-09 16:10:31 +0000106
107class NoSectionError(Error):
108 def __init__(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000109 Error.__init__(self, 'No section: %s' % section)
110 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +0000111
112class DuplicateSectionError(Error):
113 def __init__(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000114 Error.__init__(self, "Section %s already exists" % section)
115 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +0000116
117class NoOptionError(Error):
118 def __init__(self, option, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000119 Error.__init__(self, "No option `%s' in section: %s" %
120 (option, section))
121 self.option = option
122 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +0000123
124class InterpolationError(Error):
Barry Warsaw64462121998-08-06 18:48:41 +0000125 def __init__(self, reference, option, section, rawval):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000126 Error.__init__(self,
Barry Warsaw64462121998-08-06 18:48:41 +0000127 "Bad value substitution:\n"
128 "\tsection: [%s]\n"
129 "\toption : %s\n"
130 "\tkey : %s\n"
131 "\trawval : %s\n"
132 % (section, option, reference, rawval))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000133 self.reference = reference
134 self.option = option
135 self.section = section
Guido van Rossum3d209861997-12-09 16:10:31 +0000136
Fred Drake2a37f9f2000-09-27 22:43:54 +0000137class InterpolationDepthError(Error):
138 def __init__(self, option, section, rawval):
139 Error.__init__(self,
140 "Value interpolation too deeply recursive:\n"
141 "\tsection: [%s]\n"
142 "\toption : %s\n"
143 "\trawval : %s\n"
144 % (section, option, rawval))
145 self.option = option
146 self.section = section
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000147
148class ParsingError(Error):
149 def __init__(self, filename):
150 Error.__init__(self, 'File contains parsing errors: %s' % filename)
151 self.filename = filename
152 self.errors = []
153
154 def append(self, lineno, line):
155 self.errors.append((lineno, line))
156 self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line)
157
Fred Drake2a37f9f2000-09-27 22:43:54 +0000158class MissingSectionHeaderError(ParsingError):
159 def __init__(self, filename, lineno, line):
160 Error.__init__(
161 self,
162 'File contains no section headers.\nfile: %s, line: %d\n%s' %
163 (filename, lineno, line))
164 self.filename = filename
165 self.lineno = lineno
166 self.line = line
167
Guido van Rossum3d209861997-12-09 16:10:31 +0000168
169
170class ConfigParser:
171 def __init__(self, defaults=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000172 self.__sections = {}
173 if defaults is None:
174 self.__defaults = {}
175 else:
176 self.__defaults = defaults
Guido van Rossum3d209861997-12-09 16:10:31 +0000177
178 def defaults(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000179 return self.__defaults
Guido van Rossum3d209861997-12-09 16:10:31 +0000180
181 def sections(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000182 """Return a list of section names, excluding [DEFAULT]"""
183 # self.__sections will never have [DEFAULT] in it
184 return self.__sections.keys()
Guido van Rossum3d209861997-12-09 16:10:31 +0000185
186 def add_section(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000187 """Create a new section in the configuration.
Guido van Rossum3d209861997-12-09 16:10:31 +0000188
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000189 Raise DuplicateSectionError if a section by the specified name
190 already exists.
191 """
192 if self.__sections.has_key(section):
193 raise DuplicateSectionError(section)
194 self.__sections[section] = {}
Guido van Rossum3d209861997-12-09 16:10:31 +0000195
196 def has_section(self, section):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000197 """Indicate whether the named section is present in the configuration.
Guido van Rossum3d209861997-12-09 16:10:31 +0000198
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000199 The DEFAULT section is not acknowledged.
200 """
Fred Drake2a37f9f2000-09-27 22:43:54 +0000201 return section in self.sections()
Guido van Rossum3d209861997-12-09 16:10:31 +0000202
203 def options(self, section):
Guido van Rossuma5a24b71999-10-04 19:58:22 +0000204 """Return a list of option names for the given section name."""
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000205 try:
206 opts = self.__sections[section].copy()
207 except KeyError:
208 raise NoSectionError(section)
209 opts.update(self.__defaults)
Fred Drake2a37f9f2000-09-27 22:43:54 +0000210 if opts.has_key('__name__'):
211 del opts['__name__']
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000212 return opts.keys()
Guido van Rossum3d209861997-12-09 16:10:31 +0000213
Guido van Rossuma5a24b71999-10-04 19:58:22 +0000214 def has_option(self, section, option):
215 """Return whether the given section has the given option."""
Fred Drake2a37f9f2000-09-27 22:43:54 +0000216 return option in self.options(section)
Guido van Rossuma5a24b71999-10-04 19:58:22 +0000217
Guido van Rossum3d209861997-12-09 16:10:31 +0000218 def read(self, filenames):
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000219 """Read and parse a filename or a list of filenames.
220
221 Files that cannot be opened are silently ignored; this is
Barry Warsaw25394511999-10-12 16:12:48 +0000222 designed so that you can specify a list of potential
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000223 configuration file locations (e.g. current directory, user's
224 home directory, systemwide directory), and all existing
225 configuration files in the list will be read. A single
226 filename may also be given.
227 """
Fred Drakefd4114e2000-05-09 14:46:40 +0000228 if type(filenames) in [type(''), type(u'')]:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000229 filenames = [filenames]
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000230 for filename in filenames:
231 try:
232 fp = open(filename)
233 except IOError:
234 continue
235 self.__read(fp, filename)
Fred Drake2438a481999-10-04 18:11:56 +0000236 fp.close()
Guido van Rossum3d209861997-12-09 16:10:31 +0000237
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000238 def readfp(self, fp, filename=None):
239 """Like read() but the argument must be a file-like object.
240
241 The `fp' argument must have a `readline' method. Optional
242 second argument is the `filename', which if not given, is
243 taken from fp.name. If fp has no `name' attribute, `<???>' is
244 used.
245
246 """
247 if filename is None:
248 try:
249 filename = fp.name
250 except AttributeError:
251 filename = '<???>'
252 self.__read(fp, filename)
253
Guido van Rossume6506e71999-01-26 19:29:25 +0000254 def get(self, section, option, raw=0, vars=None):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000255 """Get an option value for a given section.
Guido van Rossum3d209861997-12-09 16:10:31 +0000256
Barry Warsawf09f6a51999-01-26 22:01:37 +0000257 All % interpolations are expanded in the return values, based on the
258 defaults passed into the constructor, unless the optional argument
259 `raw' is true. Additional substitutions may be provided using the
260 `vars' argument, which must be a dictionary whose contents overrides
261 any pre-existing defaults.
Guido van Rossum3d209861997-12-09 16:10:31 +0000262
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000263 The section DEFAULT is special.
264 """
265 try:
266 sectdict = self.__sections[section].copy()
267 except KeyError:
268 if section == DEFAULTSECT:
269 sectdict = {}
270 else:
271 raise NoSectionError(section)
272 d = self.__defaults.copy()
273 d.update(sectdict)
Guido van Rossume6506e71999-01-26 19:29:25 +0000274 # Update with the entry specific variables
275 if vars:
276 d.update(vars)
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000277 option = self.optionxform(option)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000278 try:
279 rawval = d[option]
280 except KeyError:
281 raise NoOptionError(option, section)
Fred Drake2a37f9f2000-09-27 22:43:54 +0000282
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000283 if raw:
284 return rawval
Guido van Rossum3d209861997-12-09 16:10:31 +0000285
Fred Drake2a37f9f2000-09-27 22:43:54 +0000286 # do the string interpolation
Guido van Rossume6506e71999-01-26 19:29:25 +0000287 value = rawval # Make it a pretty variable name
Guido van Rossum72ce8581999-02-12 14:13:10 +0000288 depth = 0
289 while depth < 10: # Loop through this until it's done
290 depth = depth + 1
Guido van Rossuma5a24b71999-10-04 19:58:22 +0000291 if string.find(value, "%(") >= 0:
Guido van Rossume6506e71999-01-26 19:29:25 +0000292 try:
293 value = value % d
294 except KeyError, key:
295 raise InterpolationError(key, option, section, rawval)
296 else:
Fred Drake2a37f9f2000-09-27 22:43:54 +0000297 break
298 if value.find("%(") >= 0:
299 raise InterpolationDepthError(option, section, rawval)
300 return value
Guido van Rossume6506e71999-01-26 19:29:25 +0000301
Guido van Rossum3d209861997-12-09 16:10:31 +0000302 def __get(self, section, conv, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000303 return conv(self.get(section, option))
Guido van Rossum3d209861997-12-09 16:10:31 +0000304
305 def getint(self, section, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000306 return self.__get(section, string.atoi, option)
Guido van Rossum3d209861997-12-09 16:10:31 +0000307
308 def getfloat(self, section, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000309 return self.__get(section, string.atof, option)
Guido van Rossum3d209861997-12-09 16:10:31 +0000310
311 def getboolean(self, section, option):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000312 v = self.get(section, option)
313 val = string.atoi(v)
314 if val not in (0, 1):
315 raise ValueError, 'Not a boolean: %s' % v
316 return val
Guido van Rossum3d209861997-12-09 16:10:31 +0000317
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000318 def optionxform(self, optionstr):
319 return string.lower(optionstr)
320
Eric S. Raymond417c4892000-07-10 18:11:00 +0000321 def has_option(self, section, option):
322 """Check for the existence of a given option in a given section."""
323 if not section or section == "DEFAULT":
324 return self.__defaults.has_key(option)
325 elif not self.has_section(section):
326 return 0
327 else:
328 return self.__sections[section].has_key(option)
329
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 sectdict[option] = value
340
341 def write(self, fp):
342 """Write an .ini-format representation of the configuration state."""
343 if self.__defaults:
344 fp.write("[DEFAULT]\n")
Eric S. Raymond649685a2000-07-14 14:28:22 +0000345 for (key, value) in self.__defaults.items():
346 fp.write("%s = %s\n" % (key, value))
Eric S. Raymond417c4892000-07-10 18:11:00 +0000347 fp.write("\n")
348 for section in self.sections():
349 fp.write("[" + section + "]\n")
350 sectdict = self.__sections[section]
Eric S. Raymond649685a2000-07-14 14:28:22 +0000351 for (key, value) in sectdict.items():
Eric S. Raymond417c4892000-07-10 18:11:00 +0000352 if key == "__name__":
353 continue
Eric S. Raymond649685a2000-07-14 14:28:22 +0000354 fp.write("%s = %s\n" % (key, value))
Eric S. Raymond417c4892000-07-10 18:11:00 +0000355 fp.write("\n")
356
Thomas Woutersff4df6d2000-07-21 05:19:59 +0000357 def remove_option(self, section, option):
Eric S. Raymond649685a2000-07-14 14:28:22 +0000358 """Remove an option."""
359 if not section or section == "DEFAULT":
360 sectdict = self.__defaults
361 else:
362 try:
363 sectdict = self.__sections[section]
364 except KeyError:
365 raise NoSectionError(section)
Fred Drakeff4a23b2000-12-04 16:29:13 +0000366 existed = sectdict.has_key(option)
Eric S. Raymond649685a2000-07-14 14:28:22 +0000367 if existed:
Fred Drakeff4a23b2000-12-04 16:29:13 +0000368 del sectdict[option]
Eric S. Raymond649685a2000-07-14 14:28:22 +0000369 return existed
370
Thomas Woutersff4df6d2000-07-21 05:19:59 +0000371 def remove_section(self, section):
Eric S. Raymond649685a2000-07-14 14:28:22 +0000372 """Remove a file section."""
373 if self.__sections.has_key(section):
374 del self.__sections[section]
375 return 1
376 else:
377 return 0
378
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000379 #
380 # Regular expressions for parsing section headers and options. Note a
381 # slight semantic change from the previous version, because of the use
382 # of \w, _ is allowed in section header names.
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000383 SECTCRE = re.compile(
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000384 r'\[' # [
Fred Drake2a37f9f2000-09-27 22:43:54 +0000385 r'(?P<header>[-\w_.*,(){} ]+)' # a lot of stuff found by IvL
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000386 r'\]' # ]
387 )
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000388 OPTCRE = re.compile(
Fred Drake1ab41fc2000-02-28 23:23:55 +0000389 r'(?P<option>[-\w_.*,(){}]+)' # a lot of stuff found by IvL
Fred Drakec517b9b2000-02-28 20:59:03 +0000390 r'[ \t]*(?P<vi>[:=])[ \t]*' # any number of space/tab,
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000391 # followed by separator
392 # (either : or =), followed
393 # by any # space/tab
394 r'(?P<value>.*)$' # everything up to eol
395 )
396
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000397 def __read(self, fp, fpname):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000398 """Parse a sectioned setup file.
Guido van Rossum3d209861997-12-09 16:10:31 +0000399
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000400 The sections in setup file contains a title line at the top,
401 indicated by a name in square brackets (`[]'), plus key/value
402 options lines, indicated by `name: value' format lines.
403 Continuation are represented by an embedded newline then
404 leading whitespace. Blank lines, lines beginning with a '#',
405 and just about everything else is ignored.
406 """
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000407 cursect = None # None, or a dictionary
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000408 optname = None
409 lineno = 0
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000410 e = None # None, or an exception
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000411 while 1:
412 line = fp.readline()
413 if not line:
414 break
415 lineno = lineno + 1
416 # comment or blank line?
417 if string.strip(line) == '' or line[0] in '#;':
418 continue
419 if string.lower(string.split(line)[0]) == 'rem' \
Fred Drakec517b9b2000-02-28 20:59:03 +0000420 and line[0] in "rR": # no leading whitespace
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000421 continue
422 # continuation line?
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000423 if line[0] in ' \t' and cursect is not None and optname:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000424 value = string.strip(line)
425 if value:
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000426 cursect[optname] = cursect[optname] + '\n ' + value
427 # a section header or option header?
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000428 else:
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000429 # is it a section header?
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000430 mo = self.SECTCRE.match(line)
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000431 if mo:
432 sectname = mo.group('header')
433 if self.__sections.has_key(sectname):
434 cursect = self.__sections[sectname]
435 elif sectname == DEFAULTSECT:
436 cursect = self.__defaults
437 else:
Barry Warsaw64462121998-08-06 18:48:41 +0000438 cursect = {'__name__': sectname}
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000439 self.__sections[sectname] = cursect
440 # So sections can't start with a continuation line
441 optname = None
442 # no section header in the file?
443 elif cursect is None:
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000444 raise MissingSectionHeaderError(fpname, lineno, `line`)
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000445 # an option line?
446 else:
Guido van Rossum9e480ad1999-06-17 18:41:42 +0000447 mo = self.OPTCRE.match(line)
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000448 if mo:
Fred Drakec517b9b2000-02-28 20:59:03 +0000449 optname, vi, optval = mo.group('option', 'vi', 'value')
Jeremy Hylton820314e2000-03-03 20:43:57 +0000450 if vi in ('=', ':') and ';' in optval:
Fred Drakec517b9b2000-02-28 20:59:03 +0000451 # ';' is a comment delimiter only if it follows
452 # a spacing character
453 pos = string.find(optval, ';')
454 if pos and optval[pos-1] in string.whitespace:
455 optval = optval[:pos]
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000456 optval = string.strip(optval)
457 # allow empty values
458 if optval == '""':
459 optval = ''
Guido van Rossum41267362000-09-25 14:42:33 +0000460 cursect[self.optionxform(optname)] = optval
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000461 else:
462 # a non-fatal parsing error occurred. set up the
463 # exception but keep going. the exception will be
464 # raised at the end of the file and will contain a
465 # list of all bogus lines
466 if not e:
Guido van Rossum6a8d84b1999-10-04 18:57:27 +0000467 e = ParsingError(fpname)
Barry Warsawbfa3f6b1998-07-01 20:41:12 +0000468 e.append(lineno, `line`)
469 # if any parsing errors occurred, raise an exception
470 if e:
471 raise e