Open
Description
Bug Description
#[pyclass(module = "module")]
struct Foo {}
Correctly sets the __module__
attribute of the class.
The same behavior for other (sub) pymodule
s is expected.
The attribute is needed for tools such as https://github.com/mkdocstrings/griffe to properly find the submodule. See PyO3/maturin#1365.
What seems to happen is the module
value of the submodule is used to determine the module
value of the (inlined) pyclass
es.
Steps to Reproduce
- Create a module with a submodule. Use module="..."
/// Module documentation: A Python module implemented in Rust.
#[pymodule]
mod mymodule {
use pyo3::prelude::*;
/// Sub-Module documentation!!!
#[pymodule(module="mymodule.mymodule.submodule")]
mod submodule {
use super::*;
#[pyclass]
struct Foo{};
/// Hack: workaround for https://github.com/PyO3/pyo3/issues/759
fn init(m: &Bound<'_, PyModule>) -> PyResult<()> {
Python::with_gil(|py| {
py.import("sys")?
.getattr("modules")?
.set_item("mymodule.submodule", m)
})
}
}
}
- Check the
__module__
attribute`
>>> from mymodule import submodule
>>> submodule.__module__
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
submodule.__module__
AttributeError: module 'submodule' has no attribute '__module__'
Backtrace
Your operating system and version
Fedora 41
Your Python version (python --version
)
Python 3.13.1
Your Rust version (rustc --version
)
rustc 1.81.0 (eeb90cda1 2024-09-04)
Your PyO3 version
pyo3 v0.23.3 (https://github.com/PyO3/pyo3#5c363b5d)
How did you install python? Did you use a virtualenv?
dnf install python
Additional Info
As a workaround, __module__
attribute could be set manually:
fn init(m: &Bound<'_, PyModule>) -> PyResult<()> {
Python::with_gil(|py| {
py.import("sys")?
.getattr("modules")?
.set_item("mymodule.submodule", m)
})?;
m.setattr("__module__", "mymodule.mymodule.submodule") // <-- Add this
}