I have the following function that uses PyO3 to call a python function and get a result (in this case, an int
that gets assigned to a i32
):
fn run_python<'a, T: FromPyObject<'a> + Clone>(func_name: &str) -> Result<T, ()> {
Python::with_gil(|py| {
let pyapi = match py.import("pyapi") {
Ok(v) => v,
Err(e) => { e.print_and_set_sys_last_vars(py); return Err(()) },
};
let locals = [("pyapi", pyapi)].into_py_dict(py);
let eval_result: PyResult<&PyAny> = py.eval("pyapi.{}(**kwargs)", None, Some(&locals));
let wrapped_obj: &PyAny = match eval_result {
Ok(v) => v,
Err(e) => { e.print_and_set_sys_last_vars(py); return Err(()) },
};
let unwrapped_result: PyResult<T> = wrapped_obj.extract();
match unwrapped_result {
Ok(v) => return Ok(v.clone()),
Err(e) => return Err(()),
};
})
}
When I try to compile, I get the following error:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'p` due to conflicting requirements
--> src\bin\launch.rs:89:30
|
89 | let eval_result = py.eval("pyapi.{}(**kwargs)", None, Some(&locals));
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 82:22...
--> src\bin\launch.rs:82:22
|
82 | Python::with_gil(|py| {
| ______________________^
83 | | let pyapi = match py.import("pyapi") {
84 | | Ok(v) => v,
85 | | Err(e) => { e.print_and_set_sys_last_vars(py); return Err(()) },
... |
101 | | };
102 | | })
| |_____^
note: ...so that the types are compatible
--> src\bin\launch.rs:89:30
|
89 | let eval_result = py.eval("pyapi.{}(**kwargs)", None, Some(&locals));
| ^^^^
= note: expected `pyo3::Python<'_>`
found `pyo3::Python<'_>`
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 81:15...
--> src\bin\launch.rs:81:15
|
81 | fn run_python<'a, T: FromPyObject<'a> + Clone>(func_name: &str) -> Result<T, ()> {
| ^^
note: ...so that the types are compatible
--> src\bin\launch.rs:96:57
|
96 | let unwrapped_result: PyResult<T> = wrapped_obj.extract();
| ^^^^^^^
= note: expected `pyo3::FromPyObject<'_>`
found `pyo3::FromPyObject<'a>`
I'm very new to Rust, and am probably doing something silly (and very likely could be an X/Y problem). How can I get a value out of py.eval
that doesn't have a lifetime tied to the python interpreter (which is what I'm assuming is going on here)?