diff --git a/pipenv/core.py b/pipenv/core.py index 07a88d66..f8d03b9e 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1505,6 +1505,11 @@ def pip_install( def pip_download(package_name): + pip_config = { + 'PIP_CACHE_DIR': PIPENV_CACHE_DIR, + 'PIP_WHEEL_DIR': os.path.join(PIPENV_CACHE_DIR, 'wheels'), + 'PIP_DESTINATION_DIR': os.path.join(PIPENV_CACHE_DIR, 'pkgs'), + } for source in project.sources: cmd = '{0} download "{1}" -i {2} -d {3}'.format( escape_grouped_arguments(which_pip()), @@ -1512,7 +1517,7 @@ def pip_download(package_name): source['url'], project.download_location, ) - c = delegator.run(cmd, env={'PIP_CACHE_DIR': PIPENV_CACHE_DIR}) + c = delegator.run(cmd, env=pip_config) if c.return_code == 0: break diff --git a/tasks/vendoring/patches/patched/piptools.patch b/tasks/vendoring/patches/patched/piptools.patch index a3220d39..3f6595b4 100644 --- a/tasks/vendoring/patches/patched/piptools.patch +++ b/tasks/vendoring/patches/patched/piptools.patch @@ -19,7 +19,7 @@ index 4e6174c..75f9b49 100644 # NOTE # We used to store the cache dir under ~/.pip-tools, which is not the diff --git a/pipenv/patched/piptools/repositories/pypi.py b/pipenv/patched/piptools/repositories/pypi.py -index 1c4b943..858d697 100644 +index 1c4b943..1ffbf1d 100644 --- a/pipenv/patched/piptools/repositories/pypi.py +++ b/pipenv/patched/piptools/repositories/pypi.py @@ -4,6 +4,7 @@ from __future__ import (absolute_import, division, print_function, @@ -129,20 +129,17 @@ index 1c4b943..858d697 100644 def freshen_build_caches(self): """ -@@ -114,10 +163,21 @@ class PyPIRepository(BaseRepository): +@@ -114,10 +163,18 @@ class PyPIRepository(BaseRepository): if ireq.editable: return ireq # return itself as the best match - all_candidates = self.find_all_candidates(ireq.name) -+ _all_candidates = self.find_all_candidates(ireq.name) -+ all_candidates = [] + py_version = parse_version(os.environ.get('PIP_PYTHON_VERSION', str(sys.version_info[:3]))) -+ for c in _all_candidates: -+ if c.requires_python: -+ python_specifier = SpecifierSet(c.requires_python) -+ if not python_specifier.contains(py_version): -+ continue -+ all_candidates.append(c) ++ all_candidates = [ ++ c for c in self.find_all_candidates(ireq.name) ++ if SpecifierSet(c.requires_python).contains(py_version) ++ ] ++ candidates_by_version = lookup_table(all_candidates, key=lambda c: c.version, unique=True) - matching_versions = ireq.specifier.filter((candidate.version for candidate in all_candidates), + try: @@ -153,7 +150,7 @@ index 1c4b943..858d697 100644 # Reuses pip's internal candidate sort key to sort matching_candidates = [candidates_by_version[ver] for ver in matching_versions] -@@ -126,11 +186,61 @@ class PyPIRepository(BaseRepository): +@@ -126,11 +183,71 @@ class PyPIRepository(BaseRepository): best_candidate = max(matching_candidates, key=self.finder._candidate_sort_key) # Turn the candidate into a pinned InstallRequirement @@ -174,22 +171,33 @@ index 1c4b943..858d697 100644 + raise TypeError('Expected pinned InstallRequirement, got {}'.format(ireq)) + + def gen(ireq): -+ if self.DEFAULT_INDEX_URL in self.finder.index_urls: ++ if self.DEFAULT_INDEX_URL not in self.finder.index_urls: ++ return + -+ url = 'https://pypi.org/pypi/{0}/json'.format(ireq.req.name) -+ r = self.session.get(url) ++ url = 'https://pypi.org/pypi/{0}/json'.format(ireq.req.name) ++ releases = self.session.get(url).json()['releases'] + -+ # TODO: Latest isn't always latest. -+ releases = list(r.json()['releases'].keys()) -+ match = [r for r in releases if '=={0}'.format(r) == str(ireq.req.specifier)] -+ if match: -+ release_url = 'https://pypi.org/pypi/{0}/{1}/json'.format(ireq.req.name, match[0]) -+ release_requires = self.session.get(release_url) -+ for requires in release_requires.json().get('info', {}).get('requires_dist', {}): -+ i = InstallRequirement.from_line(requires) ++ matches = [ ++ r for r in releases ++ if '=={0}'.format(r) == str(ireq.req.specifier) ++ ] ++ if not matches: ++ return + -+ if 'extra' not in repr(i.markers): -+ yield i ++ release_requires = self.session.get( ++ 'https://pypi.org/pypi/{0}/{1}/json'.format( ++ ireq.req.name, matches[0], ++ ), ++ ).json() ++ try: ++ requires_dist = release_requires['info']['requires_dist'] ++ except KeyError: ++ return ++ ++ for requires in requires_dist: ++ i = InstallRequirement.from_line(requires) ++ if 'extra' not in repr(i.markers): ++ yield i + + try: + if ireq not in self._json_dep_cache: @@ -213,12 +221,11 @@ index 1c4b943..858d697 100644 + + return json_results + -+ + def get_legacy_dependencies(self, ireq): """ Given a pinned or an editable InstallRequirement, returns a set of dependencies (also InstallRequirements, but not necessarily pinned). -@@ -139,6 +249,21 @@ class PyPIRepository(BaseRepository): +@@ -139,6 +256,21 @@ class PyPIRepository(BaseRepository): if not (ireq.editable or is_pinned_requirement(ireq)): raise TypeError('Expected pinned or editable InstallRequirement, got {}'.format(ireq)) @@ -240,7 +247,7 @@ index 1c4b943..858d697 100644 if ireq not in self._dependencies_cache: if ireq.editable and (ireq.source_dir and os.path.exists(ireq.source_dir)): # No download_dir for locally available editable requirements. -@@ -164,11 +289,14 @@ class PyPIRepository(BaseRepository): +@@ -164,11 +296,14 @@ class PyPIRepository(BaseRepository): download_dir=download_dir, wheel_download_dir=self._wheel_download_dir, session=self.session, @@ -257,7 +264,7 @@ index 1c4b943..858d697 100644 ) except TypeError: # Pip >= 10 (new resolver!) -@@ -190,14 +318,44 @@ class PyPIRepository(BaseRepository): +@@ -190,14 +325,44 @@ class PyPIRepository(BaseRepository): upgrade_strategy="to-satisfy-only", force_reinstall=False, ignore_dependencies=False, @@ -304,7 +311,7 @@ index 1c4b943..858d697 100644 reqset.cleanup_files() return set(self._dependencies_cache[ireq]) -@@ -224,17 +382,10 @@ class PyPIRepository(BaseRepository): +@@ -224,17 +389,10 @@ class PyPIRepository(BaseRepository): matching_candidates = candidates_by_version[matching_versions[0]] return {