Beispiel #1
0
    def test_parse_ini_file_missing_section_header(self, mock_config_parser_type):
        mock_config_parser = mock_config_parser_type()
        mock_config_parser.read.side_effect = \
            configparser.MissingSectionHeaderError(mock.Mock(), 321, mock.Mock())

        with self.assertRaises(configparser.MissingSectionHeaderError):
            utils.parse_ini_file('my_path')
Beispiel #2
0
    def _read_duplicate(self, file_fp, fpname, dummy_overwrite_first=False):
        """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
        # None, or an exception
        exception = None

        seen = []

        while True:
            line = file_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:
                    # pylint: disable=unsupported-assignment-operation
                    # pylint: disable=unsubscriptable-object
                    cursect[optname] = "%s\n%s" % (cursect[optname], value)
            # a section header or option header?
            else:
                # is it a section header?
                mo_header = self.SECTCRE.match(line)
                if mo_header:
                    sectname = mo_header.group('header')
                    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
                    # 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_option = self.OPTCRE.match(line)
                    if mo_option:
                        optname, vi_sep, optval = mo_option.group(
                            'option', 'vi', 'value'
                        )
                        if vi_sep 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() or pos == 0
                                )
                            ):
                                optval = optval[:pos]

                        optval = optval.strip()
                        # allow empty values
                        if optval == '""':
                            optval = ''
                        optname = self.optionxform(optname.rstrip())

                        # if option already exists, append to a list
                        # pylint: disable=unsubscriptable-object
                        # pylint: disable=unsupported-membership-test
                        # pylint: disable=unsupported-assignment-operation
                        if optname in cursect and optname in seen:
                            if isinstance(cursect[optname], list):
                                cursect[optname].append(optval)
                            else:
                                cursect[optname] = [cursect[optname], optval]
                        else:
                            cursect[optname] = optval
                            seen.append(optname)
                    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 exception:
                            exception = configparser.ParsingError(fpname)
                        exception.append(lineno, repr(line))

        # if any parsing errors occurred, raise an exception
        if exception is not None:
            raise exception  # pylint: disable=raising-bad-type