Misc. changes based on ABI explorations (#10458)

This commit is contained in:
Charlie Marsh 2025-01-10 08:10:39 -05:00 committed by GitHub
parent 8d25f295af
commit bee2baa64e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 36 additions and 48 deletions

View file

@ -222,7 +222,7 @@ impl Display for IncompatibleDist {
} }
} }
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum PythonRequirementKind { pub enum PythonRequirementKind {
/// The installed version of Python. /// The installed version of Python.
Installed, Installed,
@ -266,7 +266,7 @@ pub enum IncompatibleSource {
NoBuild, NoBuild,
} }
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum HashComparison { pub enum HashComparison {
/// The hash is present, but does not match the expected value. /// The hash is present, but does not match the expected value.
Mismatched, Mismatched,

View file

@ -56,17 +56,17 @@ pub enum Os {
impl fmt::Display for Os { impl fmt::Display for Os {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
Self::Manylinux { .. } => write!(f, "Manylinux"), Self::Manylinux { .. } => write!(f, "manylinux"),
Self::Musllinux { .. } => write!(f, "Musllinux"), Self::Musllinux { .. } => write!(f, "musllinux"),
Self::Windows => write!(f, "Windows"), Self::Windows => write!(f, "windows"),
Self::Macos { .. } => write!(f, "MacOS"), Self::Macos { .. } => write!(f, "macos"),
Self::FreeBsd { .. } => write!(f, "FreeBSD"), Self::FreeBsd { .. } => write!(f, "freebsd"),
Self::NetBsd { .. } => write!(f, "NetBSD"), Self::NetBsd { .. } => write!(f, "netbsd"),
Self::OpenBsd { .. } => write!(f, "OpenBSD"), Self::OpenBsd { .. } => write!(f, "openbsd"),
Self::Dragonfly { .. } => write!(f, "DragonFly"), Self::Dragonfly { .. } => write!(f, "dragonfly"),
Self::Illumos { .. } => write!(f, "Illumos"), Self::Illumos { .. } => write!(f, "illumos"),
Self::Haiku { .. } => write!(f, "Haiku"), Self::Haiku { .. } => write!(f, "haiku"),
Self::Android { .. } => write!(f, "Android"), Self::Android { .. } => write!(f, "android"),
} }
} }
} }

View file

