From 238bad2d2a1f1dbb47d740c84b5b4f5224f8a965 Mon Sep 17 00:00:00 2001 From: Ronny Pfannschmidt Date: Wed, 24 Jul 2024 08:09:28 +0200 Subject: [PATCH] Merge pull request #12656 from RonnyPfannschmidt/fix-12652-detect-conda-env (cherry picked from commit 6c806b499ddbb844753b5c8c4d70a8b98b9d1c3a) --- changelog/12652.bugfix.rst | 3 +++ src/_pytest/main.py | 15 +++++++++++++-- testing/test_collection.py | 28 ++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 changelog/12652.bugfix.rst diff --git a/changelog/12652.bugfix.rst b/changelog/12652.bugfix.rst new file mode 100644 index 00000000000..da7644df06d --- /dev/null +++ b/changelog/12652.bugfix.rst @@ -0,0 +1,3 @@ +Resolve regression `conda` environments where no longer being automatically detected. + +-- by :user:`RonnyPfannschmidt` diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 8ec26906003..befc7ccce6e 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -370,9 +370,20 @@ 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 pyvenv.cfg file. - [https://peps.python.org/pep-0405/]""" + + [https://peps.python.org/pep-0405/] + + For regression protection we also check for conda environments that do not include pyenv.cfg yet -- + https://github.com/conda/conda/issues/13337 is the conda issue tracking adding pyenv.cfg. + + Checking for the `conda-meta/history` file per https://github.com/pytest-dev/pytest/issues/12652#issuecomment-2246336902. + + """ try: - return path.joinpath("pyvenv.cfg").is_file() + return ( + path.joinpath("pyvenv.cfg").is_file() + or path.joinpath("conda-meta", "history").is_file() + ) except OSError: return False diff --git a/testing/test_collection.py b/testing/test_collection.py index f5822240335..aba8f8ea48d 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -3,6 +3,7 @@ import os from pathlib import Path +from pathlib import PurePath import pprint import shutil import sys @@ -152,8 +153,17 @@ def test_ignored_certain_directories(self, pytester: Pytester) -> None: assert "test_notfound" not in s assert "test_found" in s - def test_ignored_virtualenvs(self, pytester: Pytester) -> None: - ensure_file(pytester.path / "virtual" / "pyvenv.cfg") + known_environment_types = pytest.mark.parametrize( + "env_path", + [ + pytest.param(PurePath("pyvenv.cfg"), id="venv"), + pytest.param(PurePath("conda-meta", "history"), id="conda"), + ], + ) + + @known_environment_types + def test_ignored_virtualenvs(self, pytester: Pytester, env_path: PurePath) -> None: + ensure_file(pytester.path / "virtual" / env_path) testfile = ensure_file(pytester.path / "virtual" / "test_invenv.py") testfile.write_text("def test_hello(): pass", encoding="utf-8") @@ -167,11 +177,12 @@ def test_ignored_virtualenvs(self, pytester: Pytester) -> None: result = pytester.runpytest("virtual") assert "test_invenv" in result.stdout.str() + @known_environment_types def test_ignored_virtualenvs_norecursedirs_precedence( - self, pytester: Pytester + self, pytester: Pytester, env_path ) -> None: # norecursedirs takes priority - ensure_file(pytester.path / ".virtual" / "pyvenv.cfg") + ensure_file(pytester.path / ".virtual" / env_path) 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") @@ -180,13 +191,14 @@ def test_ignored_virtualenvs_norecursedirs_precedence( result = pytester.runpytest("--collect-in-virtualenv", ".virtual") assert "test_invenv" in result.stdout.str() - def test__in_venv(self, pytester: Pytester) -> None: + @known_environment_types + def test__in_venv(self, pytester: Pytester, env_path: PurePath) -> None: """Directly test the virtual env detection function""" - # no pyvenv.cfg, not a virtualenv + # no env path, not a env base_path = pytester.mkdir("venv") assert _in_venv(base_path) is False - # with pyvenv.cfg, totally a virtualenv - base_path.joinpath("pyvenv.cfg").touch() + # with env path, totally a env + ensure_file(base_path.joinpath(env_path)) assert _in_venv(base_path) is True def test_custom_norecursedirs(self, pytester: Pytester) -> None: