From e155c6d8e31aefb63b56271368ddff9d594cc40a Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Wed, 5 Feb 2025 01:24:36 +0100 Subject: [PATCH 1/9] [BUGFIX] TOML config interpreting set_env=file|... --- src/tox/config/loader/toml/__init__.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/tox/config/loader/toml/__init__.py b/src/tox/config/loader/toml/__init__.py index fb402bcfe..87f8ce174 100644 --- a/src/tox/config/loader/toml/__init__.py +++ b/src/tox/config/loader/toml/__init__.py @@ -1,11 +1,14 @@ from __future__ import annotations +import inspect import logging from pathlib import Path from typing import TYPE_CHECKING, Dict, Iterator, List, Mapping, TypeVar, cast from tox.config.loader.api import ConfigLoadArgs, Loader, Override +from tox.config.set_env import SetEnv from tox.config.types import Command, EnvList +from tox.report import HandledError from ._api import TomlTypes from ._replace import Unroll @@ -55,15 +58,34 @@ def load_raw_from_root(self, path: str) -> TomlTypes: def build( # noqa: PLR0913 self, - key: str, # noqa: ARG002 + key: str, of_type: type[_T], factory: Factory[_T], conf: Config | None, raw: TomlTypes, args: ConfigLoadArgs, ) -> _T: + delay_replace = inspect.isclass(of_type) and issubclass(of_type, SetEnv) + + def replacer(raw_: str, args_: ConfigLoadArgs) -> str: + if conf is None: + replaced = raw_ # no replacement supported in the core section + else: + reference_replacer = Unroll(conf, self, args) + try: + replaced = str(reference_replacer(raw_)) # do replacements + except Exception as exception: + if isinstance(exception, HandledError): + raise + msg = f"replace failed in {args_.env_name}.{key} with {exception!r}" + raise HandledError(msg) from exception + return replaced + exploded = Unroll(conf=conf, loader=self, args=args)(raw) - return self.to(exploded, of_type, factory) + refactoried = self.to(exploded, of_type, factory) + if delay_replace: + refactoried.use_replacer(replacer, args=args) # type: ignore[attr-defined] # issubclass(to_type, SetEnv) + return refactoried def found_keys(self) -> set[str]: return set(self.content.keys()) - self._unused_exclude From 9017a260a19c0f7825f10671daf75e8d0a56147d Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Wed, 5 Feb 2025 01:24:53 +0100 Subject: [PATCH 2/9] Tests --- tests/config/test_set_env.py | 40 +++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/config/test_set_env.py b/tests/config/test_set_env.py index d4440ab22..54ec20f7c 100644 --- a/tests/config/test_set_env.py +++ b/tests/config/test_set_env.py @@ -1,7 +1,7 @@ from __future__ import annotations from pathlib import Path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Literal from unittest.mock import ANY import pytest @@ -51,10 +51,14 @@ def test_set_env_bad_line() -> None: SetEnv("A", "py", "py", Path()) +_ConfType = Literal["ini", "toml"] + + class EvalSetEnv(Protocol): def __call__( self, - tox_ini: str, + config: str, + conf_type: _ConfType = "ini", extra_files: dict[str, Any] | None = ..., from_cwd: Path | None = ..., ) -> SetEnv: ... @@ -62,8 +66,16 @@ def __call__( @pytest.fixture def eval_set_env(tox_project: ToxProjectCreator) -> EvalSetEnv: - def func(tox_ini: str, extra_files: dict[str, Any] | None = None, from_cwd: Path | None = None) -> SetEnv: - prj = tox_project({"tox.ini": tox_ini, **(extra_files or {})}) + def func( + config: str, + conf_type: _ConfType = "ini", + extra_files: dict[str, Any] | None = None, + from_cwd: Path | None = None, + ) -> SetEnv: + if conf_type == "ini": + prj = tox_project({"tox.ini": config, **(extra_files or {})}) + else: + prj = tox_project({"tox.toml": config, **(extra_files or {})}) result = prj.run("c", "-k", "set_env", "-e", "py", from_cwd=None if from_cwd is None else prj.path / from_cwd) result.assert_success() set_env: SetEnv = result.env_conf("py")["set_env"] @@ -149,7 +161,19 @@ def test_set_env_honor_override(eval_set_env: EvalSetEnv) -> None: assert set_env.load("PIP_DISABLE_PIP_VERSION_CHECK") == "0" -def test_set_env_environment_file(eval_set_env: EvalSetEnv) -> None: +@pytest.mark.parametrize( + ("conf_type", "config"), + [ + ("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\nchange_dir=C"), + ("toml", '[env_run_base]\npackage="skip"\nset_env="file|A{/}a.txt"\nchange_dir="C"'), + # Using monkeypatched env setting as a reference + ("ini", "[testenv]\npackage=skip\nset_env=file|{env:myenvfile}\nchange_dir=C"), + ("toml", '[env_run_base]\npackage="skip"\nset_env="file|{env:myenvfile}"\nchange_dir="C"'), + ], +) +def test_set_env_environment_file( + conf_type: _ConfType, config: str, eval_set_env: EvalSetEnv, monkeypatch: MonkeyPatch +) -> None: env_file = """ A=1 B= 2 @@ -158,9 +182,11 @@ def test_set_env_environment_file(eval_set_env: EvalSetEnv) -> None: E = "1" F = """ + # Monkeypatch only used for some of the parameters + monkeypatch.setenv("myenvfile", "A{/}a.txt") + extra = {"A": {"a.txt": env_file}, "B": None, "C": None} - ini = "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\nchange_dir=C" - set_env = eval_set_env(ini, extra_files=extra, from_cwd=Path("B")) + set_env = eval_set_env(config, conf_type=conf_type, extra_files=extra, from_cwd=Path("B")) content = {k: set_env.load(k) for k in set_env} assert content == { "PIP_DISABLE_PIP_VERSION_CHECK": "1", From 9d1f105a27ad3596a1bf9e4a7e2a3b0576fd7da7 Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Wed, 5 Feb 2025 01:49:58 +0100 Subject: [PATCH 3/9] Changelog entry --- docs/changelog/3474.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/changelog/3474.bugfix.rst diff --git a/docs/changelog/3474.bugfix.rst b/docs/changelog/3474.bugfix.rst new file mode 100644 index 000000000..4bc0317dc --- /dev/null +++ b/docs/changelog/3474.bugfix.rst @@ -0,0 +1 @@ +TOML config did not accept set_env=file| terminology, despite suggesting equal support as for INI. From 4ec2bf53e27249fb8e4fc34a9c20ccfac5a51c26 Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Tue, 18 Feb 2025 11:57:33 +0100 Subject: [PATCH 4/9] Added set_env 'file' option in TOML as dict --- src/tox/config/set_env.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tox/config/set_env.py b/src/tox/config/set_env.py index cf29cee0c..878481bce 100644 --- a/src/tox/config/set_env.py +++ b/src/tox/config/set_env.py @@ -11,7 +11,7 @@ class SetEnv: - def __init__( # noqa: C901 + def __init__( # noqa: C901, PLR0912 self, raw: str | dict[str, str] | list[dict[str, str]], name: str, env_name: str | None, root: Path ) -> None: self.changed = False @@ -24,13 +24,21 @@ def __init__( # noqa: C901 from .loader.replacer import MatchExpression, find_replace_expr # noqa: PLC0415 if isinstance(raw, dict): - self._raw = raw + # TOML 'file' attribute is to be handled separately later + self._raw = dict(raw) + if "file" in raw: + self._env_files.append(raw["file"]) + self._raw.pop("file") + return + if isinstance(raw, list): self._raw = reduce(lambda a, b: {**a, **b}, raw) return + for line in raw.splitlines(): # noqa: PLR1702 if line.strip(): + # INI 'file|' attribute is to be handled separately later if line.startswith("file|"): self._env_files.append(line[len("file|") :]) else: From 222c89c63f9b547e21c1fc9b0b9a322b80d5e0e8 Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Tue, 18 Feb 2025 11:57:57 +0100 Subject: [PATCH 5/9] Testing set_env 'file' option in TOML as dict --- tests/config/test_set_env.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/tests/config/test_set_env.py b/tests/config/test_set_env.py index 54ec20f7c..a5c435fbf 100644 --- a/tests/config/test_set_env.py +++ b/tests/config/test_set_env.py @@ -165,10 +165,10 @@ def test_set_env_honor_override(eval_set_env: EvalSetEnv) -> None: ("conf_type", "config"), [ ("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\nchange_dir=C"), - ("toml", '[env_run_base]\npackage="skip"\nset_env="file|A{/}a.txt"\nchange_dir="C"'), + ("toml", '[env_run_base]\npackage="skip"\nset_env={file="A{/}a.txt"}\nchange_dir="C"'), # Using monkeypatched env setting as a reference ("ini", "[testenv]\npackage=skip\nset_env=file|{env:myenvfile}\nchange_dir=C"), - ("toml", '[env_run_base]\npackage="skip"\nset_env="file|{env:myenvfile}"\nchange_dir="C"'), + ("toml", '[env_run_base]\npackage="skip"\nset_env={file="{env:myenvfile}"}\nchange_dir="C"'), ], ) def test_set_env_environment_file( @@ -200,6 +200,37 @@ def test_set_env_environment_file( } +@pytest.mark.parametrize( + ("conf_type", "config"), + [ + ("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\n X=y\nchange_dir=C"), + ("toml", '[env_run_base]\npackage="skip"\nset_env={file="A{/}a.txt", X="y"}\nchange_dir="C"'), + # Using monkeypatched env setting as a reference + ("ini", "[testenv]\npackage=skip\nset_env=file|{env:myenvfile}\n X=y\nchange_dir=C"), + ("toml", '[env_run_base]\npackage="skip"\nset_env={file="{env:myenvfile}", X="y"}\nchange_dir="C"'), + ], +) +def test_set_env_environment_file_combined_with_normal_setting( + conf_type: _ConfType, config: str, eval_set_env: EvalSetEnv, monkeypatch: MonkeyPatch +) -> None: + env_file = """ + A=1 + """ + # Monkeypatch only used for some of the parameters + monkeypatch.setenv("myenvfile", "A{/}a.txt") + + extra = {"A": {"a.txt": env_file}, "B": None, "C": None} + set_env = eval_set_env(config, conf_type=conf_type, extra_files=extra, from_cwd=Path("B")) + content = {k: set_env.load(k) for k in set_env} + assert content == { + "PIP_DISABLE_PIP_VERSION_CHECK": "1", + "PYTHONHASHSEED": ANY, + "A": "1", + "X": "y", + "PYTHONIOENCODING": "utf-8", + } + + def test_set_env_environment_file_missing(tox_project: ToxProjectCreator) -> None: project = tox_project({"tox.ini": "[testenv]\npackage=skip\nset_env=file|magic.txt"}) result = project.run("r") From c0356a1df7240508fe9ffa8ec07b4ab3012146ca Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Tue, 18 Feb 2025 11:58:27 +0100 Subject: [PATCH 6/9] Updating docs on set_env 'file' option (INI vs TOML) --- docs/config.rst | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index db1c27d73..0d8e1b18c 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -551,8 +551,26 @@ Base options .. conf:: :keys: set_env, setenv - A dictionary of environment variables to set when running commands in the tox environment. Lines starting with a - ``file|`` prefix define the location of environment file. + A dictionary of environment variables to set when running commands in the tox environment. + + In addition, there is an option to include an existing environment file. See the different syntax for TOML and INI below. + + .. tab:: TOML + + .. code-block:: toml + + [tool.tox.env_run_base] + set_env = { file = "conf{/}local.env", TEST_TIMEOUT = 30 } + + .. tab:: INI + + + .. code-block:: ini + + [testenv] + set_env = file|conf{/}local.env + TEST_TIMEOUT = 30 + .. note:: From e4cabe83b5152d862642cfddf9a2b6dbddef7be7 Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Fri, 21 Feb 2025 18:13:52 +0100 Subject: [PATCH 7/9] Removing INI-specific check from TOML internal replacer function --- src/tox/config/loader/toml/__init__.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/tox/config/loader/toml/__init__.py b/src/tox/config/loader/toml/__init__.py index 87f8ce174..25cae1e5c 100644 --- a/src/tox/config/loader/toml/__init__.py +++ b/src/tox/config/loader/toml/__init__.py @@ -68,17 +68,14 @@ def build( # noqa: PLR0913 delay_replace = inspect.isclass(of_type) and issubclass(of_type, SetEnv) def replacer(raw_: str, args_: ConfigLoadArgs) -> str: - if conf is None: - replaced = raw_ # no replacement supported in the core section - else: - reference_replacer = Unroll(conf, self, args) - try: - replaced = str(reference_replacer(raw_)) # do replacements - except Exception as exception: - if isinstance(exception, HandledError): - raise - msg = f"replace failed in {args_.env_name}.{key} with {exception!r}" - raise HandledError(msg) from exception + reference_replacer = Unroll(conf, self, args) + try: + replaced = str(reference_replacer(raw_)) # do replacements + except Exception as exception: + if isinstance(exception, HandledError): + raise + msg = f"replace failed in {args_.env_name}.{key} with {exception!r}" + raise HandledError(msg) from exception return replaced exploded = Unroll(conf=conf, loader=self, args=args)(raw) From 7a0971db54e9e02d76ff98b96f62793aac722483 Mon Sep 17 00:00:00 2001 From: Judit Novak Date: Thu, 27 Feb 2025 14:38:55 +0100 Subject: [PATCH 8/9] Additional extension on docs, highlighting internal references --- docs/config.rst | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/config.rst b/docs/config.rst index 0d8e1b18c..fb099c3d9 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -564,7 +564,6 @@ Base options .. tab:: INI - .. code-block:: ini [testenv] @@ -572,6 +571,24 @@ Base options TEST_TIMEOUT = 30 + The env file path may include previously defined tox variables: + + + .. tab:: TOML + + .. code-block:: toml + + [tool.tox.env_run_base] + set_env = { file = "{env:variable}" } + + .. tab:: INI + + .. code-block:: ini + + [testenv] + set_env = file|{env:variable} + + .. note:: Environment files are processed using the following rules: From 015cf6b1dc4fd0a4e2f7767b31d9ea475f7a8d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Thu, 6 Mar 2025 13:42:15 -0800 Subject: [PATCH 9/9] PR feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- docs/changelog/3474.bugfix.rst | 2 +- src/tox/config/loader/toml/__init__.py | 24 +++-------- src/tox/config/set_env.py | 11 ++--- tests/config/test_set_env.py | 56 ++++++++++++++------------ 4 files changed, 40 insertions(+), 53 deletions(-) diff --git a/docs/changelog/3474.bugfix.rst b/docs/changelog/3474.bugfix.rst index 4bc0317dc..5cf3c29e3 100644 --- a/docs/changelog/3474.bugfix.rst +++ b/docs/changelog/3474.bugfix.rst @@ -1 +1 @@ -TOML config did not accept set_env=file| terminology, despite suggesting equal support as for INI. +Support ``set_env = { file = "conf{/}local.env"}`` for TOML format - by :user:`juditnovak`. diff --git a/src/tox/config/loader/toml/__init__.py b/src/tox/config/loader/toml/__init__.py index 25cae1e5c..4c4c6cb03 100644 --- a/src/tox/config/loader/toml/__init__.py +++ b/src/tox/config/loader/toml/__init__.py @@ -58,31 +58,18 @@ def load_raw_from_root(self, path: str) -> TomlTypes: def build( # noqa: PLR0913 self, - key: str, + key: str, # noqa: ARG002 of_type: type[_T], factory: Factory[_T], conf: Config | None, raw: TomlTypes, args: ConfigLoadArgs, ) -> _T: - delay_replace = inspect.isclass(of_type) and issubclass(of_type, SetEnv) - - def replacer(raw_: str, args_: ConfigLoadArgs) -> str: - reference_replacer = Unroll(conf, self, args) - try: - replaced = str(reference_replacer(raw_)) # do replacements - except Exception as exception: - if isinstance(exception, HandledError): - raise - msg = f"replace failed in {args_.env_name}.{key} with {exception!r}" - raise HandledError(msg) from exception - return replaced - exploded = Unroll(conf=conf, loader=self, args=args)(raw) - refactoried = self.to(exploded, of_type, factory) - if delay_replace: - refactoried.use_replacer(replacer, args=args) # type: ignore[attr-defined] # issubclass(to_type, SetEnv) - return refactoried + result = self.to(exploded, of_type, factory) + if inspect.isclass(of_type) and issubclass(of_type, SetEnv): + result.use_replacer(lambda c, s: c, args=args) # type: ignore[attr-defined] # noqa: ARG005 + return result def found_keys(self) -> set[str]: return set(self.content.keys()) - self._unused_exclude @@ -126,5 +113,6 @@ def to_env_list(value: TomlTypes) -> EnvList: __all__ = [ + "HandledError", "TomlLoader", ] diff --git a/src/tox/config/set_env.py b/src/tox/config/set_env.py index 878481bce..0686200c3 100644 --- a/src/tox/config/set_env.py +++ b/src/tox/config/set_env.py @@ -24,22 +24,17 @@ def __init__( # noqa: C901, PLR0912 from .loader.replacer import MatchExpression, find_replace_expr # noqa: PLC0415 if isinstance(raw, dict): - # TOML 'file' attribute is to be handled separately later - self._raw = dict(raw) - if "file" in raw: + self._raw = raw + if "file" in raw: # environment files to be handled later self._env_files.append(raw["file"]) self._raw.pop("file") - return - if isinstance(raw, list): self._raw = reduce(lambda a, b: {**a, **b}, raw) return - for line in raw.splitlines(): # noqa: PLR1702 if line.strip(): - # INI 'file|' attribute is to be handled separately later - if line.startswith("file|"): + if line.startswith("file|"): # environment files to be handled later self._env_files.append(line[len("file|") :]) else: try: diff --git a/tests/config/test_set_env.py b/tests/config/test_set_env.py index a5c435fbf..f72a23299 100644 --- a/tests/config/test_set_env.py +++ b/tests/config/test_set_env.py @@ -51,14 +51,15 @@ def test_set_env_bad_line() -> None: SetEnv("A", "py", "py", Path()) -_ConfType = Literal["ini", "toml"] +ConfigFileFormat = Literal["ini", "toml"] class EvalSetEnv(Protocol): def __call__( self, config: str, - conf_type: _ConfType = "ini", + *, + of_type: ConfigFileFormat = "ini", extra_files: dict[str, Any] | None = ..., from_cwd: Path | None = ..., ) -> SetEnv: ... @@ -68,14 +69,12 @@ def __call__( def eval_set_env(tox_project: ToxProjectCreator) -> EvalSetEnv: def func( config: str, - conf_type: _ConfType = "ini", + *, + of_type: ConfigFileFormat = "ini", extra_files: dict[str, Any] | None = None, from_cwd: Path | None = None, ) -> SetEnv: - if conf_type == "ini": - prj = tox_project({"tox.ini": config, **(extra_files or {})}) - else: - prj = tox_project({"tox.toml": config, **(extra_files or {})}) + prj = tox_project({f"tox.{of_type}": config, **(extra_files or {})}) result = prj.run("c", "-k", "set_env", "-e", "py", from_cwd=None if from_cwd is None else prj.path / from_cwd) result.assert_success() set_env: SetEnv = result.env_conf("py")["set_env"] @@ -162,17 +161,18 @@ def test_set_env_honor_override(eval_set_env: EvalSetEnv) -> None: @pytest.mark.parametrize( - ("conf_type", "config"), + ("of_type", "config"), [ - ("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\nchange_dir=C"), - ("toml", '[env_run_base]\npackage="skip"\nset_env={file="A{/}a.txt"}\nchange_dir="C"'), - # Using monkeypatched env setting as a reference - ("ini", "[testenv]\npackage=skip\nset_env=file|{env:myenvfile}\nchange_dir=C"), - ("toml", '[env_run_base]\npackage="skip"\nset_env={file="{env:myenvfile}"}\nchange_dir="C"'), + pytest.param("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\nchange_dir=C", id="ini"), + pytest.param("toml", '[env_run_base]\npackage="skip"\nset_env={file="A{/}a.txt"}\nchange_dir="C"', id="toml"), + pytest.param("ini", "[testenv]\npackage=skip\nset_env=file|{env:env_file}\nchange_dir=C", id="ini-env"), + pytest.param( + "toml", '[env_run_base]\npackage="skip"\nset_env={file="{env:env_file}"}\nchange_dir="C"', id="toml-env" + ), ], ) def test_set_env_environment_file( - conf_type: _ConfType, config: str, eval_set_env: EvalSetEnv, monkeypatch: MonkeyPatch + of_type: ConfigFileFormat, config: str, eval_set_env: EvalSetEnv, monkeypatch: MonkeyPatch ) -> None: env_file = """ A=1 @@ -182,11 +182,10 @@ def test_set_env_environment_file( E = "1" F = """ - # Monkeypatch only used for some of the parameters - monkeypatch.setenv("myenvfile", "A{/}a.txt") + monkeypatch.setenv("env_file", "A{/}a.txt") extra = {"A": {"a.txt": env_file}, "B": None, "C": None} - set_env = eval_set_env(config, conf_type=conf_type, extra_files=extra, from_cwd=Path("B")) + set_env = eval_set_env(config, of_type=of_type, extra_files=extra, from_cwd=Path("B")) content = {k: set_env.load(k) for k in set_env} assert content == { "PIP_DISABLE_PIP_VERSION_CHECK": "1", @@ -201,26 +200,31 @@ def test_set_env_environment_file( @pytest.mark.parametrize( - ("conf_type", "config"), + ("of_type", "config"), [ - ("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\n X=y\nchange_dir=C"), - ("toml", '[env_run_base]\npackage="skip"\nset_env={file="A{/}a.txt", X="y"}\nchange_dir="C"'), - # Using monkeypatched env setting as a reference - ("ini", "[testenv]\npackage=skip\nset_env=file|{env:myenvfile}\n X=y\nchange_dir=C"), - ("toml", '[env_run_base]\npackage="skip"\nset_env={file="{env:myenvfile}", X="y"}\nchange_dir="C"'), + pytest.param("ini", "[testenv]\npackage=skip\nset_env=file|A{/}a.txt\n X=y\nchange_dir=C", id="ini"), + pytest.param( + "toml", '[env_run_base]\npackage="skip"\nset_env={file="A{/}a.txt", X="y"}\nchange_dir="C"', id="toml" + ), + pytest.param("ini", "[testenv]\npackage=skip\nset_env=file|{env:env_file}\n X=y\nchange_dir=C", id="ini-env"), + pytest.param( + "toml", + '[env_run_base]\npackage="skip"\nset_env={file="{env:env_file}", X="y"}\nchange_dir="C"', + id="toml-env", + ), ], ) def test_set_env_environment_file_combined_with_normal_setting( - conf_type: _ConfType, config: str, eval_set_env: EvalSetEnv, monkeypatch: MonkeyPatch + of_type: ConfigFileFormat, config: str, eval_set_env: EvalSetEnv, monkeypatch: MonkeyPatch ) -> None: env_file = """ A=1 """ # Monkeypatch only used for some of the parameters - monkeypatch.setenv("myenvfile", "A{/}a.txt") + monkeypatch.setenv("env_file", "A{/}a.txt") extra = {"A": {"a.txt": env_file}, "B": None, "C": None} - set_env = eval_set_env(config, conf_type=conf_type, extra_files=extra, from_cwd=Path("B")) + set_env = eval_set_env(config, of_type=of_type, extra_files=extra, from_cwd=Path("B")) content = {k: set_env.load(k) for k in set_env} assert content == { "PIP_DISABLE_PIP_VERSION_CHECK": "1",