diff --git a/poetry/utils/env.py b/poetry/utils/env.py index dcdec0363bf..7a74f713391 100644 --- a/poetry/utils/env.py +++ b/poetry/utils/env.py @@ -34,6 +34,20 @@ from poetry.version.markers import BaseMarker +# pip version requirements when creating venvs are specified here. +# The maximal version is chosen to be the last version in the 19.3 branch, as +# it seems to be relatively bug free, and to work well with poetry (poetry +# uses pip internally, and pip API might change in ways that can break stuff). +# Note that pip 19.3 is required to find and install manylinux2014 packages. +# This version should be updated from time to time. +PIP_VERSION_MAX = "19.3.1" +# We use a different minimal version to allow fallback in case of older python +# versions. This version was chosen to be 19.1.1, as it is the most recent +# version that supports python 3.4. +# When poetry will drop support for EOL python versions, it might be possible +# to update this version, or to use a pinned version instead. +PIP_VERSION_MIN = "19.1.1" + GET_ENVIRONMENT_INFO = """\ import json import os @@ -656,26 +670,37 @@ def build_venv(cls, path, executable=None): 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) - build = builder.create - except ImportError: - # We fallback on virtualenv for Python 2.7 - from virtualenv import create_environment - - build = create_environment - - build(path) + else: + 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) + build = builder.create + except ImportError: + # We fallback on virtualenv for Python 2.7 + from virtualenv import create_environment + + build = create_environment + + build(path) + + # update pip version + the_venv = VirtualEnv(Path(path)) + the_venv.run( + "python", + "-m", + "pip", + "install", + "--upgrade", + '"pip>={},<={}"'.format(PIP_VERSION_MIN, PIP_VERSION_MAX), + shell=True, + ) def remove_venv(self, path): # type: (str) -> None shutil.rmtree(path) diff --git a/tests/utils/test_env.py b/tests/utils/test_env.py index e5926e68862..82a8ba71434 100644 --- a/tests/utils/test_env.py +++ b/tests/utils/test_env.py @@ -11,6 +11,7 @@ from poetry.semver import Version from poetry.utils._compat import WINDOWS from poetry.utils._compat import Path +from poetry.utils.env import PIP_VERSION_MAX from poetry.utils.env import EnvCommandError from poetry.utils.env import EnvManager from poetry.utils.env import NoCompatiblePythonVersionFound @@ -575,6 +576,11 @@ def test_run_with_input_non_zero_return(tmp_dir, tmp_venv): assert processError.value.e.returncode == 1 +def test_env_pip_version(tmp_dir, tmp_venv): + venv_pip_version = tmp_venv.run("pip", "-V", shell=True) + assert venv_pip_version.split()[:2] == ["pip", PIP_VERSION_MAX] + + def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_ones_first( manager, poetry, config, mocker ):