diff --git a/dvc/parsing/__init__.py b/dvc/parsing/__init__.py index 6d3f47ab0..fce30b6af 100644 --- a/dvc/parsing/__init__.py +++ b/dvc/parsing/__init__.py @@ -135,6 +135,7 @@ def make_definition( class DataResolver: def __init__(self, repo: "Repo", wdir: str, d: dict): self.fs = fs = repo.fs + self.parsing_config = repo.config.get("parsing", {}) if os.path.isabs(wdir): wdir = fs.path.relpath(wdir) @@ -301,7 +302,10 @@ class EntryDefinition: ) -> "DictStrAny": try: return context.resolve( - value, skip_interpolation_checks=skip_checks, key=key + value, + skip_interpolation_checks=skip_checks, + key=key, + config=self.resolver.parsing_config, ) except (ParseError, KeyNotInContext) as exc: format_and_raise(exc, f"'{self.where}.{self.name}.{key}'", self.relpath) diff --git a/dvc/parsing/context.py b/dvc/parsing/context.py index 221c5feab..6484f0829 100644 --- a/dvc/parsing/context.py +++ b/dvc/parsing/context.py @@ -495,7 +495,12 @@ class Context(CtxDict): self.data.pop(key, None) def resolve( - self, src, unwrap=True, skip_interpolation_checks=False, key=None + self, + src, + unwrap=True, + skip_interpolation_checks=False, + key=None, + config=None, ) -> Any: """Recursively resolves interpolation and returns resolved data. @@ -511,10 +516,15 @@ class Context(CtxDict): {'lst': [1, 2, 3]} """ func = recurse(self.resolve_str) - return func(src, unwrap, skip_interpolation_checks, key) + return func(src, unwrap, skip_interpolation_checks, key, config) def resolve_str( - self, src: str, unwrap=True, skip_interpolation_checks=False, key=None + self, + src: str, + unwrap=True, + skip_interpolation_checks=False, + key=None, + config=None, ) -> str: """Resolves interpolated string to it's original value, or in case of multiple interpolations, a combined string. @@ -535,7 +545,12 @@ class Context(CtxDict): return value # but not "${num} days" return str_interpolate( - src, matches, self, skip_checks=skip_interpolation_checks, key=key + src, + matches, + self, + skip_checks=skip_interpolation_checks, + key=key, + config=config, ) diff --git a/dvc/parsing/interpolate.py b/dvc/parsing/interpolate.py index a423c0a1b..4b9b0686c 100644 --- a/dvc/parsing/interpolate.py +++ b/dvc/parsing/interpolate.py @@ -82,20 +82,18 @@ def escape_str(value): @singledispatch -def to_str(obj) -> str: +def to_str(obj, config=None) -> str: # noqa: ARG001, pylint: disable=unused-argument return str(obj) @to_str.register(bool) -def _(obj: bool): +def _(obj: bool, config=None): # noqa: ARG001, pylint: disable=unused-argument return "true" if obj else "false" @to_str.register(dict) -def _(obj: dict): # noqa: C901 - from dvc.config import Config - - config = Config.from_cwd().get("parsing", {}) +def _(obj: dict, config=None): # noqa: C901 + config = config or {} result = "" for k, v in flatten(obj).items(): @@ -211,6 +209,7 @@ def str_interpolate( context: "Context", skip_checks: bool = False, key=None, + config=None, ): index, buf = 0, "" for match in matches: @@ -218,7 +217,7 @@ def str_interpolate( expr = get_expression(match, skip_checks=skip_checks) value = context.select(expr, unwrap=True) validate_value(value, key) - buf += template[index:start] + to_str(value) + buf += template[index:start] + to_str(value, config=config) index = end buf += template[index:] # regex already backtracks and avoids any `${` starting with