Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-dep-logic for
openSUSE:Factory checked in at 2024-07-01 11:19:46
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-dep-logic (Old)
and /work/SRC/openSUSE:Factory/.python-dep-logic.new.18349 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-dep-logic"
Mon Jul 1 11:19:46 2024 rev:3 rq:1184006 version:0.3.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-dep-logic/python-dep-logic.changes
2024-03-07 18:32:37.868131310 +0100
+++
/work/SRC/openSUSE:Factory/.python-dep-logic.new.18349/python-dep-logic.changes
2024-07-01 11:20:07.274516012 +0200
@@ -1,0 +2,8 @@
+Sat Jun 29 16:04:51 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 0.3.0:
+ * New module dep_logic.tags for compatibility check with wheel
+ tags
+ * Use the same marker environment for current platform
+
+-------------------------------------------------------------------
Old:
----
dep_logic-0.2.0.tar.gz
New:
----
dep_logic-0.3.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-dep-logic.spec ++++++
--- /var/tmp/diff_new_pack.MJAVcU/_old 2024-07-01 11:20:08.014542971 +0200
+++ /var/tmp/diff_new_pack.MJAVcU/_new 2024-07-01 11:20:08.014542971 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-dep-logic
-Version: 0.2.0
+Version: 0.3.0
Release: 0
Summary: Python dependency specifications supporting logical operations
License: Apache-2.0
++++++ dep_logic-0.2.0.tar.gz -> dep_logic-0.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/PKG-INFO new/dep_logic-0.3.0/PKG-INFO
--- old/dep_logic-0.2.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/dep_logic-0.3.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,8 +1,8 @@
Metadata-Version: 2.1
Name: dep-logic
-Version: 0.2.0
+Version: 0.3.0
Summary: Python dependency specifications supporting logical operations
-Keywords: dependency specification logic packaging
+Keywords: dependency,specification,logic,packaging
Author-Email: Frost Ming <[email protected]>
License: Apache-2.0
Classifier: Intended Audience :: Developers
@@ -74,6 +74,12 @@
Furthermore, `poetry-core` does not always comply with PEP-508. As a result,
this project aims to offer a lightweight utility for dependency specification
logic using [PyPA's packaging](https://github.com/pypa/packaging).
+Submodules:
+
+- `dep_logic.specifiers` - PEP 440 version specifiers
+- `dep_logic.markers` - PEP 508 environment markers
+- `dep_logic.tags` - PEP 425 platform tags
+
## Caveats
Logic operations with `===<string>` specifiers is partially supported.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/README.md
new/dep_logic-0.3.0/README.md
--- old/dep_logic-0.2.0/README.md 2024-02-23 06:00:55.137874400 +0100
+++ new/dep_logic-0.3.0/README.md 2024-06-28 11:09:19.946395600 +0200
@@ -55,6 +55,12 @@
Furthermore, `poetry-core` does not always comply with PEP-508. As a result,
this project aims to offer a lightweight utility for dependency specification
logic using [PyPA's packaging](https://github.com/pypa/packaging).
+Submodules:
+
+- `dep_logic.specifiers` - PEP 440 version specifiers
+- `dep_logic.markers` - PEP 508 environment markers
+- `dep_logic.tags` - PEP 425 platform tags
+
## Caveats
Logic operations with `===<string>` specifiers is partially supported.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/pyproject.toml
new/dep_logic-0.3.0/pyproject.toml
--- old/dep_logic-0.2.0/pyproject.toml 2024-02-23 06:01:06.997811300 +0100
+++ new/dep_logic-0.3.0/pyproject.toml 2024-06-28 11:09:32.842571500 +0200
@@ -26,7 +26,7 @@
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: Apache Software License",
]
-version = "0.2.0"
+version = "0.3.0"
[project.license]
text = "Apache-2.0"
@@ -39,6 +39,15 @@
[tool.ruff]
line-length = 88
+src = [
+ "src",
+]
+exclude = [
+ "tests/fixtures",
+]
+target-version = "py310"
+
+[tool.ruff.lint]
extend-select = [
"I",
"B",
@@ -53,18 +62,11 @@
"B019",
"B905",
]
-src = [
- "src",
-]
-exclude = [
- "tests/fixtures",
-]
-target-version = "py310"
-[tool.ruff.mccabe]
+[tool.ruff.lint.mccabe]
max-complexity = 10
-[tool.ruff.isort]
+[tool.ruff.lint.isort]
known-first-party = [
"dep_logic",
]
@@ -91,4 +93,4 @@
venvPath = "."
venv = ".venv"
pythonVersion = "3.11"
-reportPrivateImportUsage = "information"
+reportPrivateImportUsage = "none"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/src/dep_logic/tags/__init__.py
new/dep_logic-0.3.0/src/dep_logic/tags/__init__.py
--- old/dep_logic-0.2.0/src/dep_logic/tags/__init__.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dep_logic-0.3.0/src/dep_logic/tags/__init__.py 2024-06-28
11:09:19.946395600 +0200
@@ -0,0 +1,11 @@
+from .platform import Platform, PlatformError
+from .tags import EnvSpec, InvalidWheelFilename, TagsError,
UnsupportedImplementation
+
+__all__ = [
+ "Platform",
+ "PlatformError",
+ "TagsError",
+ "UnsupportedImplementation",
+ "InvalidWheelFilename",
+ "EnvSpec",
+]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/src/dep_logic/tags/os.py
new/dep_logic-0.3.0/src/dep_logic/tags/os.py
--- old/dep_logic-0.2.0/src/dep_logic/tags/os.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dep_logic-0.3.0/src/dep_logic/tags/os.py 2024-06-28
11:09:19.946395600 +0200
@@ -0,0 +1,60 @@
+from dataclasses import dataclass
+
+
+class Os:
+ def __str__(self) -> str:
+ return self.__class__.__name__
+
+
+@dataclass(frozen=True)
+class Manylinux(Os):
+ major: int
+ minor: int
+
+
+@dataclass(frozen=True)
+class Musllinux(Os):
+ major: int
+ minor: int
+
+
+@dataclass(frozen=True)
+class Windows(Os):
+ pass
+
+
+@dataclass(frozen=True)
+class Macos(Os):
+ major: int
+ minor: int
+
+
+@dataclass(frozen=True)
+class FreeBsd(Os):
+ release: str
+
+
+@dataclass(frozen=True)
+class NetBsd(Os):
+ release: str
+
+
+@dataclass(frozen=True)
+class OpenBsd(Os):
+ release: str
+
+
+@dataclass(frozen=True)
+class Dragonfly(Os):
+ release: str
+
+
+@dataclass(frozen=True)
+class Illumos(Os):
+ release: str
+ arch: str
+
+
+@dataclass(frozen=True)
+class Haiku(Os):
+ release: str
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/src/dep_logic/tags/platform.py
new/dep_logic-0.3.0/src/dep_logic/tags/platform.py
--- old/dep_logic-0.2.0/src/dep_logic/tags/platform.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dep_logic-0.3.0/src/dep_logic/tags/platform.py 2024-06-28
11:09:19.946395600 +0200
@@ -0,0 +1,322 @@
+# Abstractions for understanding the current platform (operating system and
architecture).
+from __future__ import annotations
+
+import sys
+from dataclasses import dataclass
+from enum import Enum
+from functools import cached_property
+
+from . import os
+
+
+class PlatformError(Exception):
+ pass
+
+
+@dataclass(frozen=True)
+class Platform:
+ os: os.Os
+ arch: Arch
+
+ @classmethod
+ def parse(cls, platform: str) -> Platform:
+ """Parse a platform string (e.g., `linux_x86_64`,
`macosx_10_9_x86_64`, or `win_amd64`)
+
+ Available operating systems:
+ - `linux`: an alias for `manylinux_2_17_x86_64`
+ - `windows`: an alias for `win_x86_64`
+ - `macos`: an alias for `macos_12_0_arm64`
+ - `alpine`: an alias for `musllinux_1_2_x86_64`
+ - `windows_amd64`: an alias for `win_x86_64`
+ - `windows_x86`
+ - `macos_arm64`: an alias for `macos_12_0_arm64`
+ - `macos_x86_64`: an alias for `macos_12_0_x86_64`
+ - `macos_X_Y_arm64`
+ - `macos_X_Y_x86_64`
+ - `manylinux_X_Y_x86_64`
+ - `manylinux_X_Y_aarch64`
+ - `musllinux_X_Y_x86_64`
+ - `musllinux_X_Y_aarch64`
+ """
+ if platform == "linux":
+ return cls(os.Manylinux(2, 17), Arch.X86_64)
+ elif platform == "windows":
+ return cls(os.Windows(), Arch.X86_64)
+ elif platform == "macos":
+ return cls(os.Macos(12, 0), Arch.Aarch64)
+ elif platform == "alpine":
+ return cls(os.Musllinux(1, 2), Arch.X86_64)
+ elif platform == "windows_amd64":
+ return cls(os.Windows(), Arch.X86_64)
+ elif platform == "windows_x86":
+ return cls(os.Windows(), Arch.X86)
+ elif platform == "macos_arm64":
+ return cls(os.Macos(12, 0), Arch.Aarch64)
+ elif platform == "macos_x86_64":
+ return cls(os.Macos(12, 0), Arch.X86_64)
+ elif platform.startswith("macos_"):
+ parts = platform.split("_")
+ major = int(parts[1])
+ minor = int(parts[2])
+ return cls(os.Macos(major, minor), Arch.parse(parts[3]))
+ elif platform.startswith("musllinux_"):
+ parts = platform.split("_")
+ major = int(parts[1])
+ minor = int(parts[2])
+ return cls(os.Musllinux(major, minor), Arch.parse(parts[3]))
+ elif platform.startswith("manylinux_"):
+ parts = platform.split("_")
+ major = int(parts[1])
+ minor = int(parts[2])
+ return cls(os.Manylinux(major, minor), Arch.parse(parts[3]))
+ else:
+ raise PlatformError(
+ f"Unsupported platform {platform}, expected one of
{cls.choices()}"
+ )
+
+ @classmethod
+ def current(cls) -> Platform:
+ """Return the current platform."""
+ import platform
+
+ system = platform.system()
+ arch = Arch.parse(platform.machine())
+ if system == "Linux":
+ libc_ver = platform.libc_ver()[1]
+ if libc_ver:
+ parts = libc_ver.split(".")
+ return cls(os.Manylinux(int(parts[0]), int(parts[1])), arch)
+ else: # musl
+ from packaging._musllinux import _get_musl_version
+
+ musl_version = _get_musl_version(sys.executable)
+ if musl_version is None:
+ raise PlatformError(
+ "Failed to detect musl version or glibc version"
+ )
+ return cls(os.Musllinux(musl_version.major,
musl_version.minor), arch)
+ elif system == "Windows":
+ return cls(os.Windows(), arch)
+ elif system == "Darwin":
+ mac_ver = platform.mac_ver()[0].split(".")
+ return cls(os.Macos(int(mac_ver[0]), int(mac_ver[1])), arch)
+ else:
+ raise PlatformError("Unsupported platform")
+
+ @classmethod
+ def choices(cls) -> list[str]:
+ return [
+ "linux",
+ "windows",
+ "macos",
+ "alpine",
+ "windows_amd64",
+ "windows_x86",
+ "macos_arm64",
+ "macos_x86_64",
+ "macos_X_Y_arm64",
+ "macos_X_Y_x86_64",
+ "manylinux_X_Y_x86_64",
+ "manylinux_X_Y_aarch64",
+ "musllinux_X_Y_x86_64",
+ "musllinux_X_Y_aarch64",
+ ]
+
+ @cached_property
+ def compatible_tags(self) -> list[str]:
+ """Returns the compatible tags for the current [`Platform`] (e.g.,
`manylinux_2_17`,
+ `macosx_11_0_arm64`, or `win_amd64`).
+
+ We have two cases: Actual platform specific tags (including "merged"
tags such as universal2)
+ and "any".
+
+ Bit of a mess, needs to be cleaned up.
+ """
+ os_ = self.os
+ arch = self.arch
+ platform_tags: list[str] = []
+ if isinstance(os_, os.Manylinux):
+ if (min_minor := arch.get_minimum_manylinux_minor()) is not None:
+ for minor in range(os_.minor, min_minor - 1, -1):
+
platform_tags.append(f"manylinux_{os_.major}_{minor}_{arch}")
+ # Support legacy manylinux tags with lower priority
+ # <https://peps.python.org/pep-0600/#legacy-manylinux-tags>
+ if minor == 12:
+ platform_tags.append(f"manylinux2010_{arch}")
+ if minor == 17:
+ platform_tags.append(f"manylinux2014_{arch}")
+ if minor == 5:
+ platform_tags.append(f"manylinux1_{arch}")
+ # Non-manylinux is lowest priority
+ #
<https://github.com/pypa/packaging/blob/fd4f11139d1c884a637be8aa26bb60a31fbc9411/packaging/tags.py#L444>
+ platform_tags.append(f"linux_{arch}")
+ elif isinstance(os_, os.Musllinux):
+ platform_tags.append(f"linux_{arch}")
+ for minor in range(1, os_.minor + 1):
+ # musl 1.1 is the lowest supported version in musllinux
+ platform_tags.append(f"musllinux_{os_.major}_{minor}_{arch}")
+ elif isinstance(os_, os.Macos) and arch == Arch.X86_64:
+ if os_.major == 10:
+ for minor in range(os_.minor, 3, -1):
+ for binary_format in arch.get_mac_binary_formats():
+
platform_tags.append(f"macosx_10_{minor}_{binary_format}")
+ elif isinstance(os_.major, int) and os_.major >= 11:
+ # Starting with Mac OS 11, each yearly release bumps the major
version number.
+ # The minor versions are now the midyear updates.
+ for major in range(os_.major, 10, -1):
+ for binary_format in arch.get_mac_binary_formats():
+
platform_tags.append(f"macosx_{major}_0_{binary_format}")
+ # The "universal2" binary format can have a macOS version
earlier than 11.0
+ # when the x86_64 part of the binary supports that version of
macOS.
+ for minor in range(16, 3, -1):
+ for binary_format in arch.get_mac_binary_formats():
+
platform_tags.append(f"macosx_10_{minor}_{binary_format}")
+ else:
+ raise PlatformError(f"Unsupported macOS version {os_.major}")
+ elif isinstance(os_, os.Macos) and arch == Arch.Aarch64:
+ # Starting with Mac OS 11, each yearly release bumps the major
version number.
+ # The minor versions are now the midyear updates.
+ for major in range(os_.major, 10, -1):
+ for binary_format in arch.get_mac_binary_formats():
+ platform_tags.append(f"macosx_{major}_0_{binary_format}")
+ # The "universal2" binary format can have a macOS version earlier
than 11.0
+ # when the x86_64 part of the binary supports that version of
macOS.
+ for minor in range(16, 3, -1):
+ platform_tags.append(f"macosx_10_{minor}_universal2")
+ elif isinstance(os_, os.Windows):
+ if arch == Arch.X86:
+ platform_tags.append("win32")
+ elif arch == Arch.X86_64:
+ platform_tags.append("win_amd64")
+ elif arch == Arch.Aarch64:
+ platform_tags.append("win_arm64")
+ else:
+ raise PlatformError(f"Unsupported Windows architecture {arch}")
+ elif isinstance(
+ os_, (os.FreeBsd, os.NetBsd, os.OpenBsd, os.Dragonfly, os.Haiku)
+ ):
+ release = os_.release.replace(".", "_").replace("-", "_")
+ platform_tags.append(f"{str(os_).lower()}_{release}_{arch}")
+ elif isinstance(os_, os.Illumos):
+ # See
https://github.com/python/cpython/blob/46c8d915715aa2bd4d697482aa051fe974d440e1/Lib/sysconfig.py#L722-L730
+ try:
+ major, other = os_.release.split("_", 1)
+ except ValueError:
+
platform_tags.append(f"{str(os_).lower()}_{os_.release}_{arch}")
+ else:
+ major_ver = int(major)
+ if major_ver >= 5:
+ # SunOS 5 == Solaris 2
+ release = f"{major_ver - 3}_{other}"
+ arch = f"{arch}_64bit"
+ platform_tags.append(f"solaris_{release}_{arch}")
+ else:
+ raise PlatformError(
+ f"Unsupported operating system and architecture combination:
{os_} {arch}"
+ )
+ return platform_tags
+
+ @cached_property
+ def os_name(self) -> str:
+ return "nt" if isinstance(self.os, os.Windows) else "posix"
+
+ @cached_property
+ def sys_platform(self) -> str:
+ if isinstance(self.os, os.Windows):
+ return "win32"
+ elif isinstance(self.os, (os.Macos, os.Illumos)):
+ return "darwin"
+ else:
+ return "linux"
+
+ @cached_property
+ def platform_machine(self) -> str:
+ if isinstance(self.os, (os.Windows, os.Macos)) and self.arch ==
Arch.Aarch64:
+ return "arm64"
+ if isinstance(self.os, os.Windows) and self.arch == Arch.X86_64:
+ return "AMD64"
+ return str(self.arch)
+
+ @cached_property
+ def platform_release(self) -> str:
+ return ""
+
+ @cached_property
+ def platform_version(self) -> str:
+ return ""
+
+ @cached_property
+ def platform_system(self) -> str:
+ if isinstance(self.os, os.Macos):
+ return "Darwin"
+ if isinstance(self.os, os.Windows):
+ return "Windows"
+ return "Linux"
+
+ def is_current(self) -> bool:
+ current = self.current()
+ return isinstance(self.os, type(current.os)) and self.arch ==
current.arch
+
+ def markers(self) -> dict[str, str]:
+ if self.is_current():
+ return {}
+ return {
+ "os_name": self.os_name,
+ "platform_machine": self.platform_machine,
+ "platform_release": self.platform_release,
+ "platform_system": self.platform_system,
+ "platform_version": self.platform_version,
+ "sys_platform": self.sys_platform,
+ }
+
+
+class Arch(Enum):
+ Aarch64 = "aarch64"
+ Armv6L = "armv6l"
+ Armv7L = "armv7l"
+ Powerpc64Le = "ppc64le"
+ Powerpc64 = "ppc64"
+ X86 = "x86"
+ X86_64 = "x86_64"
+ S390X = "s390x"
+
+ def __str__(self) -> str:
+ return self.value
+
+ def get_minimum_manylinux_minor(self) -> int | None:
+ if self in [
+ Arch.Aarch64,
+ Arch.Armv7L,
+ Arch.Powerpc64,
+ Arch.Powerpc64Le,
+ Arch.S390X,
+ ]:
+ return 17
+ elif self in [Arch.X86, Arch.X86_64]:
+ return 5
+ else:
+ return None
+
+ def get_mac_binary_formats(self) -> list[str]:
+ formats = [self.value]
+
+ if self == Arch.X86_64:
+ formats.extend(["intel", "fat64", "fat32"])
+
+ if self in [Arch.X86_64, Arch.Aarch64]:
+ formats.append("universal2")
+
+ if self == Arch.X86_64:
+ formats.append("universal")
+
+ return formats
+
+ @classmethod
+ def parse(cls, arch: str) -> Arch:
+ if arch in ("i386", "i686"):
+ return cls.X86
+ if arch == "amd64":
+ return cls.X86_64
+ if arch == "arm64":
+ return cls.Aarch64
+ return cls(arch)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/src/dep_logic/tags/tags.py
new/dep_logic-0.3.0/src/dep_logic/tags/tags.py
--- old/dep_logic-0.2.0/src/dep_logic/tags/tags.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dep_logic-0.3.0/src/dep_logic/tags/tags.py 2024-06-28
11:09:19.946395600 +0200
@@ -0,0 +1,187 @@
+from __future__ import annotations
+
+from dataclasses import dataclass
+from platform import python_implementation, python_version
+from typing import TYPE_CHECKING
+
+from ..specifiers import InvalidSpecifier, VersionSpecifier,
parse_version_specifier
+from .platform import Platform
+
+if TYPE_CHECKING:
+ from typing import Literal
+
+
+def parse_wheel_tags(filename: str) -> tuple[list[str], list[str], list[str]]:
+ if not filename.endswith(".whl"):
+ raise InvalidWheelFilename(
+ f"Invalid wheel filename (extension must be '.whl'): {filename}"
+ )
+
+ filename = filename[:-4]
+ dashes = filename.count("-")
+ if dashes not in (4, 5):
+ raise InvalidWheelFilename(
+ f"Invalid wheel filename (wrong number of parts): {filename}"
+ )
+
+ parts = filename.split("-")
+ python, abi, platform = parts[-3:]
+ return python.split("."), abi.split("."), platform.split(".")
+
+
+def _ensure_version_specifier(spec: str) -> VersionSpecifier:
+ parsed = parse_version_specifier(spec)
+ if not isinstance(parsed, VersionSpecifier):
+ raise InvalidSpecifier(f"Invalid version specifier {spec}")
+ return parsed
+
+
+class TagsError(Exception):
+ pass
+
+
+class InvalidWheelFilename(TagsError, ValueError):
+ pass
+
+
+class UnsupportedImplementation(TagsError, ValueError):
+ pass
+
+
+@dataclass(frozen=True)
+class Implementation:
+ name: Literal["cpython", "pypy", "pyston"]
+ gil_disabled: bool = False
+
+ @property
+ def short(self) -> str:
+ if self.name == "cpython":
+ return "cp"
+ elif self.name == "pypy":
+ return "pp"
+ else:
+ return "pt"
+
+ @classmethod
+ def current(cls) -> Implementation:
+ import sysconfig
+
+ implementation = python_implementation()
+
+ return cls.parse(
+ implementation.lower(),
sysconfig.get_config_var("Py_GIL_DISABLED") or False
+ )
+
+ @classmethod
+ def parse(cls, name: str, gil_disabled: bool = False) -> Implementation:
+ if gil_disabled and name != "cpython":
+ raise UnsupportedImplementation("Only CPython supports GIL
disabled mode")
+ if name in ("cpython", "pypy", "pyston"):
+ return Implementation(name, gil_disabled)
+ else:
+ raise UnsupportedImplementation(
+ f"Unsupported implementation: {name}, expected cpython, pypy,
or pyston"
+ )
+
+
+@dataclass(frozen=True)
+class EnvSpec:
+ requires_python: VersionSpecifier
+ platform: Platform
+ implementation: Implementation
+
+ @classmethod
+ def from_spec(
+ cls,
+ requires_python: str,
+ platform: str,
+ implementation: str,
+ gil_disabled: bool = False,
+ ) -> EnvSpec:
+ return cls(
+ _ensure_version_specifier(requires_python),
+ Platform.parse(platform),
+ Implementation.parse(implementation, gil_disabled=gil_disabled),
+ )
+
+ @classmethod
+ def current(cls) -> EnvSpec:
+ requires_python = _ensure_version_specifier(f"=={python_version()}")
+ platform = Platform.current()
+ implementation = Implementation.current()
+ return cls(requires_python, platform, implementation)
+
+ def _evaluate_python(
+ self, python_tag: str, abi_tag: str
+ ) -> tuple[int, int, int] | None:
+ impl, major, minor = python_tag[:2], python_tag[2], python_tag[3:]
+ if impl not in [self.implementation.short, "py"]:
+ return None
+ abi_impl = (
+ abi_tag.split("_", 1)[0]
+ .replace("pypy", "pp")
+ .replace("pyston", "pt")
+ .lower()
+ )
+ if impl == "cp" and abi_impl == "abi3":
+ if (
+ parse_version_specifier(f">={major}.{minor or 0}")
+ & self.requires_python
+ ).is_empty():
+ return None
+ return (int(major), int(minor or 0), 1) # 1 for abi3
+ # cp36-cp36m-*
+ # cp312-cp312m-*
+ # pp310-pypy310_pp75-*
+ if abi_impl != "none" and not abi_impl.startswith(python_tag.lower()):
+ return None
+ if major and minor:
+ wheel_range = parse_version_specifier(f"=={major}.{minor}.*")
+ else:
+ wheel_range = parse_version_specifier(f"=={major}.*")
+ if (wheel_range & self.requires_python).is_empty():
+ return None
+ return (int(major), int(minor or 0), 0 if abi_impl == "none" else 2)
+
+ def _evaluate_platform(self, platform_tag: str) -> int | None:
+ platform_tags = [*self.platform.compatible_tags, "any"]
+ if platform_tag not in platform_tags:
+ return None
+ return len(platform_tags) - platform_tags.index(platform_tag)
+
+ def compatibility(
+ self,
+ wheel_python_tags: list[str],
+ wheel_abi_tags: list[str],
+ wheel_platform_tags: list[str],
+ ) -> tuple[int, int, int, int] | None:
+ python_abi_combinations = (
+ (python_tag, abi_tag)
+ for python_tag in wheel_python_tags
+ for abi_tag in wheel_abi_tags
+ )
+ python_compat = max(
+ filter(
+ None, (self._evaluate_python(*comb) for comb in
python_abi_combinations)
+ ),
+ default=None,
+ )
+ if python_compat is None:
+ return None
+ platform_compat = max(
+ filter(None, map(self._evaluate_platform, wheel_platform_tags)),
+ default=None,
+ )
+ if platform_compat is None:
+ return None
+ return (*python_compat, platform_compat)
+
+ def wheel_compatibility(
+ self, wheel_filename: str
+ ) -> tuple[int, int, int, int] | None:
+ wheel_python_tags, wheel_abi_tags, wheel_platform_tags =
parse_wheel_tags(
+ wheel_filename
+ )
+ return self.compatibility(
+ wheel_python_tags, wheel_abi_tags, wheel_platform_tags
+ )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/src/dep_logic/utils.py
new/dep_logic-0.3.0/src/dep_logic/utils.py
--- old/dep_logic-0.2.0/src/dep_logic/utils.py 2024-02-23 06:00:55.137874400
+0100
+++ new/dep_logic-0.3.0/src/dep_logic/utils.py 2024-06-28 11:09:19.946395600
+0200
@@ -25,11 +25,9 @@
class Ident(Protocol):
- def __hash__(self) -> int:
- ...
+ def __hash__(self) -> int: ...
- def __eq__(self, __value: object) -> bool:
- ...
+ def __eq__(self, __value: object) -> bool: ...
T = TypeVar("T", bound=Ident)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/tests/specifier/test_arbitrary.py
new/dep_logic-0.3.0/tests/specifier/test_arbitrary.py
--- old/dep_logic-0.2.0/tests/specifier/test_arbitrary.py 2024-02-23
06:00:55.137874400 +0100
+++ new/dep_logic-0.3.0/tests/specifier/test_arbitrary.py 2024-06-28
11:09:19.946395600 +0200
@@ -42,6 +42,6 @@
def test_arbitrary_unsupported(a: str, b: str, operand: str) -> None:
with pytest.raises(ValueError):
if operand == "and":
- parse_version_specifier(a) & parse_version_specifier(b)
+ _ = parse_version_specifier(a) & parse_version_specifier(b)
else:
- parse_version_specifier(a) | parse_version_specifier(b)
+ _ = parse_version_specifier(a) | parse_version_specifier(b)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/tests/tags/test_platform.py
new/dep_logic-0.3.0/tests/tags/test_platform.py
--- old/dep_logic-0.2.0/tests/tags/test_platform.py 1970-01-01
01:00:00.000000000 +0100
+++ new/dep_logic-0.3.0/tests/tags/test_platform.py 2024-06-28
11:09:19.946395600 +0200
@@ -0,0 +1,334 @@
+import pytest
+
+from dep_logic.tags import os
+from dep_logic.tags.platform import Arch, Platform
+
+
+def test_platform_tags_manylinux():
+ tags = Platform(os.Manylinux(2, 20), Arch.X86_64).compatible_tags
+ assert tags == [
+ "manylinux_2_20_x86_64",
+ "manylinux_2_19_x86_64",
+ "manylinux_2_18_x86_64",
+ "manylinux_2_17_x86_64",
+ "manylinux2014_x86_64",
+ "manylinux_2_16_x86_64",
+ "manylinux_2_15_x86_64",
+ "manylinux_2_14_x86_64",
+ "manylinux_2_13_x86_64",
+ "manylinux_2_12_x86_64",
+ "manylinux2010_x86_64",
+ "manylinux_2_11_x86_64",
+ "manylinux_2_10_x86_64",
+ "manylinux_2_9_x86_64",
+ "manylinux_2_8_x86_64",
+ "manylinux_2_7_x86_64",
+ "manylinux_2_6_x86_64",
+ "manylinux_2_5_x86_64",
+ "manylinux1_x86_64",
+ "linux_x86_64",
+ ]
+
+
+def test_platform_tags_macos():
+ tags = Platform(os.Macos(21, 6), Arch.X86_64).compatible_tags
+ assert tags == [
+ "macosx_21_0_x86_64",
+ "macosx_21_0_intel",
+ "macosx_21_0_fat64",
+ "macosx_21_0_fat32",
+ "macosx_21_0_universal2",
+ "macosx_21_0_universal",
+ "macosx_20_0_x86_64",
+ "macosx_20_0_intel",
+ "macosx_20_0_fat64",
+ "macosx_20_0_fat32",
+ "macosx_20_0_universal2",
+ "macosx_20_0_universal",
+ "macosx_19_0_x86_64",
+ "macosx_19_0_intel",
+ "macosx_19_0_fat64",
+ "macosx_19_0_fat32",
+ "macosx_19_0_universal2",
+ "macosx_19_0_universal",
+ "macosx_18_0_x86_64",
+ "macosx_18_0_intel",
+ "macosx_18_0_fat64",
+ "macosx_18_0_fat32",
+ "macosx_18_0_universal2",
+ "macosx_18_0_universal",
+ "macosx_17_0_x86_64",
+ "macosx_17_0_intel",
+ "macosx_17_0_fat64",
+ "macosx_17_0_fat32",
+ "macosx_17_0_universal2",
+ "macosx_17_0_universal",
+ "macosx_16_0_x86_64",
+ "macosx_16_0_intel",
+ "macosx_16_0_fat64",
+ "macosx_16_0_fat32",
+ "macosx_16_0_universal2",
+ "macosx_16_0_universal",
+ "macosx_15_0_x86_64",
+ "macosx_15_0_intel",
+ "macosx_15_0_fat64",
+ "macosx_15_0_fat32",
+ "macosx_15_0_universal2",
+ "macosx_15_0_universal",
+ "macosx_14_0_x86_64",
+ "macosx_14_0_intel",
+ "macosx_14_0_fat64",
+ "macosx_14_0_fat32",
+ "macosx_14_0_universal2",
+ "macosx_14_0_universal",
+ "macosx_13_0_x86_64",
+ "macosx_13_0_intel",
+ "macosx_13_0_fat64",
+ "macosx_13_0_fat32",
+ "macosx_13_0_universal2",
+ "macosx_13_0_universal",
+ "macosx_12_0_x86_64",
+ "macosx_12_0_intel",
+ "macosx_12_0_fat64",
+ "macosx_12_0_fat32",
+ "macosx_12_0_universal2",
+ "macosx_12_0_universal",
+ "macosx_11_0_x86_64",
+ "macosx_11_0_intel",
+ "macosx_11_0_fat64",
+ "macosx_11_0_fat32",
+ "macosx_11_0_universal2",
+ "macosx_11_0_universal",
+ "macosx_10_16_x86_64",
+ "macosx_10_16_intel",
+ "macosx_10_16_fat64",
+ "macosx_10_16_fat32",
+ "macosx_10_16_universal2",
+ "macosx_10_16_universal",
+ "macosx_10_15_x86_64",
+ "macosx_10_15_intel",
+ "macosx_10_15_fat64",
+ "macosx_10_15_fat32",
+ "macosx_10_15_universal2",
+ "macosx_10_15_universal",
+ "macosx_10_14_x86_64",
+ "macosx_10_14_intel",
+ "macosx_10_14_fat64",
+ "macosx_10_14_fat32",
+ "macosx_10_14_universal2",
+ "macosx_10_14_universal",
+ "macosx_10_13_x86_64",
+ "macosx_10_13_intel",
+ "macosx_10_13_fat64",
+ "macosx_10_13_fat32",
+ "macosx_10_13_universal2",
+ "macosx_10_13_universal",
+ "macosx_10_12_x86_64",
+ "macosx_10_12_intel",
+ "macosx_10_12_fat64",
+ "macosx_10_12_fat32",
+ "macosx_10_12_universal2",
+ "macosx_10_12_universal",
+ "macosx_10_11_x86_64",
+ "macosx_10_11_intel",
+ "macosx_10_11_fat64",
+ "macosx_10_11_fat32",
+ "macosx_10_11_universal2",
+ "macosx_10_11_universal",
+ "macosx_10_10_x86_64",
+ "macosx_10_10_intel",
+ "macosx_10_10_fat64",
+ "macosx_10_10_fat32",
+ "macosx_10_10_universal2",
+ "macosx_10_10_universal",
+ "macosx_10_9_x86_64",
+ "macosx_10_9_intel",
+ "macosx_10_9_fat64",
+ "macosx_10_9_fat32",
+ "macosx_10_9_universal2",
+ "macosx_10_9_universal",
+ "macosx_10_8_x86_64",
+ "macosx_10_8_intel",
+ "macosx_10_8_fat64",
+ "macosx_10_8_fat32",
+ "macosx_10_8_universal2",
+ "macosx_10_8_universal",
+ "macosx_10_7_x86_64",
+ "macosx_10_7_intel",
+ "macosx_10_7_fat64",
+ "macosx_10_7_fat32",
+ "macosx_10_7_universal2",
+ "macosx_10_7_universal",
+ "macosx_10_6_x86_64",
+ "macosx_10_6_intel",
+ "macosx_10_6_fat64",
+ "macosx_10_6_fat32",
+ "macosx_10_6_universal2",
+ "macosx_10_6_universal",
+ "macosx_10_5_x86_64",
+ "macosx_10_5_intel",
+ "macosx_10_5_fat64",
+ "macosx_10_5_fat32",
+ "macosx_10_5_universal2",
+ "macosx_10_5_universal",
+ "macosx_10_4_x86_64",
+ "macosx_10_4_intel",
+ "macosx_10_4_fat64",
+ "macosx_10_4_fat32",
+ "macosx_10_4_universal2",
+ "macosx_10_4_universal",
+ ]
+
+ tags = Platform(os.Macos(14, 0), Arch.X86_64).compatible_tags
+ assert tags == [
+ "macosx_14_0_x86_64",
+ "macosx_14_0_intel",
+ "macosx_14_0_fat64",
+ "macosx_14_0_fat32",
+ "macosx_14_0_universal2",
+ "macosx_14_0_universal",
+ "macosx_13_0_x86_64",
+ "macosx_13_0_intel",
+ "macosx_13_0_fat64",
+ "macosx_13_0_fat32",
+ "macosx_13_0_universal2",
+ "macosx_13_0_universal",
+ "macosx_12_0_x86_64",
+ "macosx_12_0_intel",
+ "macosx_12_0_fat64",
+ "macosx_12_0_fat32",
+ "macosx_12_0_universal2",
+ "macosx_12_0_universal",
+ "macosx_11_0_x86_64",
+ "macosx_11_0_intel",
+ "macosx_11_0_fat64",
+ "macosx_11_0_fat32",
+ "macosx_11_0_universal2",
+ "macosx_11_0_universal",
+ "macosx_10_16_x86_64",
+ "macosx_10_16_intel",
+ "macosx_10_16_fat64",
+ "macosx_10_16_fat32",
+ "macosx_10_16_universal2",
+ "macosx_10_16_universal",
+ "macosx_10_15_x86_64",
+ "macosx_10_15_intel",
+ "macosx_10_15_fat64",
+ "macosx_10_15_fat32",
+ "macosx_10_15_universal2",
+ "macosx_10_15_universal",
+ "macosx_10_14_x86_64",
+ "macosx_10_14_intel",
+ "macosx_10_14_fat64",
+ "macosx_10_14_fat32",
+ "macosx_10_14_universal2",
+ "macosx_10_14_universal",
+ "macosx_10_13_x86_64",
+ "macosx_10_13_intel",
+ "macosx_10_13_fat64",
+ "macosx_10_13_fat32",
+ "macosx_10_13_universal2",
+ "macosx_10_13_universal",
+ "macosx_10_12_x86_64",
+ "macosx_10_12_intel",
+ "macosx_10_12_fat64",
+ "macosx_10_12_fat32",
+ "macosx_10_12_universal2",
+ "macosx_10_12_universal",
+ "macosx_10_11_x86_64",
+ "macosx_10_11_intel",
+ "macosx_10_11_fat64",
+ "macosx_10_11_fat32",
+ "macosx_10_11_universal2",
+ "macosx_10_11_universal",
+ "macosx_10_10_x86_64",
+ "macosx_10_10_intel",
+ "macosx_10_10_fat64",
+ "macosx_10_10_fat32",
+ "macosx_10_10_universal2",
+ "macosx_10_10_universal",
+ "macosx_10_9_x86_64",
+ "macosx_10_9_intel",
+ "macosx_10_9_fat64",
+ "macosx_10_9_fat32",
+ "macosx_10_9_universal2",
+ "macosx_10_9_universal",
+ "macosx_10_8_x86_64",
+ "macosx_10_8_intel",
+ "macosx_10_8_fat64",
+ "macosx_10_8_fat32",
+ "macosx_10_8_universal2",
+ "macosx_10_8_universal",
+ "macosx_10_7_x86_64",
+ "macosx_10_7_intel",
+ "macosx_10_7_fat64",
+ "macosx_10_7_fat32",
+ "macosx_10_7_universal2",
+ "macosx_10_7_universal",
+ "macosx_10_6_x86_64",
+ "macosx_10_6_intel",
+ "macosx_10_6_fat64",
+ "macosx_10_6_fat32",
+ "macosx_10_6_universal2",
+ "macosx_10_6_universal",
+ "macosx_10_5_x86_64",
+ "macosx_10_5_intel",
+ "macosx_10_5_fat64",
+ "macosx_10_5_fat32",
+ "macosx_10_5_universal2",
+ "macosx_10_5_universal",
+ "macosx_10_4_x86_64",
+ "macosx_10_4_intel",
+ "macosx_10_4_fat64",
+ "macosx_10_4_fat32",
+ "macosx_10_4_universal2",
+ "macosx_10_4_universal",
+ ]
+
+ tags = Platform(os.Macos(10, 6), Arch.X86_64).compatible_tags
+ assert tags == [
+ "macosx_10_6_x86_64",
+ "macosx_10_6_intel",
+ "macosx_10_6_fat64",
+ "macosx_10_6_fat32",
+ "macosx_10_6_universal2",
+ "macosx_10_6_universal",
+ "macosx_10_5_x86_64",
+ "macosx_10_5_intel",
+ "macosx_10_5_fat64",
+ "macosx_10_5_fat32",
+ "macosx_10_5_universal2",
+ "macosx_10_5_universal",
+ "macosx_10_4_x86_64",
+ "macosx_10_4_intel",
+ "macosx_10_4_fat64",
+ "macosx_10_4_fat32",
+ "macosx_10_4_universal2",
+ "macosx_10_4_universal",
+ ]
+
+
+def test_platform_tags_windows():
+ tags = Platform(os.Windows(), Arch.X86_64).compatible_tags
+ assert tags == ["win_amd64"]
+
+
+def test_platform_tags_musl():
+ tags = Platform(os.Musllinux(1, 2), Arch.Aarch64).compatible_tags
+ assert tags == ["linux_aarch64", "musllinux_1_1_aarch64",
"musllinux_1_2_aarch64"]
+
+
[email protected](
+ "text,expected",
+ [
+ ("linux", Platform(os.Manylinux(2, 17), Arch.X86_64)),
+ ("macos", Platform(os.Macos(12, 0), Arch.Aarch64)),
+ ("windows", Platform(os.Windows(), Arch.X86_64)),
+ ("alpine", Platform(os.Musllinux(1, 2), Arch.X86_64)),
+ ("manylinux_2_20_aarch64", Platform(os.Manylinux(2, 20),
Arch.Aarch64)),
+ ("macos_14_0_arm64", Platform(os.Macos(14, 0), Arch.Aarch64)),
+ ("windows_amd64", Platform(os.Windows(), Arch.X86_64)),
+ ],
+)
+def test_parse_platform(text, expected):
+ assert Platform.parse(text) == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/dep_logic-0.2.0/tests/tags/test_tags.py
new/dep_logic-0.3.0/tests/tags/test_tags.py
--- old/dep_logic-0.2.0/tests/tags/test_tags.py 1970-01-01 01:00:00.000000000
+0100
+++ new/dep_logic-0.3.0/tests/tags/test_tags.py 2024-06-28 11:09:19.946395600
+0200
@@ -0,0 +1,41 @@
+from dep_logic.tags import EnvSpec
+
+
+def test_check_wheel_tags():
+ wheels = [
+ "protobuf-5.27.2-cp310-abi3-win32.whl",
+ "protobuf-5.27.2-cp310-abi3-win_amd64.whl",
+ "protobuf-5.27.2-cp38-abi3-macosx_10_9_universal2.whl",
+ "protobuf-5.27.2-cp38-abi3-manylinux2014_aarch64.whl",
+ "protobuf-5.27.2-cp38-abi3-manylinux2014_x86_64.whl",
+ "protobuf-5.27.2-cp38-cp38-win32.whl",
+ "protobuf-5.27.2-cp38-cp38-win_amd64.whl",
+ "protobuf-5.27.2-cp39-cp39-win32.whl",
+ "protobuf-5.27.2-cp39-cp39-win_amd64.whl",
+ "protobuf-5.27.2-py3-none-any.whl",
+ ]
+
+ linux_env = EnvSpec.from_spec(">=3.9", "linux", "cpython")
+ wheel_compats = {
+ f: c
+ for f, c in {f: linux_env.wheel_compatibility(f) for f in
wheels}.items()
+ if c is not None
+ }
+ filtered_wheels = sorted(wheel_compats, key=wheel_compats.__getitem__,
reverse=True)
+ assert filtered_wheels == [
+ "protobuf-5.27.2-cp38-abi3-manylinux2014_x86_64.whl",
+ "protobuf-5.27.2-py3-none-any.whl",
+ ]
+
+ windows_env = EnvSpec.from_spec(">=3.9", "windows", "cpython")
+ wheel_compats = {
+ f: c
+ for f, c in {f: windows_env.wheel_compatibility(f) for f in
wheels}.items()
+ if c is not None
+ }
+ filtered_wheels = sorted(wheel_compats, key=wheel_compats.__getitem__,
reverse=True)
+ assert filtered_wheels == [
+ "protobuf-5.27.2-cp310-abi3-win_amd64.whl",
+ "protobuf-5.27.2-cp39-cp39-win_amd64.whl",
+ "protobuf-5.27.2-py3-none-any.whl",
+ ]