Skip to content

Commit

Permalink
make no-pip and no-setuptools config explicit
Browse files Browse the repository at this point in the history
This makes the `virtualenv.options.no-pip` and
`virtualenv.options.no-setuptools` options explicitly available to
users.

We default these to false as otherwise it can cause breakages for
certain development tools.
  • Loading branch information
abn committed Apr 15, 2022
1 parent 819d6d4 commit 6696468
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 59 deletions.
38 changes: 33 additions & 5 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ cache-dir = "/path/to/cache/directory"
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = true
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs" # /path/to/cache/directory/virtualenvs
virtualenvs.prefer-active-python = false
Expand Down Expand Up @@ -148,11 +150,6 @@ Defaults to `true`.

If set to `false`, poetry will install dependencies into the current python environment.

{{% note %}}
When setting this configuration to `false`, the Python environment used must have `pip`
installed and available.
{{% /note %}}

### `virtualenvs.in-project`

**Type**: boolean
Expand Down Expand Up @@ -181,6 +178,37 @@ Defaults to `{cache-dir}/virtualenvs` (`{cache-dir}\virtualenvs` on Windows).
If set to `true` the `--always-copy` parameter is passed to `virtualenv` on creation of the venv. Thus all needed files are copied into the venv instead of symlinked.
Defaults to `false`.

### `virtualenvs.options.no-pip`

**Type**: boolean

If set to `true` the `--no-pip` parameter is passed to `virtualenv` on creation of the venv. This means when a new
virtual environment is created, `pip` will not be installed in the environment.
Defaults to `false`.

{{% note %}}
Poetry, for its internal operations, uses the `pip` wheel embedded in the `virtualenv` package installed as a dependency
in Poetry's runtime environment. If a user runs `poetry run pip` when this option is set to `true`, the `pip` the
embedded instance of `pip` is used.

You can safely set this, along with `no-setuptools`, to `true`, if you desire a virtual environment with no additional
packages. This is desirable for production environments.
{{% /note %}}

### `virtualenvs.options.no-setuptools`

**Type**: boolean

If set to `true` the `--no-setuptools` parameter is passed to `virtualenv` on creation of the venv. This means when a new
virtual environment is created, `setuptools` will not be installed in the environment. Poetry, for its internal operations,
does not require `setuptools` and this can safely be set to `true`.
Defaults to `false`.

{{% warning %}}
Some development tools like IDEs, make an assumption that `setuptools` (and other) packages are always present and
available within a virtual environment. This can cause some features in these tools to not work as expected.
{{% /warning %}}

### `virtualenvs.options.system-site-packages`

