def _read(self, fp, fpname): cursect = None # None, or a dictionary optname = None lineno = 0 e = None # None, or an exception while True: line = fp.readline() if not line: break lineno = lineno + 1 # comment or blank line? if line.strip() == '' or line[0] in '#;': continue if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": # no leading whitespace continue # continuation line? if line[0].isspace() and cursect is not None and optname: value = line.strip() if 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: raise ValueError('Duplicate section %r' % sectname) elif sectname == DEFAULTSECT: cursect = self._defaults else: cursect = self._dict() cursect['__name__'] = sectname self._sections[sectname] = cursect # So sections can't start with a continuation line optname = None # no section header in the file? elif cursect is None: raise MissingSectionHeaderError(fpname, lineno, line) # an option line? else: try: mo = self._optcre.match(line) # 2.7 except AttributeError: mo = self.OPTCRE.match(line) # 2.6 if mo: optname, vi, optval = mo.group('option', 'vi', 'value') optname = self.optionxform(optname.rstrip()) # This check is fine because the OPTCRE cannot # match if it would set optval to None if optval is not None: if vi in ('=', ':') and ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] optval = optval.strip() # allow empty values if optval == '""': optval = '' cursect[optname] = [optval] else: # valueless option handling cursect[optname] = optval else: # a non-fatal parsing error occurred. set up the # exception but keep going. the exception will be # raised at the end of the file and will contain a # list of all bogus lines if not e: e = ParsingError(fpname) e.append(lineno, repr(line)) # if any parsing errors occurred, raise an exception if e: raise e # join the multi-line values collected while reading all_sections = [self._defaults] all_sections.extend(self._sections.values()) for options in all_sections: for name, val in options.items(): if isinstance(val, list): options[name] = '\n'.join(val)
def _read(self, fp, fpname): cursect = None # None, or a dictionary optname = None lineno = 0 e = None # None, or an exception firstline = True while True: line = fp.readline() if not line: break lineno = lineno + 1 if firstline: # Skip BOM if line[:3] == '\xef\xbb\xbf': line = line[3:] self.encoding = 'utf_8' else: self.encoding = sys.getfilesystemencoding() firstline = False # comment or blank line? if line.strip() == '' or line[0] in '#;': continue if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": # no leading whitespace continue # continuation line? if line[0].isspace() and cursect is not None and optname: value = line.strip() if value: cursect[optname] = "%s\n%s" % (cursect[optname], value.decode(self.encoding)) # 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 else: cursect = {'__name__': sectname} self._sections[sectname] = cursect # So sections can't start with a continuation line optname = None # no section header in the file? elif cursect is None: raise MissingSectionHeaderError(fpname, lineno, line) # an option line? else: mo = self.OPTCRE.match(line) if mo: optname, vi, optval = mo.group('option', 'vi', 'value') if vi in ('=', ':') and ';' in optval: # ';' is a comment delimiter only if it follows # a spacing character pos = optval.find(';') 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()) try: _opt = optval.decode(self.encoding) except UnicodeDecodeError: self.encoding = sys.getfilesystemencoding() _opt = optval.decode(self.encoding) cursect[optname] = _opt else: # a non-fatal parsing error occurred. set up the # exception but keep going. the exception will be # raised at the end of the file and will contain a # list of all bogus lines if not e: e = ParsingError(fpname) e.append(lineno, repr(line)) # if any parsing errors occurred, raise an exception if e: raise e
def _readfp(self, fp): cur_section = None cur_option = None cur_section_name = None cur_option_name = None pending_lines = [] pending_empty_lines = False try: fname = fp.name except AttributeError: fname = '<???>' linecount = 0 exc = None line = None for line in readline_iterator(fp): # Check for BOM on first line if linecount == 0 and isinstance(line, unicode): if line[0] == u'\ufeff': line = line[1:] self._bom = True lineobj = self._parse(line) linecount += 1 if not cur_section and not isinstance( lineobj, (CommentLine, EmptyLine, SectionLine)): if self._parse_exc: raise MissingSectionHeaderError(fname, linecount, line) else: lineobj = make_comment(line) if lineobj is None: if self._parse_exc: if exc is None: exc = ParsingError(fname) exc.append(linecount, line) lineobj = make_comment(line) if isinstance(lineobj, ContinuationLine): if cur_option: if pending_lines: cur_option.extend(pending_lines) pending_lines = [] if pending_empty_lines: optobj._compat_skip_empty_lines.add( cur_option_name) pending_empty_lines = False cur_option.add(lineobj) else: # illegal continuation line - convert to comment if self._parse_exc: if exc is None: exc = ParsingError(fname) exc.append(linecount, line) lineobj = make_comment(line) if isinstance(lineobj, OptionLine): if pending_lines: cur_section.extend(pending_lines) pending_lines = [] pending_empty_lines = False cur_option = LineContainer(lineobj) cur_section.add(cur_option) if self._optionxform: cur_option_name = self._optionxform(cur_option.name) else: cur_option_name = cur_option.name if cur_section_name == DEFAULTSECT: optobj = self._defaults else: optobj = self._sections[cur_section_name] optobj._options[cur_option_name] = cur_option if isinstance(lineobj, SectionLine): self._data.extend(pending_lines) pending_lines = [] pending_empty_lines = False cur_section = LineContainer(lineobj) self._data.add(cur_section) cur_option = None cur_option_name = None if cur_section.name == DEFAULTSECT: self._defaults._lines.append(cur_section) cur_section_name = DEFAULTSECT else: if self._sectionxform: cur_section_name = self._sectionxform(cur_section.name) else: cur_section_name = cur_section.name if cur_section_name not in self._sections: self._sections[cur_section_name] = \ INISection(cur_section, defaults=self._defaults, optionxformsource=self) else: self._sections[cur_section_name]._lines.append( cur_section) if isinstance(lineobj, (CommentLine, EmptyLine)): pending_lines.append(lineobj) if isinstance(lineobj, EmptyLine): pending_empty_lines = True self._data.extend(pending_lines) if line and line[-1] == '\n': self._data.add(EmptyLine()) if exc: raise exc
def _read(self, fp, fpname): cursect = None optname = None lineno = 0 e = None firstline = True while True: line = fp.readline() if not line: break lineno = lineno + 1 if firstline: if line[:3] == '\xef\xbb\xbf': line = line[3:] self.encoding = 'utf_8' else: self.encoding = sys.getfilesystemencoding() if self.encoding is None: self.encoding = 'utf_8' firstline = False if line.strip() == '' or line[0] in '#;': continue if line.split(None, 1)[0].lower() == 'rem' and line[0] in 'rR': continue if line[0].isspace() and cursect is not None and optname: value = line.strip() if value: cursect[optname] = '%s\n%s' % (cursect[optname], value.decode(self.encoding)) else: 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 else: cursect = {'__name__': sectname} self._sections[sectname] = cursect optname = None elif cursect is None: raise MissingSectionHeaderError(fpname, lineno, line) else: mo = self.OPTCRE.match(line) if mo: optname, vi, optval = mo.group('option', 'vi', 'value') if vi in ('=', ':') and ';' in optval: pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] optval = optval.strip() if optval == '""': optval = '' optname = self.optionxform(optname.rstrip()) try: _opt = optval.decode(self.encoding) except UnicodeDecodeError: self.encoding = sys.getfilesystemencoding() if self.encoding is None: self.encoding = 'utf_8' _opt = optval.decode(self.encoding) cursect[optname] = _opt else: if not e: e = ParsingError(fpname) e.append(lineno, repr(line)) if e: raise e
def _set_into_file(self, section, option, value, replace_opt=None): """Set the value in the file contents Parsing logic and lot of the code was copied directly from the ConfigParser module of Python standard library. """ cursect = None # None, or a str optname = None new_line = '%s = %s\n' % (option, value) new_line_written = False last_section_line = None lineno = -1 for lineno in range(len(self._flines)): line = self._flines[lineno] # We might have 'None' lines because of earlier updates if line is None: continue # comment or blank line? if line.strip() == '' or line[0] in '#;': continue if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": # no leading whitespace continue # continuation line? if line[0].isspace() and cursect == section and \ (optname == option or optname == replace_opt): self._flines[lineno] = None else: # is it a section header? match = self.SECTCRE.match(line) if match: cursect = match.group('header') # So sections can't start with a continuation line optname = None # no section header in the file? elif cursect is None: raise MissingSectionHeaderError(self._fpname, lineno + 1, line) # an option line? else: match = self.OPTCRE.match(line) if match: optname = match.group('option') optname = self.optionxform(optname.rstrip()) # Replace / remove options if cursect == section and \ (optname == option or optname == replace_opt): if not new_line_written: self._flines[lineno] = new_line new_line_written = True else: # Just remove all matching lines, if we've # already written the new value self._flines[lineno] = None # Just ignore non-fatal parsing errors # Save the last line of the matching section if cursect == section: last_section_line = lineno # Insert new key if not new_line_written: if last_section_line is not None: self._flines.insert(last_section_line + 1, new_line) else: if lineno >= 0: self._flines.insert(lineno + 1, '\n') self._flines.insert(lineno + 2, '[%s]\n' % section) self._flines.insert(lineno + 3, new_line)
def readfp(self, fp): cur_section = None cur_option = None cur_section_name = None cur_option_name = None line = None pending_lines = [] try: fname = fp.name except AttributeError: fname = '<???>' linecount = 0 exc = None for line in fp: lineobj = self._parse(line) linecount += 1 if not cur_section and not isinstance(lineobj, (comment_line, empty_line, section_line)): if self._parse_exc: raise MissingSectionHeaderError(fname, linecount, line) else: lineobj = make_comment(line) if lineobj is None: if self._parse_exc: if exc is None: exc = ParsingError(fname) exc.append(linecount, line) lineobj = make_comment(line) if isinstance(lineobj, continuation_line): if cur_option: cur_option.add(lineobj) else: # illegal continuation line - convert to comment if self._parse_exc: if exc is None: exc = ParsingError(fname) exc.append(linecount, line) lineobj = make_comment(line) else: cur_option = None cur_option_name = None if isinstance(lineobj, option_line): cur_section.extend(pending_lines) pending_lines = [] cur_option = line_container(lineobj) cur_section.add(cur_option) if self._optionxform: cur_option_name = self._optionxform(cur_option.name) else: cur_option_name = cur_option.name if cur_section_name == DEFAULTSECT: optobj = self._defaults else: optobj = self._sections[cur_section_name] optobj._options[cur_option_name] = cur_option if isinstance(lineobj, section_line): self._data.extend(pending_lines) pending_lines = [] cur_section = line_container(lineobj) self._data.add(cur_section) if cur_section.name == DEFAULTSECT: self._defaults._lines.append(cur_section) cur_section_name = DEFAULTSECT else: if self._sectionxform: cur_section_name = self._sectionxform(cur_section.name) else: cur_section_name = cur_section.name if not self._sections.has_key(cur_section_name): self._sections[cur_section_name] = \ section(cur_section, defaults=self._defaults, optionxform=self._optionxform) else: self._sections[cur_section_name]._lines.append(cur_section) if isinstance(lineobj, (comment_line, empty_line)): pending_lines.append(lineobj) self._data.extend(pending_lines) if line and line[-1]=='\n': self._data.add(empty_line()) if exc: raise exc