Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/_pytest/config/findpaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import os
from pathlib import Path
import sys
import tempfile
from typing import TypeAlias

import iniconfig
Expand Down Expand Up @@ -184,6 +185,28 @@ def get_dir_from_path(path: Path) -> Path:
CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supported, change to [tool:pytest] instead."


def _is_system_temp_or_parent(path: Path) -> bool:
"""Check if path is the system temp directory.

This prevents pytest from treating /tmp as a valid rootdir when
a /tmp/setup.py file exists on the system.

Args:
path: The path to check

Returns:
True if path is the system temp directory, False otherwise
"""
try:
system_temp = Path(tempfile.gettempdir()).resolve()
path = path.resolve()
# Skip exact matches with the system temp directory
return path == system_temp
except (OSError, RuntimeError):
# If we can't resolve paths, play it safe and don't skip
return False


def determine_setup(
*,
inifile: str | None,
Expand Down Expand Up @@ -220,6 +243,9 @@ def determine_setup(
)
if rootdir is None and rootdir_cmd_arg is None:
for possible_rootdir in (ancestor, *ancestor.parents):
# Skip system temp directories to avoid false positives (issue #13822)
if _is_system_temp_or_parent(possible_rootdir):
continue
if (possible_rootdir / "setup.py").is_file():
rootdir = possible_rootdir
break
Expand Down
36 changes: 36 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,42 @@ def test_with_config_also_in_parent_directory(
assert rootpath == tmp_path / "myproject"
assert inipath == tmp_path / "myproject" / "setup.cfg"

def test_tmp_setup_py_does_not_affect_rootdir(
self, tmp_path: Path, monkeypatch: MonkeyPatch
) -> None:
"""Regression test for issue #13822.

Ensure that setup.py in the system temp directory doesn't
affect rootdir detection.
"""
# Create a fake project structure
project = tmp_path / "my_project"
project.mkdir()
test_dir = project / "tests"
test_dir.mkdir()

# Create project's own setup.py
(project / "setup.py").write_text("# project setup", "utf-8")

# Monkeypatch tempfile.gettempdir() to simulate /tmp/setup.py existing
fake_temp = tmp_path / "fake_tmp"
fake_temp.mkdir()
(fake_temp / "setup.py").write_text("# tmp setup", "utf-8")

monkeypatch.setattr("tempfile.gettempdir", lambda: str(fake_temp))
monkeypatch.chdir(test_dir)

rootpath, inipath, *_ = determine_setup(
inifile=None,
args=[str(test_dir)],
rootdir_cmd_arg=None,
invocation_dir=test_dir,
)

# Rootpath should be project, not fake temp
assert rootpath == project
assert rootpath != fake_temp


class TestOverrideIniArgs:
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())
Expand Down