diff --git a/src/ffi/descrobject.rs b/src/ffi/descrobject.rs index 0651eee5..6cdb91a4 100644 --- a/src/ffi/descrobject.rs +++ b/src/ffi/descrobject.rs @@ -1,6 +1,6 @@ use crate::ffi::methodobject::PyMethodDef; use crate::ffi::object::{PyObject, PyTypeObject}; -#[cfg(not(PyPy))] +#[cfg(all(not(PyPy), not(Py_LIMITED_API)))] use crate::ffi::object::{PyObject_GenericGetDict, PyObject_GenericSetDict}; use crate::ffi::structmember::PyMemberDef; use std::os::raw::{c_char, c_int, c_void}; @@ -28,11 +28,12 @@ pub const PyGetSetDef_INIT: PyGetSetDef = PyGetSetDef { closure: ptr::null_mut(), }; -#[cfg(PyPy)] +#[cfg(any(PyPy, Py_LIMITED_API))] pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef_INIT; // PyPy doesn't export neither PyObject_GenericGetDict/PyObject_GenericSetDict -#[cfg(not(PyPy))] +// Py_LIMITED_API exposes PyObject_GenericSetDict but not Get. +#[cfg(all(not(PyPy), not(Py_LIMITED_API)))] pub const PyGetSetDef_DICT: PyGetSetDef = PyGetSetDef { name: "__dict__\0".as_ptr() as *mut c_char, get: Some(PyObject_GenericGetDict), diff --git a/src/ffi/funcobject.rs b/src/ffi/funcobject.rs index 10b15345..e57a87a7 100644 --- a/src/ffi/funcobject.rs +++ b/src/ffi/funcobject.rs @@ -4,10 +4,12 @@ use crate::ffi::object::{PyObject, PyTypeObject, Py_TYPE}; #[cfg_attr(windows, link(name = "pythonXY"))] extern "C" { + #[cfg(not(Py_LIMITED_API))] #[cfg_attr(PyPy, link_name = "PyPyFunction_Type")] pub static mut PyFunction_Type: PyTypeObject; } +#[cfg(not(Py_LIMITED_API))] #[inline] pub unsafe fn PyFunction_Check(op: *mut PyObject) -> c_int { (Py_TYPE(op) == &mut PyFunction_Type) as c_int diff --git a/src/ffi/marshal.rs b/src/ffi/marshal.rs index 00237908..01494ce6 100644 --- a/src/ffi/marshal.rs +++ b/src/ffi/marshal.rs @@ -1,6 +1,7 @@ use super::PyObject; use std::os::raw::{c_char, c_int}; +#[cfg(not(Py_LIMITED_API))] extern "C" { #[cfg_attr(PyPy, link_name = "PyPyMarshal_WriteObjectToString")] pub fn PyMarshal_WriteObjectToString(object: *mut PyObject, version: c_int) -> *mut PyObject; diff --git a/src/ffi/object.rs b/src/ffi/object.rs index 80c9278d..10255639 100644 --- a/src/ffi/object.rs +++ b/src/ffi/object.rs @@ -716,6 +716,7 @@ extern "C" { arg2: *mut PyObject, arg3: *mut PyObject, ) -> c_int; + #[cfg(not(Py_LIMITED_API))] pub fn PyObject_GenericGetDict(arg1: *mut PyObject, arg2: *mut c_void) -> *mut PyObject; pub fn PyObject_GenericSetDict( arg1: *mut PyObject, diff --git a/src/lib.rs b/src/lib.rs index 7826fcfb..c5e5e760 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,6 +184,7 @@ mod gil; mod instance; #[macro_use] mod internal_tricks; +#[cfg(not(Py_LIMITED_API))] pub mod marshal; pub mod once_cell; pub mod panic; diff --git a/src/marshal.rs b/src/marshal.rs index d0c7350b..f8bcb6a4 100644 --- a/src/marshal.rs +++ b/src/marshal.rs @@ -1,3 +1,5 @@ +#![cfg(not(Py_LIMITED_API))] + use crate::ffi; use crate::types::{PyAny, PyBytes}; use crate::{AsPyPointer, FromPyPointer, PyResult, Python}; diff --git a/src/types/function.rs b/src/types/function.rs index d215d6c4..5acb3ddd 100644 --- a/src/types/function.rs +++ b/src/types/function.rs @@ -87,4 +87,5 @@ impl PyCFunction { #[repr(transparent)] pub struct PyFunction(PyAny); +#[cfg(not(Py_LIMITED_API))] pyobject_native_var_type!(PyFunction, ffi::PyFunction_Type, ffi::PyFunction_Check); diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index f24f7266..8a1e52d2 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -1,7 +1,9 @@ #[cfg(not(Py_LIMITED_API))] use pyo3::buffer::PyBuffer; use pyo3::prelude::*; -use pyo3::types::{PyCFunction, PyFunction}; +use pyo3::types::PyCFunction; +#[cfg(not(Py_LIMITED_API))] +use pyo3::types::PyFunction; use pyo3::{raw_pycfunction, wrap_pyfunction}; mod common; @@ -67,6 +69,7 @@ assert a, array.array("i", [2, 4, 6, 8]) ); } +#[cfg(not(Py_LIMITED_API))] #[pyfunction] fn function_with_pyfunction_arg(fun: &PyFunction) -> PyResult<&PyAny> { fun.call((), None) @@ -81,21 +84,31 @@ fn function_with_pycfunction_arg(fun: &PyCFunction) -> PyResult<&PyAny> { fn test_functions_with_function_args() { let gil = Python::acquire_gil(); let py = gil.python(); - let py_func_arg = wrap_pyfunction!(function_with_pyfunction_arg)(py).unwrap(); let py_cfunc_arg = wrap_pyfunction!(function_with_pycfunction_arg)(py).unwrap(); let bool_to_string = wrap_pyfunction!(optional_bool)(py).unwrap(); pyo3::py_run!( py, - py_func_arg py_cfunc_arg bool_to_string, r#" - def foo(): return "bar" - assert py_func_arg(foo) == "bar" assert py_cfunc_arg(bool_to_string) == "Some(true)" "# - ) + ); + + #[cfg(not(Py_LIMITED_API))] + { + let py_func_arg = wrap_pyfunction!(function_with_pyfunction_arg)(py).unwrap(); + + pyo3::py_run!( + py, + py_func_arg, + r#" + def foo(): return "bar" + assert py_func_arg(foo) == "bar" + "# + ); + } } #[test]