Skip to content

Commit 31e1984

Browse files
author
Andrew J Westlake
committed
Cleaned up some docs
1 parent a45c3c8 commit 31e1984

File tree

5 files changed

+23
-134
lines changed

5 files changed

+23
-134
lines changed

pytests/test_tokio_asyncio.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
mod common;
22

3-
use std::{
4-
future::{pending, Future},
5-
thread,
6-
time::Duration,
7-
};
3+
use std::{future::Future, time::Duration};
84

9-
use lazy_static::lazy_static;
105
use pyo3::{prelude::*, wrap_pyfunction};
11-
use tokio::runtime::{Builder, Runtime};
126

137
use pyo3_asyncio::{
148
testing::Test,

src/async_std.rs

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::future::Future;
22

33
use async_std::task;
4-
use futures::channel::oneshot;
54
use pyo3::prelude::*;
65

76
use crate::generic::{self, JoinError, Runtime};
@@ -70,45 +69,6 @@ where
7069
generic::run_until_complete::<AsyncStdRuntime, _>(py, fut)
7170
}
7271

73-
#[pyclass]
74-
struct PyTaskCompleter {
75-
tx: Option<oneshot::Sender<PyResult<PyObject>>>,
76-
}
77-
78-
#[pymethods]
79-
impl PyTaskCompleter {
80-
#[call]
81-
#[args(task)]
82-
pub fn __call__(&mut self, task: &PyAny) -> PyResult<()> {
83-
debug_assert!(task.call_method0("done")?.extract()?);
84-
85-
let result = match task.call_method0("result") {
86-
Ok(val) => Ok(val.into()),
87-
Err(e) => Err(e),
88-
};
89-
90-
// unclear to me whether or not this should be a panic or silent error.
91-
//
92-
// calling PyTaskCompleter twice should not be possible, but I don't think it really hurts
93-
// anything if it happens.
94-
if let Some(tx) = self.tx.take() {
95-
if tx.send(result).is_err() {
96-
// cancellation is not an error
97-
}
98-
}
99-
100-
Ok(())
101-
}
102-
}
103-
104-
fn dump_err(py: Python<'_>) -> impl FnOnce(PyErr) + '_ {
105-
move |e| {
106-
// We can't display Python exceptions via std::fmt::Display,
107-
// so print the error here manually.
108-
e.print_and_set_sys_last_vars(py);
109-
}
110-
}
111-
11272
/// Convert a Rust Future into a Python coroutine
11373
///
11474
/// # Arguments
@@ -230,11 +190,7 @@ pub mod testing {
230190
use async_std::task;
231191
use pyo3::prelude::*;
232192

233-
use crate::{
234-
async_std::{dump_err, run_until_complete},
235-
testing::{parse_args, test_harness, Test},
236-
with_runtime,
237-
};
193+
use crate::{async_std::AsyncStdRuntime, generic, testing::Test};
238194

239195
/// Construct a test from a blocking function (like the traditional `#[test]` attribute)
240196
pub fn new_sync_test<F>(name: String, func: F) -> Test
@@ -250,14 +206,6 @@ pub mod testing {
250206
/// additional control over the initialization (i.e. env_logger initialization), you can use this
251207
/// function as a template.
252208
pub fn test_main(suite_name: &str, tests: Vec<Test>) {
253-
Python::with_gil(|py| {
254-
with_runtime(py, || {
255-
let args = parse_args(suite_name);
256-
run_until_complete(py, test_harness(tests, args))?;
257-
Ok(())
258-
})
259-
.map_err(dump_err(py))
260-
.unwrap();
261-
})
209+
generic::testing::test_main::<AsyncStdRuntime>(suite_name, tests)
262210
}
263211
}

src/generic.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@ use std::future::Future;
33
use futures::channel::oneshot;
44
use pyo3::{exceptions::PyException, prelude::*};
55

6-
use crate::{get_event_loop, CALL_SOON, CREATE_FUTURE, EXPECT_INIT};
6+
use crate::{dump_err, get_event_loop, CALL_SOON, CREATE_FUTURE, EXPECT_INIT};
77

8+
/// Generic utilities for a JoinError
89
pub trait JoinError {
10+
/// Check if the spawned task exited because of a panic
911
fn is_panic(&self) -> bool;
1012
}
1113

14+
/// Generic Rust async/await runtime
1215
pub trait Runtime {
16+
/// The type of errors that a JoinHandle can return after awaited
1317
type JoinError: JoinError + Send;
18+
/// A future that completes with the result of the spawned task
1419
type JoinHandle: Future<Output = Result<(), Self::JoinError>> + Send;
1520

21+
/// Spawn a function onto this runtime's event loop
1622
fn spawn<F>(fut: F) -> Self::JoinHandle
1723
where
1824
F: Future<Output = ()> + Send + 'static;
@@ -153,14 +159,6 @@ fn set_result(py: Python, future: &PyAny, result: PyResult<PyObject>) -> PyResul
153159
Ok(())
154160
}
155161

156-
fn dump_err(py: Python<'_>) -> impl FnOnce(PyErr) + '_ {
157-
move |e| {
158-
// We can't display Python exceptions via std::fmt::Display,
159-
// so print the error here manually.
160-
e.print_and_set_sys_last_vars(py);
161-
}
162-
}
163-
164162
/// Convert a Rust Future into a Python coroutine with a generic runtime
165163
///
166164
/// # Arguments
@@ -272,7 +270,8 @@ pub mod testing {
272270
use pyo3::prelude::*;
273271

274272
use crate::{
275-
generic::{dump_err, run_until_complete, Runtime},
273+
dump_err,
274+
generic::{run_until_complete, Runtime},
276275
testing::{parse_args, test_harness, Test},
277276
with_runtime,
278277
};

src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ pub mod async_std;
9090
#[doc(inline)]
9191
pub mod tokio;
9292

93+
/// Generic implementations of PyO3 Asyncio utilities that can be used for any Rust runtime
9394
pub mod generic;
9495

9596
use std::future::Future;
@@ -372,3 +373,11 @@ pub fn into_future(
372373
}
373374
})
374375
}
376+
377+
fn dump_err(py: Python<'_>) -> impl FnOnce(PyErr) + '_ {
378+
move |e| {
379+
// We can't display Python exceptions via std::fmt::Display,
380+
// so print the error here manually.
381+
e.print_and_set_sys_last_vars(py);
382+
}
383+
}

src/tokio.rs

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ use ::tokio::{
77
runtime::{Builder, Runtime},
88
task,
99
};
10-
use futures::channel::oneshot;
1110
use lazy_static::lazy_static;
1211
use pyo3::prelude::*;
1312

14-
use crate::{generic, CALL_SOON, EXPECT_INIT};
13+
use crate::generic;
1514

1615
lazy_static! {
1716
static ref CURRENT_THREAD_RUNTIME: Runtime = {
@@ -97,66 +96,6 @@ where
9796
generic::run_until_complete::<TokioRuntime, _>(py, fut)
9897
}
9998

100-
#[pyclass]
101-
struct PyTaskCompleter {
102-
tx: Option<oneshot::Sender<PyResult<PyObject>>>,
103-
}
104-
105-
#[pymethods]
106-
impl PyTaskCompleter {
107-
#[call]
108-
#[args(task)]
109-
pub fn __call__(&mut self, task: &PyAny) -> PyResult<()> {
110-
debug_assert!(task.call_method0("done")?.extract()?);
111-
112-
let result = match task.call_method0("result") {
113-
Ok(val) => Ok(val.into()),
114-
Err(e) => Err(e),
115-
};
116-
117-
// unclear to me whether or not this should be a panic or silent error.
118-
//
119-
// calling PyTaskCompleter twice should not be possible, but I don't think it really hurts
120-
// anything if it happens.
121-
if let Some(tx) = self.tx.take() {
122-
if tx.send(result).is_err() {
123-
// cancellation is not an error
124-
}
125-
}
126-
127-
Ok(())
128-
}
129-
}
130-
131-
fn set_result(py: Python, future: &PyAny, result: PyResult<PyObject>) -> PyResult<()> {
132-
match result {
133-
Ok(val) => {
134-
let set_result = future.getattr("set_result")?;
135-
CALL_SOON
136-
.get()
137-
.expect(EXPECT_INIT)
138-
.call1(py, (set_result, val))?;
139-
}
140-
Err(err) => {
141-
let set_exception = future.getattr("set_exception")?;
142-
CALL_SOON
143-
.get()
144-
.expect(EXPECT_INIT)
145-
.call1(py, (set_exception, err))?;
146-
}
147-
}
148-
149-
Ok(())
150-
}
151-
152-
fn dump_err(py: Python<'_>) -> impl FnOnce(PyErr) + '_ {
153-
move |e| {
154-
// We can't display Python exceptions via std::fmt::Display,
155-
// so print the error here manually.
156-
e.print_and_set_sys_last_vars(py);
157-
}
158-
}
159-
16099
/// Convert a Rust Future into a Python coroutine
161100
///
162101
/// # Arguments
@@ -275,8 +214,8 @@ pub mod testing {
275214
use pyo3::prelude::*;
276215

277216
use crate::{
217+
dump_err,
278218
testing::{parse_args, test_harness, Test},
279-
tokio::dump_err,
280219
with_runtime,
281220
};
282221

0 commit comments

Comments
 (0)