port `PyComplex::from_complex` to `Bound` API (#3866)

* port `PyComplex::from_complex` to `Bound` API

* add `PyComplexMethods` to the prelude
This commit is contained in:
Icxolu 2024-02-19 00:37:02 +01:00 committed by GitHub
parent a85ed34c45
commit 0bb9cab6d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 9 deletions

View File

@ -93,21 +93,37 @@
//! result = get_eigenvalues(m11,m12,m21,m22) //! result = get_eigenvalues(m11,m12,m21,m22)
//! assert result == [complex(1,-1), complex(-2,0)] //! assert result == [complex(1,-1), complex(-2,0)]
//! ``` //! ```
#[cfg(any(Py_LIMITED_API, PyPy))]
use crate::types::any::PyAnyMethods;
use crate::{ use crate::{
ffi, types::PyComplex, Bound, FromPyObject, PyAny, PyErr, PyObject, PyResult, Python, ffi,
ToPyObject, ffi_ptr_ext::FfiPtrExt,
types::{any::PyAnyMethods, PyComplex},
Bound, FromPyObject, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
}; };
use num_complex::Complex; use num_complex::Complex;
use std::os::raw::c_double; use std::os::raw::c_double;
impl PyComplex { impl PyComplex {
/// Creates a new Python `PyComplex` object from `num_complex`'s [`Complex`]. /// Deprecated form of [`PyComplex::from_complex_bound`]
#[cfg_attr(
not(feature = "gil-refs"),
deprecated(
since = "0.21.0",
note = "`PyComplex::from_complex` will be replaced by `PyComplex::from_complex_bound` in a future PyO3 version"
)
)]
pub fn from_complex<F: Into<c_double>>(py: Python<'_>, complex: Complex<F>) -> &PyComplex { pub fn from_complex<F: Into<c_double>>(py: Python<'_>, complex: Complex<F>) -> &PyComplex {
Self::from_complex_bound(py, complex).into_gil_ref()
}
/// Creates a new Python `PyComplex` object from `num_complex`'s [`Complex`].
pub fn from_complex_bound<F: Into<c_double>>(
py: Python<'_>,
complex: Complex<F>,
) -> Bound<'_, PyComplex> {
unsafe { unsafe {
let ptr = ffi::PyComplex_FromDoubles(complex.re.into(), complex.im.into()); ffi::PyComplex_FromDoubles(complex.re.into(), complex.im.into())
py.from_owned_ptr(ptr) .assume_owned(py)
.downcast_into_unchecked()
} }
} }
} }
@ -183,13 +199,14 @@ complex_conversion!(f64);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::types::complex::PyComplexMethods;
use crate::types::PyModule; use crate::types::PyModule;
#[test] #[test]
fn from_complex() { fn from_complex() {
Python::with_gil(|py| { Python::with_gil(|py| {
let complex = Complex::new(3.0, 1.2); let complex = Complex::new(3.0, 1.2);
let py_c = PyComplex::from_complex(py, complex); let py_c = PyComplex::from_complex_bound(py, complex);
assert_eq!(py_c.real(), 3.0); assert_eq!(py_c.real(), 3.0);
assert_eq!(py_c.imag(), 1.2); assert_eq!(py_c.imag(), 1.2);
}); });

View File

@ -30,6 +30,7 @@ pub use crate::types::boolobject::PyBoolMethods;
pub use crate::types::bytearray::PyByteArrayMethods; pub use crate::types::bytearray::PyByteArrayMethods;
pub use crate::types::bytes::PyBytesMethods; pub use crate::types::bytes::PyBytesMethods;
pub use crate::types::capsule::PyCapsuleMethods; pub use crate::types::capsule::PyCapsuleMethods;
pub use crate::types::complex::PyComplexMethods;
pub use crate::types::dict::PyDictMethods; pub use crate::types::dict::PyDictMethods;
pub use crate::types::float::PyFloatMethods; pub use crate::types::float::PyFloatMethods;
pub use crate::types::frozenset::PyFrozenSetMethods; pub use crate::types::frozenset::PyFrozenSetMethods;

View File

@ -283,7 +283,7 @@ pub(crate) mod bytes;
pub(crate) mod capsule; pub(crate) mod capsule;
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
mod code; mod code;
mod complex; pub(crate) mod complex;
#[cfg(not(Py_LIMITED_API))] #[cfg(not(Py_LIMITED_API))]
pub(crate) mod datetime; pub(crate) mod datetime;
pub(crate) mod dict; pub(crate) mod dict;