pyo3_pytests/
awaitable.rs1use pyo3::exceptions::PyStopIteration;
9use pyo3::prelude::*;
10
11#[pyclass]
12#[derive(Debug)]
13pub(crate) struct IterAwaitable {
14 result: Option<PyResult<PyObject>>,
15}
16
17#[pymethods]
18impl IterAwaitable {
19 #[new]
20 fn new(result: PyObject) -> Self {
21 IterAwaitable {
22 result: Some(Ok(result)),
23 }
24 }
25
26 fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
27 pyself
28 }
29
30 fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
31 pyself
32 }
33
34 fn __next__(&mut self, py: Python<'_>) -> PyResult<PyObject> {
35 match self.result.take() {
36 Some(res) => match res {
37 Ok(v) => Err(PyStopIteration::new_err(v)),
38 Err(err) => Err(err),
39 },
40 _ => Ok(py.None()),
41 }
42 }
43}
44
45#[pyclass]
46pub(crate) struct FutureAwaitable {
47 #[pyo3(get, set, name = "_asyncio_future_blocking")]
48 py_block: bool,
49 result: Option<PyResult<PyObject>>,
50}
51
52#[pymethods]
53impl FutureAwaitable {
54 #[new]
55 fn new(result: PyObject) -> Self {
56 FutureAwaitable {
57 py_block: false,
58 result: Some(Ok(result)),
59 }
60 }
61
62 fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
63 pyself
64 }
65
66 fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
67 pyself
68 }
69
70 fn __next__(mut pyself: PyRefMut<'_, Self>) -> PyResult<PyRefMut<'_, Self>> {
71 match pyself.result {
72 Some(_) => match pyself.result.take().unwrap() {
73 Ok(v) => Err(PyStopIteration::new_err(v)),
74 Err(err) => Err(err),
75 },
76 _ => Ok(pyself),
77 }
78 }
79}
80
81#[pymodule(gil_used = false)]
82pub fn awaitable(m: &Bound<'_, PyModule>) -> PyResult<()> {
83 m.add_class::<IterAwaitable>()?;
84 m.add_class::<FutureAwaitable>()?;
85 Ok(())
86}