From 48246414f164cb650c939d40df592e0bbc664e38 Mon Sep 17 00:00:00 2001 From: David Hewitt Date: Wed, 21 Aug 2024 18:16:51 +0100 Subject: [PATCH] ffi: add compat functions for no-argument calls (#4461) --- newsfragments/4461.added.md | 1 + pyo3-ffi/src/compat/mod.rs | 2 ++ pyo3-ffi/src/compat/py_3_9.rs | 21 +++++++++++++++++++++ src/types/any.rs | 32 ++++++-------------------------- 4 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 newsfragments/4461.added.md create mode 100644 pyo3-ffi/src/compat/py_3_9.rs diff --git a/newsfragments/4461.added.md b/newsfragments/4461.added.md new file mode 100644 index 00000000000..c151664c843 --- /dev/null +++ b/newsfragments/4461.added.md @@ -0,0 +1 @@ +Add FFI definitions `compat::PyObject_CallNoArgs` and `compat::PyObject_CallMethodNoArgs`. diff --git a/pyo3-ffi/src/compat/mod.rs b/pyo3-ffi/src/compat/mod.rs index db41c834b3d..11f2912848e 100644 --- a/pyo3-ffi/src/compat/mod.rs +++ b/pyo3-ffi/src/compat/mod.rs @@ -52,6 +52,8 @@ macro_rules! compat_function { mod py_3_10; mod py_3_13; +mod py_3_9; pub use self::py_3_10::*; pub use self::py_3_13::*; +pub use self::py_3_9::*; diff --git a/pyo3-ffi/src/compat/py_3_9.rs b/pyo3-ffi/src/compat/py_3_9.rs new file mode 100644 index 00000000000..285f2b2ae7e --- /dev/null +++ b/pyo3-ffi/src/compat/py_3_9.rs @@ -0,0 +1,21 @@ +compat_function!( + originally_defined_for(all( + not(PyPy), + not(GraalPy), + any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // Added to python in 3.9 but to limited API in 3.10 + )); + + #[inline] + pub unsafe fn PyObject_CallNoArgs(obj: *mut crate::PyObject) -> *mut crate::PyObject { + crate::PyObject_CallObject(obj, std::ptr::null_mut()) + } +); + +compat_function!( + originally_defined_for(all(Py_3_9, not(any(Py_LIMITED_API, PyPy, GraalPy)))); + + #[inline] + pub unsafe fn PyObject_CallMethodNoArgs(obj: *mut crate::PyObject, name: *mut crate::PyObject) -> *mut crate::PyObject { + crate::PyObject_CallMethodObjArgs(obj, name, std::ptr::null_mut::()) + } +); diff --git a/src/types/any.rs b/src/types/any.rs index fdeab37712d..335986c60b9 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -2052,20 +2052,7 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { } fn call0(&self) -> PyResult> { - cfg_if::cfg_if! { - if #[cfg(all( - not(PyPy), - not(GraalPy), - any(Py_3_10, all(not(Py_LIMITED_API), Py_3_9)) // PyObject_CallNoArgs was added to python in 3.9 but to limited API in 3.10 - ))] { - // Optimized path on python 3.9+ - unsafe { - ffi::PyObject_CallNoArgs(self.as_ptr()).assume_owned_or_err(self.py()) - } - } else { - self.call((), None) - } - } + unsafe { ffi::compat::PyObject_CallNoArgs(self.as_ptr()).assume_owned_or_err(self.py()) } } fn call1(&self, args: impl IntoPy>) -> PyResult> { @@ -2090,18 +2077,11 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> { where N: IntoPy>, { - cfg_if::cfg_if! { - if #[cfg(all(Py_3_9, not(any(Py_LIMITED_API, PyPy, GraalPy))))] { - let py = self.py(); - - // Optimized path on python 3.9+ - unsafe { - let name = name.into_py(py).into_bound(py); - ffi::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr()).assume_owned_or_err(py) - } - } else { - self.call_method(name, (), None) - } + let py = self.py(); + let name = name.into_py(py).into_bound(py); + unsafe { + ffi::compat::PyObject_CallMethodNoArgs(self.as_ptr(), name.as_ptr()) + .assume_owned_or_err(py) } }