Ejemplo n.º 1
0
    def GetValue(self, parser, section, option, path):
        path = path.split(":")
        if (len(path) == 1):
            sec = section
            opt = parser.optionxform(path[0])
        elif (len(path) == 2):
            sec = path[0]
            opt = parser.optionxform(path[1])
        else:
            raise InterpolationSyntaxError(option, section,
                                           "More than one ':' found.")

        try:
            return self.GetCached(sec, opt)
        except KeyError:
            pass

        try:
            value = parser.get(sec, opt, raw=True)
            # print("GetValue: successful parser access: '{0}'".format(value))
        except (KeyError, NoSectionError, NoOptionError) as ex:
            raise InterpolationMissingOptionError(option, section, "",
                                                  ":".join(path)) from ex

        if (("$" in value) or ("%" in value)):
            value = self.interpolate(parser, sec, opt, value, {})

        self.UpdateCache(sec, opt, value)
        return value
Ejemplo n.º 2
0
 def _interpolate_some(self, parser, option, accum, rest, section, map,
                       depth):
     rawval = parser.get(section, option, raw=True, fallback=rest)
     if depth > MAX_INTERPOLATION_DEPTH:
         raise InterpolationDepthError(option, section, rawval)
     while rest:
         p = rest.find("$")
         if p < 0:
             accum.append(rest)
             return
         if p > 0:
             accum.append(rest[:p])
             rest = rest[p:]
         # p is no longer used
         c = rest[1:2]
         if c == "$":
             accum.append("$")
             rest = rest[2:]
         elif c == "{":
             m = self._KEYCRE.match(rest)
             if m is None:
                 raise InterpolationSyntaxError(
                     option, section,
                     "bad interpolation variable reference %r" % rest)
             path = m.group(1).split(':')
             rest = rest[m.end():]
             sect = section
             opt = option
             try:
                 if len(path) == 1:
                     opt = parser.optionxform(path[0])
                     v = self._resolve_option(opt, map)
                 elif len(path) == 2:
                     sect = path[0]
                     opt = path[1]
                     v = self._resolve_section_option(sect, opt, parser)
                 else:
                     raise InterpolationSyntaxError(
                         option, section,
                         "More than one ':' found: %r" % (rest, ))
             except (KeyError, NoSectionError, NoOptionError):
                 raise InterpolationMissingOptionError(
                     option, section, rawval, ":".join(path)) from None
             if "$" in v:
                 self._interpolate_some(parser, opt, accum, v, sect,
                                        dict(parser.items(sect, raw=True)),
                                        depth + 1)
             else:
                 accum.append(v)
         else:
             raise InterpolationSyntaxError(
                 option, section, "'$' must be followed by '$' or '{', "
                 "found: %r" % (rest, ))
Ejemplo n.º 3
0
 def interpolate_section_names(self, **kwargs):
     """Interpolate a specific key in a section name using val
     """
     for section in self.sections():
         s = section
         for key in self._interpvar_re.findall(section):
             try:
                 val = kwargs[key]
             except KeyError:
                 raise InterpolationMissingOptionError(
                     '[%s]' % section, section, key, '%%(%s)s' % key)
             s = section % {key: val}
         self._sections[s] = self._sections.pop(section)
Ejemplo n.º 4
0
 def _interpolate(self, section, option, rawval, vars):
     # do the string interpolation
     value = rawval
     depth = MAX_INTERPOLATION_DEPTH
     while depth:  # Loop through this until it's done
         depth -= 1
         if "%(" in value:
             try:
                 value = value % vars
             except KeyError as e:
                 raise InterpolationMissingOptionError(
                     option, section, rawval, e.args[0])
         else:
             break
     if value.find("%(") != -1:
         raise InterpolationDepthError(option, section, rawval)
     return value
