diff --git a/news/4549.bugfix.rst b/news/4549.bugfix.rst new file mode 100644 index 0000000000..d2d568a981 --- /dev/null +++ b/news/4549.bugfix.rst @@ -0,0 +1 @@ +Fix a bug that ``importlib-metadata`` from the project's dependencies conflicts with that from ``pipenv``'s. diff --git a/news/5632-fh3h343-n234h3jh4d-sfdd.trivial b/news/5632-fh3h343-n234h3jh4d-sfdd.trivial deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pipenv/environment.py b/pipenv/environment.py index 88c6dbb09f..579a34d46c 100644 --- a/pipenv/environment.py +++ b/pipenv/environment.py @@ -118,7 +118,12 @@ def resolve_dist(cls, dist, working_set): except (KeyError, AttributeError, OSError, IOError): # The METADATA file can't be found return deps for req in reqs: - dist = working_set.find(req) + try: + dist = working_set.find(req) + except pkg_resources.VersionConflict: + # https://github.com/pypa/pipenv/issues/4549 + # The requirement is already present with incompatible version. + continue deps |= cls.resolve_dist(dist, working_set) return deps diff --git a/pipenv/resolver.py b/pipenv/resolver.py index a362f2477b..80de9281d6 100644 --- a/pipenv/resolver.py +++ b/pipenv/resolver.py @@ -12,7 +12,7 @@ def find_site_path(pkg, site_dir=None): import pkg_resources - if site_dir is not None: + if site_dir is None: site_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) working_set = pkg_resources.WorkingSet([site_dir] + sys.path[:]) for dist in working_set: diff --git a/tasks/vendoring/__init__.py b/tasks/vendoring/__init__.py index f58e4ad184..03b25e683f 100644 --- a/tasks/vendoring/__init__.py +++ b/tasks/vendoring/__init__.py @@ -6,6 +6,7 @@ import io import itertools import json +import os import re import shutil @@ -21,7 +22,7 @@ from urllib3.util import parse_url as urllib3_parse -from pipenv.vendor.vistir.compat import NamedTemporaryFile, TemporaryDirectory +from pipenv.vendor.vistir.compat import TemporaryDirectory from pipenv.vendor.vistir.contextmanagers import open_file from pipenv.vendor.requirementslib.models.lockfile import Lockfile, merge_items import pipenv.vendor.parse as parse @@ -205,14 +206,10 @@ def _recursive_write_to_zip(zf, path, root=None): @invoke.task def update_safety(ctx): - ignore_subdeps = ["pip", "pip-egg-info", "bin", "pipenv", "virtualenv", "virtualenv-clone", "setuptools",] + ignore_subdeps = ["pip", "pip-egg-info", "bin", "pipenv", "virtualenv", "virtualenv-clone", "setuptools"] ignore_files = ["pip-delete-this-directory.txt", "PKG-INFO", "easy_install.py", "clonevirtualenv.py"] ignore_patterns = ["*.pyd", "*.so", "**/*.pyc", "*.pyc"] - cmd_envvars = { - "PIPENV_NO_INHERIT": "true", - "PIPENV_IGNORE_VIRTUALENVS": "true", - "PIPENV_VENV_IN_PROJECT": "true" - } + patched_dir = _get_patched_dir(ctx) vendor_dir = _get_vendor_dir(ctx) safety_dir = Path(__file__).absolute().parent.joinpath("safety") @@ -264,7 +261,7 @@ def update_safety(ctx): ) log("downloading deps via pip: {0}".format(pip_command)) ctx.run(pip_command) - safety_build_dir = build_dir / "safety" + yaml_build_dir = build_dir / "pyyaml" lib_dir = safety_dir.joinpath("lib") @@ -384,14 +381,15 @@ def install_pyyaml(ctx, vendor_dir): if build_dir.exists() and build_dir.is_dir(): log("dropping pre-existing build dir at {0}".format(build_dir.as_posix())) drop_dir(build_dir) + build_dir.mkdir() with TemporaryDirectory(prefix="pipenv-", suffix="-safety") as download_dir: pip_command = "pip download -b {0} --no-binary=:all: --no-clean --no-deps -d {1} pyyaml safety".format( build_dir.absolute().as_posix(), str(download_dir.name), ) + temp_env = "TEMP" if os.name == "nt" else "TMPDIR" log("downloading deps via pip: {0}".format(pip_command)) - ctx.run(pip_command) - safety_build_dir = build_dir / "safety" - yaml_build_dir = build_dir / "pyyaml" + ctx.run(pip_command, env={temp_env: str(build_dir)}) + yaml_build_dir = next(build_dir.glob('pip-download-*/pyyaml_*')) yaml_dir = vendor_dir / "yaml" yaml_lib_dir_map = { "2": {