From 7cde95bba4f672b4840dcd8543e3da0076bd49ec Mon Sep 17 00:00:00 2001 From: Thomas Tanon Date: Tue, 12 Mar 2024 23:57:31 +0100 Subject: [PATCH] Documents experimental-declarative-modules feature (#3953) * Documents experimental-declarative-modules feature * More details on experimental-declarative-modules progress --- guide/src/features.md | 6 +++++ guide/src/module.md | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/guide/src/features.md b/guide/src/features.md index 6e4e5ab7..0816770a 100644 --- a/guide/src/features.md +++ b/guide/src/features.md @@ -57,6 +57,12 @@ This feature adds support for `async fn` in `#[pyfunction]` and `#[pymethods]`. The feature has some unfinished refinements and performance improvements. To help finish this off, see [issue #1632](https://github.com/PyO3/pyo3/issues/1632) and its associated draft PRs. +### `experimental-declarative-modules` + +This feature allows to declare Python modules using `#[pymodule] mod my_module { ... }` syntax. + +The feature has some unfinished refinements and edge cases. To help finish this off, see [issue #3900](https://github.com/PyO3/pyo3/issues/3900). + ### `experimental-inspect` This feature adds the `pyo3::inspect` module, as well as `IntoPy::type_output` and `FromPyObject::type_input` APIs to produce Python type "annotations" for Rust types. diff --git a/guide/src/module.md b/guide/src/module.md index 8cac9a5b..c9c7f78a 100644 --- a/guide/src/module.md +++ b/guide/src/module.md @@ -105,3 +105,55 @@ submodules by using `from parent_module import child_module`. For more informati [#1517](https://github.com/PyO3/pyo3/issues/1517#issuecomment-808664021). It is not necessary to add `#[pymodule]` on nested modules, which is only required on the top-level module. + +## Declarative modules (experimental) + +Another syntax based on Rust inline modules is also available to declare modules. +The `experimental-declarative-modules` feature must be enabled to use it. + +For example: +```rust +# #[cfg(feature = "experimental-declarative-modules")] +# mod declarative_module_test { +use pyo3::prelude::*; + +#[pyfunction] +fn double(x: usize) -> usize { + x * 2 +} + +#[pymodule] +mod my_extension { + use super::*; + + #[pymodule_export] + use super::double; // Exports the double function as part of the module + + #[pyfunction] // This will be part of the module + fn triple(x: usize) -> usize { + x * 3 + } + + #[pyclass] // This will be part of the module + struct Unit; + + #[pymodule] + mod submodule { + // This is a submodule + } + + #[pymodule_init] + fn init(m: &Bound<'_, PyModule>) -> PyResult<()> { + // Arbitrary code to run at the module initialization + m.add("double2", m.getattr("double")?)?; + Ok(()) + } +} +# } +``` + +Some changes are planned to this feature before stabilization, like automatically +filling submodules into `sys.modules` to allow easier imports (see [issue #759](https://github.com/PyO3/pyo3/issues/759)) +and filling the `module` argument of inlined `#[pyclass]` automatically with the proper module name. +Macro names might also change. +See [issue #3900](https://github.com/PyO3/pyo3/issues/3900) to track this feature progress.