@ -21,7 +21,7 @@ pub enum TagsError {
GilIsACPythonProblem(String), GilIsACPythonProblem(String),
} }
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Clone)] #[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Copy, Clone)]
pub enum IncompatibleTag { pub enum IncompatibleTag {
/// The tag is invalid and cannot be used. /// The tag is invalid and cannot be used.
Invalid, Invalid,
@ -35,7 +35,7 @@ pub enum IncompatibleTag {
Platform, Platform,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum TagCompatibility { pub enum TagCompatibility {
Incompatible(IncompatibleTag), Incompatible(IncompatibleTag),
Compatible(TagPriority), Compatible(TagPriority),
@ -59,6 +59,7 @@ impl PartialOrd for TagCompatibility {
} }
impl TagCompatibility { impl TagCompatibility {
/// Returns `true` if the tag is compatible.
pub fn is_compatible(&self) -> bool { pub fn is_compatible(&self) -> bool {
matches!(self, Self::Compatible(_)) matches!(self, Self::Compatible(_))
} }
@ -128,7 +129,7 @@ impl Tags {
if let Implementation::CPython { gil_disabled } = implementation { if let Implementation::CPython { gil_disabled } = implementation {
// For some reason 3.2 is the minimum python for the cp abi // For some reason 3.2 is the minimum python for the cp abi
for minor in (2..=python_version.1).rev() { for minor in (2..=python_version.1).rev() {
// No abi3 for freethreading python // No abi3 for free-threading python
if !gil_disabled { if !gil_disabled {
for platform_tag in &platform_tags { for platform_tag in &platform_tags {
tags.push(( tags.push((
@ -406,8 +407,6 @@ impl Implementation {
/// ///
/// We have two cases: Actual platform specific tags (including "merged" tags such as universal2) /// We have two cases: Actual platform specific tags (including "merged" tags such as universal2)
/// and "any". /// and "any".
///
/// Bit of a mess, needs to be cleaned up.
fn compatible_tags(platform: &Platform) -> Result<Vec<String>, PlatformError> { fn compatible_tags(platform: &Platform) -> Result<Vec<String>, PlatformError> {
let os = platform.os(); let os = platform.os();
let arch = platform.arch(); let arch = platform.arch();
@ -431,13 +430,13 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<String>, PlatformError> {
} }
} }
} }
// Non-manylinux is lowest priority // Non-manylinux is given lowest priority.
// <https://github.com/pypa/packaging/blob/fd4f11139d1c884a637be8aa26bb60a31fbc9411/packaging/tags.py#L444> // <https://github.com/pypa/packaging/blob/fd4f11139d1c884a637be8aa26bb60a31fbc9411/packaging/tags.py#L444>
platform_tags.push(format!("linux_{arch}")); platform_tags.push(format!("linux_{arch}"));
platform_tags platform_tags
} }
(Os::Musllinux { major, minor }, _) => { (Os::Musllinux { major, minor }, _) => {
let mut platform_tags = vec![format!("linux_{}", arch)]; let mut platform_tags = vec![format!("linux_{arch}")];
// musl 1.1 is the lowest supported version in musllinux // musl 1.1 is the lowest supported version in musllinux
platform_tags platform_tags
.extend((1..=*minor).map(|minor| format!("musllinux_{major}_{minor}_{arch}"))); .extend((1..=*minor).map(|minor| format!("musllinux_{major}_{minor}_{arch}")));
@ -516,12 +515,7 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<String>, PlatformError> {
_, _,
) => { ) => {
let release = release.replace(['.', '-'], "_"); let release = release.replace(['.', '-'], "_");
vec![format!( vec![format!("{os}_{release}_{arch}")]
"{}_{}_{}",
os.to_string().to_lowercase(),
release,
arch
)]
} }
(Os::Illumos { release, arch }, _) => { (Os::Illumos { release, arch }, _) => {
// See https://github.com/python/cpython/blob/46c8d915715aa2bd4d697482aa051fe974d440e1/Lib/sysconfig.py#L722-L730 // See https://github.com/python/cpython/blob/46c8d915715aa2bd4d697482aa051fe974d440e1/Lib/sysconfig.py#L722-L730
@ -533,23 +527,17 @@ fn compatible_tags(platform: &Platform) -> Result<Vec<String>, PlatformError> {
})?; })?;
if major_ver >= 5 { if major_ver >= 5 {
// SunOS 5 == Solaris 2 // SunOS 5 == Solaris 2
let os = "solaris".to_string(); let os = "solaris";
let release = format!("{}_{}", major_ver - 3, other); let release = format!("{}_{}", major_ver - 3, other);
let arch = format!("{arch}_64bit"); let arch = format!("{arch}_64bit");
return Ok(vec![format!("{}_{}_{}", os, release, arch)]); return Ok(vec![format!("{os}_{release}_{arch}")]);
} }
} }
let os = os.to_string().to_lowercase(); vec![format!("{os}_{release}_{arch}")]
vec![format!("{}_{}_{}", os, release, arch)]
} }
(Os::Android { api_level }, _) => { (Os::Android { api_level }, _) => {
vec![format!( vec![format!("{os}_{api_level}_{arch}")]
"{}_{}_{}",
os.to_string().to_lowercase(),
api_level,
arch
)]
} }
_ => { _ => {
return Err(PlatformError::OsVersionDetectionError(format!( return Err(PlatformError::OsVersionDetectionError(format!(

View file

@ -521,14 +521,22 @@ impl VersionMapLazy {
} }
// Determine a compatibility for the wheel based on tags. // Determine a compatibility for the wheel based on tags.
let priority = match &self.tags { let priority = if let Some(tags) = &self.tags {
Some(tags) => match filename.compatibility(tags) { match filename.compatibility(tags) {
TagCompatibility::Incompatible(tag) => { TagCompatibility::Incompatible(tag) => {
return WheelCompatibility::Incompatible(IncompatibleWheel::Tag(tag)) return WheelCompatibility::Incompatible(IncompatibleWheel::Tag(tag))
} }
TagCompatibility::Compatible(priority) => Some(priority), TagCompatibility::Compatible(priority) => Some(priority),
}, }
None => None, } else {
// Check if the wheel is compatible with the `requires-python` (i.e., the Python
// ABI tag is not less than the `requires-python` minimum version).
if !self.requires_python.matches_wheel_tag(filename) {
return WheelCompatibility::Incompatible(IncompatibleWheel::Tag(
IncompatibleTag::AbiPythonVersion,
));
}
None
}; };
// Check if hashes line up. If hashes aren't required, they're considered matching. // Check if hashes line up. If hashes aren't required, they're considered matching.
@ -546,14 +554,6 @@ impl VersionMapLazy {
} }
}; };
// Check if the wheel is compatible with the `requires-python` (i.e., the Python ABI tag
// is not less than the `requires-python` minimum version).
if !self.requires_python.matches_wheel_tag(filename) {
return WheelCompatibility::Incompatible(IncompatibleWheel::Tag(
IncompatibleTag::AbiPythonVersion,
));
}
// Break ties with the build tag. // Break ties with the build tag.
let build_tag = filename.build_tag.clone(); let build_tag = filename.build_tag.clone();