PyO3/rust-numpy

Is there a way to return an iterator of numpy arrays?

Closed this issue · 2 comments

basically I'm trying this

#[pyclass(name = "Iterator", unsendable)]
pub struct PyGenericIterator {
    iter: Box<dyn Iterator<Item = PyObject>>,
}

impl<I, T> From<I> for PyGenericIterator
where
    I: Iterator<Item = T> + 'static,
    T: IntoPy<PyObject> + 'static,
{
    fn from(value: I) -> Self {
        let py_iter = Box::new(value.map(|item| Python::with_gil(|py| item.into_py(py))));
        Self { iter: py_iter }
    }
}

#[pymethods]
impl PyGenericIterator {
    fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
        slf
    }
    fn __next__(&mut self) -> Option<PyObject> {
        self.iter.next()
    }
}

    
    fn history_numpy(&self, py: Python<'_>) -> PyGenericIterator {
        PyGenericIterator::from((0..10).map(|_| {
            let v = vec![1, 2, 3];
            v.into_pyarray(py).to_owned()
        }))
    }```

but the compiler disagrees with me

error[E0521]: borrowed data escapes outside of method
--> raphtory/src/python/graph/edges.rs:177:33
|
176 | fn history_numpy(&self, py: Python<'>) -> PyGenericIterator {
| --
| |
| py is a reference that is only valid in the method body
| has type pyo3::Python<'1>
177 | PyGenericIterator::from((0..10).map(|
| {
| _______________________^
178 | | let v = vec![1, 2, 3];
179 | | v.into_pyarray(py).to_owned()
180 | | }))
| | ^
| | |
| |
py escapes the method body here
| argument requires that '1 must outlive 'static

You probably cannot pass py: Python<'_> into the .map() closure and instead will need to do something like

        PyGenericIterator::from((0..10).map(|_| {
            let v = vec![1, 2, 3];
            Python::with_gil(|py| v.into_pyarray(py).to_owned())
        }))

Thanks, I figured it out