pypy/graalpy: set Py_LIMITED_API when abi3 requested (#4237)

* pypy/graalpy: set `Py_LIMITED_API` when `abi3` requested

* add newsfragment
This commit is contained in:
David Hewitt 2024-06-10 08:26:05 +01:00 committed by GitHub
parent d2dca2169c
commit f66124a79b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 50 additions and 33 deletions

View file

@ -0,0 +1 @@
Respect the Python "limited API" when building for the `abi3` feature on PyPy or GraalPy.

View file

@ -26,7 +26,7 @@ use target_lexicon::{Environment, OperatingSystem};
use crate::{
bail, ensure,
errors::{Context, Error, Result},
format_warn, warn,
warn,
};
/// Minimum Python version PyO3 supports.
@ -171,20 +171,13 @@ impl InterpreterConfig {
out.push(format!("cargo:rustc-cfg=Py_3_{}", i));
}
if self.implementation.is_pypy() {
out.push("cargo:rustc-cfg=PyPy".to_owned());
if self.abi3 {
out.push(format_warn!(
"PyPy does not yet support abi3 so the build artifacts will be version-specific. \
See https://foss.heptapod.net/pypy/pypy/-/issues/3397 for more information."
));
}
} else if self.implementation.is_graalpy() {
println!("cargo:rustc-cfg=GraalPy");
if self.abi3 {
warn!("GraalPy does not support abi3 so the build artifacts will be version-specific.");
}
} else if self.abi3 {
match self.implementation {
PythonImplementation::CPython => {}
PythonImplementation::PyPy => out.push("cargo:rustc-cfg=PyPy".to_owned()),
PythonImplementation::GraalPy => out.push("cargo:rustc-cfg=GraalPy".to_owned()),
}
if self.abi3 {
out.push("cargo:rustc-cfg=Py_LIMITED_API".to_owned());
}
@ -2722,10 +2715,7 @@ mod tests {
"cargo:rustc-cfg=Py_3_6".to_owned(),
"cargo:rustc-cfg=Py_3_7".to_owned(),
"cargo:rustc-cfg=PyPy".to_owned(),
"cargo:warning=PyPy does not yet support abi3 so the build artifacts \
will be version-specific. See https://foss.heptapod.net/pypy/pypy/-/issues/3397 \
for more information."
.to_owned(),
"cargo:rustc-cfg=Py_LIMITED_API".to_owned(),
]
);
}

View file

@ -4,7 +4,7 @@ use pyo3_build_config::{
cargo_env_var, env_var, errors::Result, is_linking_libpython, resolve_interpreter_config,
InterpreterConfig, PythonVersion,
},
PythonImplementation,
warn, PythonImplementation,
};
/// Minimum Python version PyO3 supports.
@ -104,6 +104,19 @@ fn ensure_python_version(interpreter_config: &InterpreterConfig) -> Result<()> {
}
}
if interpreter_config.abi3 {
match interpreter_config.implementation {
PythonImplementation::CPython => {}
PythonImplementation::PyPy => warn!(
"PyPy does not yet support abi3 so the build artifacts will be version-specific. \
See https://foss.heptapod.net/pypy/pypy/-/issues/3397 for more information."
),
PythonImplementation::GraalPy => warn!(
"GraalPy does not support abi3 so the build artifacts will be version-specific."
),
}
}
Ok(())
}

View file

@ -135,13 +135,9 @@ extern "C" {
}
#[inline]
#[cfg(not(GraalPy))]
#[cfg(not(any(PyPy, GraalPy)))]
pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject {
#[cfg(not(PyPy))]
return Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1);
#[cfg(PyPy)]
Py_CompileStringFlags(string, p, s, std::ptr::null_mut())
Py_CompileStringExFlags(string, p, s, std::ptr::null_mut(), -1)
}
#[inline]

View file

@ -1,7 +1,7 @@
use crate::object::*;
#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))]
use libc::FILE;
#[cfg(all(not(PyPy), any(Py_LIMITED_API, not(Py_3_10), GraalPy)))]
#[cfg(any(Py_LIMITED_API, not(Py_3_10), PyPy, GraalPy))]
use std::os::raw::c_char;
use std::os::raw::c_int;
@ -20,6 +20,28 @@ extern "C" {
pub fn PyErr_DisplayException(exc: *mut PyObject);
}
#[inline]
#[cfg(PyPy)]
pub unsafe fn Py_CompileString(string: *const c_char, p: *const c_char, s: c_int) -> *mut PyObject {
// PyPy's implementation of Py_CompileString always forwards to Py_CompileStringFlags; this
// is only available in the non-limited API and has a real definition for all versions in
// the cpython/ subdirectory.
#[cfg(Py_LIMITED_API)]
extern "C" {
#[link_name = "PyPy_CompileStringFlags"]
pub fn Py_CompileStringFlags(
string: *const c_char,
p: *const c_char,
s: c_int,
f: *mut std::os::raw::c_void, // Actually *mut Py_CompilerFlags in the real definition
) -> *mut PyObject;
}
#[cfg(not(Py_LIMITED_API))]
use crate::Py_CompileStringFlags;
Py_CompileStringFlags(string, p, s, std::ptr::null_mut())
}
// skipped PyOS_InputHook
pub const PYOS_STACK_MARGIN: c_int = 2048;

View file

@ -2,10 +2,7 @@ use crate::ffi::*;
use crate::types::any::PyAnyMethods;
use crate::Python;
#[cfg(all(PyPy, feature = "macros"))]
use crate::types::PyString;
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
#[cfg(all(not(Py_LIMITED_API), any(not(PyPy), feature = "macros")))]
use crate::types::PyString;
#[cfg(not(Py_LIMITED_API))]
@ -164,7 +161,6 @@ fn ascii_object_bitfield() {
#[test]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
#[cfg_attr(Py_3_10, allow(deprecated))]
fn ascii() {
Python::with_gil(|py| {
// This test relies on implementation details of PyString.
@ -206,7 +202,6 @@ fn ascii() {
#[test]
#[cfg(not(any(Py_LIMITED_API, PyPy)))]
#[cfg_attr(Py_3_10, allow(deprecated))]
fn ucs4() {
Python::with_gil(|py| {
let s = "哈哈🐈";