diff --git a/src/hatch/project/config.py b/src/hatch/project/config.py index 972a2f2d6..38ffe5289 100644 --- a/src/hatch/project/config.py +++ b/src/hatch/project/config.py @@ -15,12 +15,15 @@ if TYPE_CHECKING: from packaging.requirements import Requirement + from hatchling.utils.context import Context + class ProjectConfig: - def __init__(self, root, config, plugin_manager=None): + def __init__(self, root, config, plugin_manager=None, metadata=None): self.root = root self.config = config self.plugin_manager = plugin_manager + self.metadata = metadata self._matrices = None self._env = None @@ -34,6 +37,18 @@ def __init__(self, root, config, plugin_manager=None): self._publish = None self._scripts = None self._cached_env_overrides = {} + self._context = None + + @property + def context(self) -> Context: + if self._context is None: + if self.metadata: + self._context = self.metadata.context + else: + from hatchling.utils.context import Context + + self._context = Context(self.root) + return self._context @cached_property def build(self): @@ -74,7 +89,7 @@ def env_requires_complex(self) -> list[Requirement]: raise TypeError(message) try: - requires_complex.append(Requirement(entry)) + requires_complex.append(Requirement(self.context.format(entry))) except InvalidRequirement as e: message = f'Requirement #{i} in `tool.hatch.env.requires` is invalid: {e}' raise ValueError(message) from None diff --git a/src/hatch/project/core.py b/src/hatch/project/core.py index 6f4e7d407..22dea2e38 100644 --- a/src/hatch/project/core.py +++ b/src/hatch/project/core.py @@ -52,7 +52,7 @@ def config(self): if self._config is None: from hatch.project.config import ProjectConfig - self._config = ProjectConfig(self.location, self.metadata.hatch.config, self.plugin_manager) + self._config = ProjectConfig(self.location, self.metadata.hatch.config, self.plugin_manager, self.metadata) return self._config diff --git a/tests/project/test_config.py b/tests/project/test_config.py index 1edd48d49..bc920bffa 100644 --- a/tests/project/test_config.py +++ b/tests/project/test_config.py @@ -91,6 +91,15 @@ def test_defined(self, isolation): assert project_config.env_requires == ['foo', 'bar', 'baz'] + def test_context_formatting(self, isolation, uri_slash_prefix): + absolute_path = str(isolation) + project_config = ProjectConfig(isolation, {'env': {'requires': ['plugin@ {root:uri}']}}) + + normalized_path = absolute_path.replace('\\', '/') + assert project_config.env_requires == [ + f'plugin@ file:{uri_slash_prefix}{normalized_path}', + ] + class TestEnvCollectors: def test_not_table(self, isolation):