diff --git a/src/binding_generator/pyo3_binding.rs b/src/binding_generator/pyo3_binding.rs index c109d2c30..2c8d5ef62 100644 --- a/src/binding_generator/pyo3_binding.rs +++ b/src/binding_generator/pyo3_binding.rs @@ -38,6 +38,7 @@ pub struct Pyo3BindingGenerator<'a> { enum BindingType<'a> { Abi3(Option<&'a PythonInterpreter>), + Abi3t(Option<&'a PythonInterpreter>), VersionSpecific(&'a PythonInterpreter), } @@ -50,6 +51,7 @@ impl<'a> Pyo3BindingGenerator<'a> { let binding_type = match stable_abi { Some(kind) => match kind { StableAbiKind::Abi3 => BindingType::Abi3(interpreter), + StableAbiKind::Abi3t => BindingType::Abi3t(interpreter), }, None => { let interpreter = interpreter.ok_or_else(|| { @@ -102,6 +104,7 @@ impl<'a> BindingGenerator for Pyo3BindingGenerator<'a> { let so_filename = match self.binding_type { BindingType::Abi3(interpreter) => ext_suffix(target, interpreter, ext_name, "abi3"), + BindingType::Abi3t(interpreter) => ext_suffix(target, interpreter, ext_name, "abi3t"), BindingType::VersionSpecific(interpreter) => interpreter.get_library_name(ext_name), }; let artifact_target = ArtifactTarget::ExtensionModule(module.join(so_filename)); diff --git a/src/bridge/detection.rs b/src/bridge/detection.rs index 447074956..2161995be 100644 --- a/src/bridge/detection.rs +++ b/src/bridge/detection.rs @@ -184,7 +184,7 @@ fn has_stable_abi( if abi3.is_some() { return Ok(abi3); } - Ok(None) + has_stable_abi_from_kind(deps, extra_features, StableAbiKind::Abi3t) } /// pyo3 supports building stable abi wheels if the unstable-api feature is not selected diff --git a/src/bridge/mod.rs b/src/bridge/mod.rs index cd45f35ad..adc777e46 100644 --- a/src/bridge/mod.rs +++ b/src/bridge/mod.rs @@ -131,6 +131,14 @@ impl StableAbi { version: StableAbiVersion::Version(major, minor), } } + + /// Create a StableAbi instance from a known abi3t version + pub fn from_abi3t_version(major: u8, minor: u8) -> StableAbi { + StableAbi { + kind: StableAbiKind::Abi3t, + version: StableAbiVersion::Version(major, minor), + } + } } /// Python version to use as the abi3/abi3t target. @@ -145,7 +153,7 @@ pub enum StableAbiVersion { } impl StableAbiVersion { - /// Convert `StableAbiVersion` into an Option, where CurrentPython maps None + /// Convert `StableAbiVersion` into an Option, where CurrentPython maps to None pub fn min_version(&self) -> Option<(u8, u8)> { match self { StableAbiVersion::CurrentPython => None, @@ -159,12 +167,15 @@ impl StableAbiVersion { pub enum StableAbiKind { /// The original stable ABI, supporting Python 3.2 and up Abi3, + /// The free-threaded stable ABI, supporting Python 3.15 and up + Abi3t, } impl fmt::Display for StableAbiKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { StableAbiKind::Abi3 => write!(f, "abi3"), + StableAbiKind::Abi3t => write!(f, "abi3t"), } } } @@ -174,6 +185,7 @@ impl StableAbiKind { pub fn wheel_tag(&self) -> &str { match self { StableAbiKind::Abi3 => "abi3", + StableAbiKind::Abi3t => "abi3.abi3t", } } } @@ -341,6 +353,7 @@ impl BridgeModel { .and_then(|pyo3| match pyo3.stable_abi { Some(stable_abi) => match stable_abi.kind { StableAbiKind::Abi3 => Some(true), + _ => None, }, None => None, }) diff --git a/src/build_orchestrator.rs b/src/build_orchestrator.rs index 8d76ec2df..c71a8d4ff 100644 --- a/src/build_orchestrator.rs +++ b/src/build_orchestrator.rs @@ -286,15 +286,15 @@ impl<'a> BuildOrchestrator<'a> { let interp = &self.context.python.interpreter[0]; match bindings.stable_abi { Some(stable_abi) => { - let wheel_tag = stable_abi.kind.wheel_tag(); + let abi_tag = stable_abi.kind.wheel_tag(); match stable_abi.version { StableAbiVersion::Version(major, minor) => { - vec![format!("cp{major}{minor}-{wheel_tag}-{platform}")] + vec![format!("cp{major}{minor}-{abi_tag}-{platform}")] } StableAbiVersion::CurrentPython => { vec![format!( - "cp{major}{minor}-{wheel_tag}-{platform}", + "cp{major}{minor}-{abi_tag}-{platform}", major = interp.major, minor = interp.minor )]