Commit 2def3571 by Alexey Committed by GitHub

update env remove logic (#6195)

Resolves: #6018 

1. Added a check so that if `python` argument is a file (then it should
be a python path) - extract it's venv name and raise `IncorrectEnvError`
if it doesn't belong to this project
    **Before**
    ```
└❯ poetry env remove
~/.cache/pypoetry/virtualenvs/different-project-OKfJHH_5-py3.10/bin/python
    /bin/sh: 1: different-project-OKfJHH_5-py3.10: not found

Deleted virtualenv: ~/.cache/pypoetry/virtualenvs/poetry-4pWfmigs-py3.10
    ```
    Removes current project's env, which is wrong.
    **After**
    ```
└❯ poetry env remove
~/.cache/pypoetry/virtualenvs/different-project-OKfJHH_5-py3.10/bin/python

Env different-project-OKfJHH_5-py3.10 doesn't belong to this project.
    ```
2. Added the exact same check as before ^, but for cases where env name
is passed.
    **Before**
    ```
    └❯ poetry env remove different-project-OKfJHH_5-py3.10      
     /bin/sh: 1: different-project-OKfJHH_5-py3.10: not found

Command different-project-OKfJHH_5-py3.10 -c "import sys;
print('.'.join([str(s) for s in sys.version_info[:3]]))" errored with
the following return code 127, and output:
    ```
Errors while trying to exec env name as an interpreter, error is not
clear.
    **After**
    ```
└❯ poetry env remove different-project-OKfJHH_5-py3.10

Env different-project-OKfJHH_5-py3.10 doesn't belong to this project.
    ```
3. Added a couple of tests for **new** and for **old** scenarios which
weren't tested.
4. Added `venv_name` fixture for `tests/utils` directory to use in
`test_env`. Also replaced some of `"simple-project"` hardcoded value to
use `poetry.package.name`

It's up to maintainers to choose what they want for this project - I'm
happy either way if we at least fix the bug. I can remove/change any of
the stuff I added on top of the fix. But yeah I just decided that if we
fix the bug, we might also make some improvements/changes in this area
of code. Any thoughts on this are welcome, thanks!
parent b61a4ddb
...@@ -175,6 +175,7 @@ print('.'.join([str(s) for s in sys.version_info[:3]])) ...@@ -175,6 +175,7 @@ print('.'.join([str(s) for s in sys.version_info[:3]]))
GET_PYTHON_VERSION_ONELINER = ( GET_PYTHON_VERSION_ONELINER = (
"\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\"" "\"import sys; print('.'.join([str(s) for s in sys.version_info[:3]]))\""
) )
GET_ENV_PATH_ONELINER = '"import sys; print(sys.prefix)"'
GET_SYS_PATH = """\ GET_SYS_PATH = """\
import json import json
...@@ -461,6 +462,12 @@ class EnvError(Exception): ...@@ -461,6 +462,12 @@ class EnvError(Exception):
pass pass
class IncorrectEnvError(EnvError):
def __init__(self, env_name: str) -> None:
message = f"Env {env_name} doesn't belong to this project."
super().__init__(message)
class EnvCommandError(EnvError): class EnvCommandError(EnvError):
def __init__(self, e: CalledProcessError, input: str | None = None) -> None: def __init__(self, e: CalledProcessError, input: str | None = None) -> None:
self.e = e self.e = e
...@@ -740,6 +747,15 @@ class EnvManager: ...@@ -740,6 +747,15 @@ class EnvManager:
env_list.insert(0, VirtualEnv(venv)) env_list.insert(0, VirtualEnv(venv))
return env_list return env_list
@staticmethod
def check_env_is_for_current_project(env: str, base_env_name: str) -> bool:
"""
Check if env name starts with projects name.
This is done to prevent action on other project's envs.
"""
return env.startswith(base_env_name)
def remove(self, python: str) -> Env: def remove(self, python: str) -> Env:
venv_path = self._poetry.config.virtualenvs_path venv_path = self._poetry.config.virtualenvs_path
...@@ -747,7 +763,23 @@ class EnvManager: ...@@ -747,7 +763,23 @@ class EnvManager:
envs_file = TOMLFile(venv_path / self.ENVS_FILE) envs_file = TOMLFile(venv_path / self.ENVS_FILE)
base_env_name = self.generate_env_name(self._poetry.package.name, str(cwd)) base_env_name = self.generate_env_name(self._poetry.package.name, str(cwd))
if python.startswith(base_env_name): python_path = Path(python)
if python_path.is_file():
# Validate env name if provided env is a full path to python
try:
env_dir = decode(
subprocess.check_output(
list_to_shell_command([python, "-c", GET_ENV_PATH_ONELINER]),
shell=True,
)
).strip("\n")
env_name = Path(env_dir).name
if not self.check_env_is_for_current_project(env_name, base_env_name):
raise IncorrectEnvError(env_name)
except CalledProcessError as e:
raise EnvCommandError(e)
if self.check_env_is_for_current_project(python, base_env_name):
venvs = self.list() venvs = self.list()
for venv in venvs: for venv in venvs:
if venv.path.name == python: if venv.path.name == python:
...@@ -778,6 +810,12 @@ class EnvManager: ...@@ -778,6 +810,12 @@ class EnvManager:
raise ValueError( raise ValueError(
f'<warning>Environment "{python}" does not exist.</warning>' f'<warning>Environment "{python}" does not exist.</warning>'
) )
else:
venv_path = self._poetry.config.virtualenvs_path
# Get all the poetry envs, even for other projects
env_names = [Path(p).name for p in sorted(venv_path.glob("*-*-py*"))]
if python in env_names:
raise IncorrectEnvError(python)
try: try:
python_version = Version.parse(python) python_version = Version.parse(python)
......
...@@ -18,7 +18,10 @@ if TYPE_CHECKING: ...@@ -18,7 +18,10 @@ if TYPE_CHECKING:
@pytest.fixture @pytest.fixture
def venv_name(app: PoetryTestApplication) -> str: def venv_name(app: PoetryTestApplication) -> str:
return EnvManager.generate_env_name("simple-project", str(app.poetry.file.parent)) return EnvManager.generate_env_name(
app.poetry.package.name,
str(app.poetry.file.parent),
)
@pytest.fixture @pytest.fixture
......
from __future__ import annotations
from typing import TYPE_CHECKING
import pytest
if TYPE_CHECKING:
from poetry.poetry import Poetry
from poetry.utils.env import EnvManager
@pytest.fixture
def venv_name(
manager: EnvManager,
poetry: Poetry,
) -> str:
return manager.generate_env_name(
poetry.package.name,
str(poetry.file.parent),
)
...@@ -22,6 +22,7 @@ from poetry.utils.env import GET_BASE_PREFIX ...@@ -22,6 +22,7 @@ from poetry.utils.env import GET_BASE_PREFIX
from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvCommandError
from poetry.utils.env import EnvManager from poetry.utils.env import EnvManager
from poetry.utils.env import GenericEnv from poetry.utils.env import GenericEnv
from poetry.utils.env import IncorrectEnvError
from poetry.utils.env import InvalidCurrentPythonVersionError from poetry.utils.env import InvalidCurrentPythonVersionError
from poetry.utils.env import MockEnv from poetry.utils.env import MockEnv
from poetry.utils.env import NoCompatiblePythonVersionFound from poetry.utils.env import NoCompatiblePythonVersionFound
...@@ -208,6 +209,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -208,6 +209,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -225,7 +227,6 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file( ...@@ -225,7 +227,6 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv) m = mocker.patch("poetry.utils.env.EnvManager.build_venv", side_effect=build_venv)
env = manager.activate("python3.7", NullIO()) env = manager.activate("python3.7", NullIO())
venv_name = EnvManager.generate_env_name("simple-project", str(poetry.file.parent))
m.assert_called_with( m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.7", Path(tmp_dir) / f"{venv_name}-py3.7",
...@@ -255,12 +256,11 @@ def test_activate_activates_existing_virtualenv_no_envs_file( ...@@ -255,12 +256,11 @@ def test_activate_activates_existing_virtualenv_no_envs_file(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
os.mkdir(os.path.join(tmp_dir, f"{venv_name}-py3.7")) os.mkdir(os.path.join(tmp_dir, f"{venv_name}-py3.7"))
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
...@@ -295,12 +295,11 @@ def test_activate_activates_same_virtualenv_with_envs_file( ...@@ -295,12 +295,11 @@ def test_activate_activates_same_virtualenv_with_envs_file(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") envs_file = TOMLFile(Path(tmp_dir) / "envs.toml")
doc = tomlkit.document() doc = tomlkit.document()
doc[venv_name] = {"minor": "3.7", "patch": "3.7.1"} doc[venv_name] = {"minor": "3.7", "patch": "3.7.1"}
...@@ -339,11 +338,11 @@ def test_activate_activates_different_virtualenv_with_envs_file( ...@@ -339,11 +338,11 @@ def test_activate_activates_different_virtualenv_with_envs_file(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") envs_file = TOMLFile(Path(tmp_dir) / "envs.toml")
doc = tomlkit.document() doc = tomlkit.document()
doc[venv_name] = {"minor": "3.7", "patch": "3.7.1"} doc[venv_name] = {"minor": "3.7", "patch": "3.7.1"}
...@@ -392,11 +391,11 @@ def test_activate_activates_recreates_for_different_patch( ...@@ -392,11 +391,11 @@ def test_activate_activates_recreates_for_different_patch(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") envs_file = TOMLFile(Path(tmp_dir) / "envs.toml")
doc = tomlkit.document() doc = tomlkit.document()
doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"} doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"}
...@@ -458,11 +457,11 @@ def test_activate_does_not_recreate_when_switching_minor( ...@@ -458,11 +457,11 @@ def test_activate_does_not_recreate_when_switching_minor(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
envs_file = TOMLFile(Path(tmp_dir) / "envs.toml") envs_file = TOMLFile(Path(tmp_dir) / "envs.toml")
doc = tomlkit.document() doc = tomlkit.document()
doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"} doc[venv_name] = {"minor": "3.7", "patch": "3.7.0"}
...@@ -509,12 +508,11 @@ def test_deactivate_non_activated_but_existing( ...@@ -509,12 +508,11 @@ def test_deactivate_non_activated_but_existing(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
python = ".".join(str(c) for c in sys.version_info[:2]) python = ".".join(str(c) for c in sys.version_info[:2])
(Path(tmp_dir) / f"{venv_name}-py{python}").mkdir() (Path(tmp_dir) / f"{venv_name}-py{python}").mkdir()
...@@ -538,11 +536,11 @@ def test_deactivate_activated( ...@@ -538,11 +536,11 @@ def test_deactivate_activated(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
version = Version.from_parts(*sys.version_info[:3]) version = Version.from_parts(*sys.version_info[:3])
other_version = Version.parse("3.4") if version.major == 2 else version.next_minor() other_version = Version.parse("3.4") if version.major == 2 else version.next_minor()
(Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}").mkdir() (Path(tmp_dir) / f"{venv_name}-py{version.major}.{version.minor}").mkdir()
...@@ -581,11 +579,10 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( ...@@ -581,11 +579,10 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
os.environ["VIRTUAL_ENV"] = "/environment/prefix" os.environ["VIRTUAL_ENV"] = "/environment/prefix"
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
...@@ -609,10 +606,15 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var( ...@@ -609,10 +606,15 @@ def test_get_prefers_explicitly_activated_virtualenvs_over_env_var(
assert env.base == Path("/prefix") assert env.base == Path("/prefix")
def test_list(tmp_dir: str, manager: EnvManager, poetry: Poetry, config: Config): def test_list(
tmp_dir: str,
manager: EnvManager,
poetry: Poetry,
config: Config,
venv_name: str,
):
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
(Path(tmp_dir) / f"{venv_name}-py3.6").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.6").mkdir()
...@@ -629,10 +631,10 @@ def test_remove_by_python_version( ...@@ -629,10 +631,10 @@ def test_remove_by_python_version(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
(Path(tmp_dir) / f"{venv_name}-py3.6").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.6").mkdir()
...@@ -654,10 +656,10 @@ def test_remove_by_name( ...@@ -654,10 +656,10 @@ def test_remove_by_name(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
(Path(tmp_dir) / f"{venv_name}-py3.6").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.6").mkdir()
...@@ -673,16 +675,149 @@ def test_remove_by_name( ...@@ -673,16 +675,149 @@ def test_remove_by_name(
assert not expected_venv_path.exists() assert not expected_venv_path.exists()
def test_remove_by_string_with_python_and_version(
tmp_dir: str,
manager: EnvManager,
poetry: Poetry,
config: Config,
mocker: MockerFixture,
venv_name: str,
):
config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
(Path(tmp_dir) / f"{venv_name}-py3.6").mkdir()
mocker.patch(
"subprocess.check_output",
side_effect=check_output_wrapper(Version.parse("3.6.6")),
)
venv = manager.remove("python3.6")
expected_venv_path = Path(tmp_dir) / f"{venv_name}-py3.6"
assert venv.path == expected_venv_path
assert not expected_venv_path.exists()
def test_remove_by_full_path_to_python(
tmp_dir: str,
manager: EnvManager,
poetry: Poetry,
config: Config,
mocker: MockerFixture,
venv_name: str,
):
config.merge({"virtualenvs": {"path": str(tmp_dir)}})
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
(Path(tmp_dir) / f"{venv_name}-py3.6").mkdir()
mocker.patch(
"subprocess.check_output",
side_effect=check_output_wrapper(Version.parse("3.6.6")),
)
expected_venv_path = Path(tmp_dir) / f"{venv_name}-py3.6"
python_path = expected_venv_path / "bin" / "python"
venv = manager.remove(str(python_path))
assert venv.path == expected_venv_path
assert not expected_venv_path.exists()
def test_raises_if_acting_on_different_project_by_full_path(
tmp_dir: str,
manager: EnvManager,
poetry: Poetry,
config: Config,
mocker: MockerFixture,
):
config.merge({"virtualenvs": {"path": str(tmp_dir)}})
different_venv_name = "different-project"
different_venv_path = Path(tmp_dir) / f"{different_venv_name}-py3.6"
different_venv_bin_path = different_venv_path / "bin"
different_venv_bin_path.mkdir(parents=True)
python_path = different_venv_bin_path / "python"
python_path.touch(exist_ok=True)
# Patch initial call where python env path is extracted
mocker.patch(
"subprocess.check_output",
side_effect=lambda *args, **kwargs: str(different_venv_path),
)
with pytest.raises(IncorrectEnvError):
manager.remove(str(python_path))
def test_raises_if_acting_on_different_project_by_name(
tmp_dir: str,
manager: EnvManager,
poetry: Poetry,
config: Config,
):
config.merge({"virtualenvs": {"path": str(tmp_dir)}})
different_venv_name = (
EnvManager.generate_env_name(
"different-project",
str(poetry.file.parent),
)
+ "-py3.6"
)
different_venv_path = Path(tmp_dir) / different_venv_name
different_venv_bin_path = different_venv_path / "bin"
different_venv_bin_path.mkdir(parents=True)
python_path = different_venv_bin_path / "python"
python_path.touch(exist_ok=True)
with pytest.raises(IncorrectEnvError):
manager.remove(different_venv_name)
def test_raises_when_passing_old_env_after_dir_rename(
tmp_dir: str,
manager: EnvManager,
poetry: Poetry,
config: Config,
venv_name: str,
):
# Make sure that poetry raises when trying to remove old venv after you've renamed
# root directory of the project, which will create another venv with new name.
# This is not ideal as you still "can't" remove it by name, but it at least doesn't
# cause any unwanted side effects
config.merge({"virtualenvs": {"path": str(tmp_dir)}})
previous_venv_name = EnvManager.generate_env_name(
poetry.package.name,
"previous_dir_name",
)
venv_path = Path(tmp_dir) / f"{venv_name}-py3.6"
venv_path.mkdir()
previous_venv_name = f"{previous_venv_name}-py3.6"
previous_venv_path = Path(tmp_dir) / previous_venv_name
previous_venv_path.mkdir()
with pytest.raises(IncorrectEnvError):
manager.remove(previous_venv_name)
def test_remove_also_deactivates( def test_remove_also_deactivates(
tmp_dir: str, tmp_dir: str,
manager: EnvManager, manager: EnvManager,
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
(Path(tmp_dir) / f"{venv_name}-py3.7").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.7").mkdir()
(Path(tmp_dir) / f"{venv_name}-py3.6").mkdir() (Path(tmp_dir) / f"{venv_name}-py3.6").mkdir()
...@@ -712,12 +847,12 @@ def test_remove_keeps_dir_if_not_deleteable( ...@@ -712,12 +847,12 @@ def test_remove_keeps_dir_if_not_deleteable(
poetry: Poetry, poetry: Poetry,
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
venv_name: str,
): ):
# Ensure we empty rather than delete folder if its is an active mount point. # Ensure we empty rather than delete folder if its is an active mount point.
# See https://github.com/python-poetry/poetry/pull/2064 # See https://github.com/python-poetry/poetry/pull/2064
config.merge({"virtualenvs": {"path": str(tmp_dir)}}) config.merge({"virtualenvs": {"path": str(tmp_dir)}})
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
venv_path = Path(tmp_dir) / f"{venv_name}-py3.6" venv_path = Path(tmp_dir) / f"{venv_name}-py3.6"
venv_path.mkdir() venv_path.mkdir()
...@@ -848,12 +983,12 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ ...@@ -848,12 +983,12 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
poetry.package.python_versions = "^3.6" poetry.package.python_versions = "^3.6"
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
mocker.patch("sys.version_info", (2, 7, 16)) mocker.patch("sys.version_info", (2, 7, 16))
mocker.patch( mocker.patch(
...@@ -885,12 +1020,12 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific ...@@ -885,12 +1020,12 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
poetry.package.python_versions = "^3.6" poetry.package.python_versions = "^3.6"
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
mocker.patch("sys.version_info", (2, 7, 16)) mocker.patch("sys.version_info", (2, 7, 16))
mocker.patch("subprocess.check_output", side_effect=["3.5.3", "3.9.0"]) mocker.patch("subprocess.check_output", side_effect=["3.5.3", "3.9.0"])
...@@ -971,6 +1106,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility( ...@@ -971,6 +1106,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
...@@ -979,7 +1115,6 @@ def test_create_venv_uses_patch_version_to_detect_compatibility( ...@@ -979,7 +1115,6 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
poetry.package.python_versions = "^" + ".".join( poetry.package.python_versions = "^" + ".".join(
str(c) for c in sys.version_info[:3] str(c) for c in sys.version_info[:3]
) )
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
mocker.patch("sys.version_info", (version.major, version.minor, version.patch + 1)) mocker.patch("sys.version_info", (version.major, version.minor, version.patch + 1))
check_output = mocker.patch( check_output = mocker.patch(
...@@ -1012,13 +1147,13 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable( ...@@ -1012,13 +1147,13 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
version = Version.from_parts(*sys.version_info[:3]) version = Version.from_parts(*sys.version_info[:3])
poetry.package.python_versions = f"~{version.major}.{version.minor-1}.0" poetry.package.python_versions = f"~{version.major}.{version.minor-1}.0"
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
check_output = mocker.patch( check_output = mocker.patch(
"subprocess.check_output", "subprocess.check_output",
...@@ -1320,12 +1455,12 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel( ...@@ -1320,12 +1455,12 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel(
config: Config, config: Config,
mocker: MockerFixture, mocker: MockerFixture,
config_virtualenvs_path: Path, config_virtualenvs_path: Path,
venv_name: str,
): ):
if "VIRTUAL_ENV" in os.environ: if "VIRTUAL_ENV" in os.environ:
del os.environ["VIRTUAL_ENV"] del os.environ["VIRTUAL_ENV"]
poetry.package.python_versions = "~3.5.1" poetry.package.python_versions = "~3.5.1"
venv_name = manager.generate_env_name("simple-project", str(poetry.file.parent))
check_output = mocker.patch( check_output = mocker.patch(
"subprocess.check_output", "subprocess.check_output",
...@@ -1353,9 +1488,12 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel( ...@@ -1353,9 +1488,12 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel(
) )
def test_generate_env_name_ignores_case_for_case_insensitive_fs(tmp_dir: str): def test_generate_env_name_ignores_case_for_case_insensitive_fs(
venv_name1 = EnvManager.generate_env_name("simple-project", "MyDiR") poetry: Poetry,
venv_name2 = EnvManager.generate_env_name("simple-project", "mYdIr") tmp_dir: str,
):
venv_name1 = EnvManager.generate_env_name(poetry.package.name, "MyDiR")
venv_name2 = EnvManager.generate_env_name(poetry.package.name, "mYdIr")
if sys.platform == "win32": if sys.platform == "win32":
assert venv_name1 == venv_name2 assert venv_name1 == venv_name2
else: else:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment