1use pyo3::prelude::*;
2use pyo3_stub_gen::{define_stub_info_gatherer, derive::*};
3
4#[gen_stub_pyclass]
6#[pyclass(module = "mixed_sub.main_mod")]
7#[derive(Debug, Clone)]
8struct A {
9 x: usize,
10}
11
12#[gen_stub_pymethods]
13#[pymethods]
14impl A {
15 fn show_x(&self) {
16 println!("x = {}", self.x);
17 }
18}
19
20#[gen_stub_pyfunction(module = "mixed_sub.main_mod")]
21#[pyfunction]
22fn create_a(x: usize) -> A {
23 A { x }
24}
25
26#[gen_stub_pyclass]
28#[pyclass]
29#[derive(Debug, Clone)]
30struct B {
31 x: usize,
32}
33
34#[gen_stub_pymethods]
35#[pymethods]
36impl B {
37 fn show_x(&self) {
38 println!("x = {}", self.x);
39 }
40}
41
42#[gen_stub_pyfunction]
43#[pyfunction]
44fn create_b(x: usize) -> B {
45 B { x }
46}
47
48#[gen_stub_pyfunction(module = "mixed_sub.main_mod.mod_a")]
50#[pyfunction(name = "greet_a")]
51pub fn greet_a() {
52 println!("Hello from mod_A!")
53}
54
55#[gen_stub_pyfunction(module = "mixed_sub.main_mod")]
56#[pyfunction(name = "greet_main")]
57pub fn greet_main() {
58 println!("Hello from main_mod!")
59}
60
61#[gen_stub_pyfunction(module = "mixed_sub.main_mod.mod_b")]
62#[pyfunction(name = "greet_b")]
63pub fn greet_b() {
64 println!("Hello from mod_B!")
65}
66
67#[gen_stub_pyclass]
69#[pyclass(module = "mixed_sub.main_mod.mod_a")]
70#[derive(Debug)]
71struct C {
72 a: A,
73 b: B,
74}
75
76#[gen_stub_pymethods]
77#[pymethods]
78impl C {
79 fn show_x(&self) {
80 println!("a.x:");
81 self.a.show_x();
82 println!("b.x:");
83 self.b.show_x();
84 }
85}
86
87#[gen_stub_pyfunction(module = "mixed_sub.main_mod.mod_a")]
88#[pyfunction]
89fn create_c(a: A, b: B) -> C {
90 C { a, b }
91}
92
93#[gen_stub_pyclass]
95#[pyclass(module = "mixed_sub.main_mod.mod_b")]
96#[derive(Debug)]
97struct D {
98 x: usize,
99}
100
101#[gen_stub_pymethods]
102#[pymethods]
103impl D {
104 fn show_x(&self) {
105 println!("x = {}", self.x);
106 }
107}
108
109#[gen_stub_pyfunction(module = "mixed_sub.main_mod.mod_b")]
110#[pyfunction]
111fn create_d(x: usize) -> D {
112 D { x }
113}
114
115#[gen_stub_pyfunction(module = "mixed_sub.main_mod.int")]
117#[pyfunction]
118fn dummy_int_fun(x: usize) -> usize {
119 x
120}
121
122#[pymodule]
123fn main_mod(m: &Bound<PyModule>) -> PyResult<()> {
124 m.add_class::<A>()?;
126 m.add_class::<B>()?;
127 m.add_function(wrap_pyfunction!(create_a, m)?)?;
128 m.add_function(wrap_pyfunction!(create_b, m)?)?;
129 m.add_function(wrap_pyfunction!(greet_main, m)?)?;
130
131 mod_a(m)?;
133 mod_b(m)?;
134 int_mod(m)?;
135 Ok(())
136}
137
138fn mod_a(parent: &Bound<PyModule>) -> PyResult<()> {
139 let py = parent.py();
140 let sub = PyModule::new(py, "mod_a")?;
141 sub.add_class::<C>()?;
142 sub.add_function(wrap_pyfunction!(greet_a, &sub)?)?;
143 sub.add_function(wrap_pyfunction!(create_c, &sub)?)?;
144 parent.add_submodule(&sub)?;
145 Ok(())
146}
147
148fn mod_b(parent: &Bound<PyModule>) -> PyResult<()> {
149 let py = parent.py();
150 let sub = PyModule::new(py, "mod_b")?;
151 sub.add_class::<D>()?;
152 sub.add_function(wrap_pyfunction!(greet_b, &sub)?)?;
153 sub.add_function(wrap_pyfunction!(create_d, &sub)?)?;
154 parent.add_submodule(&sub)?;
155 Ok(())
156}
157
158fn int_mod(parent: &Bound<PyModule>) -> PyResult<()> {
160 let py = parent.py();
161 let sub = PyModule::new(py, "int")?;
162 sub.add_function(wrap_pyfunction!(dummy_int_fun, &sub)?)?;
163 parent.add_submodule(&sub)?;
164 Ok(())
165}
166
167define_stub_info_gatherer!(stub_info);
168
169#[cfg(test)]
171mod test {
172 #[test]
173 fn test() {
174 assert_eq!(2 + 2, 4);
175 }
176}