Skip to content

Support venv detection on Windows with mingw Python #12545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ Yusuke Kadowaki
Yutian Li
Yuval Shimon
Zac Hatfield-Dodds
Zach Snicker
Zachary Kneupper
Zachary OBrien
Zhouxin Qiu
Expand Down
15 changes: 2 additions & 13 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,22 +369,11 @@ def pytest_runtestloop(session: Session) -> bool:

def _in_venv(path: Path) -> bool:
"""Attempt to detect if ``path`` is the root of a Virtual Environment by
checking for the existence of the appropriate activate script."""
bindir = path.joinpath("Scripts" if sys.platform.startswith("win") else "bin")
checking for the existence of the pyvenv.cfg file."""
try:
if not bindir.is_dir():
return False
return path.joinpath("pyvenv.cfg").exists()
except OSError:
return False
activates = (
"activate",
"activate.csh",
"activate.fish",
"Activate",
"Activate.bat",
"Activate.ps1",
)
return any(fname.name in activates for fname in bindir.iterdir())


def pytest_ignore_collect(collection_path: Path, config: Config) -> bool | None:
Expand Down
54 changes: 8 additions & 46 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,20 +152,8 @@ def test_ignored_certain_directories(self, pytester: Pytester) -> None:
assert "test_notfound" not in s
assert "test_found" in s

@pytest.mark.parametrize(
"fname",
(
"activate",
"activate.csh",
"activate.fish",
"Activate",
"Activate.bat",
"Activate.ps1",
),
)
def test_ignored_virtualenvs(self, pytester: Pytester, fname: str) -> None:
bindir = "Scripts" if sys.platform.startswith("win") else "bin"
ensure_file(pytester.path / "virtual" / bindir / fname)
def test_ignored_virtualenvs(self, pytester: Pytester) -> None:
ensure_file(pytester.path / "virtual" / "pyvenv.cfg")
testfile = ensure_file(pytester.path / "virtual" / "test_invenv.py")
testfile.write_text("def test_hello(): pass", encoding="utf-8")

Expand All @@ -179,23 +167,11 @@ def test_ignored_virtualenvs(self, pytester: Pytester, fname: str) -> None:
result = pytester.runpytest("virtual")
assert "test_invenv" in result.stdout.str()

@pytest.mark.parametrize(
"fname",
(
"activate",
"activate.csh",
"activate.fish",
"Activate",
"Activate.bat",
"Activate.ps1",
),
)
def test_ignored_virtualenvs_norecursedirs_precedence(
self, pytester: Pytester, fname: str
self, pytester: Pytester
) -> None:
bindir = "Scripts" if sys.platform.startswith("win") else "bin"
# norecursedirs takes priority
ensure_file(pytester.path / ".virtual" / bindir / fname)
ensure_file(pytester.path / ".virtual" / "pyvenv.cfg")
testfile = ensure_file(pytester.path / ".virtual" / "test_invenv.py")
testfile.write_text("def test_hello(): pass", encoding="utf-8")
result = pytester.runpytest("--collect-in-virtualenv")
Expand All @@ -204,27 +180,13 @@ def test_ignored_virtualenvs_norecursedirs_precedence(
result = pytester.runpytest("--collect-in-virtualenv", ".virtual")
assert "test_invenv" in result.stdout.str()

@pytest.mark.parametrize(
"fname",
(
"activate",
"activate.csh",
"activate.fish",
"Activate",
"Activate.bat",
"Activate.ps1",
),
)
def test__in_venv(self, pytester: Pytester, fname: str) -> None:
def test__in_venv(self, pytester: Pytester) -> None:
"""Directly test the virtual env detection function"""
bindir = "Scripts" if sys.platform.startswith("win") else "bin"
# no bin/activate, not a virtualenv
# no pyvenv.cfg, not a virtualenv
base_path = pytester.mkdir("venv")
assert _in_venv(base_path) is False
# with bin/activate, totally a virtualenv
bin_path = base_path.joinpath(bindir)
bin_path.mkdir()
bin_path.joinpath(fname).touch()
# with pyvenv.cfg, totally a virtualenv
base_path.joinpath("pyvenv.cfg").touch()
assert _in_venv(base_path) is True

def test_custom_norecursedirs(self, pytester: Pytester) -> None:
Expand Down