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
|
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.
|
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
|
```rust
|
||||||
# mod declarative_module_module_attr_test {
|
# mod declarative_module_module_attr_test {
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
@ -166,7 +165,7 @@ mod my_extension {
|
||||||
#[pymodule_export]
|
#[pymodule_export]
|
||||||
use super::Ext;
|
use super::Ext;
|
||||||
|
|
||||||
#[pymodule(submodule)]
|
#[pymodule]
|
||||||
mod submodule {
|
mod submodule {
|
||||||
use super::*;
|
use super::*;
|
||||||
// This is a submodule
|
// 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.
|
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<()> {
|
fn set_submodule(&mut self, submod: SubmoduleAttribute) -> Result<()> {
|
||||||
ensure_spanned!(
|
ensure_spanned!(
|
||||||
!self.is_submodule,
|
!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;
|
self.is_submodule = true;
|
||||||
|
@ -116,7 +116,14 @@ pub fn pymodule_module_impl(
|
||||||
} else {
|
} else {
|
||||||
name.to_string()
|
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 = Vec::new();
|
||||||
let mut module_items_cfg_attrs = 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);
|
set_module_attribute(&mut item_mod.attrs, &full_name);
|
||||||
}
|
}
|
||||||
|
item_mod.attrs.push(parse_quote!(#[pyo3(submodule)]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item::ForeignMod(item) => {
|
Item::ForeignMod(item) => {
|
||||||
|
|
|
@ -66,4 +66,5 @@ fn test_compile_errors() {
|
||||||
t.compile_fail("tests/ui/abi3_weakref.rs");
|
t.compile_fail("tests/ui/abi3_weakref.rs");
|
||||||
#[cfg(all(Py_LIMITED_API, not(Py_3_9)))]
|
#[cfg(all(Py_LIMITED_API, not(Py_3_9)))]
|
||||||
t.compile_fail("tests/ui/abi3_dict.rs");
|
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")]
|
#[pyo3(module = "custom_root")]
|
||||||
mod inner_custom_root {
|
mod inner_custom_root {
|
||||||
use super::*;
|
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