I'm using pyo3 to try and make python functions run in rust
I am trying to make a function which takes in two PyAny objects and gets a f64 value out of them and uses those to initialize a PyComplex object and then return it as a PyResult. The .into_py()
is giving me a strange error
the trait bound `&PyComplex: pyo3::IntoPy<PyObject>` is not satisfied
the trait `pyo3::IntoPy<Py<PyComplex>>` is implemented for `&PyComplex`
for that trait implementation, expected `Py<PyComplex>`, found `PyObject`
My function is the following:
#[pyfunction]
fn imaginary(a: &PyAny, b: &PyAny) -> PyResult<PyObject> {
let gil: GILGuard = Python::acquire_gil();
let py: Python<'_> = gil.python();
let real: f64 = a.extract()?;
let imag: f64 = b.extract()?;
let d: PyObject = PyComplex::from_doubles(py, real, imag).into_py(py);
Ok(d)
}
Please excuse the sloppy code, I'm only just learning how to use pyo3 and pointers are appreciated
I tried the compilers suggestion which was to use this line
let d: PyObject = <&PyComplex as pyo3::IntoPy<T>>::into_py(PyComplex::from_doubles(py, real, imag), py)?;
instead of the other let d:
line I had, but it didn't work because T isn't defined in the scope. I tried adding T to the function signature but that didn't work because python functions cant take a rust type parameter.
I also tried replacing T with PyComplex or &PyComplex hoping that would work but no luck.
What can I do to get this working?
The easiest way to do this conversion is by calling to_object
method.
use pyo3::{prelude::*, types::PyComplex};
#[pyfunction]
fn imaginary(py: Python<'_>, a: &PyAny, b: &PyAny) -> PyResult<PyObject> {
let real: f64 = a.extract()?;
let imag: f64 = b.extract()?;
let d: PyObject = PyComplex::from_doubles(py, real, imag).to_object(py);
Ok(d)
}
/// A Python module implemented in Rust.
#[pymodule]
fn complex_python(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(imaginary, m)?)?;
Ok(())
}
Now you can import this into your python interpretter.
>>> import complex_python
>>>
>>> complex = complex_python.imaginary(1, 2)
>>> complex
(1+2j)
>>> type(_)
<class 'complex'>