Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make no-pip and no-setuptools config explicit #5455

Merged
merged 1 commit into from
May 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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