mixed_sub/
lib.rs

1use pyo3::prelude::*;
2use pyo3_stub_gen::{define_stub_info_gatherer, derive::*};
3
4// Classes that can be cross-referenced between modules (from mixed_sub_import_type)
5#[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// Class without explicit module specification
27#[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// Original functions from mixed_sub
49#[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// Class C in mod_a that references A and B (demonstrates cross-module type references)
68#[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// Simple class in mod_b (from mixed_sub)
94#[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// Function in int submodule to test namespace collision
116#[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    // Add classes and functions to main module
125    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    // Add submodules
132    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
158/// A dummy module to test namespace collision with built-in 'int'
159fn 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/// Test of unit test for testing link problem
170#[cfg(test)]
171mod test {
172    #[test]
173    fn test() {
174        assert_eq!(2 + 2, 4);
175    }
176}