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#[gen_stub_pyfunction(
125 module = "mixed_sub.main_mod.mod_a",
126 python = r#"
127 import typing
128
129 def test_module_with_python(x: typing.Generator[int, None, None]) -> int:
130 """Test function with both module and python parameters"""
131"#
132)]
133#[pyfunction]
134fn test_module_with_python(_x: &Bound<PyAny>) -> PyResult<usize> {
135 Ok(42)
136}
137
138#[pymodule]
139fn main_mod(m: &Bound<PyModule>) -> PyResult<()> {
140 m.add_class::<A>()?;
142 m.add_class::<B>()?;
143 m.add_function(wrap_pyfunction!(create_a, m)?)?;
144 m.add_function(wrap_pyfunction!(create_b, m)?)?;
145 m.add_function(wrap_pyfunction!(greet_main, m)?)?;
146
147 mod_a(m)?;
149 mod_b(m)?;
150 int_mod(m)?;
151 Ok(())
152}
153
154fn mod_a(parent: &Bound<PyModule>) -> PyResult<()> {
155 let py = parent.py();
156 let sub = PyModule::new(py, "mod_a")?;
157 sub.add_class::<C>()?;
158 sub.add_function(wrap_pyfunction!(greet_a, &sub)?)?;
159 sub.add_function(wrap_pyfunction!(create_c, &sub)?)?;
160 sub.add_function(wrap_pyfunction!(test_module_with_python, &sub)?)?;
161 parent.add_submodule(&sub)?;
162 Ok(())
163}
164
165fn mod_b(parent: &Bound<PyModule>) -> PyResult<()> {
166 let py = parent.py();
167 let sub = PyModule::new(py, "mod_b")?;
168 sub.add_class::<D>()?;
169 sub.add_function(wrap_pyfunction!(greet_b, &sub)?)?;
170 sub.add_function(wrap_pyfunction!(create_d, &sub)?)?;
171 parent.add_submodule(&sub)?;
172 Ok(())
173}
174
175fn int_mod(parent: &Bound<PyModule>) -> PyResult<()> {
177 let py = parent.py();
178 let sub = PyModule::new(py, "int")?;
179 sub.add_function(wrap_pyfunction!(dummy_int_fun, &sub)?)?;
180 parent.add_submodule(&sub)?;
181 Ok(())
182}
183
184use pyo3_stub_gen::inventory::submit;
186
187submit! {
188 gen_function_from_python! {
189 module = "mixed_sub.main_mod.mod_b",
190 r#"
191 import typing
192
193 def test_submit_with_module(values: typing.List[int]) -> int:
194 """Test function defined with gen_function_from_python! and module parameter"""
195 "#
196 }
197}
198
199define_stub_info_gatherer!(stub_info);
200
201#[cfg(test)]
203mod test {
204 #[test]
205 fn test() {
206 assert_eq!(2 + 2, 4);
207 }
208}