Вектор пользовательской структуры в PyO3 - PullRequest
0 голосов
/ 16 января 2019

Я новичок в Rust и PyO3 (из Python), так что это может быть очевидно для более опытных людей.

Я объявил структуру Pyclass в PyO3.

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

Затем я использую Block в функции ржавчины, которая берет вектор Block и выводит вектор int (подпись ниже)

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

Когда я компилирую, используя nightly-x86_64-apple-darwin, я получаю следующую ошибку:

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

Как мне решить эту проблему?

EDIT: Кайо прав. Я сделал ошибку в отслеживании ошибки. Ранее я писал

Затем я использую Block в функции ржавчины, которая берет вектор int и выводит вектор Block (подпись ниже)

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

Но фактическая нарушающая функция:

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

Я обновил вопрос, чтобы сделать его более понятным.

Ответы [ 3 ]

0 голосов
/ 16 января 2019

FromPyObject предназначен для использования типами, которые могут быть извлечены из мира Python. Вот почему я думаю, что вы пытались написать fn to_blocks(list: Vec<Block>) -> Vec<i32> вместо fn to_blocks(list: Vec<i32>) -> Vec<Block>. Если это так, давайте перейдем к цепочке реализации.

FromPyObject имеет реализацию по умолчанию для any & T, которая реализует PyTryFrom , а PyTryFrom имеет реализацию по умолчанию для любого T, который реализует PyTypeInfo . [pyclass] реализует PyObjectAlloc или PyObjectWithFreeList в соответствии с методом impl_class, и обе черты имеют предел черты PyTypeInfo. Следовательно, ваш класс / структура будет прекрасно работать со ссылками, например ::11019

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

Вы можете увидеть в официальной документации это объяснение в обобщенном виде.

FromPyObject реализуется различными типами, которые могут быть извлечены из объекта Python ссылка .

0 голосов
/ 16 января 2019

Какая версия PyO3 у вас установлена? Ваш код работает для меня на 0.5.3 и 0.6.0-alpha.1.

Из-за этого я не могу проверить это, но я думаю, вам нужно вернуть PyResult:

#[pyfunction]
fn to_blocks(list: Vec<i32>) -> PyResult<Vec<Block>>
0 голосов
/ 16 января 2019

Похоже, что атрибут pyfunction генерирует код, который требует, чтобы возвращаемый тип реализовывал черту FromPyObject. Хотя есть общая реализация FromPyObject for Vec<T> where T: FromPyObject, похоже, что код, сгенерированный для атрибута pyclass, не включает реализацию FromPyObject для вашего Block типа.

Поскольку я незнаком с PyO3, за исключением нескольких минут, я просто посмотрел его API-документацию, чтобы подтвердить этот ответ, я не уверен, как вам лучше получить реализацию FromPyObject - возможно, есть derive за это?

...