Skip to content

Commit d9a315a

Browse files
committed
🐛 fix(config): start TOML walk from inipath
When pytest resolves config to a subdirectory (e.g. tests_integration/pytest.toml), rootpath still points to the project root. This caused the parent pyproject.toml to be found first, ignoring the subdirectory's pytest_env config. Starting from inipath.parent ensures the walk begins at the directory of the resolved config file, finding the correct pytest_env section. Falls back to rootpath when no config file is found.
1 parent c291176 commit d9a315a

2 files changed

Lines changed: 24 additions & 6 deletions

File tree

src/pytest_env/plugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ def _parse_toml_config(config: dict[str, Any]) -> Generator[Entry, None, None]:
6161

6262
def _load_values(early_config: pytest.Config) -> Iterator[Entry]:
6363
has_toml = False
64-
for path in chain.from_iterable([[early_config.rootpath], early_config.rootpath.parents]):
64+
start_path = early_config.inipath.parent if early_config.inipath is not None else early_config.rootpath
65+
for path in chain.from_iterable([[start_path], start_path.parents]):
6566
for pytest_toml_name in ("pytest.toml", ".pytest.toml", "pyproject.toml"):
6667
pytest_toml_file = path / pytest_toml_name
6768
if pytest_toml_file.exists():

tests/test_env.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,15 @@ def test_env_via_pytest(
220220
"pytest.toml",
221221
id="pytest toml over pyproject toml",
222222
),
223+
pytest.param(
224+
{},
225+
'[tool.pytest_env]\nMAGIC = "parent"',
226+
'[pytest_env]\nMAGIC = "child"',
227+
"",
228+
{"MAGIC": "child"},
229+
"sub/pytest.toml",
230+
id="subdir pytest toml over parent pyproject toml",
231+
),
223232
],
224233
)
225234
def test_env_via_toml( # noqa: PLR0913, PLR0917
@@ -234,13 +243,21 @@ def test_env_via_toml( # noqa: PLR0913, PLR0917
234243
) -> None:
235244
tmp_dir = Path(str(testdir.tmpdir))
236245
test_name = re.sub(r"\W|^(?=\d)", "_", request.node.callspec.id).lower()
237-
Path(str(tmp_dir / f"test_{test_name}.py")).symlink_to(Path(__file__).parent / "template.py")
238-
if ini:
239-
(tmp_dir / "pytest.ini").write_text(ini, encoding="utf-8")
240246
if pyproject_toml:
241247
(tmp_dir / "pyproject.toml").write_text(pyproject_toml, encoding="utf-8")
242248
if pytest_toml and pytest_toml_name:
243-
(tmp_dir / pytest_toml_name).write_text(pytest_toml, encoding="utf-8")
249+
toml_path = tmp_dir / pytest_toml_name
250+
toml_path.parent.mkdir(parents=True, exist_ok=True)
251+
toml_path.write_text(pytest_toml, encoding="utf-8")
252+
253+
if pytest_toml_name and "/" in pytest_toml_name:
254+
test_dir = tmp_dir / Path(pytest_toml_name).parent
255+
else:
256+
test_dir = tmp_dir
257+
if ini:
258+
(tmp_dir / "pytest.ini").write_text(ini, encoding="utf-8")
259+
260+
Path(str(test_dir / f"test_{test_name}.py")).symlink_to(Path(__file__).parent / "template.py")
244261

245262
new_env = {
246263
**env,
@@ -251,7 +268,7 @@ def test_env_via_toml( # noqa: PLR0913, PLR0917
251268

252269
# monkeypatch persists env variables across parametrized tests, therefore using mock.patch.dict
253270
with mock.patch.dict(os.environ, new_env, clear=True):
254-
result = testdir.runpytest()
271+
result = testdir.runpytest(str(test_dir))
255272

256273
result.assert_outcomes(passed=1)
257274

0 commit comments

Comments
 (0)