Skip to content

Commit

Permalink
Add PyPy3.11 (#4760)
Browse files Browse the repository at this point in the history
* allow pypy3.11

* run CI on pypy3.11

* change const declaration

* change link name for PyExc_BaseExceptionGroup

* PyObject_DelAttr* are inline functions on pypy3.11

* use nightly until official release

* DOC: add a news fragment

* conditionally compile 'use' statements

* fix format

* changes from review

* pypy 3.11 released

* fixes for PyPy

* typo

* exclude _PyInterpreterFrame on PyPy

* more pypy fixes

* more excluding _PyFrameEvalFunction on PyPy

* fixes for PyPy struct differences

* format

* fix test

---------

Co-authored-by: Icxolu <[email protected]>
  • Loading branch information
2 people authored and davidhewitt committed Feb 20, 2025
1 parent f2a8460 commit ce2d6e9
Show file tree
Hide file tree
Showing 17 changed files with 35 additions and 22 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ jobs:
"3.13",
"pypy3.9",
"pypy3.10",
"pypy3.11",
"graalpy24.0",
]
platform:
Expand Down
1 change: 1 addition & 0 deletions newsfragments/4760.packaging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add support for PyPy3.11
6 changes: 3 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
PYO3_GUIDE_TARGET = PYO3_TARGET / "guide"
PYO3_DOCS_TARGET = PYO3_TARGET / "doc"
PY_VERSIONS = ("3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13")
PYPY_VERSIONS = ("3.9", "3.10")
PYPY_VERSIONS = ("3.9", "3.10", "3.11")
FREE_THREADED_BUILD = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))


Expand Down Expand Up @@ -673,8 +673,8 @@ def test_version_limits(session: nox.Session):
config_file.set("PyPy", "3.8")
_run_cargo(session, "check", env=env, expect_error=True)

assert "3.11" not in PYPY_VERSIONS
config_file.set("PyPy", "3.11")
assert "3.12" not in PYPY_VERSIONS
config_file.set("PyPy", "3.12")
_run_cargo(session, "check", env=env, expect_error=True)


Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const SUPPORTED_VERSIONS_PYPY: SupportedVersions = SupportedVersions {
min: PythonVersion { major: 3, minor: 9 },
max: PythonVersion {
major: 3,
minor: 10,
minor: 11,
},
};

Expand Down
10 changes: 8 additions & 2 deletions pyo3-ffi/src/abstract_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ use crate::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int};

#[inline]
#[cfg(all(not(Py_3_13), not(PyPy)))] // CPython exposed as a function in 3.13, in object.h
#[cfg(all(
not(Py_3_13), // CPython exposed as a function in 3.13, in object.h
not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+
))]
pub unsafe fn PyObject_DelAttrString(o: *mut PyObject, attr_name: *const c_char) -> c_int {
PyObject_SetAttrString(o, attr_name, std::ptr::null_mut())
}

#[inline]
#[cfg(all(not(Py_3_13), not(PyPy)))] // CPython exposed as a function in 3.13, in object.h
#[cfg(all(
not(Py_3_13), // CPython exposed as a function in 3.13, in object.h
not(all(PyPy, not(Py_3_11))) // PyPy exposed as a function until PyPy 3.10, macro in 3.11+
))]
pub unsafe fn PyObject_DelAttr(o: *mut PyObject, attr_name: *mut PyObject) -> c_int {
PyObject_SetAttr(o, attr_name, std::ptr::null_mut())
}
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/abstract_.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{PyObject, Py_ssize_t};
#[cfg(not(all(Py_3_11, GraalPy)))]
#[cfg(any(all(Py_3_8, not(any(PyPy, GraalPy))), not(Py_3_11)))]
use std::os::raw::c_char;
use std::os::raw::c_int;

Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/genobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::object::*;
use crate::PyFrameObject;
#[cfg(not(any(PyPy, GraalPy)))]
use crate::_PyErr_StackItem;
#[cfg(all(Py_3_11, not(GraalPy)))]
#[cfg(all(Py_3_11, not(any(PyPy, GraalPy))))]
use std::os::raw::c_char;
use std::os::raw::c_int;
use std::ptr::addr_of_mut;
Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub use self::object::*;
pub use self::objimpl::*;
pub use self::pydebug::*;
pub use self::pyerrors::*;
#[cfg(Py_3_11)]
#[cfg(all(Py_3_11, not(PyPy)))]
pub use self::pyframe::*;
#[cfg(all(Py_3_8, not(PyPy)))]
pub use self::pylifecycle::*;
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/cpython/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ pub struct PyHeapTypeObject {
pub ht_cached_keys: *mut c_void,
#[cfg(Py_3_9)]
pub ht_module: *mut object::PyObject,
#[cfg(Py_3_11)]
#[cfg(all(Py_3_11, not(PyPy)))]
_ht_tpname: *mut c_char,
#[cfg(Py_3_11)]
#[cfg(all(Py_3_11, not(PyPy)))]
_spec_cache: _specialization_cache,
}

Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/objimpl.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[cfg(not(all(Py_3_11, GraalPy)))]
#[cfg(not(all(Py_3_11, any(PyPy, GraalPy))))]
use libc::size_t;
use std::os::raw::c_int;

