def _interpolate_some(self, parser, option, accum, rest, section, map, depth): raw_val = parser.get(section, option, raw=True, fallback=rest) if depth > cp.MAX_INTERPOLATION_DEPTH: raise cp.InterpolationDepthError(option, section, raw_val) 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 != "(": rest = "%" + rest elif c == "(": m = self._KEYCRE.match(rest) if m is None: raise cp.InterpolationSyntaxError( option, section, "bad interpolation variable reference %r" % rest) var = parser.optionxform(m.group(1)) rest = rest[m.end():] try: v = map[var] except KeyError: raise cp.InterpolationMissingOptionError( option, section, raw_val, var) from None if "%" in v: self._interpolate_some(parser, option, accum, v, section, map, depth + 1) else: accum.append(v) else: raise cp.InterpolationSyntaxError( option, section, "'%%' must be followed by '%%' or '(', found: %r" % (rest, ))
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 = map[opt] elif len(path) == 2: sect = path[0] opt = parser.optionxform(path[1]) v = parser.get(sect, opt, raw=True) else: raise configparser.InterpolationSyntaxError( option, section, "More than one '.' found: %r" % (rest,)) except (KeyError, configparser.NoSectionError, configparser.NoOptionError): raise configparser.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 configparser.InterpolationSyntaxError( option, section, "'$' must be followed by '$' or '{', " "found: %r" % (rest,))
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 configparser.InterpolationMissingOptionError( '[%s]' % section, section, key, '%%(%s)s' % key) s = section % {key: val} self._sections[s] = self._sections.pop(section)
def format_str(value: str) -> str: # Because dictionaries use the symbols `{}`, we must proactively escape the symbols so that # .format() does not try to improperly interpolate. escaped_str = value.replace("{", "{{").replace("}", "}}") new_style_format_str = re.sub( pattern=r"%\((?P<interpolated>[a-zA-Z_0-9]*)\)s", repl=r"{\g<interpolated>}", string=escaped_str, ) try: possible_interpolations = {**self.defaults, **section_values} return new_style_format_str.format(**possible_interpolations) except KeyError as e: bad_reference = e.args[0] raise configparser.InterpolationMissingOptionError( option, section, raw_value, bad_reference, )
def _interpolate_some(self, parser, option, accum, rest, section, mapping, depth): """The default ExtendedInterpolation does not account for default values in nested interpolations. ie: The following does not work when get() is given the kwargs 'section = "debugging"' and 'vars = {"filePath_versionDir": "C:/"}'). [admin] alembicPath = ${filePath_versionDir}/Schema/main/ [debugging] alembicPath = ${admin:alembicPath} """ rawval = parser.get(section, option, raw=True, fallback=rest) if (depth > configparser.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) is 1): opt = parser.optionxform(path[0]) v = mapping[opt] elif (len(path) is 2): sect = path[0] opt = parser.optionxform(path[1]) v = parser.get(sect, opt, raw=True) else: raise configparser.InterpolationSyntaxError( option, section, "More than one ':' found: %r" % (rest, )) except (KeyError, NoSectionError, NoOptionError): raise configparser.InterpolationMissingOptionError( option, section, rawval, ":".join(path)) from None if ("$" in v): self._interpolate_some(parser, opt, accum, v, sect, { **mapping, **dict(parser.items(sect, raw=True)) }, depth + 1) # <- This was the only change else: accum.append(v) else: raise InterpolationSyntaxError( option, section, "'$' must be followed by '$' or '{', " "found: %r" % (rest, ))