Ejemplo n.º 5
0
 def _interpolate_some(self, option, accum, rest, section, map, depth):
     if depth > MAX_INTERPOLATION_DEPTH:
         raise InterpolationDepthError(option, section, rest)
     while rest:
         p = rest.find("%")
         if p < 0:
             accum.append(rest)
             return
         if p > 0:
             accum.append(rest[:p])
             rest = rest[p:]
         # p is no longer used
         c = rest[1:2]
         if c == "%":
             accum.append("%")
             rest = rest[2:]
         elif c == "(":
             m = self._interpvar_match(rest)
             if m is None:
                 raise InterpolationSyntaxError(
                     option, section,
                     "bad interpolation variable reference %r" % rest)
             var = m.group(1)
             rest = rest[m.end():]
             try:
                 v = map[var]
             except KeyError:
                 raise InterpolationMissingOptionError(
                     option, section, rest, var)
             if "%" in v:
                 self._interpolate_some(option, accum, v, section, map,
                                        depth + 1)
             else:
                 accum.append(v)
         else:
             raise InterpolationSyntaxError(
                 option, section,
                 "'%' must be followed by '%' or '(', found: " + repr(rest))
Ejemplo n.º 6
0
    def before_get(self, parser, section, option, value, defaults):
        dollar_ind = value.find('$')
        if dollar_ind == -1:
            return value

        colon_ind = value.find('::')
        if colon_ind != -1 and value[dollar_ind + 1:colon_ind] == 'ENV':
            env_name = value[colon_ind + 2:]
            return parser.env.get(env_name)

        m = self._KEYCRE.match(value[dollar_ind:])
        if m is None:
            raise InterpolationSyntaxError(option, section,
                                           f'bad interpolation variable reference {value}')
        var = parser.optionxform(m.group(1))
        try:
            val = defaults[var]
        except KeyError:
            raise InterpolationMissingOptionError(option, section, value, var) from None

        # the resolved value can also contain variables
        val = self.before_get(parser, section, option, val, defaults)

        return val + value[m.end():]
Ejemplo n.º 7
0
 def interpolate(self, parser, option, accum, rest, section, map, depth):
     # Mostly copy-pasted from the built-in configparser implementation.
     # We need to overwrite this method so we can add special handling for
     # block references :( All values produced here should be strings –
     # we need to wait until the whole config is interpreted anyways so
     # filling in incomplete values here is pointless. All we need is the
     # section reference so we can fetch it later.
     rawval = parser.get(section, option, raw=True, fallback=rest)
     if depth > MAX_INTERPOLATION_DEPTH:
         raise InterpolationDepthError(option, section, rawval)
     while rest:
         p = rest.find("$")
         if p < 0:
             accum.append(rest)
             return
         if p > 0:
             accum.append(rest[:p])
             rest = rest[p:]
         # p is no longer used
         c = rest[1:2]
         if c == "$":
             accum.append("$")
             rest = rest[2:]
         elif c == "{":
             # We want to treat both ${a:b} and ${a.b} the same
             m = self._KEYCRE.match(rest)
             if m is None:
                 err = f"bad interpolation variable reference {rest}"
                 raise InterpolationSyntaxError(option, section, err)
             path = m.group(1).replace(":", ".").rsplit(".", 1)
             rest = rest[m.end():]
             sect = section
             opt = option
             try:
                 if len(path) == 1:
                     opt = parser.optionxform(path[0])
                     if opt in map:
                         v = map[opt]
                     else:
                         # We have block reference, store it as a special key
                         section_name = parser[parser.optionxform(
                             path[0])]._name
                         v = self._get_section_name(section_name)
                 elif len(path) == 2:
                     sect = path[0]
                     opt = parser.optionxform(path[1])
                     fallback = "__FALLBACK__"
                     v = parser.get(sect, opt, raw=True, fallback=fallback)
                     # If a variable doesn't exist, try again and treat the
                     # reference as a section
                     if v == fallback:
                         v = self._get_section_name(
                             parser[f"{sect}.{opt}"]._name)
                 else:
                     err = f"More than one ':' found: {rest}"
                     raise InterpolationSyntaxError(option, section, err)
             except (KeyError, NoSectionError, NoOptionError):
                 raise InterpolationMissingOptionError(
                     option, section, rawval, ":".join(path)) from None
             if "$" in v:
                 new_map = dict(parser.items(sect, raw=True))
                 self.interpolate(parser, opt, accum, v, sect, new_map,
                                  depth + 1)
             else:
                 accum.append(v)
         else:
             err = "'$' must be followed by '$' or '{', " "found: %r" % (
                 rest, )
             raise InterpolationSyntaxError(option, section, err)