From b24d01dc1864133b6b412138068d16763ecfc135 Mon Sep 17 00:00:00 2001 From: messense Date: Mon, 13 Jan 2025 19:17:27 +0800 Subject: [PATCH] Consider abi3 minor version when resolving Python interpreters --- src/bridge.rs | 34 ++++++++++++++++++++++++++++++++-- src/python_interpreter/mod.rs | 23 ++++++----------------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/bridge.rs b/src/bridge.rs index 3825fa81b..dd87bc4fd 100644 --- a/src/bridge.rs +++ b/src/bridge.rs @@ -1,5 +1,7 @@ use std::fmt::{Display, Formatter}; +use crate::python_interpreter::{MINIMUM_PYPY_MINOR, MINIMUM_PYTHON_MINOR}; + /// The name and version of the bindings crate #[derive(Clone, Debug, PartialEq, Eq)] pub struct Bindings { @@ -11,7 +13,7 @@ pub struct Bindings { impl Bindings { /// Returns the minimum python minor version supported - pub fn minimal_python_minor_version(&self) -> usize { + fn minimal_python_minor_version(&self) -> usize { use crate::python_interpreter::MINIMUM_PYTHON_MINOR; match self.name.as_str() { @@ -30,7 +32,7 @@ impl Bindings { } /// Returns the minimum PyPy minor version supported - pub fn minimal_pypy_minor_version(&self) -> usize { + fn minimal_pypy_minor_version(&self) -> usize { use crate::python_interpreter::MINIMUM_PYPY_MINOR; match self.name.as_str() { @@ -121,6 +123,34 @@ impl BridgeModel { matches!(self, BridgeModel::Bin(_)) } + /// Returns the minimum python minor version supported + pub fn minimal_python_minor_version(&self) -> usize { + match self { + BridgeModel::Bin(Some(bindings)) | BridgeModel::Bindings(bindings) => { + bindings.minimal_python_minor_version() + } + BridgeModel::BindingsAbi3 { + bindings, + minor: abi3_minor, + .. + } => { + let bindings_minor = bindings.minimal_python_minor_version(); + bindings_minor.max(*abi3_minor as usize) + } + BridgeModel::Bin(None) | BridgeModel::Cffi | BridgeModel::UniFfi => { + MINIMUM_PYTHON_MINOR + } + } + } + + /// Returns the minimum PyPy minor version supported + pub fn minimal_pypy_minor_version(&self) -> usize { + match self.bindings() { + Some(bindings) => bindings.minimal_pypy_minor_version(), + None => MINIMUM_PYPY_MINOR, + } + } + /// free-threaded Python support pub fn supports_free_threaded(&self) -> bool { match self { diff --git a/src/python_interpreter/mod.rs b/src/python_interpreter/mod.rs index 20e3afbc8..6a782f178 100644 --- a/src/python_interpreter/mod.rs +++ b/src/python_interpreter/mod.rs @@ -732,12 +732,11 @@ impl PythonInterpreter { requires_python: Option<&VersionSpecifiers>, bridge: Option<&BridgeModel>, ) -> Vec { - let bindings = bridge.and_then(|bridge| bridge.bindings()); - let min_python_minor = bindings - .map(|bindings| bindings.minimal_python_minor_version()) + let min_python_minor = bridge + .map(|bridge| bridge.minimal_python_minor_version()) .unwrap_or(MINIMUM_PYTHON_MINOR); - let min_pypy_minor = bindings - .map(|bindings| bindings.minimal_pypy_minor_version()) + let min_pypy_minor = bridge + .map(|bridge| bridge.minimal_pypy_minor_version()) .unwrap_or(MINIMUM_PYPY_MINOR); let supports_free_threaded = bridge .map(|bridge| bridge.supports_free_threaded()) @@ -794,18 +793,8 @@ impl PythonInterpreter { bridge: &BridgeModel, requires_python: Option<&VersionSpecifiers>, ) -> Result> { - let min_python_minor = match bridge { - BridgeModel::Bindings(bindings) | BridgeModel::Bin(Some(bindings)) => { - bindings.minimal_python_minor_version() - } - _ => MINIMUM_PYTHON_MINOR, - }; - let min_pypy_minor = match bridge { - BridgeModel::Bindings(bindings) | BridgeModel::Bin(Some(bindings)) => { - bindings.minimal_pypy_minor_version() - } - _ => MINIMUM_PYPY_MINOR, - }; + let min_python_minor = bridge.minimal_python_minor_version(); + let min_pypy_minor = bridge.minimal_pypy_minor_version(); let executables = if target.is_windows() { // TOFIX: add PyPy support to Windows find_all_windows(target, min_python_minor, requires_python)?