Skip to content
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
1 change: 1 addition & 0 deletions news/6426.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Restored ignore compatibility finder patch to enable comprehensive cross-platform hash collection in lock files.
33 changes: 22 additions & 11 deletions pipenv/patched/pip/_internal/index/package_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ def __init__(
target_python: TargetPython,
allow_yanked: bool,
ignore_requires_python: Optional[bool] = None,
ignore_compatibility: Optional[bool] = None,
Copy link
Preview

Copilot AI Jun 26, 2025

Choose a reason for hiding this comment

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

[nitpick] For consistency with how ignore_requires_python is handled, initialize ignore_compatibility to False when it's None (e.g., if ignore_compatibility is None: ignore_compatibility = False). This avoids relying on truthiness of None.

Copilot uses AI. Check for mistakes.

) -> None:
"""
:param project_name: The user supplied package name.
Expand All @@ -152,6 +153,8 @@ def __init__(
:param ignore_requires_python: Whether to ignore incompatible
PEP 503 "data-requires-python" values in HTML links. Defaults
to False.
:param ignore_compatibility: Whether to ignore
compatibility of python versions and allow all versions of packages.
"""
if ignore_requires_python is None:
ignore_requires_python = False
Expand All @@ -161,7 +164,7 @@ def __init__(
self._ignore_requires_python = ignore_requires_python
self._formats = formats
self._target_python = target_python

self._ignore_compatibility = ignore_compatibility
self.project_name = project_name

def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
Expand Down Expand Up @@ -191,10 +194,10 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
LinkType.format_unsupported,
f"unsupported archive format: {ext}",
)
if "binary" not in self._formats and ext == WHEEL_EXTENSION:
if "binary" not in self._formats and ext == WHEEL_EXTENSION and not self._ignore_compatibility:
reason = f"No binaries permitted for {self.project_name}"
return (LinkType.format_unsupported, reason)
if "macosx10" in link.path and ext == ".zip":
if "macosx10" in link.path and ext == ".zip" and not self._ignore_compatibility:
return (LinkType.format_unsupported, "macosx10 one")
if ext == WHEEL_EXTENSION:
try:
Expand All @@ -209,7 +212,7 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
return (LinkType.different_project, reason)

supported_tags = self._target_python.get_unsorted_tags()
if not wheel.supported(supported_tags):
if not wheel.supported(supported_tags) and not self._ignore_compatibility:
# Include the wheel's tags in the reason string to
# simplify troubleshooting compatibility issues.
file_tags = ", ".join(wheel.get_formatted_file_tags())
Expand Down Expand Up @@ -250,7 +253,7 @@ def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
version_info=self._target_python.py_version_info,
ignore_requires_python=self._ignore_requires_python,
)
if not supports_python:
if not supports_python and not self._ignore_compatibility:
reason = f"{version} Requires-Python {link.requires_python}"
return (LinkType.requires_python_mismatch, reason)

Expand Down Expand Up @@ -473,7 +476,11 @@ def get_applicable_candidates(

return sorted(filtered_applicable_candidates, key=self._sort_key)
Copy link
Preview

Copilot AI Jun 26, 2025

Choose a reason for hiding this comment

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

The new ignore_compatibility parameter on _sort_key is never passed when sorting (sorted(..., key=self._sort_key)), so it always uses the default True. Update the sort call to key=lambda c: self._sort_key(c, self._ignore_compatibility) to honor the instance flag.

Suggested change
return sorted(filtered_applicable_candidates, key=self._sort_key)
return sorted(filtered_applicable_candidates, key=lambda c: self._sort_key(c, self._ignore_compatibility))

Copilot uses AI. Check for mistakes.


def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey:
def _sort_key(
self,
candidate: InstallationCandidate,
ignore_compatibility: bool = True,
) -> CandidateSortingKey:
"""
Function to pass as the `key` argument to a call to sorted() to sort
InstallationCandidates by preference.
Expand Down Expand Up @@ -518,10 +525,12 @@ def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey:
)
)
except ValueError:
raise UnsupportedWheel(
f"{wheel.filename} is not a supported wheel for this platform. It "
"can't be sorted."
)
if not ignore_compatibility:
raise UnsupportedWheel(
f"{wheel.filename} is not a supported wheel for this platform. It "
"can't be sorted."
)
pri = -support_num
if self._prefer_binary:
binary_preference = 1
build_tag = wheel.build_tag
Expand Down Expand Up @@ -584,6 +593,7 @@ def __init__(
format_control: Optional[FormatControl] = None,
candidate_prefs: Optional[CandidatePreferences] = None,
ignore_requires_python: Optional[bool] = None,
ignore_compatibility: Optional[bool] = False,
) -> None:
"""
This constructor is primarily meant to be used by the create() class
Expand All @@ -605,7 +615,7 @@ def __init__(
self._ignore_requires_python = ignore_requires_python
self._link_collector = link_collector
self._target_python = target_python

self._ignore_compatibility = ignore_compatibility
self.format_control = format_control

# These are boring links that have already been logged somehow.
Expand Down Expand Up @@ -730,6 +740,7 @@ def make_link_evaluator(self, project_name: str) -> LinkEvaluator:
target_python=self._target_python,
allow_yanked=self._allow_yanked,
ignore_requires_python=self._ignore_requires_python,
ignore_compatibility=self._ignore_compatibility,
)

def _sort_links(self, links: Iterable[Link]) -> List[Link]:
Expand Down
114 changes: 114 additions & 0 deletions tasks/vendoring/patches/patched/pip_finder_ignore_compatability.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
--- a/pipenv/patched/pip/_internal/index/package_finder.py
+++ b/pipenv/patched/pip/_internal/index/package_finder.py
@@ -135,6 +135,7 @@ class LinkEvaluator:
target_python: TargetPython,
allow_yanked: bool,
ignore_requires_python: Optional[bool] = None,
+ ignore_compatibility: Optional[bool] = None,
) -> None:
"""
:param project_name: The user supplied package name.
@@ -152,6 +153,8 @@ class LinkEvaluator:
:param ignore_requires_python: Whether to ignore incompatible
PEP 503 "data-requires-python" values in HTML links. Defaults
to False.
+ :param ignore_compatibility: Whether to ignore
+ compatibility of python versions and allow all versions of packages.
"""
if ignore_requires_python is None:
ignore_requires_python = False
@@ -161,7 +164,7 @@ class LinkEvaluator:
self._ignore_requires_python = ignore_requires_python
self._formats = formats
self._target_python = target_python
-
+ self._ignore_compatibility = ignore_compatibility
self.project_name = project_name

