parent
186c7d3315
commit
e73112f3f6
|
@ -151,7 +151,6 @@ For nested modules, the name of the parent module is automatically added.
|
|||
In the following example, the `Unit` class will have for `module` `my_extension.submodule` because it is properly nested
|
||||
but the `Ext` class will have for `module` the default `builtins` because it not nested.
|
||||
|
||||
You can provide the `submodule` argument to `pymodule()` for modules that are not top-level modules.
|
||||
```rust
|
||||
# mod declarative_module_module_attr_test {
|
||||
use pyo3::prelude::*;
|
||||
|
@ -166,7 +165,7 @@ mod my_extension {
|
|||
#[pymodule_export]
|
||||
use super::Ext;
|
||||
|
||||
#[pymodule(submodule)]
|
||||
#[pymodule]
|
||||
mod submodule {
|
||||
use super::*;
|
||||
// This is a submodule
|
||||
|
@ -179,3 +178,4 @@ mod my_extension {
|
|||
```
|
||||
It is possible to customize the `module` value for a `#[pymodule]` with the `#[pyo3(module = "MY_MODULE")]` option.
|
||||
|
||||
You can provide the `submodule` argument to `pymodule()` for modules that are not top-level modules -- it is automatically set for modules nested inside of a `#[pymodule]`.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Nested declarative `#[pymodule]` are automatically treated as submodules (no `PyInit_` entrypoint is created)
|
|
@ -80,7 +80,7 @@ impl PyModuleOptions {
|
|||
fn set_submodule(&mut self, submod: SubmoduleAttribute) -> Result<()> {
|
||||
ensure_spanned!(
|
||||
!self.is_submodule,
|
||||
submod.span() => "`submodule` may only be specified once"
|
||||
submod.span() => "`submodule` may only be specified once (it is implicitly always specified for nested modules)"
|
||||
);
|
||||
|
||||
self.is_submodule = true;
|
||||
|
@ -116,7 +116,14 @@ pub fn pymodule_module_impl(
|
|||
} else {
|
||||
name.to_string()
|
||||
};
|
||||
is_submodule = is_submodule || options.is_submodule;
|
||||
|
||||
is_submodule = match (is_submodule, options.is_submodule) {
|
||||
(true, true) => {
|
||||
bail_spanned!(module.span() => "`submodule` may only be specified once (it is implicitly always specified for nested modules)")
|
||||
}
|
||||
(false, false) => false,
|
||||
(true, false) | (false, true) => true,
|
||||
};
|
||||
|
||||
let mut module_items = Vec::new();
|
||||
let mut module_items_cfg_attrs = Vec::new();
|
||||
|
@ -273,6 +280,7 @@ pub fn pymodule_module_impl(
|
|||
)? {
|
||||
set_module_attribute(&mut item_mod.attrs, &full_name);
|
||||
}
|
||||
item_mod.attrs.push(parse_quote!(#[pyo3(submodule)]));
|
||||
}
|
||||
}
|
||||
Item::ForeignMod(item) => {
|
||||
|
|
|
@ -66,4 +66,5 @@ fn test_compile_errors() {
|
|||
t.compile_fail("tests/ui/abi3_weakref.rs");
|
||||
#[cfg(all(Py_LIMITED_API, not(Py_3_9)))]
|
||||
t.compile_fail("tests/ui/abi3_dict.rs");
|
||||
t.compile_fail("tests/ui/duplicate_pymodule_submodule.rs");
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ mod declarative_module {
|
|||
}
|
||||
}
|
||||
|
||||
#[pymodule(submodule)]
|
||||
#[pymodule]
|
||||
#[pyo3(module = "custom_root")]
|
||||
mod inner_custom_root {
|
||||
use super::*;
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#[pyo3::pymodule]
|
||||
mod mymodule {
|
||||
#[pyo3::pymodule(submodule)]
|
||||
mod submod {}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,11 @@
|
|||
error: `submodule` may only be specified once (it is implicitly always specified for nested modules)
|
||||
--> tests/ui/duplicate_pymodule_submodule.rs:4:2
|
||||
|
|
||||
4 | mod submod {}
|
||||
| ^^^
|
||||
|
||||
error[E0433]: failed to resolve: use of undeclared crate or module `submod`
|
||||
--> tests/ui/duplicate_pymodule_submodule.rs:4:6
|
||||
|
|
||||
4 | mod submod {}
|
||||
| ^^^^^^ use of undeclared crate or module `submod`
|
Loading…
Reference in New Issue