|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import inspect |
3 | 4 | import logging
|
4 | 5 | from pathlib import Path
|
5 | 6 | from typing import TYPE_CHECKING, Dict, Iterator, List, Mapping, TypeVar, cast
|
6 | 7 |
|
7 | 8 | from tox.config.loader.api import ConfigLoadArgs, Loader, Override
|
| 9 | +from tox.config.set_env import SetEnv |
8 | 10 | from tox.config.types import Command, EnvList
|
| 11 | +from tox.report import HandledError |
9 | 12 |
|
10 | 13 | from ._api import TomlTypes
|
11 | 14 | from ._replace import Unroll
|
@@ -55,15 +58,34 @@ def load_raw_from_root(self, path: str) -> TomlTypes:
|
55 | 58 |
|
56 | 59 | def build( # noqa: PLR0913
|
57 | 60 | self,
|
58 |
| - key: str, # noqa: ARG002 |
| 61 | + key: str, |
59 | 62 | of_type: type[_T],
|
60 | 63 | factory: Factory[_T],
|
61 | 64 | conf: Config | None,
|
62 | 65 | raw: TomlTypes,
|
63 | 66 | args: ConfigLoadArgs,
|
64 | 67 | ) -> _T:
|
| 68 | + delay_replace = inspect.isclass(of_type) and issubclass(of_type, SetEnv) |
| 69 | + |
| 70 | + def replacer(raw_: str, args_: ConfigLoadArgs) -> str: |
| 71 | + if conf is None: |
| 72 | + replaced = raw_ # no replacement supported in the core section |
| 73 | + else: |
| 74 | + reference_replacer = Unroll(conf, self, args) |
| 75 | + try: |
| 76 | + replaced = str(reference_replacer(raw_)) # do replacements |
| 77 | + except Exception as exception: |
| 78 | + if isinstance(exception, HandledError): |
| 79 | + raise |
| 80 | + msg = f"replace failed in {args_.env_name}.{key} with {exception!r}" |
| 81 | + raise HandledError(msg) from exception |
| 82 | + return replaced |
| 83 | + |
65 | 84 | exploded = Unroll(conf=conf, loader=self, args=args)(raw)
|
66 |
| - return self.to(exploded, of_type, factory) |
| 85 | + refactoried = self.to(exploded, of_type, factory) |
| 86 | + if delay_replace: |
| 87 | + refactoried.use_replacer(replacer, args=args) # type: ignore[attr-defined] # issubclass(to_type, SetEnv) |
| 88 | + return refactoried |
67 | 89 |
|
68 | 90 | def found_keys(self) -> set[str]:
|
69 | 91 | return set(self.content.keys()) - self._unused_exclude
|
|
0 commit comments