Я хочу написать Rust backend для моей библиотеки, и мне нужно реализовать эквивалент следующей функции в pyo3
:
def f(x):
return x
Это должно вернуть тот же объект как вход, и функция, получающая возвращаемое значение, должна содержать новую ссылку на вход.Если бы я писал это в C API, я написал бы это как:
PyObject * f(PyObject * x) {
Py_XINCREF(x);
return x;
}
В PyO3 , я нахожу это довольно запутанным для навигации по различиям между PyObject
, PyObjectRef
, &PyObject
, Py<PyObject>
, Py<&PyObject>
.
Наиболее наивная версия этой функции:
extern crate pyo3;
use pyo3::prelude::*;
#[pyfunction]
pub fn f(_py: Python, x: &PyObject) -> PyResult<&PyObject> {
Ok(x)
}
Среди прочего, время жизни x
и возвращениезначения не совпадают, плюс я не вижу возможности для pyo3
увеличить счетчик ссылок для x
, и на самом деле компилятор, похоже, согласен со мной:
error[E0106]: missing lifetime specifier
--> src/lib.rs:4:49
|
4 | pub fn f(_py: Python, x: &PyObject) -> PyResult<&PyObject> {
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_py` or `x`
Возможно, есть способдля меня вручную увеличить счетчик ссылок с помощью параметра _py
и использовать аннотации времени жизни, чтобы компилятор был доволен, но у меня сложилось впечатление, что pyo3
намеревается управлять подсчетом ссылок сама используя время жизни объекта.
Как правильно написать эту функцию?Должен ли я пытаться обернуть его в Py
контейнер?