def _read(self, fp, fpname): u"""Parse a sectioned setup file. The sections in setup file contains a title line at the top, indicated by a name in square brackets (`[]'), plus key/value options lines, indicated by `name: value' format lines. Continuations are represented by an embedded newline then leading whitespace. Blank lines, lines beginning with a '#', and just about everything else are ignored. """ 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: #JAZ add environment variable expansion if not getattr(self, 'no_expand_vars', False): line = os.path.expandvars(line) # 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 == configparser.DEFAULTSECT: cursect = self._defaults else: cursect = self._dict() self._sections[sectname] = cursect # So sections can't start with a continuation line optname = None # no section header in the file? elif line.lower().startswith('%include'): if not getattr(self, 'no_expand_includes', False): include_statement, filename = line.split() filename = filename.strip('"').strip("'") sys.stdout.write("Reading included ini file: `" + filename + "'\n") if not os.path.exists(filename): # TODO: remove direct sys.stderr writes raise ValueError("Tried to include non-existent " "ini file: `" + filename + "'\n") self.read(filename) cursect = None elif cursect is None: raise configparser.MissingSectionHeaderError( fpname, lineno, line) # an option line? else: mo = self._optcre.match(line) 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 = configparser.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(list(self._sections.values())) for options in all_sections: for name, val in list(options.items()): if isinstance(val, list): options[name] = '\n'.join(val)
def _read(self, fp, fpname): """Parse a sectioned setup file. The sections in setup file contains a title line at the top, indicated by a name in square brackets (`[]'), plus key/value options lines, indicated by `name: value' format lines. Continuations are represented by an embedded newline then leading whitespace. Blank lines, lines beginning with a '#', and just about everything else are ignored. """ 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: cursect = self._sections[sectname] elif sectname == 'DEFAULT': 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 configparser.MissingSectionHeaderError( fpname, lineno, line) # an option line? else: mo = self._optcre.match(line) 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: # XXX Added support for '#' inline comments if vi in ('=', ':') and (';' in optval or '#' in optval): # strip comments optval = re.split(r'\s+(;|#)', optval)[0] # if what is left is comment as a value, fallback to an empty string # that is: `foo = ;` would mean `foo` is '', which brings parity with # what ceph-conf tool does if optval in [';', '#']: optval = '' 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 = configparser.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): """Parse a sectioned setup file. The sections in setup file contains a title line at the top, indicated by a name in square brackets (`[]'), plus key/value options lines, indicated by `name: value' format lines. Continuations are represented by an embedded newline then leading whitespace. Blank lines, lines beginning with a '#', and just about everything else are ignored. """ 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 '#;': self._sections.add_other(cursect, line) 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) #self.set(cursect, optname, "%s\n%s" % (self.get(cursect, optname), value)) if cursect == configparser.DEFAULTSECT: self._defaults[optname] = "%s\n%s" % ( self._defaults[optname], value) else: # use the raw value here (original version uses raw=False) self._sections[cursect]._find( optname).value = '%s\n%s' % (self.get( cursect, optname, raw=True), 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 == configparser.DEFAULTSECT: cursect = self._defaults else: #cursect = {'__name__': sectname} #self._sections[sectname] = cursect self.add_section(sectname) self.set(sectname, '__name__', sectname) # So sections can't start with a continuation line cursect = sectname optname = None # no section header in the file? elif cursect is None: raise configparser.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()) if cursect == configparser.DEFAULTSECT: self._defaults[optname] = optval else: self._sections[cursect]._add_option(optname, line=line) 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 = configparser.ParsingError(fpname) e.append(lineno, repr(line)) # if any parsing errors occurred, raise an exception if e: raise e # pylint: disable-msg=E0702
def _read(self, fp: Union[BufferedReader, IO[bytes]], fpname: str) -> None: """A direct copy of the py2.4 version of the super class's _read method to assure it uses ordered dicts. Had to change one line to make it work. Future versions have this fixed, but in fact its quite embarrassing for the guys not to have done it right in the first place ! Removed big comments to make it more compact. Made sure it ignores initial whitespace as git uses tabs""" cursect = None # None, or a dictionary optname = None lineno = 0 is_multi_line = False e = None # None, or an exception def string_decode(v: str) -> str: if v[-1] == '\\': v = v[:-1] # end cut trailing escapes to prevent decode error return v.encode(defenc).decode('unicode_escape') # end # end while True: # we assume to read binary ! line = fp.readline().decode(defenc) if not line: break lineno = lineno + 1 # comment or blank line? if line.strip() == '' or self.re_comment.match(line): continue if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": # no leading whitespace continue # is it a section header? mo = self.SECTCRE.match(line.strip()) if not is_multi_line and mo: sectname: str = mo.group('header').strip() if sectname in self._sections: cursect = self._sections[sectname] elif sectname == cp.DEFAULTSECT: cursect = self._defaults else: cursect = self._dict((('__name__', sectname), )) self._sections[sectname] = cursect self._proxies[sectname] = None # So sections can't start with a continuation line optname = None # no section header in the file? elif cursect is None: raise cp.MissingSectionHeaderError(fpname, lineno, line) # an option line? elif not is_multi_line: mo = self.OPTCRE.match(line) if mo: # We might just have handled the last line, which could contain a quotation we want to remove optname, vi, optval = mo.group('option', 'vi', 'value') if vi in ('=', ':') and ';' in optval and not optval.strip( ).startswith('"'): pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] optval = optval.strip() if optval == '""': optval = '' # end handle empty string optname = self.optionxform(optname.rstrip()) if len(optval ) > 1 and optval[0] == '"' and optval[-1] != '"': is_multi_line = True optval = string_decode(optval[1:]) # end handle multi-line # preserves multiple values for duplicate optnames cursect.add(optname, optval) else: # check if it's an option with no value - it's just ignored by git if not self.OPTVALUEONLY.match(line): if not e: e = cp.ParsingError(fpname) e.append(lineno, repr(line)) continue else: line = line.rstrip() if line.endswith('"'): is_multi_line = False line = line[:-1] # end handle quotations optval = cursect.getlast(optname) cursect.setlast(optname, optval + string_decode(line)) # END parse section or option # END while reading # if any parsing errors occurred, raise an exception if e: raise e
def _read(self, fp, fpname): """Parse a sectioned configuration file. Each section in a configuration file contains a header, indicated by a name in square brackets (`[]'), plus key/value options, indicated by `name' and `value' delimited with a specific substring (`=' or `:' by default). Values can span multiple lines, as long as they are indented deeper than the first line of the value. Depending on the parser's mode, blank lines may be treated as parts of multiline values or ignored. Configuration files may include comments, prefixed by specific characters (`#' and `;' by default). Comments may appear on their own in an otherwise empty line or may be entered in lines holding values or section names. """ elements_added = set() cursect = None # None, or a dictionary sectname = None optname = None lineno = 0 indent_level = 0 e = None # None, or an exception for lineno, line in enumerate(fp, start=1): comment_start = None # strip inline comments for prefix in self._inline_comment_prefixes: index = line.find(prefix) if index == 0 or (index > 0 and line[index - 1].isspace()): comment_start = index break # strip full line comments for prefix in self._comment_prefixes: if line.strip().startswith(prefix): comment_start = 0 break value = line[:comment_start].strip() if not value: if self._empty_lines_in_values: # add empty line to the value, but only if there was no # comment on the line if (comment_start is None and cursect is not None and optname and cursect[optname] is not None): cursect[optname].append('') # newlines added at join else: # empty line marks end of value indent_level = sys.maxsize continue # continuation line? first_nonspace = self.NONSPACECRE.search(line) cur_indent_level = first_nonspace.start() if first_nonspace else 0 if (cursect is not None and optname and cur_indent_level > indent_level): cursect[optname].append(value) # a section header or option header? else: indent_level = cur_indent_level # is it a section header? mo = self.SECTCRE.match(value) if mo: sectname = mo.group('header') if sectname in self._sections: if self._strict and sectname in elements_added: raise configparser.DuplicateSectionError( sectname, fpname, lineno) cursect = self._sections[sectname] elements_added.add(sectname) elif sectname == self.default_section: cursect = self._defaults else: cursect = self._dict() self._sections[sectname] = cursect self._proxies[sectname] = configparser.SectionProxy( self, sectname) elements_added.add(sectname) # So sections can't start with a continuation line optname = None # no section header in the file? elif cursect is None: raise configparser.MissingSectionHeaderError( fpname, lineno, line) # an option line? else: mo = self._optcre.match(value) if mo: optname, vi, optval = mo.group('option', 'vi', 'value') if not optname: e = self._handle_error(e, fpname, lineno, line) optname = self.optionxform(optname.rstrip()) if (self._strict and (sectname, optname) in elements_added): raise configparser.DuplicateOptionError( sectname, optname, fpname, lineno) elements_added.add((sectname, optname)) # This check is fine because the OPTCRE cannot # match if it would set optval to None if optval is not None: optval = optval.strip() # Check if this optname already exists if (optname in cursect) and (cursect[optname] is not None): # If it does, convert it to a tuple if it isn't already one if not isinstance(cursect[optname], tuple): cursect[optname] = tuple(cursect[optname]) cursect[optname] = cursect[optname] + tuple( [optval]) else: cursect[optname] = [optval] else: # valueless option handling cursect[optname] = None 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 e = self._handle_error(e, fpname, lineno, line) # if any parsing errors occurred, raise an exception if e: raise e self._join_multiline_values()
def _read(self, fp, fpname): cursect = None optname = None lineno = 0 is_multi_line = False e = None def string_decode(v): if v[-1] == '\\': v = v[:-1] # end cut trailing escapes to prevent decode error if PY3: return v.encode(defenc).decode('unicode_escape') else: return v.decode('string_escape') # end # end while True: # we assume to read binary ! line = fp.readline().decode(defenc) if not line: break lineno = lineno + 1 # comment or blank line? if line.strip() == '' or self.re_comment.match(line): continue if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": # no leading whitespace continue # is it a section header? mo = self.SECTCRE.match(line.strip()) if not is_multi_line and mo: sectname = mo.group('header').strip() if sectname in self._sections: cursect = self._sections[sectname] elif sectname == cp.DEFAULTSECT: cursect = self._defaults else: cursect = self._dict((('__name__', sectname), )) self._sections[sectname] = cursect self._proxies[sectname] = None # So sections can't start with a continuation line optname = None # no section header in the file? elif cursect is None: raise cp.MissingSectionHeaderError(fpname, lineno, line) # an option line? elif not is_multi_line: mo = self.OPTCRE.match(line) if mo: # We might just have handled the last line, which could # contain a quotation we want to remove optname, vi, optval = mo.group('option', 'vi', 'value') if vi in ('=', ':') and ';' in optval and not optval.strip( ).startswith('"'): pos = optval.find(';') if pos != -1 and optval[pos - 1].isspace(): optval = optval[:pos] optval = optval.strip() if optval == '""': optval = '' # end handle empty string optname = self.optionxform(optname.rstrip()) if len(optval ) > 1 and optval[0] == '"' and optval[-1] != '"': is_multi_line = True optval = string_decode(optval[1:]) # end handle multi-line cursect[optname] = optval else: if not self.OPTVALUEONLY.match(line): if not e: e = cp.ParsingError(fpname) e.append(lineno, repr(line)) continue else: line = line.rstrip() if line.endswith('"'): is_multi_line = False line = line[:-1] # end handle quotations cursect[optname] += string_decode(line) # END parse section or option # END while reading # if any parsing errors occurred, raise an exception if e: raise e