Mercurial > hgrepos > Python > libs > ConfigMix
changeset 530:28191d61b042
FIX: Handle non-cacheable interpolations properly.
Currently all non-default namespaces prohibit interpolation caching.
| author | Franz Glasner <f.glasner@feldmann-mg.com> |
|---|---|
| date | Mon, 20 Dec 2021 14:33:54 +0100 |
| parents | 9976ff66c439 |
| children | be740ed67d16 |
| files | configmix/config.py |
| diffstat | 1 files changed, 43 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/configmix/config.py Mon Dec 20 14:33:09 2021 +0100 +++ b/configmix/config.py Mon Dec 20 14:33:54 2021 +0100 @@ -631,6 +631,29 @@ else: return default + def _getvar_s_with_cache_info(self, varname): + """Internal variant of :meth:`~.getvar_s` that returns some information + whether caching of interpolated values is allowed + + Caching is currently not allowed when namespaces are used. + + Currently used by :meth:`~.interpolate_variables`. + + """ + varns, varname = self._split_ns(varname) + if not varns: + cacheable = True + if varname: + varnameparts = tuple([unquote(vp) + for vp in varname.split(_HIER_SEPARATOR)]) + else: + varnameparts = tuple() + else: + cacheable = False + varnameparts = (varname,) + obj = self.getvarl(*varnameparts, namespace=varns) + return (self.substitute_variables_in_obj(obj), cacheable) + def getfirstvar_s(self, *varnames, **kwds): """A variant of :meth:`~.getvar_s` that returns the first found variable in the list of given variables in `varnames`. @@ -776,11 +799,20 @@ return s res = self.__interpolation_cache.get(s, _MARKER) if res is not _MARKER: - return res + if res is _MISSING: + warnings.warn("Cannot interpolate variables in string " + "%r (cached)" % (s, ), + UserWarning, + stacklevel=1) + raise KeyError("Cannot interpolate variables in string " + "%r (cached)" % (s, )) + else: + return res len_s = len(s) res = [] res_append = res.append rest = 0 + use_cache = True while start != -1: res_append(s[rest:start]) end = s.find(_ENDTOK, start) @@ -790,18 +822,22 @@ varname, filters = self._split_filters( s[start+2:end]) try: - varvalue = self.getvar_s(varname) + varvalue, cacheable = self._getvar_s_with_cache_info(varname) except KeyError: + cacheable = True if NONE_FILTER in filters: varvalue = None elif EMPTY_FILTER in filters: varvalue = _EMPTY_STR else: - warnings.warn("Cannot expand variable %r in string " + self.__interpolation_cache[s] = _MISSING + warnings.warn("Cannot interpolate variable %r in string " "%r" % (varname, s, ), UserWarning, stacklevel=1) raise + if not cacheable: + use_cache = False varvalue = self._apply_filters(filters, varvalue) rest = end + 2 # @@ -809,7 +845,8 @@ # the whole `s` is just one expansion # if (start == 0) and (rest == len_s): - self.__interpolation_cache[s] = varvalue + if use_cache: + self.__interpolation_cache[s] = varvalue return varvalue if varvalue is None: pass @@ -819,7 +856,8 @@ start = s.find(_STARTTOK, rest) res_append(s[rest:]) res = _EMPTY_STR.join(res) - self.__interpolation_cache[s] = res + if use_cache: + self.__interpolation_cache[s] = res return res def _apply_filters(self, filters, value):
