Skip to content

Commit 5a0f355

Browse files
authored
Migrate all pytests modules to declarative modules and adds stubs (#5735)
1 parent cb0c461 commit 5a0f355

File tree

17 files changed

+299
-229
lines changed

17 files changed

+299
-229
lines changed

pytests/src/awaitable.rs

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,82 +5,80 @@
55
//! when awaited, see guide examples related to pyo3-async-runtimes for ways
66
//! to suspend tasks and await results.
77
8-
use pyo3::exceptions::PyStopIteration;
98
use pyo3::prelude::*;
109

11-
#[pyclass]
12-
#[derive(Debug)]
13-
pub(crate) struct IterAwaitable {
14-
result: Option<PyResult<Py<PyAny>>>,
15-
}
16-
17-
#[pymethods]
18-
impl IterAwaitable {
19-
#[new]
20-
fn new(result: Py<PyAny>) -> Self {
21-
IterAwaitable {
22-
result: Some(Ok(result)),
23-
}
24-
}
10+
#[pymodule]
11+
pub mod awaitable {
12+
use pyo3::exceptions::PyStopIteration;
13+
use pyo3::prelude::*;
2514

26-
fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
27-
pyself
15+
#[pyclass]
16+
#[derive(Debug)]
17+
pub(crate) struct IterAwaitable {
18+
result: Option<PyResult<Py<PyAny>>>,
2819
}
2920

30-
fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
31-
pyself
32-
}
21+
#[pymethods]
22+
impl IterAwaitable {
23+
#[new]
24+
fn new(result: Py<PyAny>) -> Self {
25+
IterAwaitable {
26+
result: Some(Ok(result)),
27+
}
28+
}
3329

34-
fn __next__(&mut self, py: Python<'_>) -> PyResult<Py<PyAny>> {
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()),
30+
fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
31+
pyself
4132
}
42-
}
43-
}
4433

45-
#[pyclass]
46-
pub(crate) struct FutureAwaitable {
47-
#[pyo3(get, set, name = "_asyncio_future_blocking")]
48-
py_block: bool,
49-
result: Option<PyResult<Py<PyAny>>>,
50-
}
34+
fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
35+
pyself
36+
}
5137

52-
#[pymethods]
53-
impl FutureAwaitable {
54-
#[new]
55-
fn new(result: Py<PyAny>) -> Self {
56-
FutureAwaitable {
57-
py_block: false,
58-
result: Some(Ok(result)),
38+
fn __next__(&mut self, py: Python<'_>) -> PyResult<Py<PyAny>> {
39+
match self.result.take() {
40+
Some(res) => match res {
41+
Ok(v) => Err(PyStopIteration::new_err(v)),
42+
Err(err) => Err(err),
43+
},
44+
_ => Ok(py.None()),
45+
}
5946
}
6047
}
6148

62-
fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
63-
pyself
49+
#[pyclass]
50+
pub(crate) struct FutureAwaitable {
51+
#[pyo3(get, set, name = "_asyncio_future_blocking")]
52+
py_block: bool,
53+
result: Option<PyResult<Py<PyAny>>>,
6454
}
6555

66-
fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
67-
pyself
68-
}
56+
#[pymethods]
57+
impl FutureAwaitable {
58+
#[new]
59+
fn new(result: Py<PyAny>) -> Self {
60+
FutureAwaitable {
61+
py_block: false,
62+
result: Some(Ok(result)),
63+
}
64+
}
6965

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),
66+
fn __await__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
67+
pyself
7768
}
78-
}
79-
}
8069

