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)"] ...@@ -1150,7 +1150,7 @@ docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"] testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"]
[metadata] [metadata]
content-hash = "363cbb8480f9bbda72b318c6edfcaa1de130ceecba7c7d0e774005a3bca91df5" content-hash = "31e245abc965de18a070191e854be0f3e7161386fb22439b0a297f187d94b3d7"
python-versions = "~2.7 || ^3.5" python-versions = "~2.7 || ^3.5"
[metadata.files] [metadata.files]
...@@ -1426,6 +1426,11 @@ markupsafe = [ ...@@ -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-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-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"},
{file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, {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"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"},
] ]
mkdocs = [ mkdocs = [
......
...@@ -15,12 +15,14 @@ from typing import Dict ...@@ -15,12 +15,14 @@ from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
from typing import Tuple from typing import Tuple
from typing import Union
import tomlkit import tomlkit
from clikit.api.io import IO from clikit.api.io import IO
import packaging.tags import packaging.tags
import virtualenv
from packaging.tags import Tag from packaging.tags import Tag
from packaging.tags import interpreter_name from packaging.tags import interpreter_name
...@@ -141,27 +143,6 @@ import sysconfig ...@@ -141,27 +143,6 @@ import sysconfig
print(json.dumps(sysconfig.get_paths())) 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): class EnvError(Exception):
...@@ -697,43 +678,20 @@ class EnvManager(object): ...@@ -697,43 +678,20 @@ class EnvManager(object):
return VirtualEnv(venv) return VirtualEnv(venv)
@classmethod @classmethod
def build_venv(cls, path, executable=None): def build_venv(
if executable is not None: cls, path, executable=None
# Create virtualenv by using an external executable ): # type: (str, Optional[Union[str, Path]]) -> virtualenv.run.session.Session
try: if isinstance(executable, Path):
p = subprocess.Popen( executable = executable.resolve()
list_to_shell_command([executable, "-"]), return virtualenv.cli_run(
stdin=subprocess.PIPE, [
shell=True, "--no-download",
"--no-periodic-update",
"--python",
executable or sys.executable,
path,
]
) )
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 remove_venv(self, path): # type: (str) -> None def remove_venv(self, path): # type: (str) -> None
shutil.rmtree(path) shutil.rmtree(path)
......
...@@ -38,6 +38,7 @@ shellingham = "^1.1" ...@@ -38,6 +38,7 @@ shellingham = "^1.1"
tomlkit = "^0.5.11" tomlkit = "^0.5.11"
pexpect = "^4.7.0" pexpect = "^4.7.0"
packaging = "^20.4" packaging = "^20.4"
virtualenv = { version = "^20.0.26" }
# The typing module is not in the stdlib in Python 2.7 # The typing module is not in the stdlib in Python 2.7
typing = { version = "^3.6", python = "~2.7" } typing = { version = "^3.6", python = "~2.7" }
...@@ -48,8 +49,6 @@ pathlib2 = { version = "^2.3", python = "~2.7" } ...@@ -48,8 +49,6 @@ pathlib2 = { version = "^2.3", python = "~2.7" }
futures = { version = "^3.3.0", python = "~2.7" } futures = { version = "^3.3.0", python = "~2.7" }
# Use glob2 for Python 2.7 and 3.4 # Use glob2 for Python 2.7 and 3.4
glob2 = { version = "^0.6", python = "~2.7" } 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 is needed for Python 2.7
functools32 = { version = "^3.2.3", python = "~2.7" } functools32 = { version = "^3.2.3", python = "~2.7" }
keyring = [ keyring = [
......
...@@ -9,6 +9,7 @@ from clikit.io import NullIO ...@@ -9,6 +9,7 @@ from clikit.io import NullIO
from poetry.core.semver import Version from poetry.core.semver import Version
from poetry.factory import Factory from poetry.factory import Factory
from poetry.utils._compat import PY2
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvCommandError
from poetry.utils.env import EnvManager from poetry.utils.env import EnvManager
...@@ -535,16 +536,10 @@ def test_remove_also_deactivates(tmp_dir, manager, poetry, config, mocker): ...@@ -535,16 +536,10 @@ def test_remove_also_deactivates(tmp_dir, manager, poetry, config, mocker):
assert venv_name not in envs 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): 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)
......
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