Skip to content

Commit 286e43b

Browse files
committed
env: improve error handling if .venv is not a directory but a file (#10777)
(cherry picked from commit 8f6d382)
1 parent d6e72c9 commit 286e43b

3 files changed

Lines changed: 68 additions & 4 deletions

File tree

src/poetry/utils/env/env_manager.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def activate(self, python: str) -> Env:
125125
if self.use_in_project_venv():
126126
create = False
127127
venv = self.in_project_venv
128-
if venv.exists():
128+
if venv.is_dir():
129129
# We need to check if the patch version is correct
130130
_venv = VirtualEnv(venv)
131131
current_patch = ".".join(str(v) for v in _venv.version_info[:3])
@@ -452,7 +452,7 @@ def create_venv(
452452
f"Invalid template string in 'virtualenvs.prompt' setting: {e}"
453453
) from e
454454

455-
if not venv.exists():
455+
if not venv.is_dir():
456456
if create_venv is False:
457457
self._io.write_error_line(
458458
"<fg=black;bg=yellow>"
@@ -463,6 +463,12 @@ def create_venv(
463463

464464
return self.get_system_env()
465465

466+
if venv.is_file():
467+
self._io.write_error_line(
468+
f"<warning>{venv} is not a virtual environment but a file. Removing it.</warning>"
469+
)
470+
venv.unlink()
471+
466472
self._io.write_error_line(
467473
f"Creating virtualenv <c1>{name}</> in"
468474
f" {venv_path if not WINDOWS else get_real_windows_path(venv_path)!s}"

tests/utils/env/conftest.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import pytest
66

7+
from cleo.io.buffered_io import BufferedIO
8+
79
from poetry.utils.env import EnvManager
810

911

@@ -19,5 +21,10 @@ def poetry(project_factory: ProjectFactory, fixture_dir: FixtureDirGetter) -> Po
1921

2022

2123
@pytest.fixture
22-
def manager(poetry: Poetry) -> EnvManager:
23-
return EnvManager(poetry)
24+
def io() -> BufferedIO:
25+
return BufferedIO()
26+
27+
28+
@pytest.fixture
29+
def manager(poetry: Poetry, io: BufferedIO) -> EnvManager:
30+
return EnvManager(poetry, io)

tests/utils/env/test_env_manager.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from collections.abc import Iterator
3333
from unittest.mock import MagicMock
3434

35+
from cleo.io.buffered_io import BufferedIO
3536
from pytest import LogCaptureFixture
3637
from pytest_mock import MockerFixture
3738

@@ -470,6 +471,56 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
470471
assert not envs_file.exists()
471472

472473

474+
def test_activate_with_in_project_setting_if_venv_is_file(
475+
manager: EnvManager,
476+
poetry: Poetry,
477+
io: BufferedIO,
478+
config: Config,
479+
tmp_path: Path,
480+
mocker: MockerFixture,
481+
venv_flags_default: dict[str, bool],
482+
mocked_python_register: MockedPythonRegister,
483+
) -> None:
484+
if "VIRTUAL_ENV" in os.environ:
485+
del os.environ["VIRTUAL_ENV"]
486+
487+
config.merge(
488+
{
489+
"virtualenvs": {
490+
"path": str(tmp_path / "virtualenvs"),
491+
"in-project": True,
492+
}
493+
}
494+
)
495+
496+
mocked_python_register("3.7.1")
497+
m = mocker.patch("poetry.utils.env.EnvManager.build_venv")
498+
499+
venv_path = poetry.file.path.parent / ".venv"
500+
assert not venv_path.exists()
501+
venv_path.touch()
502+
assert venv_path.is_file()
503+
504+
manager.activate("python3.7")
505+
506+
m.assert_called_with(
507+
poetry.file.path.parent / ".venv",
508+
executable=Path("/usr/bin/python3.7"),
509+
flags=venv_flags_default,
510+
prompt="simple-project-py3.7",
511+
)
512+
513+
envs_file = TOMLFile(tmp_path / "virtualenvs" / "envs.toml")
514+
assert not envs_file.exists()
515+
516+
# The .venv file is removed, but no .venv is created because we mocked build_venv.
517+
assert not venv_path.exists()
518+
assert (
519+
f"{venv_path} is not a virtual environment but a file. Removing it."
520+
in io.fetch_error()
521+
)
522+
523+
473524
def test_deactivate_non_activated_but_existing(
474525
tmp_path: Path,
475526
manager: EnvManager,

0 commit comments

Comments
 (0)