Issue 5023 Fix hash link generation (#5024)

* Ensure that we generate a hash when there are no applicable candidates but the ireq.link exists.

* refactor and improve collect_hashes logic.

* Further fix hash searching and package index restrictions.

* Factor out common method, fixing code path in process.

* add news fragment.
This commit is contained in:
Matt Davis
2022-04-01 05:20:39 -04:00
committed by GitHub
parent 9a3b3ce706
commit 45f32373da
2 changed files with 41 additions and 21 deletions
+2
View File
@@ -0,0 +1,2 @@
Fix an edge case of hash collection in index restricted packages whereby the hashes for some packages would
be missing from the ``Pipfile.lock`` following package index restrictions added in ``pipenv==2022.3.23``.
+39 -21
View File
@@ -533,6 +533,17 @@ class Resolver:
self._session = self.pip_command._build_session(self.pip_options)
return self._session
def prepare_index_lookup(self):
index_mapping = {}
for source in self.sources:
if source.get("name"):
index_mapping[source["name"]] = source["url"]
alt_index_lookup = {}
for req_name, index in self.index_lookup.items():
if index_mapping.get(index):
alt_index_lookup[req_name] = index_mapping[index]
return alt_index_lookup
@property
def finder(self):
from pipenv.vendor.pip_shims import shims
@@ -543,16 +554,9 @@ class Resolver:
options=self.pip_options,
session=self.session,
)
index_mapping = {}
for source in self.sources:
if source.get("name"):
index_mapping[source["name"]] = source["url"]
alt_index_lookup = {}
for req_name, index in self.index_lookup.items():
if index_mapping.get(index):
alt_index_lookup[req_name] = index_mapping[index]
self._finder._link_collector.index_lookup = alt_index_lookup
self._finder._link_collector.search_scope.index_lookup = alt_index_lookup
index_lookup = self.prepare_index_lookup()
self._finder._link_collector.index_lookup = index_lookup
self._finder._link_collector.search_scope.index_lookup = index_lookup
return self._finder
@property
@@ -568,8 +572,13 @@ class Resolver:
# It would be nice if `shims.get_package_finder` took an
# `ignore_compatibility` parameter, but that's some vendorered code
# we'd rather avoid touching.
index_lookup = self.prepare_index_lookup()
ignore_compatibility_finder._ignore_compatibility = True
self._ignore_compatibility_finder = ignore_compatibility_finder
self._ignore_compatibility_finder._link_collector.index_lookup = index_lookup
self._ignore_compatibility_finder._link_collector.search_scope.index_lookup = (
index_lookup
)
return self._ignore_compatibility_finder
@property
@@ -723,19 +732,21 @@ class Resolver:
return None
def collect_hashes(self, ireq):
if ireq.link:
link = ireq.link
if link.is_vcs or (link.is_file and link.is_existing_dir()):
return set()
if ireq.original_link:
return {self._get_hash_from_link(ireq.original_link)}
link = ireq.link # Handle VCS and file links first
if link and (link.is_vcs or (link.is_file and link.is_existing_dir())):
return set()
if not is_pinned_requirement(ireq):
return set()
sources = self.sources # Enforce index restrictions
if ireq.name in self.index_lookup:
sources = list(
filter(lambda s: s.get("name") == self.index_lookup[ireq.name], sources)
)
if any(
"python.org" in source["url"] or "pypi.org" in source["url"]
for source in self.sources
for source in sources
):
hashes = self._get_hashes_from_pypi(ireq)
if hashes:
@@ -744,10 +755,17 @@ class Resolver:
applicable_candidates = self.ignore_compatibility_finder.find_best_candidate(
ireq.name, ireq.specifier
).iter_applicable()
return {
self._get_hash_from_link(candidate.link)
for candidate in applicable_candidates
}
applicable_candidates = list(applicable_candidates)
if applicable_candidates:
return {
self._get_hash_from_link(candidate.link)
for candidate in applicable_candidates
}
if link:
return {self._get_hash_from_link(link)}
if ireq.original_link:
return {self._get_hash_from_link(ireq.original_link)}
return set()
def resolve_hashes(self):
if self.results is not None: