remove internal APIs from pyo3-ffi (#4201)
* remove internal APIs from pyo3-ffi * fix formating * add conditional import * remove _Py_c_neg/abs/pow * fix formating * adding changelog * expose PyAnyMethods::neg/pos/abs and use them * Update src/types/any.rs Co-authored-by: David Hewitt <mail@davidhewitt.dev> * Update src/types/any.rs Co-authored-by: David Hewitt <mail@davidhewitt.dev> * Adding details to changelog * update docs * remove PyREsultExt import for GraalPy --------- Co-authored-by: David Hewitt <mail@davidhewitt.dev>
This commit is contained in:
parent
93ef056711
commit
37a5f6a94e
|
@ -0,0 +1 @@
|
||||||
|
Remove CPython internal ffi call for complex number including: add, sub, mul, div, neg, abs, pow. Added PyAnyMethods::{abs, pos, neg}
|
|
@ -1127,6 +1127,21 @@ pub trait PyAnyMethods<'py>: crate::sealed::Sealed {
|
||||||
where
|
where
|
||||||
O: ToPyObject;
|
O: ToPyObject;
|
||||||
|
|
||||||
|
/// Computes the negative of self.
|
||||||
|
///
|
||||||
|
/// Equivalent to the Python expression `-self`.
|
||||||
|
fn neg(&self) -> PyResult<Bound<'py, PyAny>>;
|
||||||
|
|
||||||
|
/// Computes the positive of self.
|
||||||
|
///
|
||||||
|
/// Equivalent to the Python expression `+self`.
|
||||||
|
fn pos(&self) -> PyResult<Bound<'py, PyAny>>;
|
||||||
|
|
||||||
|
/// Computes the absolute of self.
|
||||||
|
///
|
||||||
|
/// Equivalent to the Python expression `abs(self)`.
|
||||||
|
fn abs(&self) -> PyResult<Bound<'py, PyAny>>;
|
||||||
|
|
||||||
/// Tests whether this object is less than another.
|
/// Tests whether this object is less than another.
|
||||||
///
|
///
|
||||||
/// This is equivalent to the Python expression `self < other`.
|
/// This is equivalent to the Python expression `self < other`.
|
||||||
|
@ -1862,6 +1877,26 @@ impl<'py> PyAnyMethods<'py> for Bound<'py, PyAny> {
|
||||||
inner(self, other.to_object(py).into_bound(py), compare_op)
|
inner(self, other.to_object(py).into_bound(py), compare_op)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn neg(&self) -> PyResult<Bound<'py, PyAny>> {
|
||||||
|
unsafe { ffi::PyNumber_Negative(self.as_ptr()).assume_owned_or_err(self.py()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pos(&self) -> PyResult<Bound<'py, PyAny>> {
|
||||||
|
fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
|
||||||
|
unsafe { ffi::PyNumber_Positive(any.as_ptr()).assume_owned_or_err(any.py()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn abs(&self) -> PyResult<Bound<'py, PyAny>> {
|
||||||
|
fn inner<'py>(any: &Bound<'py, PyAny>) -> PyResult<Bound<'py, PyAny>> {
|
||||||
|
unsafe { ffi::PyNumber_Absolute(any.as_ptr()).assume_owned_or_err(any.py()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner(self)
|
||||||
|
}
|
||||||
|
|
||||||
fn lt<O>(&self, other: O) -> PyResult<bool>
|
fn lt<O>(&self, other: O) -> PyResult<bool>
|
||||||
where
|
where
|
||||||
O: ToPyObject,
|
O: ToPyObject,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
||||||
|
use crate::py_result_ext::PyResultExt;
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
use crate::PyNativeType;
|
use crate::PyNativeType;
|
||||||
use crate::{ffi, types::any::PyAnyMethods, Bound, PyAny, Python};
|
use crate::{ffi, types::any::PyAnyMethods, Bound, PyAny, Python};
|
||||||
|
@ -59,7 +61,6 @@ impl PyComplex {
|
||||||
|
|
||||||
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
||||||
mod not_limited_impls {
|
mod not_limited_impls {
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
|
||||||
use crate::Borrowed;
|
use crate::Borrowed;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -77,27 +78,17 @@ mod not_limited_impls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub(super) unsafe fn complex_operation<'py>(
|
|
||||||
l: Borrowed<'_, 'py, PyComplex>,
|
|
||||||
r: Borrowed<'_, 'py, PyComplex>,
|
|
||||||
operation: unsafe extern "C" fn(ffi::Py_complex, ffi::Py_complex) -> ffi::Py_complex,
|
|
||||||
) -> *mut ffi::PyObject {
|
|
||||||
let l_val = (*l.as_ptr().cast::<ffi::PyComplexObject>()).cval;
|
|
||||||
let r_val = (*r.as_ptr().cast::<ffi::PyComplexObject>()).cval;
|
|
||||||
ffi::PyComplex_FromCComplex(operation(l_val, r_val))
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! bin_ops {
|
macro_rules! bin_ops {
|
||||||
($trait:ident, $fn:ident, $op:tt, $ffi:path) => {
|
($trait:ident, $fn:ident, $op:tt) => {
|
||||||
impl<'py> $trait for Borrowed<'_, 'py, PyComplex> {
|
impl<'py> $trait for Borrowed<'_, 'py, PyComplex> {
|
||||||
type Output = Bound<'py, PyComplex>;
|
type Output = Bound<'py, PyComplex>;
|
||||||
fn $fn(self, other: Self) -> Self::Output {
|
fn $fn(self, other: Self) -> Self::Output {
|
||||||
unsafe {
|
PyAnyMethods::$fn(self.as_any(), other)
|
||||||
complex_operation(self, other, $ffi)
|
.downcast_into().expect(
|
||||||
.assume_owned(self.py())
|
concat!("Complex method ",
|
||||||
.downcast_into_unchecked()
|
stringify!($fn),
|
||||||
}
|
" failed.")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,10 +130,10 @@ mod not_limited_impls {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bin_ops!(Add, add, +, ffi::_Py_c_sum);
|
bin_ops!(Add, add, +);
|
||||||
bin_ops!(Sub, sub, -, ffi::_Py_c_diff);
|
bin_ops!(Sub, sub, -);
|
||||||
bin_ops!(Mul, mul, *, ffi::_Py_c_prod);
|
bin_ops!(Mul, mul, *);
|
||||||
bin_ops!(Div, div, /, ffi::_Py_c_quot);
|
bin_ops!(Div, div, /);
|
||||||
|
|
||||||
#[cfg(feature = "gil-refs")]
|
#[cfg(feature = "gil-refs")]
|
||||||
impl<'py> Neg for &'py PyComplex {
|
impl<'py> Neg for &'py PyComplex {
|
||||||
|
@ -155,12 +146,9 @@ mod not_limited_impls {
|
||||||
impl<'py> Neg for Borrowed<'_, 'py, PyComplex> {
|
impl<'py> Neg for Borrowed<'_, 'py, PyComplex> {
|
||||||
type Output = Bound<'py, PyComplex>;
|
type Output = Bound<'py, PyComplex>;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
unsafe {
|
PyAnyMethods::neg(self.as_any())
|
||||||
let val = (*self.as_ptr().cast::<ffi::PyComplexObject>()).cval;
|
.downcast_into()
|
||||||
ffi::PyComplex_FromCComplex(ffi::_Py_c_neg(val))
|
.expect("Complex method __neg__ failed.")
|
||||||
.assume_owned(self.py())
|
|
||||||
.downcast_into_unchecked()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,24 +277,20 @@ impl<'py> PyComplexMethods<'py> for Bound<'py, PyComplex> {
|
||||||
|
|
||||||
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
||||||
fn abs(&self) -> c_double {
|
fn abs(&self) -> c_double {
|
||||||
unsafe {
|
PyAnyMethods::abs(self.as_any())
|
||||||
let val = (*self.as_ptr().cast::<ffi::PyComplexObject>()).cval;
|
.downcast_into()
|
||||||
ffi::_Py_c_abs(val)
|
.expect("Complex method __abs__ failed.")
|
||||||
}
|
.extract()
|
||||||
|
.expect("Failed to extract to c double.")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
#[cfg(not(any(Py_LIMITED_API, PyPy, GraalPy)))]
|
||||||
fn pow(&self, other: &Bound<'py, PyComplex>) -> Bound<'py, PyComplex> {
|
fn pow(&self, other: &Bound<'py, PyComplex>) -> Bound<'py, PyComplex> {
|
||||||
use crate::ffi_ptr_ext::FfiPtrExt;
|
Python::with_gil(|py| {
|
||||||
unsafe {
|
PyAnyMethods::pow(self.as_any(), other, py.None())
|
||||||
not_limited_impls::complex_operation(
|
.downcast_into()
|
||||||
self.as_borrowed(),
|
.expect("Complex method __pow__ failed.")
|
||||||
other.as_borrowed(),
|
})
|
||||||
ffi::_Py_c_pow,
|
|
||||||
)
|
|
||||||
.assume_owned(self.py())
|
|
||||||
.downcast_into_unchecked()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue