Skip to content

Commit

Permalink
fix: prefer compatible packages (#1302)
Browse files Browse the repository at this point in the history
* fix: prefer compatible packages

* add news
  • Loading branch information
frostming authored Aug 4, 2022
1 parent c1aa0f7 commit d5c88a1
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
1 change: 1 addition & 0 deletions news/1302.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Prefer compatible packages when fetching metadata.
31 changes: 22 additions & 9 deletions pdm/models/candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,21 +72,33 @@ def _filter_none(data: dict[str, Any]) -> dict[str, Any]:


def _find_best_match_link(
finder: PackageFinder, req: Requirement, hashes: dict[Link, str] | None
finder: PackageFinder,
req: Requirement,
hashes: dict[Link, str] | None,
ignore_compatibility: bool = False,
) -> Link | None:
"""Get the best matching link for a requirement"""
# This function is called when a lock file candidate is given or incompatible wheel
# In this case, the requirement must be pinned, so no need to pass allow_prereleases
# If hashes are not empty, find the best match from the links, otherwise find from
# the package sources.
if hashes is None:
best = finder.find_best_match(req.as_line()).best
def attempt_to_find() -> Link | None:
if hashes is None:
best = finder.find_best_match(req.as_line()).best
return best.link if best is not None else None
# We don't evaluate against the hashes, they will be validated later.
evaluator = finder.build_evaluator(req.name)
packages: Iterable[Package] = filter(None, map(evaluator.evaluate_link, hashes))
best = max(packages, key=finder._sort_key, default=None)
return best.link if best is not None else None
# We don't evaluate against the hashes, they will be validated later in downloading.
evaluator = finder.build_evaluator(req.name)
packages: Iterable[Package] = filter(None, map(evaluator.evaluate_link, hashes))
best = max(packages, key=finder._sort_key, default=None)
return best.link if best is not None else None

original_ignore = finder.ignore_compatibility
link = attempt_to_find()
if link is None and ignore_compatibility and not original_ignore:
finder.ignore_compatibility = ignore_compatibility
link = attempt_to_find()
finder.ignore_compatibility = original_ignore
return link


class Candidate:
Expand Down Expand Up @@ -367,7 +379,7 @@ def obtain(self, allow_all: bool = False) -> None:
hash_options = None
if not allow_all and self.candidate.hashes:
hash_options = convert_hashes(self.candidate.hashes)
with self.environment.get_finder(ignore_compatibility=allow_all) as finder:
with self.environment.get_finder() as finder:
if (
not self.link
or self.link.is_wheel
Expand All @@ -383,6 +395,7 @@ def obtain(self, allow_all: bool = False) -> None:
finder,
self.req.as_pinned_version(self.candidate.version),
self.candidate.hashes,
ignore_compatibility=allow_all,
)
if not self.link:
raise CandidateNotFound(
Expand Down

0 comments on commit d5c88a1

Please sign in to comment.