def evaluate_link(self, link: Link) -> Tuple[LinkType, str]:
@@ -191,10 +194,10 @@ class LinkEvaluator:
LinkType.format_unsupported,
f"unsupported archive format: {ext}",
)
- if "binary" not in self._formats and ext == WHEEL_EXTENSION:
+ if "binary" not in self._formats and ext == WHEEL_EXTENSION and not self._ignore_compatibility:
reason = f"No binaries permitted for {self.project_name}"
return (LinkType.format_unsupported, reason)
- if "macosx10" in link.path and ext == ".zip":
+ if "macosx10" in link.path and ext == ".zip" and not self._ignore_compatibility:
return (LinkType.format_unsupported, "macosx10 one")
if ext == WHEEL_EXTENSION:
try:
@@ -209,7 +212,7 @@ class LinkEvaluator:
return (LinkType.different_project, reason)

supported_tags = self._target_python.get_unsorted_tags()
- if not wheel.supported(supported_tags):
+ if not wheel.supported(supported_tags) and not self._ignore_compatibility:
# Include the wheel's tags in the reason string to
# simplify troubleshooting compatibility issues.
file_tags = ", ".join(wheel.get_formatted_file_tags())
@@ -250,7 +253,7 @@ class LinkEvaluator:
version_info=self._target_python.py_version_info,
ignore_requires_python=self._ignore_requires_python,
)
- if not supports_python:
+ if not supports_python and not self._ignore_compatibility:
reason = f"{version} Requires-Python {link.requires_python}"
return (LinkType.requires_python_mismatch, reason)

@@ -473,7 +476,11 @@ class PackageFinder:

return sorted(filtered_applicable_candidates, key=self._sort_key)

- def _sort_key(self, candidate: InstallationCandidate) -> CandidateSortingKey:
+ def _sort_key(
+ self,
+ candidate: InstallationCandidate,
+ ignore_compatibility: bool = True,
+ ) -> CandidateSortingKey:
"""
Function to pass as the `key` argument to a call to sorted() to sort
InstallationCandidates by preference.
@@ -518,10 +525,12 @@ class PackageFinder:
)
)
except ValueError:
- raise UnsupportedWheel(
- f"{wheel.filename} is not a supported wheel for this platform. It "
- "can't be sorted."
- )
+ if not ignore_compatibility:
+ raise UnsupportedWheel(
+ f"{wheel.filename} is not a supported wheel for this platform. It "
+ "can't be sorted."
+ )
+ pri = -support_num
if self._prefer_binary:
binary_preference = 1
build_tag = wheel.build_tag
@@ -584,6 +593,7 @@ class PackageFinder:
format_control: Optional[FormatControl] = None,
candidate_prefs: Optional[CandidatePreferences] = None,
ignore_requires_python: Optional[bool] = None,
+ ignore_compatibility: Optional[bool] = False,
) -> None:
"""
This constructor is primarily meant to be used by the create() class
@@ -605,7 +615,7 @@ class PackageFinder:
self._ignore_requires_python = ignore_requires_python
self._link_collector = link_collector
self._target_python = target_python
-
+ self._ignore_compatibility = ignore_compatibility
self.format_control = format_control

# These are boring links that have already been logged somehow.
@@ -730,6 +740,7 @@ class PackageFinder:
target_python=self._target_python,
allow_yanked=self._allow_yanked,
ignore_requires_python=self._ignore_requires_python,
+ ignore_compatibility=self._ignore_compatibility,
)

def _sort_links(self, links: Iterable[Link]) -> List[Link]:
Loading