From 8d65ac6b897553f5a03862b6b927f521ca8e3933 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 20 Jul 2023 11:05:11 +0800 Subject: [PATCH] feat: ignore wheels for pythons not in range (#2113) --- news/2113.dep.md | 1 + news/2113.feature.md | 1 + pdm.lock | 8 ++++---- pyproject.toml | 2 +- src/pdm/models/repositories.py | 36 ++++++++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 news/2113.dep.md create mode 100644 news/2113.feature.md diff --git a/news/2113.dep.md b/news/2113.dep.md new file mode 100644 index 0000000000..2834e9e614 --- /dev/null +++ b/news/2113.dep.md @@ -0,0 +1 @@ +Update `unearth` to 0.10.0 diff --git a/news/2113.feature.md b/news/2113.feature.md new file mode 100644 index 0000000000..d85c1d89f9 --- /dev/null +++ b/news/2113.feature.md @@ -0,0 +1 @@ +Ignore wheels for python versions not in range. diff --git a/pdm.lock b/pdm.lock index 5f62c35b37..cc59490c17 100644 --- a/pdm.lock +++ b/pdm.lock @@ -6,7 +6,7 @@ groups = ["default", "all", "doc", "pytest", "test", "tox", "workflow"] cross_platform = true static_urls = false lock_version = "4.3" -content_hash = "sha256:ca4416076ecc3a8b57854143681241c4e0b89b0448672128e8c08f53dbf1b541" +content_hash = "sha256:ac589b0b9f40317e0a1c3109d28ec8b02acfa1ce164e4ef69d090fdcb70987a3" [[package]] name = "arpeggio" @@ -1912,7 +1912,7 @@ files = [ [[package]] name = "unearth" -version = "0.9.1" +version = "0.10.0" requires_python = ">=3.7" summary = "A utility to fetch and download python packages" dependencies = [ @@ -1921,8 +1921,8 @@ dependencies = [ "requests>=2.25", ] files = [ - {file = "unearth-0.9.1-py3-none-any.whl", hash = "sha256:eb963a8c565324f42a72f284e142ba5ceb30db1ba982dd7454bc2d9b9a7eb3c9"}, - {file = "unearth-0.9.1.tar.gz", hash = "sha256:7205832b087005d1b746903a535ca7d0db5381c1f621ddc00290524d56afd217"}, + {file = "unearth-0.10.0-py3-none-any.whl", hash = "sha256:e8b36f6efd6b677a3ff86354675368a79e98ee8ba01aaa601858e2cc043bc51a"}, + {file = "unearth-0.10.0.tar.gz", hash = "sha256:d5b152a5ab2aa3e5149a11cf7b3ba5c5d493176dca38f66ca8969dadd5a8f645"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 385bed8ec6..204027d74e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ "virtualenv>=20", "pyproject-hooks", "requests-toolbelt", - "unearth>=0.9.0", + "unearth>=0.10.0", "findpython>=0.3.0,<1.0.0a0", "tomlkit>=0.11.1,<1", "shellingham>=1.3.2", diff --git a/src/pdm/models/repositories.py b/src/pdm/models/repositories.py index ac1a3eda16..7c7071df25 100644 --- a/src/pdm/models/repositories.py +++ b/src/pdm/models/repositories.py @@ -243,6 +243,40 @@ def _get_dependency_from_local_package(self, candidate: Candidate) -> CandidateI project.pyproject.metadata.get("description", "UNKNOWN"), ) + def _is_python_match(self, link: Link) -> bool: + from packaging.tags import Tag + from packaging.utils import parse_wheel_filename + + def is_tag_match(tag: Tag, python_requires: PySpecSet) -> bool: + if tag.interpreter.startswith(("cp", "py")): + major, minor = tag.interpreter[2], tag.interpreter[3:] + if not minor: + version = f"{major}.0" + else: + version = f"{major}.{minor}.0" + if tag.abi == "abi3": + spec = PySpecSet(f">={version}") # cp37-abi3 is compatible with >=3.7 + else: + spec = PySpecSet(f"~={version}") # cp37-cp37 is only compatible with 3.7.* + return not (spec & python_requires).is_impossible + else: + # we don't know about compatility for non-cpython implementations + # assume it is compatible + return True + + if not link.is_wheel: + return True + python_requires = self.environment.python_requires + tags = parse_wheel_filename(link.filename)[-1] + result = any(is_tag_match(tag, python_requires) for tag in tags) + if not result: + termui.logger.debug( + "Skipping %r because it is not compatible with %r", + link, + python_requires, + ) + return result + def get_hashes(self, candidate: Candidate) -> list[FileHash]: """Get hashes of all possible installable candidates of a given package version. @@ -272,6 +306,8 @@ def get_hashes(self, candidate: Candidate) -> list[FileHash]: links: list[Link] = [this_link] else: # the req must be a named requirement links = [package.link for package in finder.find_matches(req.as_line())] + if self.ignore_compatibility: + links = [link for link in links if self._is_python_match(link)] for link in links: if not link or link.is_vcs or link.is_file and link.file_path.is_dir(): # The links found can still be a local directory or vcs, skippping it.