pyo3_pytests/
pyclasses.rs1use std::{thread, time};
2
3use pyo3::exceptions::{PyStopIteration, PyValueError};
4use pyo3::prelude::*;
5use pyo3::types::PyType;
6
7#[pyclass]
8struct EmptyClass {}
9
10#[pymethods]
11impl EmptyClass {
12 #[new]
13 fn new() -> Self {
14 EmptyClass {}
15 }
16
17 fn method(&self) {}
18
19 fn __len__(&self) -> usize {
20 0
21 }
22}
23
24#[pyclass]
26#[derive(Default)]
27struct PyClassIter {
28 count: usize,
29}
30
31#[pymethods]
32impl PyClassIter {
33 #[new]
34 pub fn new() -> Self {
35 Default::default()
36 }
37
38 fn __next__(&mut self) -> PyResult<usize> {
39 if self.count < 5 {
40 self.count += 1;
41 Ok(self.count)
42 } else {
43 Err(PyStopIteration::new_err("Ended"))
44 }
45 }
46}
47
48#[pyclass]
49#[derive(Default)]
50struct PyClassThreadIter {
51 count: usize,
52}
53
54#[pymethods]
55impl PyClassThreadIter {
56 #[new]
57 pub fn new() -> Self {
58 Default::default()
59 }
60
61 fn __next__(&mut self, py: Python<'_>) -> usize {
62 let current_count = self.count;
63 self.count += 1;
64 if current_count == 0 {
65 py.allow_threads(|| thread::sleep(time::Duration::from_millis(100)));
66 }
67 self.count
68 }
69}
70
71#[pyclass(subclass)]
73#[derive(Clone, Debug)]
74struct AssertingBaseClass;
75
76#[pymethods]
77impl AssertingBaseClass {
78 #[new]
79 #[classmethod]
80 fn new(cls: &Bound<'_, PyType>, expected_type: Bound<'_, PyType>) -> PyResult<Self> {
81 if !cls.is(&expected_type) {
82 return Err(PyValueError::new_err(format!(
83 "{:?} != {:?}",
84 cls, expected_type
85 )));
86 }
87 Ok(Self)
88 }
89}
90
91#[pyclass]
92struct ClassWithoutConstructor;
93
94#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
95#[pyclass(dict)]
96struct ClassWithDict;
97
98#[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
99#[pymethods]
100impl ClassWithDict {
101 #[new]
102 fn new() -> Self {
103 ClassWithDict
104 }
105}
106
107#[pymodule(gil_used = false)]
108pub fn pyclasses(m: &Bound<'_, PyModule>) -> PyResult<()> {
109 m.add_class::<EmptyClass>()?;
110 m.add_class::<PyClassIter>()?;
111 m.add_class::<PyClassThreadIter>()?;
112 m.add_class::<AssertingBaseClass>()?;
113 m.add_class::<ClassWithoutConstructor>()?;
114 #[cfg(any(Py_3_10, not(Py_LIMITED_API)))]
115 m.add_class::<ClassWithDict>()?;
116
117 Ok(())
118}