Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector of custom struct in PyO3

Tags:

python

rust

pyo3

I'm new to Rust and PyO3 (coming from Python) so this might be obvious to more experienced people.

I declared a pyclass struct in PyO3.

#[pyclass]
struct Block {
    start: i32,
    stop: i32,
}

Then I use Block in a rust function that takes a vector of Block and outputs a vector of int (signature below)

#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>

When I compile using nightly-x86_64-apple-darwin I get the following error:

#[pyfunction]
^^^^^^^^^^^^^ the trait `pyo3::FromPyObject<'_>` is not implemented for `std::vec::Vec<Block>`

How do I solve this?

EDIT: Caio is right. I made a mistake in tracing back the error. Previously I wrote

Then I use Block in a rust function that takes a vector of int and outputs a vector of Block (signature below)

#[pyfunction]
fn to_blocks(list: Vec<i32>) -> Vec<Block>

But the actual offending function is:

#[pyfunction]
fn from_blocks(block_list: Vec<Block>) -> Vec<i32>

I've updated the question to make it clearer.

like image 440
kentwait Avatar asked Jan 16 '19 08:01

kentwait


1 Answers

FromPyObject is intended to be used by types that can be extracted from the Python world. That is why I think that you were trying to write fn to_blocks(list: Vec<Block>) -> Vec<i32> instead of fn to_blocks(list: Vec<i32>) -> Vec<Block>. If that is the case , lets go down to the implementation chain.

FromPyObject has a default implementation for any &T that implements PyTryFrom and PyTryFrom has a default implementation for any T that implements PyTypeInfo. [pyclass] implements PyObjectAlloc or PyObjectWithFreeList according to the impl_class method and both traits have the PyTypeInfo trait bound. Therefore, your class/struct will work just fine with references, e.g.:

#[pyfunction]
fn to_blocks(list: Vec<&Block>) -> Vec<i32>

You can see in the official documentation this explanation in a summarized way.

FromPyObject is implemented by various types that can be extracted from a Python object reference.

like image 174
Caio Avatar answered Nov 01 '22 19:11

Caio