Howto return a PyBytes with the new Bound interface of pyo3

I'm trying to return a PyBytes object with the new Bound interface, but the Rust compiler complains about a lifetime problem:

fn to_vec(&self, py: Python) -> PyResult<Bound<PyBytes>> {
        match self.instance.statistics.to_vec() {
            Ok(v) => {
                Ok(
                    PyBytes::new_bound_with(py, v.len(), |b| {
                        b.copy_from_slice(&v);
                        Ok(())
                    })?
                )
            }
            Err(e) => Err(PyException::new_err(e.to_string())),
        }
    }

to_vec returns a Vec<u8>. I'm confused about the lifetime problem and don't know how to solve it.

The compiler error is:

error: lifetime may not live long enough
   --> pyscandir/src/count.rs:126:17
    |
123 |       fn to_vec(&self, py: Python) -> PyResult<Bound<PyBytes>> {
    |                 -      -- has type `pyo3::Python<'1>`
    |                 |
    |                 let's call the lifetime of this reference `'2`
...
126 | /                 Ok(
127 | |                     PyBytes::new_bound_with(py, v.len(), |b| {
128 | |                         b.copy_from_slice(&v);
129 | |                         Ok(())
130 | |                     })?
131 | |                 )
    | |_________________^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
1 Like

I've found the solution:

fn to_vec(&self, py: Python) -> PyResult<Py<PyBytes>> {
        match self.instance.statistics.to_vec() {
            Ok(v) => {
                Ok(
                    PyBytes::new_bound_with(py, v.len(), |b| {
                        b.copy_from_slice(&v);
                        Ok(())
                    })?.into()
                )
            }
            Err(e) => Err(PyException::new_err(e.to_string())),
        }
    }
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.