diff --git a/CHANGELOG.md b/CHANGELOG.md index f902320f..728cdfbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Only allow each `#[pymodule]` to be initialized once. [#2523](https://github.com/PyO3/pyo3/pull/2523) - `pyo3_build_config::add_extension_module_link_args()` now also emits linker arguments for `wasm32-unknown-emscripten`. [#2538](https://github.com/PyO3/pyo3/pull/2538) - Downcasting (`PyTryFrom`) behavior has changed for `PySequence` and `PyMapping`: classes are now required to inherit from (or register with) the corresponding Python standard library abstract base class. See the [migration guide](https://pyo3.rs/latest/migration.html) for information on fixing broken downcasts. [#2477](https://github.com/PyO3/pyo3/pull/2477) +- Disable `PyFunction` on `Py_LIMITED_API` and PyPy. [#2542](https://github.com/PyO3/pyo3/pull/2542) ### Removed diff --git a/pyo3-ffi/src/funcobject.rs b/pyo3-ffi/src/cpython/funcobject.rs similarity index 88% rename from pyo3-ffi/src/funcobject.rs rename to pyo3-ffi/src/cpython/funcobject.rs index 6366e363..1d36c85e 100644 --- a/pyo3-ffi/src/funcobject.rs +++ b/pyo3-ffi/src/cpython/funcobject.rs @@ -1,8 +1,8 @@ use std::os::raw::c_int; -use crate::object::{PyObject, PyTypeObject, Py_TYPE}; +use crate::PyObject; -#[cfg(all(not(PyPy), not(Py_LIMITED_API), not(Py_3_10)))] +#[cfg(all(not(PyPy), not(Py_3_10)))] #[repr(C)] pub struct PyFunctionObject { pub ob_base: PyObject, @@ -22,7 +22,7 @@ pub struct PyFunctionObject { pub vectorcall: Option, } -#[cfg(all(not(PyPy), not(Py_LIMITED_API), Py_3_10))] +#[cfg(all(not(PyPy), Py_3_10))] #[repr(C)] pub struct PyFunctionObject { pub ob_base: PyObject, @@ -44,25 +44,24 @@ pub struct PyFunctionObject { pub func_version: u32, } -#[cfg(all(PyPy, not(Py_LIMITED_API)))] +#[cfg(PyPy)] #[repr(C)] pub struct PyFunctionObject { pub ob_base: PyObject, pub func_name: *mut PyObject, } -#[cfg(all(not(PyPy), Py_LIMITED_API))] -opaque_struct!(PyFunctionObject); - #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { + #[cfg(not(PyPy))] // broken, see https://foss.heptapod.net/pypy/pypy/-/issues/3776 #[cfg_attr(PyPy, link_name = "PyPyFunction_Type")] - pub static mut PyFunction_Type: PyTypeObject; + pub static mut PyFunction_Type: crate::PyTypeObject; } +#[cfg(not(PyPy))] #[inline] pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int { - (Py_TYPE(op) == addr_of_mut_shim!(PyFunction_Type)) as c_int + (crate::Py_TYPE(op) == addr_of_mut_shim!(PyFunction_Type)) as c_int } extern "C" { diff --git a/pyo3-ffi/src/cpython/mod.rs b/pyo3-ffi/src/cpython/mod.rs index 068cedfb..b4623e6e 100644 --- a/pyo3-ffi/src/cpython/mod.rs +++ b/pyo3-ffi/src/cpython/mod.rs @@ -12,6 +12,7 @@ pub(crate) mod dictobject; // skipped fileobject.h // skipped fileutils.h pub(crate) mod frameobject; +pub(crate) mod funcobject; pub(crate) mod genobject; pub(crate) mod import; #[cfg(all(Py_3_8, not(PyPy)))] @@ -44,6 +45,7 @@ pub use self::descrobject::*; #[cfg(not(PyPy))] pub use self::dictobject::*; pub use self::frameobject::*; +pub use self::funcobject::*; pub use self::genobject::*; pub use self::import::*; #[cfg(all(Py_3_8, not(PyPy)))] diff --git a/pyo3-ffi/src/lib.rs b/pyo3-ffi/src/lib.rs index 1e3ee855..f37b758e 100644 --- a/pyo3-ffi/src/lib.rs +++ b/pyo3-ffi/src/lib.rs @@ -299,8 +299,6 @@ pub use self::enumobject::*; pub use self::fileobject::*; pub use self::fileutils::*; pub use self::floatobject::*; -#[cfg(not(Py_LIMITED_API))] -pub use self::funcobject::*; pub use self::import::*; pub use self::intrcheck::*; pub use self::iterobject::*; @@ -368,8 +366,6 @@ mod fileobject; mod fileutils; mod floatobject; // skipped empty frameobject.h -#[cfg(not(Py_LIMITED_API))] -pub(crate) mod funcobject; // skipped genericaliasobject.h mod import; // skipped interpreteridobject.h diff --git a/src/types/function.rs b/src/types/function.rs index 04438290..e13ba123 100644 --- a/src/types/function.rs +++ b/src/types/function.rs @@ -166,7 +166,8 @@ impl PyCFunction { /// Represents a Python function object. #[repr(transparent)] +#[cfg(not(any(PyPy, Py_LIMITED_API)))] pub struct PyFunction(PyAny); -#[cfg(not(Py_LIMITED_API))] +#[cfg(not(any(PyPy, Py_LIMITED_API)))] pyobject_native_type_core!(PyFunction, ffi::PyFunction_Type, #checkfunction=ffi::PyFunction_Check); diff --git a/src/types/mod.rs b/src/types/mod.rs index f11e94a6..cebf4f46 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -20,7 +20,9 @@ pub use self::floatob::PyFloat; #[cfg(all(not(Py_LIMITED_API), not(PyPy)))] pub use self::frame::PyFrame; pub use self::frozenset::PyFrozenSet; -pub use self::function::{PyCFunction, PyFunction}; +pub use self::function::PyCFunction; +#[cfg(all(not(Py_LIMITED_API), not(PyPy)))] +pub use self::function::PyFunction; pub use self::iterator::PyIterator; pub use self::list::PyList; pub use self::mapping::PyMapping; diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index 20fc67c5..49dba14b 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -3,9 +3,11 @@ #[cfg(not(Py_LIMITED_API))] use pyo3::buffer::PyBuffer; use pyo3::prelude::*; -use pyo3::types::{self, PyCFunction}; #[cfg(not(Py_LIMITED_API))] -use pyo3::types::{PyDateTime, PyFunction}; +use pyo3::types::PyDateTime; +#[cfg(not(any(Py_LIMITED_API, PyPy)))] +use pyo3::types::PyFunction; +use pyo3::types::{self, PyCFunction}; mod common; @@ -70,7 +72,7 @@ assert a, array.array("i", [2, 4, 6, 8]) }); } -#[cfg(not(Py_LIMITED_API))] +#[cfg(not(any(Py_LIMITED_API, PyPy)))] #[pyfunction] fn function_with_pyfunction_arg(fun: &PyFunction) -> PyResult<&PyAny> { fun.call((), None) @@ -96,7 +98,7 @@ fn test_functions_with_function_args() { "# ); - #[cfg(not(Py_LIMITED_API))] + #[cfg(not(any(Py_LIMITED_API, PyPy)))] { let py_func_arg = wrap_pyfunction!(function_with_pyfunction_arg)(py).unwrap();