1use std::{
3 future::Future,
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use futures::Stream;
9use pyo3::prelude::*;
10
11#[cfg(feature = "allow-threads")]
12mod allow_threads;
13mod async_generator;
14pub mod asyncio;
15mod coroutine;
16pub mod sniffio;
17pub mod trio;
18mod utils;
19
20#[cfg(feature = "allow-threads")]
21pub use allow_threads::{AllowThreads, AllowThreadsExt};
22#[cfg(feature = "macros")]
23pub use pyo3_async_macros::{pyfunction, pymethods};
24
25pub trait PyFuture: Send {
30 fn poll_py(self: Pin<&mut Self>, py: Python, cx: &mut Context) -> Poll<PyResult<PyObject>>;
32}
33
34impl<F, T, E> PyFuture for F
35where
36 F: Future<Output = Result<T, E>> + Send,
37 T: IntoPy<PyObject> + Send,
38 E: Send,
39 PyErr: From<E>,
40{
41 fn poll_py(self: Pin<&mut Self>, py: Python, cx: &mut Context) -> Poll<PyResult<PyObject>> {
42 let poll = self.poll(cx);
43 poll.map_ok(|ok| ok.into_py(py)).map_err(PyErr::from)
44 }
45}
46
47pub trait PyStream: Send {
54 fn poll_next_py(
56 self: Pin<&mut Self>,
57 py: Python,
58 cx: &mut Context,
59 ) -> Poll<Option<PyResult<PyObject>>>;
60}
61
62impl<S, T, E> PyStream for S
63where
64 S: Stream<Item = Result<T, E>> + Send,
65 T: IntoPy<PyObject> + Send,
66 E: Send,
67 PyErr: From<E>,
68{
69 fn poll_next_py(
70 self: Pin<&mut Self>,
71 py: Python,
72 cx: &mut Context,
73 ) -> Poll<Option<PyResult<PyObject>>> {
74 let poll = self.poll_next(cx);
75 poll.map_ok(|ok| ok.into_py(py)).map_err(PyErr::from)
76 }
77}
78
79pub type ThrowCallback = Box<dyn FnMut(Python, Option<PyErr>) + Send>;