I'm implementing a zero-cost wrapper which converts nalgebra vector to numpy array using PyO3 and rust_numpy (I need this because by default rust_numpy exposes nalgebra vector as 2D numpy arrays instead of 1D and doesn't allow to share the vector between rust and python in the way I need).
The signature of conversion function looks like this:
fn pos_to_pyarray<'py>(
py: Python<'py>,
data_ptr: *mut f32,
) -> *mut PyObject;
It takes a pointer to the vector's memory buffer and maps a numpy array on top of it using low-level numpy API bindings. It works fine, but then I have a problem exposing a raw pointer to PyObject to Python. I tried something like this:
#[pymethods]
...
fn nth_pos_in_vector(&self, i: usize, _py: Python) -> PyObject {
// Get the pos vector, the details doesn't matter here
let pos = ...;
// Creates a numpy array on top of pos vector data
// returns a raw pointer to constructed numpy array
// as *mut PyObject
let v = unsafe{pos_to_pyarray(_py, pos.as_mut_ptr())};
// Return PyObject
*v
}
This fails:
#[pymethods]
| ^^^^^^^^^^^^ the trait `IntoPy<pyo3::Py<PyAny>>` is not implemented for `PyObject`
I also tried to wrap it into a Py smart pointer or PyResult with no success - it emits errors that some of the traits are not implemented by PyObject.
What is the correct way to expose such manually constructed PyObject to Python?