**Type**: boolean
Expand Down
11 changes: 10 additions & 1 deletion src/poetry/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ class Config:
"create": True,
"in-project": None,
"path": os.path.join("{cache-dir}", "virtualenvs"),
"options": {"always-copy": False, "system-site-packages": False},
"options": {
"always-copy": False,
"system-site-packages": False,
# we default to False here in order to prevent development environment
# breakages for IDEs etc. as when working in these environments
# assumptions are often made about virtual environments having pip and
# setuptools.
"no-pip": False,
"no-setuptools": False,
},
"prefer-active-python": False,
},
"experimental": {"new-installer": True},
Expand Down
10 changes: 10 additions & 0 deletions src/poetry/console/commands/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ def unique_config_values(self) -> dict[str, tuple[Any, Any, Any]]:
boolean_normalizer,
False,
),
"virtualenvs.options.no-pip": (
boolean_validator,
boolean_normalizer,
False,
),
"virtualenvs.options.no-setuptools": (
boolean_validator,
boolean_normalizer,
False,
),
"virtualenvs.path": (
str,
lambda val: str(Path(val)),
Expand Down
2 changes: 1 addition & 1 deletion src/poetry/inspection/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def _pep517_metadata(cls, path: Path) -> PackageInfo:
pass

with ephemeral_environment(
with_pip=True, with_wheel=True, with_setuptools=True
flags={"no-pip": False, "no-setuptools": False, "no-wheel": False}
) as venv:
# TODO: cache PEP 517 build environment corresponding to each project venv
dest_dir = venv.path.parent / "dist"
Expand Down
12 changes: 0 additions & 12 deletions src/poetry/utils/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -966,12 +966,6 @@ def create_venv(
venv,
executable=executable,
flags=self._poetry.config.get("virtualenvs.options"),
# TODO: in a future version switch remove pip/setuptools/wheel
# poetry does not need them these exists today to not break developer
# environment assumptions
with_pip=True,
with_setuptools=True,
with_wheel=True,
)

# venv detection:
Expand Down Expand Up @@ -1834,9 +1828,6 @@ def _bin(self, bin: str) -> str:
def ephemeral_environment(
executable: str | Path | None = None,
flags: dict[str, bool] = None,
with_pip: bool = False,
with_wheel: bool | None = None,
with_setuptools: bool | None = None,
) -> ContextManager[VirtualEnv]:
with temporary_directory() as tmp_dir:
# TODO: cache PEP 517 build environment corresponding to each project venv
Expand All @@ -1845,9 +1836,6 @@ def ephemeral_environment(
path=venv_dir.as_posix(),
executable=executable,
flags=flags,
with_pip=with_pip,
with_wheel=with_wheel,
with_setuptools=with_setuptools,
)
yield VirtualEnv(venv_dir, venv_dir)

Expand Down
10 changes: 6 additions & 4 deletions tests/console/commands/env/test_use.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,12 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
mock_build_env.assert_called_with(
venv_py37,
executable="/usr/bin/python3.7",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)

envs_file = TOMLFile(venv_cache / "envs.toml")
Expand Down
6 changes: 6 additions & 0 deletions tests/console/commands/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def test_list_displays_default_value_if_not_set(
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'}
virtualenvs.prefer-active-python = false
Expand All @@ -80,6 +82,8 @@ def test_list_displays_set_get_setting(
virtualenvs.create = false
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'}
virtualenvs.prefer-active-python = false
Expand Down Expand Up @@ -128,6 +132,8 @@ def test_list_displays_set_get_local_setting(
virtualenvs.create = false
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = {venv_path} # {config_cache_dir / 'virtualenvs'}
virtualenvs.prefer-active-python = false
Expand Down
2 changes: 2 additions & 0 deletions tests/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ def test_create_poetry_with_local_config(fixture_dir: FixtureDirGetter):
assert not poetry.config.get("virtualenvs.in-project")
assert not poetry.config.get("virtualenvs.create")
assert not poetry.config.get("virtualenvs.options.always-copy")
assert not poetry.config.get("virtualenvs.options.no-pip")
assert not poetry.config.get("virtualenvs.options.no-setuptools")
assert not poetry.config.get("virtualenvs.options.system-site-packages")


Expand Down
121 changes: 85 additions & 36 deletions tests/utils/test_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from poetry.core.toml.file import TOMLFile

from poetry.factory import Factory
from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils._compat import WINDOWS
from poetry.utils.env import GET_BASE_PREFIX
from poetry.utils.env import EnvCommandError
Expand Down Expand Up @@ -196,10 +197,12 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.7",
executable="/usr/bin/python3.7",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)

envs_file = TOMLFile(Path(tmp_dir) / "envs.toml")
Expand Down Expand Up @@ -331,10 +334,12 @@ def test_activate_activates_different_virtualenv_with_envs_file(
m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.6",
executable="/usr/bin/python3.6",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)

assert envs_file.exists()
Expand Down Expand Up @@ -392,10 +397,12 @@ def test_activate_activates_recreates_for_different_patch(
build_venv_m.assert_called_with(
Path(tmp_dir) / f"{venv_name}-py3.7",
executable="/usr/bin/python3.7",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)
remove_venv_m.assert_called_with(Path(tmp_dir) / f"{venv_name}-py3.7")

Expand Down Expand Up @@ -827,10 +834,12 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_
m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.7",
executable="python3",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)


Expand Down Expand Up @@ -858,10 +867,12 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.9",
executable="python3.9",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)


Expand Down Expand Up @@ -948,10 +959,12 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py{version.major}.{version.minor}",
executable=None,
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)


Expand Down Expand Up @@ -987,10 +1000,12 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py{version.major}.{version.minor - 1}",
executable=f"python{version.major}.{version.minor - 1}",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)


Expand Down Expand Up @@ -1055,10 +1070,12 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
m.assert_called_with(
poetry.file.parent / ".venv",
executable="/usr/bin/python3.7",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)

envs_file = TOMLFile(Path(tmp_dir) / "virtualenvs" / "envs.toml")
Expand Down Expand Up @@ -1106,6 +1123,36 @@ def test_env_system_packages(tmp_path: Path, poetry: Poetry):
assert "include-system-site-packages = true" in pyvenv_cfg.read_text()


@pytest.mark.parametrize(
("flags", "packages"),
[
({"no-pip": False}, {"pip", "wheel"}),
({"no-pip": False, "no-wheel": True}, {"pip"}),
({"no-pip": True}, set()),
({"no-setuptools": False}, {"setuptools"}),
({"no-setuptools": True}, set()),
({"no-pip": True, "no-setuptools": False}, {"setuptools"}),
({"no-wheel": False}, {"wheel"}),
({}, set()),
],
)
def test_env_no_pip(
tmp_path: Path, poetry: Poetry, flags: dict[str, bool], packages: set[str]
):
venv_path = tmp_path / "venv"
EnvManager(poetry).build_venv(path=venv_path, flags=flags)
env = VirtualEnv(venv_path)
installed_repository = InstalledRepository.load(env=env, with_dependencies=True)
installed_packages = {
package.name
for package in installed_repository.packages
# workaround for BSD test environments
if package.name != "sqlite3"
}

assert installed_packages == packages


def test_env_finds_the_correct_executables(tmp_dir: str, manager: EnvManager):
venv_path = Path(tmp_dir) / "Virtual Env"
manager.build_venv(str(venv_path), with_pip=True)
Expand Down Expand Up @@ -1256,10 +1303,12 @@ def test_create_venv_accepts_fallback_version_w_nonzero_patchlevel(
m.assert_called_with(
config_virtualenvs_path / f"{venv_name}-py3.5",
executable="python3.5",
flags={"always-copy": False, "system-site-packages": False},
with_pip=True,
with_setuptools=True,
with_wheel=True,
flags={
"always-copy": False,
"system-site-packages": False,
"no-pip": False,
"no-setuptools": False,
},
)


Expand Down

0 comments on commit 6696468

Please sign in to comment.