81-
#[pymodule]
82-
pub fn awaitable(m: &Bound<'_, PyModule>) -> PyResult<()> {
83-
m.add_class::<IterAwaitable>()?;
84-
m.add_class::<FutureAwaitable>()?;
85-
Ok(())
70+
fn __iter__(pyself: PyRef<'_, Self>) -> PyRef<'_, Self> {
71+
pyself
72+
}
73+
74+
fn __next__(mut pyself: PyRefMut<'_, Self>) -> PyResult<PyRefMut<'_, Self>> {
75+
match pyself.result {
76+
Some(_) => match pyself.result.take().unwrap() {
77+
Ok(v) => Err(PyStopIteration::new_err(v)),
78+
Err(err) => Err(err),
79+
},
80+
_ => Ok(pyself),
81+
}
82+
}
83+
}
8684
}

pytests/src/datetime.rs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -204,25 +204,12 @@ impl TzClass {
204204
}
205205

206206
#[pymodule]
207-
pub fn datetime(m: &Bound<'_, PyModule>) -> PyResult<()> {
208-
m.add_function(wrap_pyfunction!(make_date, m)?)?;
209-
m.add_function(wrap_pyfunction!(get_date_tuple, m)?)?;
210-
m.add_function(wrap_pyfunction!(date_from_timestamp, m)?)?;
211-
m.add_function(wrap_pyfunction!(make_time, m)?)?;
212-
m.add_function(wrap_pyfunction!(get_time_tuple, m)?)?;
213-
m.add_function(wrap_pyfunction!(make_delta, m)?)?;
214-
m.add_function(wrap_pyfunction!(get_delta_tuple, m)?)?;
215-
m.add_function(wrap_pyfunction!(make_datetime, m)?)?;
216-
m.add_function(wrap_pyfunction!(get_datetime_tuple, m)?)?;
217-
m.add_function(wrap_pyfunction!(datetime_from_timestamp, m)?)?;
218-
m.add_function(wrap_pyfunction!(get_datetime_tzinfo, m)?)?;
219-
m.add_function(wrap_pyfunction!(get_time_tzinfo, m)?)?;
220-
221-
m.add_function(wrap_pyfunction!(time_with_fold, m)?)?;
222-
m.add_function(wrap_pyfunction!(get_time_tuple_fold, m)?)?;
223-
m.add_function(wrap_pyfunction!(get_datetime_tuple_fold, m)?)?;
224-
225-
m.add_class::<TzClass>()?;
226-
227-
Ok(())
207+
pub mod datetime {
208+
#[pymodule_export]
209+
use super::{
210+
date_from_timestamp, datetime_from_timestamp, get_date_tuple, get_datetime_tuple,
211+
get_datetime_tuple_fold, get_datetime_tzinfo, get_delta_tuple, get_time_tuple,
212+
get_time_tuple_fold, get_time_tzinfo, make_date, make_datetime, make_delta, make_time,
213+
time_with_fold, TzClass,
214+
};
228215
}

pytests/src/dict_iter.rs

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,41 @@
1-
use pyo3::exceptions::PyRuntimeError;
21
use pyo3::prelude::*;
3-
use pyo3::types::PyDict;
42

53
#[pymodule]
6-
pub fn dict_iter(m: &Bound<'_, PyModule>) -> PyResult<()> {
7-
m.add_class::<DictSize>()?;
8-
Ok(())
9-
}
10-
11-
#[pyclass]
12-
pub struct DictSize {
13-
expected: u32,
14-
}
4+
pub mod dict_iter {
5+
use pyo3::exceptions::PyRuntimeError;
6+
use pyo3::prelude::*;
7+
use pyo3::types::PyDict;
158

16-
#[pymethods]
17-
impl DictSize {
18-
#[new]
19-
fn new(expected: u32) -> Self {
20-
DictSize { expected }
9+
#[pyclass]
10+
pub struct DictSize {
11+
expected: u32,
2112
}
2213

23-
fn iter_dict(&mut self, _py: Python<'_>, dict: &Bound<'_, PyDict>) -> PyResult<u32> {
24-
let mut seen = 0u32;
25-
for (sym, values) in dict {
26-
seen += 1;
27-
println!(
28-
"{:4}/{:4} iterations:{}=>{}",
29-
seen, self.expected, sym, values
30-
);
14+
#[pymethods]
15+
impl DictSize {
16+
#[new]
17+
fn new(expected: u32) -> Self {
18+
DictSize { expected }
3119
}
3220

33-
if seen == self.expected {
34-
Ok(seen)
35-
} else {
36-
Err(PyErr::new::<PyRuntimeError, _>(format!(
37-
"Expected {} iterations - performed {}",
38-
self.expected, seen
39-
)))
21+
fn iter_dict(&mut self, _py: Python<'_>, dict: &Bound<'_, PyDict>) -> PyResult<u32> {
22+
let mut seen = 0u32;
23+
for (sym, values) in dict {
24+
seen += 1;
25+
println!(
26+
"{:4}/{:4} iterations:{}=>{}",
27+
seen, self.expected, sym, values
28+
);
29+
}
30+
31+
if seen == self.expected {
32+
Ok(seen)
33+
} else {
34+
Err(PyErr::new::<PyRuntimeError, _>(format!(
35+
"Expected {} iterations - performed {}",
36+
self.expected, seen
37+
)))
38+
}
4039
}
4140
}
4241
}

pytests/src/lib.rs

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
use pyo3::prelude::*;
22
use pyo3::types::PyDict;
3-
use pyo3::wrap_pymodule;
43

5-
pub mod awaitable;
6-
pub mod buf_and_str;
7-
pub mod comparisons;
4+
mod awaitable;
5+
mod buf_and_str;
6+
mod comparisons;
87
mod consts;
9-
pub mod datetime;
10-
pub mod dict_iter;
11-
pub mod enums;
8+
mod datetime;
9+
mod dict_iter;
10+
mod enums;
1211
mod exception;
13-
pub mod misc;
14-
pub mod objstore;
15-
pub mod othermod;
16-
pub mod path;
17-
pub mod pyclasses;
18-
pub mod pyfunctions;
19-
pub mod sequence;
20-
pub mod subclassing;
12+
mod misc;
13+
mod objstore;
14+
mod othermod;
15+
mod path;
16+
mod pyclasses;
17+
mod pyfunctions;
18+
mod sequence;
19+
mod subclassing;
2120

2221
#[pymodule]
2322
mod pyo3_pytests {
@@ -26,29 +25,23 @@ mod pyo3_pytests {
2625
#[cfg(any(not(Py_LIMITED_API), Py_3_11))]
2726
#[pymodule_export]
2827
use buf_and_str::buf_and_str;
28+
29+
#[cfg(not(Py_LIMITED_API))]
30+
#[pymodule_export]
31+
use datetime::datetime;
32+
2933
#[pymodule_export]
3034
use {
31-
comparisons::comparisons, consts::consts, enums::enums, exception::exception,
32-
pyclasses::pyclasses, pyfunctions::pyfunctions, subclassing::subclassing,
35+
awaitable::awaitable, comparisons::comparisons, consts::consts, dict_iter::dict_iter,
36+
enums::enums, exception::exception, misc::misc, objstore::objstore, othermod::othermod,
37+
path::path, pyclasses::pyclasses, pyfunctions::pyfunctions, sequence::sequence,
38+
subclassing::subclassing,
3339
};
3440

3541
// Inserting to sys.modules allows importing submodules nicely from Python
3642
// e.g. import pyo3_pytests.buf_and_str as bas
3743
#[pymodule_init]
3844
fn init(m: &Bound<'_, PyModule>) -> PyResult<()> {
39-
m.add_wrapped(wrap_pymodule!(awaitable::awaitable))?;
40-
#[cfg(not(Py_LIMITED_API))]
41-
m.add_wrapped(wrap_pymodule!(datetime::datetime))?;
42-
m.add_wrapped(wrap_pymodule!(dict_iter::dict_iter))?;
43-
m.add_wrapped(wrap_pymodule!(misc::misc))?;
44-
m.add_wrapped(wrap_pymodule!(objstore::objstore))?;
45-
m.add_wrapped(wrap_pymodule!(othermod::othermod))?;
46-
m.add_wrapped(wrap_pymodule!(path::path))?;
47-
m.add_wrapped(wrap_pymodule!(sequence::sequence))?;
48-
49-
// Inserting to sys.modules allows importing submodules nicely from Python
50-
// e.g. import pyo3_pytests.buf_and_str as bas
51-
5245
let sys = PyModule::import(m.py(), "sys")?;
5346
let sys_modules = sys.getattr("modules")?.cast_into::<PyDict>()?;
5447
sys_modules.set_item("pyo3_pytests.awaitable", m.getattr("awaitable")?)?;

pytests/src/misc.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ fn get_item_and_run_callback(dict: Bound<'_, PyDict>, callback: Bound<'_, PyAny>
5555
}
5656

5757
#[pymodule]
58-
pub fn misc(m: &Bound<'_, PyModule>) -> PyResult<()> {
59-
m.add_function(wrap_pyfunction!(issue_219, m)?)?;
60-
m.add_function(wrap_pyfunction!(hammer_attaching_in_thread, m)?)?;
61-
m.add_function(wrap_pyfunction!(get_type_fully_qualified_name, m)?)?;
62-
m.add_function(wrap_pyfunction!(accepts_bool, m)?)?;
63-
m.add_function(wrap_pyfunction!(get_item_and_run_callback, m)?)?;
64-
Ok(())
58+
pub mod misc {
59+
#[pymodule_export]
60+
use super::{
61+
accepts_bool, get_item_and_run_callback, get_type_fully_qualified_name,
62+
hammer_attaching_in_thread, issue_219,
63+
};
6564
}

pytests/src/objstore.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
use pyo3::prelude::*;
22

3-
#[pyclass]
4-
#[derive(Default)]
5-
pub struct ObjStore {
6-
obj: Vec<Py<PyAny>>,
7-
}
3+
#[pymodule]
4+
pub mod objstore {
5+
use pyo3::prelude::*;
86

9-
#[pymethods]
10-
impl ObjStore {
11-
#[new]
12-
fn new() -> Self {
13-
ObjStore::default()
7+
#[pyclass]
8+
#[derive(Default)]
9+
pub struct ObjStore {
10+
obj: Vec<Py<PyAny>>,
1411
}
1512

16-
fn push(&mut self, obj: &Bound<'_, PyAny>) {
17-
self.obj.push(obj.clone().unbind());
18-
}
19-
}
13+
#[pymethods]
14+
impl ObjStore {
15+
#[new]
16+
fn new() -> Self {
17+
ObjStore::default()
18+
}
2019

21-
#[pymodule]
22-
pub fn objstore(m: &Bound<'_, PyModule>) -> PyResult<()> {
23-
m.add_class::<ObjStore>()
20+
fn push(&mut self, obj: &Bound<'_, PyAny>) {
21+
self.obj.push(obj.clone().unbind());
22+
}
23+
}
2424
}

0 commit comments

Comments
 (0)