@@ -3,7 +3,7 @@ use std::future::Future;
3
3
use async_std:: task;
4
4
use pyo3:: prelude:: * ;
5
5
6
- use crate :: generic:: { self , JoinError , Runtime } ;
6
+ use crate :: generic:: { self , JoinError , Runtime , SpawnLocalExt } ;
7
7
8
8
/// <span class="module-item stab portability" style="display: inline; border-radius: 3px; padding: 2px; font-size: 80%; line-height: 1.2;"><code>attributes</code></span>
9
9
/// re-exports for macros
@@ -48,6 +48,18 @@ impl Runtime for AsyncStdRuntime {
48
48
}
49
49
}
50
50
51
+ impl SpawnLocalExt for AsyncStdRuntime {
52
+ fn spawn_local < F > ( fut : F ) -> Self :: JoinHandle
53
+ where
54
+ F : Future < Output = ( ) > + ' static ,
55
+ {
56
+ task:: spawn_local ( async move {
57
+ fut. await ;
58
+ Ok ( ( ) )
59
+ } )
60
+ }
61
+ }
62
+
51
63
/// Run the event loop until the given Future completes
52
64
///
53
65
/// The event loop runs until the given future is complete.
@@ -117,3 +129,49 @@ where
117
129
{
118
130
generic:: into_coroutine :: < AsyncStdRuntime , _ > ( py, fut)
119
131
}
132
+
133
+ /// Convert a `!Send` Rust Future into a Python coroutine
134
+ ///
135
+ /// # Arguments
136
+ /// * `py` - The current PyO3 GIL guard
137
+ /// * `fut` - The Rust future to be converted
138
+ ///
139
+ /// # Examples
140
+ ///
141
+ /// ```
142
+ /// use std::{rc::Rc, time::Duration};
143
+ ///
144
+ /// use pyo3::prelude::*;
145
+ ///
146
+ /// /// Awaitable non-send sleep function
147
+ /// #[pyfunction]
148
+ /// fn sleep_for(py: Python, secs: u64) -> PyResult<PyObject> {
149
+ /// // Rc is non-send so it cannot be passed into pyo3_asyncio::tokio::into_coroutine
150
+ /// let secs = Rc::new(secs);
151
+ ///
152
+ /// pyo3_asyncio::async_std::into_local_py_future(py, async move {
153
+ /// async_std::task::sleep(Duration::from_secs(*secs)).await;
154
+ /// Python::with_gil(|py| Ok(py.None()))
155
+ /// })
156
+ /// }
157
+ ///
158
+ /// # #[cfg(all(feature = "async-std-runtime", feature = "attributes"))]
159
+ /// #[pyo3_asyncio::async_std::main]
160
+ /// async fn main() -> PyResult<()> {
161
+ /// Python::with_gil(|py| {
162
+ /// let py_future = sleep_for(py, 1)?;
163
+ /// pyo3_asyncio::into_future(py_future.as_ref(py))
164
+ /// })?
165
+ /// .await?;
166
+ ///
167
+ /// Ok(())
168
+ /// }
169
+ /// # #[cfg(not(all(feature = "async-std-runtime", feature = "attributes")))]
170
+ /// # fn main() {}
171
+ /// ```
172
+ pub fn into_local_py_future < F > ( py : Python , fut : F ) -> PyResult < PyObject >
173
+ where
174
+ F : Future < Output = PyResult < PyObject > > + ' static ,
175
+ {
176
+ generic:: into_local_py_future :: < AsyncStdRuntime , _ > ( py, fut)
177
+ }
0 commit comments