From ed8e3b32d6bcaa034e86595fdee8af5fbe1e56c4 Mon Sep 17 00:00:00 2001 From: messense Date: Sun, 4 Jun 2023 19:46:51 +0800 Subject: [PATCH] Refactor abi tag to use `EXT_SUFFIX` --- src/build_options.rs | 6 -- src/python_interpreter/config.rs | 53 ++++---------- .../get_interpreter_metadata.py | 18 ----- src/python_interpreter/mod.rs | 71 +++++++++++++++---- 4 files changed, 70 insertions(+), 78 deletions(-) diff --git a/src/build_options.rs b/src/build_options.rs index d69e41808..8327120c1 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -261,8 +261,6 @@ impl BuildOptions { .get("EXT_SUFFIX") .context("syconfig didn't define an `EXT_SUFFIX` ಠ_ಠ")?; let soabi = sysconfig_data.get("SOABI"); - let abi_tag = - soabi.and_then(|abi| abi.split('-').nth(1).map(ToString::to_string)); let interpreter_kind = soabi .and_then(|tag| { if tag.starts_with("pypy") { @@ -283,7 +281,6 @@ impl BuildOptions { interpreter_kind, abiflags, ext_suffix: ext_suffix.to_string(), - abi_tag, pointer_width: None, }, executable: PathBuf::new(), @@ -351,7 +348,6 @@ impl BuildOptions { interpreter_kind: InterpreterKind::CPython, abiflags: "".to_string(), ext_suffix: ".pyd".to_string(), - abi_tag: None, pointer_width: None, }, executable: PathBuf::new(), @@ -378,7 +374,6 @@ impl BuildOptions { interpreter_kind: InterpreterKind::CPython, abiflags: "".to_string(), ext_suffix: ".pyd".to_string(), - abi_tag: None, pointer_width: None, }, executable: PathBuf::new(), @@ -418,7 +413,6 @@ impl BuildOptions { interpreter_kind: InterpreterKind::CPython, abiflags: "".to_string(), ext_suffix: "".to_string(), - abi_tag: None, pointer_width: None, }, executable: PathBuf::new(), diff --git a/src/python_interpreter/config.rs b/src/python_interpreter/config.rs index 6ff3600f1..e7c6b7059 100644 --- a/src/python_interpreter/config.rs +++ b/src/python_interpreter/config.rs @@ -29,10 +29,6 @@ pub struct InterpreterConfig { pub abiflags: String, /// Suffix to use for extension modules as given by sysconfig. pub ext_suffix: String, - /// Part of sysconfig's SOABI specifying {major}{minor}{abiflags} - /// - /// Note that this always `None` on windows - pub abi_tag: Option, /// Pointer width pub pointer_width: Option, } @@ -78,10 +74,10 @@ impl InterpreterConfig { } else { "".to_string() }; - let abi_tag = format!("{}{}{}", major, minor, abiflags); + let ldversion = format!("{}{}{}", major, minor, abiflags); let ext_suffix = format!( ".cpython-{}-{}-linux-{}.so", - abi_tag, python_arch, target_env + ldversion, python_arch, target_env ); Some(Self { major, @@ -89,23 +85,18 @@ impl InterpreterConfig { interpreter_kind: CPython, abiflags, ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } (Os::Linux, PyPy) => { - let abi_tag = PYPY_ABI_TAG.to_string(); - let ext_suffix = format!( - ".pypy{}{}-{}-{}-linux-{}.so", - major, minor, abi_tag, python_arch, target_env - ); + let abi_tag = format!("pypy{}{}-{}", major, minor, PYPY_ABI_TAG); + let ext_suffix = format!(".{}-{}-linux-{}.so", abi_tag, python_arch, target_env); Some(Self { major, minor, interpreter_kind: PyPy, abiflags: String::new(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } @@ -115,28 +106,25 @@ impl InterpreterConfig { } else { "".to_string() }; - let abi_tag = format!("{}{}{}", major, minor, abiflags); - let ext_suffix = format!(".cpython-{}-darwin.so", abi_tag); + let ldversion = format!("{}{}{}", major, minor, abiflags); + let ext_suffix = format!(".cpython-{}-darwin.so", ldversion); Some(Self { major, minor, interpreter_kind: CPython, abiflags, ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } (Os::Macos, PyPy) => { - let abi_tag = PYPY_ABI_TAG.to_string(); - let ext_suffix = format!(".pypy{}{}-{}-darwin.so", major, minor, abi_tag); + let ext_suffix = format!(".pypy{}{}-{}-darwin.so", major, minor, PYPY_ABI_TAG); Some(Self { major, minor, interpreter_kind: PyPy, abiflags: String::new(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } @@ -158,7 +146,6 @@ impl InterpreterConfig { interpreter_kind: CPython, abiflags: String::new(), ext_suffix, - abi_tag: None, pointer_width: Some(target.pointer_width()), }) } @@ -167,15 +154,13 @@ impl InterpreterConfig { // PyPy on Windows only supports x86_64 return None; } - let abi_tag = PYPY_ABI_TAG.to_string(); - let ext_suffix = format!(".pypy{}{}-{}-win_amd64.pyd", major, minor, abi_tag); + let ext_suffix = format!(".pypy{}{}-{}-win_amd64.pyd", major, minor, PYPY_ABI_TAG); Some(Self { major, minor, interpreter_kind: PyPy, abiflags: String::new(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } @@ -185,19 +170,16 @@ impl InterpreterConfig { } else { ("".to_string(), format!(".cpython-{}{}.so", major, minor)) }; - let abi_tag = format!("{}{}{}", major, minor, abiflags); Some(Self { major, minor, interpreter_kind: CPython, abiflags, ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } (Os::NetBsd, CPython) => { - let abi_tag = format!("{}{}", major, minor); let ext_suffix = ".so".to_string(); Some(Self { major, @@ -205,33 +187,30 @@ impl InterpreterConfig { interpreter_kind: CPython, abiflags: String::new(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } (Os::OpenBsd, CPython) => { - let abi_tag = format!("{}{}", major, minor); - let ext_suffix = format!(".cpython-{}.so", abi_tag); + let ldversion = format!("{}{}", major, minor); + let ext_suffix = format!(".cpython-{}.so", ldversion); Some(Self { major, minor, interpreter_kind: CPython, abiflags: String::new(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } (Os::Emscripten, CPython) => { - let abi_tag = format!("{}{}", major, minor); - let ext_suffix = format!(".cpython-{}-{}-emscripten.so", abi_tag, python_arch); + let ldversion = format!("{}{}", major, minor); + let ext_suffix = format!(".cpython-{}-{}-emscripten.so", ldversion, python_arch); Some(Self { major, minor, interpreter_kind: CPython, abiflags: String::new(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width: Some(target.pointer_width()), }) } @@ -382,7 +361,6 @@ impl InterpreterConfig { interpreter_kind, abiflags: abiflags.unwrap_or_default(), ext_suffix, - abi_tag: Some(abi_tag), pointer_width, }) } @@ -482,7 +460,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, ""); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("pp73")); assert_eq!(sysconfig.ext_suffix, ".pypy39-pp73-x86_64-linux-gnu.so"); let sysconfig = InterpreterConfig::lookup_one( @@ -560,7 +537,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, "m"); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("37m")); assert_eq!(sysconfig.ext_suffix, ".cpython-37m-darwin.so"); // PyPy @@ -571,7 +547,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, ""); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("pp73")); assert_eq!(sysconfig.ext_suffix, ".pypy39-pp73-darwin.so"); let sysconfig = InterpreterConfig::lookup_one( @@ -630,7 +605,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, "m"); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("37m")); assert_eq!(sysconfig.ext_suffix, ".so"); let sysconfig = InterpreterConfig::lookup_one( @@ -640,7 +614,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, ""); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("310")); assert_eq!(sysconfig.ext_suffix, ".cpython-310.so"); let sysconfig = InterpreterConfig::lookup_one( @@ -678,7 +651,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, ""); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("37")); assert_eq!(sysconfig.ext_suffix, ".so"); let sysconfig = InterpreterConfig::lookup_one( @@ -728,7 +700,6 @@ mod test { ) .unwrap(); assert_eq!(sysconfig.abiflags, ""); - assert_eq!(sysconfig.abi_tag.as_deref(), Some("310")); assert_eq!(sysconfig.ext_suffix, ".cpython-310-wasm32-emscripten.so"); } diff --git a/src/python_interpreter/get_interpreter_metadata.py b/src/python_interpreter/get_interpreter_metadata.py index 438304056..badd65528 100644 --- a/src/python_interpreter/get_interpreter_metadata.py +++ b/src/python_interpreter/get_interpreter_metadata.py @@ -19,23 +19,6 @@ else: ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") - -def get_abi_tag(): - # This should probably return the ABI tag based on EXT_SUFFIX in the same - # way as pypa/packaging. See https://github.com/pypa/packaging/pull/607. - # For simplicity, we just fix it up for GraalPy for now and leave the logic - # for the other interpreters untouched, but this should be fixed properly - # down the road. - if platform.python_implementation() == "GraalVM": - ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") - parts = ext_suffix.split(".") - soabi = parts[1] - abi = "-".join(soabi.split("-")[:3]) - return abi.replace(".", "_").replace("-", "_") - else: - return (sysconfig.get_config_var("SOABI") or "-").split("-")[1] - - metadata = { # sys.implementation.name can differ from platform.python_implementation(), for example # Pyston has sys.implementation.name == "pyston" while platform.python_implementation() == cpython @@ -47,7 +30,6 @@ def get_abi_tag(): "interpreter": platform.python_implementation().lower(), "ext_suffix": ext_suffix, "soabi": sysconfig.get_config_var("SOABI") or None, - "abi_tag": get_abi_tag() or None, "platform": sysconfig.get_platform(), # This one isn't technically necessary, but still very useful for sanity checks "system": platform.system().lower(), diff --git a/src/python_interpreter/mod.rs b/src/python_interpreter/mod.rs index ef559257f..ed1dcde53 100644 --- a/src/python_interpreter/mod.rs +++ b/src/python_interpreter/mod.rs @@ -277,7 +277,6 @@ fn windows_python_info(executable: &Path) -> Result> { interpreter_kind: InterpreterKind::CPython, abiflags: String::new(), ext_suffix: String::new(), - abi_tag: None, pointer_width: Some(pointer_width), })) } else { @@ -349,7 +348,6 @@ struct InterpreterMetadataMessage { // comes from `platform.system()` system: String, soabi: Option, - abi_tag: Option, } /// The location and version of an interpreter @@ -513,14 +511,11 @@ impl PythonInterpreter { // pypy uses its version as part of the ABI, e.g. // pypy 3.7 7.3 => numpy-1.20.1-pp37-pypy37_pp73-manylinux2014_x86_64.whl format!( - "pp{major}{minor}-pypy{major}{minor}_{abi_tag}-{platform}", + "pp{major}{minor}-{abi_tag}-{platform}", major = self.major, minor = self.minor, - // TODO: Proper tag handling for pypy - abi_tag = self - .abi_tag - .clone() - .expect("PyPy's syconfig didn't define an `SOABI` ಠ_ಠ"), + abi_tag = calculate_abi_tag(&self.ext_suffix) + .expect("PyPy's syconfig didn't define a valid `EXT_SUFFIX` ಠ_ಠ"), platform = platform, ) } @@ -533,10 +528,8 @@ impl PythonInterpreter { "graalpy{major}{minor}-{abi_tag}_{arch}_{os}-{os}_i686", major = self.major, minor = self.minor, - abi_tag = self - .abi_tag - .clone() - .expect("GraalPy's syconfig didn't define an `EXT_SUFFIX` ಠ_ಠ"), + abi_tag = calculate_abi_tag(&self.ext_suffix) + .expect("GraalPy's syconfig didn't define a valid `EXT_SUFFIX` ಠ_ಠ"), os = target.get_python_os(), arch = target.get_python_arch(), ) @@ -696,7 +689,6 @@ impl PythonInterpreter { ext_suffix: message .ext_suffix .context("syconfig didn't define an `EXT_SUFFIX` ಠ_ಠ")?, - abi_tag: message.abi_tag, pointer_width: None, }, executable, @@ -955,6 +947,35 @@ impl fmt::Display for PythonInterpreter { } } +/// Calculate the ABI tag from EXT_SUFFIX +fn calculate_abi_tag(ext_suffix: &str) -> Option { + let parts = ext_suffix.split('.').collect::>(); + if parts.len() < 3 { + // CPython3.7 and earlier uses ".pyd" on Windows. + return None; + } + let soabi = parts[1]; + let mut soabi_split = soabi.split('-'); + let abi = if soabi.starts_with("cpython") { + // non-windows + format!("cp{}", soabi_split.nth(1).unwrap()) + } else if soabi.starts_with("cp") { + // windows + soabi_split.next().unwrap().to_string() + } else if soabi.starts_with("pypy") { + soabi_split.take(2).collect::>().join("-") + } else if soabi.starts_with("graalpy") { + soabi_split.take(3).collect::>().join("-") + } else if !soabi.is_empty() { + // pyston, ironpython, others? + soabi_split.nth(1).unwrap().to_string() + } else { + return None; + }; + let abi_tag = abi.replace(['.', '-', ' '], "_"); + Some(abi_tag) +} + #[cfg(test)] mod tests { use super::*; @@ -978,4 +999,28 @@ mod tests { ); assert_eq!(pythons.len(), 4); } + + #[test] + fn test_calculate_abi_tag() { + let cases = vec![ + (".cpython-37m-x86_64-linux-gnu.so", Some("cp37m")), + (".cpython-310-x86_64-linux-gnu.so", Some("cp310")), + (".cpython-310-darwin.so", Some("cp310")), + (".cp310-win_amd64.pyd", Some("cp310")), + (".cp39-mingw_x86_64.pyd", Some("cp39")), + (".cpython-312-wasm32-wasi.so", Some("cp312")), + (".cpython-38.so", Some("cp38")), + (".pyd", None), + (".so", None), + (".pypy38-pp73-x86_64-linux-gnu.so", Some("pypy38_pp73")), + ( + ".graalpy-38-native-x86_64-darwin.dylib", + Some("graalpy_38_native"), + ), + (".pyston-23-x86_64-linux-gnu.so", Some("23")), + ]; + for (ext_suffix, expected) in cases { + assert_eq!(calculate_abi_tag(ext_suffix).as_deref(), expected); + } + } }