Commit d5a99f00 by Arun Babu Neelicattu Committed by GitHub

Standardise on using virtualenv package (#2666)

Until now poetry used the built-in venv module available in Python 3.
This has presented a few concerns. Chief of which has been
inconsistent environment setup. This includes, but is not limited to,
pip version used by the `ensurepip` module which is in turn used by the
built-in `venv.EnvBuilder`. Additionally, the `virtualenv` package
allows for faster environment creation. This can also allow us to, going
forward, drop ad-hoc code required to inspect and manage environments.
parent 46dd1d74
......@@ -1150,7 +1150,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"]
[metadata]
content-hash = "363cbb8480f9bbda72b318c6edfcaa1de130ceecba7c7d0e774005a3bca91df5"
content-hash = "31e245abc965de18a070191e854be0f3e7161386fb22439b0a297f187d94b3d7"
python-versions = "~2.7 || ^3.5"
[metadata.files]
......@@ -1426,6 +1426,11 @@ markupsafe = [
{file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"},
{file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"},
{file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"},
{file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"},
{file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
]
mkdocs = [
......
......@@ -15,12 +15,14 @@ from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
from typing import Union
import tomlkit
from clikit.api.io import IO
import packaging.tags
import virtualenv
from packaging.tags import Tag
from packaging.tags import interpreter_name
......@@ -141,27 +143,6 @@ import sysconfig
print(json.dumps(sysconfig.get_paths()))
"""
CREATE_VENV_COMMAND = """\
path = {!r}
try:
from venv import EnvBuilder
builder = EnvBuilder(with_pip=True)
builder.create(path)
except ImportError:
try:
# We fallback on virtualenv for Python 2.7
from virtualenv import create_environment
create_environment(path)
except ImportError:
# since virtualenv>20 we have to use cli_run
from virtualenv import cli_run
cli_run([path])
"""
class EnvError(Exception):
......@@ -697,43 +678,20 @@ class EnvManager(object):
return VirtualEnv(venv)
@classmethod
def build_venv(cls, path, executable=None):
if executable is not None:
# Create virtualenv by using an external executable
try:
p = subprocess.Popen(
list_to_shell_command([executable, "-"]),
stdin=subprocess.PIPE,
shell=True,
)
p.communicate(encode(CREATE_VENV_COMMAND.format(path)))
except CalledProcessError as e:
raise EnvCommandError(e)
return
try:
from venv import EnvBuilder
# use the same defaults as python -m venv
if os.name == "nt":
use_symlinks = False
else:
use_symlinks = True
builder = EnvBuilder(with_pip=True, symlinks=use_symlinks)
builder.create(path)
except ImportError:
try:
# We fallback on virtualenv for Python 2.7
from virtualenv import create_environment
create_environment(path)
except ImportError:
# since virtualenv>20 we have to use cli_run
from virtualenv import cli_run
cli_run([path])
def build_venv(
cls, path, executable=None
): # type: (str, Optional[Union[str, Path]]) -> virtualenv.run.session.Session
if isinstance(executable, Path):
executable = executable.resolve()
return virtualenv.cli_run(
[
"--no-download",
"--no-periodic-update",
"--python",
executable or sys.executable,
path,
]
)
def remove_venv(self, path): # type: (str) -> None
shutil.rmtree(path)
......
......@@ -38,6 +38,7 @@ shellingham = "^1.1"
tomlkit = "^0.5.11"
pexpect = "^4.7.0"
packaging = "^20.4"
virtualenv = { version = "^20.0.26" }
# The typing module is not in the stdlib in Python 2.7
typing = { version = "^3.6", python = "~2.7" }
......@@ -48,8 +49,6 @@ pathlib2 = { version = "^2.3", python = "~2.7" }
futures = { version = "^3.3.0", python = "~2.7" }
# Use glob2 for Python 2.7 and 3.4
glob2 = { version = "^0.6", python = "~2.7" }
# Use virtualenv for Python 2.7 since venv does not exist
virtualenv = { version = "^20.0.18", python = "~2.7" }
# functools32 is needed for Python 2.7
functools32 = { version = "^3.2.3", python = "~2.7" }
keyring = [
......
......@@ -9,6 +9,7 @@ from clikit.io import NullIO
from poetry.core.semver import Version
from poetry.factory import Factory
from poetry.utils._compat import PY2
from poetry.utils._compat import Path
from poetry.utils.env import EnvCommandError
from poetry.utils.env import EnvManager
......@@ -535,17 +536,11 @@ def test_remove_also_deactivates(tmp_dir, manager, poetry, config, mocker):
assert venv_name not in envs
@pytest.mark.skipif(
os.name == "nt" or PY2, reason="Symlinks are not support for Windows"
)
def test_env_has_symlinks_on_nix(tmp_dir, tmp_venv):
venv_available = False
try:
from venv import EnvBuilder # noqa
venv_available = True
except ImportError:
pass
if os.name != "nt" and venv_available:
assert os.path.islink(tmp_venv.python)
assert os.path.islink(tmp_venv.python)
def test_run_with_input(tmp_dir, tmp_venv):
......
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