Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 5023 Fix hash link generation #5024

Merged
merged 5 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/5023.bugfix.rst
Original file line number Diff line number Diff line change
@@ -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``.
60 changes: 39 additions & 21 deletions pipenv/utils/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,17 @@ def session(self):
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
Expand All @@ -543,16 +554,9 @@ def finder(self):
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
Expand All @@ -568,8 +572,13 @@ def ignore_compatibility_finder(self):
# 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
Expand Down Expand Up @@ -723,19 +732,21 @@ def _get_hashes_from_pypi(self, ireq):
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()):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Factor out this base case of set() and move the other case to the end of this method for reasons that involve applying index restrictions first. We will also consider the ireq.link preferable to the ireq.original_link in the resulting refactor since adding in treatment of the ireq.link was important for this example edge case.

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:
Expand All @@ -744,10 +755,17 @@ def collect_hashes(self, ireq):
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:
Expand Down