Expand Down
2 changes: 1 addition & 1 deletion pyo3-ffi/src/cpython/pyframe.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#[cfg(Py_3_11)]
#[cfg(all(Py_3_11, not(PyPy)))]
opaque_struct!(_PyInterpreterFrame);
6 changes: 3 additions & 3 deletions pyo3-ffi/src/cpython/pystate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,21 @@ extern "C" {
pub fn PyThreadState_DeleteCurrent();
}

#[cfg(all(Py_3_9, not(Py_3_11)))]
#[cfg(all(Py_3_9, not(any(Py_3_11, PyPy))))]
pub type _PyFrameEvalFunction = extern "C" fn(
*mut crate::PyThreadState,
*mut crate::PyFrameObject,
c_int,
) -> *mut crate::object::PyObject;

#[cfg(Py_3_11)]
#[cfg(all(Py_3_11, not(PyPy)))]
pub type _PyFrameEvalFunction = extern "C" fn(
*mut crate::PyThreadState,
*mut crate::_PyInterpreterFrame,
c_int,
) -> *mut crate::object::PyObject;

#[cfg(Py_3_9)]
#[cfg(all(Py_3_9, not(PyPy)))]
extern "C" {
/// Get the frame evaluation function.
pub fn _PyInterpreterState_GetEvalFrameFunc(
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/cpython/unicodeobject.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[cfg(not(PyPy))]
#[cfg(any(Py_3_11, not(PyPy)))]
use crate::Py_hash_t;
use crate::{PyObject, Py_UCS1, Py_UCS2, Py_UCS4, Py_ssize_t};
use libc::wchar_t;
Expand Down Expand Up @@ -251,7 +251,7 @@ impl From<PyASCIIObjectState> for u32 {
pub struct PyASCIIObject {
pub ob_base: PyObject,
pub length: Py_ssize_t,
#[cfg(not(PyPy))]
#[cfg(any(Py_3_11, not(PyPy)))]
pub hash: Py_hash_t,
/// A bit field with various properties.
///
Expand Down
4 changes: 2 additions & 2 deletions pyo3-ffi/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ extern "C" {
arg2: *const c_char,
arg3: *mut PyObject,
) -> c_int;
#[cfg(any(Py_3_13, PyPy))] // CPython defined in 3.12 as an inline function in abstract.h
#[cfg(any(Py_3_13, all(PyPy, not(Py_3_11))))] // CPython defined in 3.12 as an inline function in abstract.h
#[cfg_attr(PyPy, link_name = "PyPyObject_DelAttrString")]
pub fn PyObject_DelAttrString(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrString")]
Expand All @@ -460,7 +460,7 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyObject_SetAttr")]
pub fn PyObject_SetAttr(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject)
-> c_int;
#[cfg(any(Py_3_13, PyPy))] // CPython defined in 3.12 as an inline function in abstract.h
#[cfg(any(Py_3_13, all(PyPy, not(Py_3_11))))] // CPython defined in 3.12 as an inline function in abstract.h
#[cfg_attr(PyPy, link_name = "PyPyObject_DelAttr")]
pub fn PyObject_DelAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
#[cfg_attr(PyPy, link_name = "PyPyObject_HasAttr")]
Expand Down
6 changes: 5 additions & 1 deletion pyo3-ffi/src/pybuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ extern "C" {
}

/// Maximum number of dimensions
pub const PyBUF_MAX_NDIM: c_int = if cfg!(PyPy) { 36 } else { 64 };
pub const PyBUF_MAX_NDIM: usize = if cfg!(all(PyPy, not(Py_3_11))) {
36
} else {
64
};

/* Flags for getting buffers */
pub const PyBUF_SIMPLE: c_int = 0;
Expand Down
1 change: 1 addition & 0 deletions pyo3-ffi/src/pyerrors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyExc_BaseException")]
pub static mut PyExc_BaseException: *mut PyObject;
#[cfg(Py_3_11)]
#[cfg_attr(PyPy, link_name = "PyPyExc_BaseExceptionGroup")]
pub static mut PyExc_BaseExceptionGroup: *mut PyObject;
#[cfg_attr(PyPy, link_name = "PyPyExc_Exception")]
pub static mut PyExc_Exception: *mut PyObject;
Expand Down
2 changes: 1 addition & 1 deletion src/ffi/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ fn ascii_object_bitfield() {
let mut o = PyASCIIObject {
ob_base,
length: 0,
#[cfg(not(PyPy))]
#[cfg(any(Py_3_11, not(PyPy)))]
hash: 0,
state: 0u32,
#[cfg(not(Py_3_12))]
Expand Down

0 comments on commit ce2d6e9

Please sign in to comment.