99 lines
2.7 KiB
Rust
99 lines
2.7 KiB
Rust
#![cfg(feature = "macros")]
|
|
#![cfg(not(target_arch = "wasm32"))]
|
|
use std::{task::Poll, thread, time::Duration};
|
|
|
|
use futures::{channel::oneshot, future::poll_fn};
|
|
use pyo3::{prelude::*, py_run};
|
|
|
|
#[path = "../src/tests/common.rs"]
|
|
mod common;
|
|
|
|
fn handle_windows(test: &str) -> String {
|
|
let set_event_loop_policy = r#"
|
|
import asyncio, sys
|
|
if sys.platform == "win32":
|
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
"#;
|
|
pyo3::unindent::unindent(set_event_loop_policy) + &pyo3::unindent::unindent(test)
|
|
}
|
|
|
|
#[test]
|
|
fn noop_coroutine() {
|
|
#[pyfunction]
|
|
async fn noop() -> usize {
|
|
42
|
|
}
|
|
Python::with_gil(|gil| {
|
|
let noop = wrap_pyfunction!(noop, gil).unwrap();
|
|
let test = "import asyncio; assert asyncio.run(noop()) == 42";
|
|
py_run!(gil, noop, &handle_windows(test));
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn sleep_0_like_coroutine() {
|
|
#[pyfunction]
|
|
async fn sleep_0() -> usize {
|
|
let mut waken = false;
|
|
poll_fn(|cx| {
|
|
if !waken {
|
|
cx.waker().wake_by_ref();
|
|
waken = true;
|
|
return Poll::Pending;
|
|
}
|
|
Poll::Ready(42)
|
|
})
|
|
.await
|
|
}
|
|
Python::with_gil(|gil| {
|
|
let sleep_0 = wrap_pyfunction!(sleep_0, gil).unwrap();
|
|
let test = "import asyncio; assert asyncio.run(sleep_0()) == 42";
|
|
py_run!(gil, sleep_0, &handle_windows(test));
|
|
})
|
|
}
|
|
|
|
#[pyfunction]
|
|
async fn sleep(seconds: f64) -> usize {
|
|
let (tx, rx) = oneshot::channel();
|
|
thread::spawn(move || {
|
|
thread::sleep(Duration::from_secs_f64(seconds));
|
|
tx.send(42).unwrap();
|
|
});
|
|
rx.await.unwrap()
|
|
}
|
|
|
|
#[test]
|
|
fn sleep_coroutine() {
|
|
Python::with_gil(|gil| {
|
|
let sleep = wrap_pyfunction!(sleep, gil).unwrap();
|
|
let test = r#"import asyncio; assert asyncio.run(sleep(0.1)) == 42"#;
|
|
py_run!(gil, sleep, &handle_windows(test));
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn cancelled_coroutine() {
|
|
Python::with_gil(|gil| {
|
|
let sleep = wrap_pyfunction!(sleep, gil).unwrap();
|
|
let test = r#"
|
|
import asyncio
|
|
async def main():
|
|
task = asyncio.create_task(sleep(1))
|
|
await asyncio.sleep(0)
|
|
task.cancel()
|
|
await task
|
|
asyncio.run(main())
|
|
"#;
|
|
let globals = gil.import("__main__").unwrap().dict();
|
|
globals.set_item("sleep", sleep).unwrap();
|
|
let err = gil
|
|
.run(
|
|
&pyo3::unindent::unindent(&handle_windows(test)),
|
|
Some(globals),
|
|
None,
|
|
)
|
|
.unwrap_err();
|
|
assert_eq!(err.value(gil).get_type().name().unwrap(), "CancelledError");
|
|
})
|
|
}
|