Skip to content

Commit 52cbe9a

Browse files
Tbruno25kdestinTJ Bruno
authored
Fix tox_root propagation to work_dir (#2962)
Co-authored-by: kdestin <101366538+kdestin@users.noreply.github.com> Co-authored-by: TJ Bruno <tj.bruno@everactive.com>
1 parent f6e3dc9 commit 52cbe9a

File tree

5 files changed

+100
-15
lines changed

5 files changed

+100
-15
lines changed

docs/changelog/2933.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix issue where ``work_dir`` was not correctly including ``tox_root`` for test runs.

src/tox/config/sets.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ def __init__(self, conf: Config, section: Section, root: Path, src_path: Path) -
179179
desc = "define environments to automatically run"
180180
self.add_config(keys=["env_list", "envlist"], of_type=EnvList, default=EnvList([]), desc=desc)
181181

182+
def _default_work_dir(self, conf: Config, env_name: str | None) -> Path: # noqa: U100
183+
return cast(Path, self["tox_root"] / ".tox")
184+
185+
def _default_temp_dir(self, conf: Config, env_name: str | None) -> Path: # noqa: U100
186+
return cast(Path, self["work_dir"] / ".tmp")
187+
188+
def _work_dir_post_process(self, dir: Path) -> Path:
189+
return self._conf.work_dir if self._conf.options.work_dir else dir
190+
182191
def register_config(self) -> None:
183192
self.add_constant(keys=["config_file_path"], desc="path to the configuration file", value=self._src_path)
184193
self.add_config(
@@ -188,23 +197,17 @@ def register_config(self) -> None:
188197
desc="the root directory (where the configuration file is found)",
189198
)
190199

191-
def work_dir_builder(conf: Config, env_name: str | None) -> Path: # noqa: U100
192-
return (conf.work_dir if conf.work_dir is not None else cast(Path, self["tox_root"])) / ".tox"
193-
194-
def work_dir_post_process(value: Path) -> Path:
195-
return self._conf.work_dir if self._conf.options.work_dir else value
196-
197200
self.add_config(
198201
keys=["work_dir", "toxworkdir"],
199202
of_type=Path,
200-
default=work_dir_builder,
201-
post_process=work_dir_post_process,
203+
default=self._default_work_dir,
204+
post_process=self._work_dir_post_process,
202205
desc="working directory",
203206
)
204207
self.add_config(
205208
keys=["temp_dir"],
206209
of_type=Path,
207-
default=lambda conf, _: cast(Path, self["work_dir"]) / ".tmp", # noqa: U100, U101
210+
default=self._default_temp_dir,
208211
desc="a folder for temporary files (is not cleaned at start)",
209212
)
210213
self.add_constant("host_python", "the host python executable path", sys.executable)

tests/session/cmd/test_sequential.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def test_skip_pkg_install(tox_project: ToxProjectCreator, demo_pkg_inline: Path)
280280
def test_skip_develop_mode(tox_project: ToxProjectCreator, demo_pkg_setuptools: Path) -> None:
281281
proj = tox_project({"tox.ini": "[testenv]\npackage=wheel\n"})
282282
execute_calls = proj.patch_execute(lambda r: 0 if "install" in r.run_id else None)
283-
result = proj.run("--root", str(demo_pkg_setuptools), "--develop")
283+
result = proj.run("--root", str(demo_pkg_setuptools), "--develop", "--workdir", str(proj.path / ".tox"))
284284
result.assert_success()
285285
calls = [(i[0][0].conf.name, i[0][3].run_id) for i in execute_calls.call_args_list]
286286
expected = [
@@ -430,7 +430,7 @@ def test_sequential_inserted_env_vars(tox_project: ToxProjectCreator, demo_pkg_i
430430
k.startswith("TOX_") or k == "VIRTUAL_ENV"]'
431431
"""
432432
project = tox_project({"tox.ini": ini})
433-
result = project.run("r", "--root", str(demo_pkg_inline))
433+
result = project.run("r", "--root", str(demo_pkg_inline), "--workdir", str(project.path / ".tox"))
434434
result.assert_success()
435435

436436
assert re.search(f"TOX_PACKAGE={re.escape(str(project.path))}.*.tar.gz{os.linesep}", result.out)

tests/test_run.py

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from pathlib import Path
4+
35
import pytest
46
from pytest_mock import MockerFixture
57

@@ -22,7 +24,77 @@ def test_re_raises_on_unexpected_exit(mocker: MockerFixture) -> None:
2224
run()
2325

2426

25-
def test_custom_work_dir(tox_project: ToxProjectCreator) -> None:
27+
def test_custom_work_dir(tox_project: ToxProjectCreator, tmp_path: Path) -> None:
28+
project = tox_project({})
29+
30+
expected_tox_root = project.path
31+
expected_work_dir = tmp_path
32+
33+
outcome = project.run("c", "--workdir", str(expected_work_dir))
34+
outcome.assert_success()
35+
36+
assert outcome.state.conf.options.work_dir == expected_work_dir, "should parse the --workdir argument"
37+
38+
assert outcome.state.conf.core["work_dir"], f"should set work_dir to {expected_work_dir}"
39+
40+
assert outcome.state.conf.core["tox_root"] == expected_tox_root, "should not update the value of tox_root"
41+
assert outcome.state.conf.core["work_dir"] != (
42+
expected_tox_root / ".tox"
43+
), "should explicitly demonstrate that tox_root and work_dir are decoupled"
44+
45+
# should update config values that depend on work_dir
46+
assert outcome.state.conf.core["temp_dir"] == expected_work_dir / ".tmp"
47+
48+
env_conf = outcome.state.conf.get_env("py")
49+
50+
assert env_conf["env_dir"] == expected_work_dir / "py"
51+
assert env_conf["env_log_dir"] == expected_work_dir / "py" / "log"
52+
assert env_conf["env_tmp_dir"] == expected_work_dir / "py" / "tmp"
53+
54+
55+
def test_custom_root_dir(tox_project: ToxProjectCreator, tmp_path: Path) -> None:
56+
project = tox_project({})
57+
58+
expected_tox_root = tmp_path
59+
expected_work_dir = expected_tox_root / ".tox"
60+
61+
outcome = project.run("c", "--root", str(expected_tox_root))
62+
outcome.assert_success()
63+
64+
assert outcome.state.conf.options.root_dir == expected_tox_root, "should parse the --root argument"
65+
66+
assert outcome.state.conf.core["tox_root"] == expected_tox_root, f"should set tox_root to {expected_tox_root}"
67+
68+
# values that depend on tox_root should also be updated
69+
70+
assert outcome.state.conf.core["work_dir"] == expected_work_dir
71+
assert outcome.state.conf.core["temp_dir"] == expected_work_dir / ".tmp"
72+
73+
env_conf = outcome.state.conf.get_env("py")
74+
75+
assert env_conf["env_dir"] == expected_work_dir / "py"
76+
assert env_conf["env_log_dir"] == expected_work_dir / "py" / "log"
77+
assert env_conf["env_tmp_dir"] == expected_work_dir / "py" / "tmp"
78+
79+
80+
def test_custom_root_dir_and_work_dir(tox_project: ToxProjectCreator, tmp_path: Path) -> None:
2681
project = tox_project({})
27-
outcome = project.run("c", "--workdir", str(project.path.parent))
28-
assert outcome.state.conf.options.work_dir == project.path.parent
82+
83+
expected_tox_root = tmp_path / "tox_root"
84+
expected_work_dir = tmp_path / "work_dir"
85+
86+
outcome = project.run("c", "--root", str(expected_tox_root), "--workdir", str(expected_work_dir))
87+
outcome.assert_success()
88+
89+
assert outcome.state.conf.core["tox_root"] == expected_tox_root, f"should set tox_root to {expected_tox_root}"
90+
assert outcome.state.conf.core["work_dir"] == expected_work_dir, f"should set work_dir to {expected_work_dir}"
91+
92+
# values that depend on work_dir should also be updated
93+
94+
assert outcome.state.conf.core["temp_dir"] == expected_work_dir / ".tmp"
95+
96+
env_conf = outcome.state.conf.get_env("py")
97+
98+
assert env_conf["env_dir"] == expected_work_dir / "py"
99+
assert env_conf["env_log_dir"] == expected_work_dir / "py" / "log"
100+
assert env_conf["env_tmp_dir"] == expected_work_dir / "py" / "tmp"

tests/tox_env/python/test_python_runner.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,16 @@ def test_journal_package_dir(tmp_path: Path) -> None:
9595

9696
def test_package_temp_dir_view(tox_project: ToxProjectCreator, demo_pkg_inline: Path) -> None:
9797
project = tox_project({"tox.ini": "[testenv]\npackage=wheel"})
98-
result = project.run("r", "-vv", "-e", "py", "--root", str(demo_pkg_inline))
98+
result = project.run(
99+
"r",
100+
"-vv",
101+
"-e",
102+
"py",
103+
"--root",
104+
str(demo_pkg_inline),
105+
"--workdir",
106+
str(project.path / ".tox"),
107+
)
99108
result.assert_success()
100109
wheel_name = "demo_pkg_inline-1.0.0-py3-none-any.whl"
101110
session_path = Path(".tmp") / "package" / "1" / wheel_name

0 commit comments

Comments
 (0)