--- ConfigParser_71564.py 2009-10-12 13:28:54.000000000 +0200 +++ ConfigParser.py 2009-10-12 13:42:02.000000000 +0200 @@ -447,10 +447,11 @@ leading whitespace. Blank lines, lines beginning with a '#', and just about everything else are ignored. """ - cursect = None # None, or a dictionary + loaded_sections = self._dict() # sections loaded in this call + cursect = None # None, or a dictionary optname = None lineno = 0 - e = None # None, or an exception + e = None # None, or an exception while True: line = fp.readline() if not line: @@ -466,21 +467,18 @@ if line[0].isspace() and cursect is not None and optname: value = line.strip() if value: - cursect[optname] = "%s\n%s" % (cursect[optname], value) + cursect[optname].append(value) # a section header or option header? else: # is it a section header? mo = self.SECTCRE.match(line) if mo: sectname = mo.group('header') - if sectname in self._sections: - cursect = self._sections[sectname] - elif sectname == DEFAULTSECT: - cursect = self._defaults + if sectname in loaded_sections: + cursect = loaded_sections[sectname] else: cursect = self._dict() - cursect['__name__'] = sectname - self._sections[sectname] = cursect + loaded_sections[sectname] = cursect # So sections can't start with a continuation line optname = None # no section header in the file? @@ -491,6 +489,7 @@ mo = self.OPTCRE.match(line) if mo: optname, vi, optval = mo.group('option', 'vi', 'value') + optname = self.optionxform(optname.rstrip()) if vi in ('=', ':') and ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character @@ -498,11 +497,13 @@ if pos != -1 and optval[pos-1].isspace(): optval = optval[:pos] optval = optval.strip() - # allow empty values - if optval == '""': - optval = '' - optname = self.optionxform(optname.rstrip()) - cursect[optname] = optval + if optval == '': + cursect[optname] = [] + elif optval == '""': + # allow empty values + cursect[optname] = [''] + else: + cursect[optname] = [optval] else: # a non-fatal parsing error occurred. set up the # exception but keep going. the exception will be @@ -515,6 +516,22 @@ if e: raise e + # Merge loaded_sections into self._sections + for sectname, options in loaded_sections.iteritems(): + if sectname in self._sections: + cursect = self._sections[sectname] + elif sectname == DEFAULTSECT: + cursect = self._defaults + else: + cursect = self._dict() + cursect['__name__'] = sectname + self._sections[sectname] = cursect + for optname, loaded_optval in options.iteritems(): + optval = cursect.get(optname) + if optval is None: + cursect[optname] = "\n".join(loaded_optval) + else: + cursect[optname] = "\n".join([optval] + loaded_optval) class ConfigParser(RawConfigParser):