-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Description
When trying to call pyo3_async_runtimes::future_into_py inside an async PyO3 method (#[pymethods] pub async fn ...
), compilation fails because the generated future captures a non-Send Python<'_> reference.
use pyo3::prelude::*;
use pyo3_async_runtimes::tokio::future_into_py;
use std::path::PathBuf;
#[pyclass]
pub struct Operator {
core: Core,
}
#[pymethods]
impl Operator {
#[pyo3(signature = (path, kwargs=None))]
pub async fn stat(&self, path: PathBuf, kwargs: Option<Py<PyDict>>) -> PyResult<Metadata> {
let this = self.core.clone();
let path = path.to_string_lossy().to_string();
let kwargs = Python::with_gil(|py| {
kwargs.map(|v| v.bind(py).extract::<StatOptions>()).transpose()
})?.unwrap_or_default();
future_into_py(py, async move {
this.stat_options(&path, kwargs.into())
.await
.map_err(format_pyerr)
.map(Metadata::new)
})
}
}
Error:
error: future cannot be sent between threads safely
--> src/operator.rs:489:1
|
489 | #[pymethods]
| ^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: within `{async block@src/operator.rs:489:1: 489:13}`, the trait `std::marker::Send` is not implemented for `*mut pyo3::Python<'static>`
note: captured value is not `Send`
--> src/operator.rs:489:1
|
489 | #[pymethods]
| ^^^^^^^^^^^^ has type `pyo3::Python<'_>` which is not `Send`
note: required by a bound in `new_coroutine`
--> /.../pyo3-0.26.0/src/impl_/coroutine.rs:22:40
|
15 | pub fn new_coroutine<'py, F, T, E>(
| ------------- required by a bound in this function
...
22 | F: Future<Output = Result<T, E>> + Send + 'static,
| ^^^^ required by this bound in `new_coroutine`
This happens because the PyO3 async coroutine internally captures a Python<'_>, which is not Send, but future_into_py currently requires Future + Send + 'static.
Could pyo3_async_runtimes provide a *_non_send or similar variant usable inside async PyO3 methods? This would make it possible to use future_into_py ergonomically from PyO3’s experimental async methods without manual runtime bridging or Send issues.
Or if there is an alternate way of solving this, it will be a great help. thanks!
Context:
- PyO3: 0.26.0 (with
experimental-async
feature) - pyo3_async_runtimes: 0.26.0
- Runtime: Tokio
Metadata
Metadata
Assignees
Labels
No labels