Skip to content

Commit

Permalink
pypy/graalpy: set Py_LIMITED_API when abi3 requested (#4237)
Browse files Browse the repository at this point in the history
* pypy/graalpy: set `Py_LIMITED_API` when `abi3` requested

* add newsfragment
  • Loading branch information
davidhewitt committed Jun 10, 2024
1 parent d2dca21 commit f66124a
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 33 deletions.
1 change: 1 addition & 0 deletions newsfragments/4237.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Respect the Python "limited API" when building for the `abi3` feature on PyPy or GraalPy.
28 changes: 9 additions & 19 deletions pyo3-build-config/src/impl_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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());
}

Expand Down Expand Up @@ -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(),
]
);
}
Expand Down
15 changes: 14 additions & 1 deletion pyo3-ffi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(())
}

Expand Down
8 changes: 2 additions & 6 deletions pyo3-ffi/src/cpython/pythonrun.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
24 changes: 23 additions & 1 deletion pyo3-ffi/src/pythonrun.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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;
Expand Down
7 changes: 1 addition & 6 deletions src/ffi/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 = "哈哈🐈";
Expand Down

0 comments on commit f66124a

Please sign in to comment.