diff --git a/src/poetry/utils/env/env_manager.py b/src/poetry/utils/env/env_manager.py index a759fdcc0d0..a0fd02463df 100644 --- a/src/poetry/utils/env/env_manager.py +++ b/src/poetry/utils/env/env_manager.py @@ -276,6 +276,7 @@ def get(self, reload: bool = False) -> Env: ).to_string() env = None + envs = None if self.envs_file.exists(): envs = self.envs_file.read() env = envs.get(self.base_env_name) @@ -310,6 +311,9 @@ def get(self, reload: bool = False) -> Env: venv = venv_path / name if not venv.exists(): + if env and envs: + del envs[self.base_env_name] + self.envs_file.write(envs) return self.get_system_env() return VirtualEnv(venv) diff --git a/tests/utils/env/test_env_manager.py b/tests/utils/env/test_env_manager.py index 55036956cac..c44aa52727e 100644 --- a/tests/utils/env/test_env_manager.py +++ b/tests/utils/env/test_env_manager.py @@ -1237,6 +1237,49 @@ def mock_check_output(cmd: str, *args: Any, **kwargs: Any) -> str: ) +@pytest.mark.parametrize("is_inconsistent_entry", [False, True]) +def test_create_venv_does_not_keep_inconsistent_envs_entry( + tmp_path: Path, + manager: EnvManager, + poetry: Poetry, + config: Config, + mocker: MockerFixture, + venv_name: str, + is_inconsistent_entry: bool, +) -> None: + if "VIRTUAL_ENV" in os.environ: + del os.environ["VIRTUAL_ENV"] + + # There is an entry in the envs.toml file but the venv does not exist + envs_file = TOMLFile(tmp_path / "envs.toml") + doc = tomlkit.document() + if is_inconsistent_entry: + doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"} + doc["other"] = {"minor": "3.7", "patch": "3.7.0"} + envs_file.write(doc) + + config.merge({"virtualenvs": {"path": str(tmp_path)}}) + + mocker.patch("shutil.which", side_effect=lambda py: f"/usr/bin/{py}") + mocker.patch( + "subprocess.check_output", + side_effect=check_output_wrapper(), + ) + m = mocker.patch( + "poetry.utils.env.EnvManager.build_venv", side_effect=lambda *args, **kwargs: "" + ) + + manager.create_venv() + + m.assert_called() + + assert envs_file.exists() + envs: dict[str, Any] = envs_file.read() + assert venv_name not in envs + assert envs["other"]["minor"] == "3.7" + assert envs["other"]["patch"] == "3.7.0" + + def test_build_venv_does_not_change_loglevel( tmp_path: Path, manager: EnvManager, caplog: LogCaptureFixture ) -> None: