From f3603a0a483448c71f1811786257d070733540bf Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Mon, 1 Jul 2024 17:54:50 -0400 Subject: [PATCH] Avoid generating functions that are only ever const evaluated with declarative modules (#4297) Refs #4286 --- newsfragments/4297.fixed.md | 1 + pyo3-macros-backend/src/module.rs | 34 ++++++++++++++----------------- 2 files changed, 16 insertions(+), 19 deletions(-) create mode 100644 newsfragments/4297.fixed.md diff --git a/newsfragments/4297.fixed.md b/newsfragments/4297.fixed.md new file mode 100644 index 00000000000..18cfd93756f --- /dev/null +++ b/newsfragments/4297.fixed.md @@ -0,0 +1 @@ +stop generating code that will never be covered with declarative modules diff --git a/pyo3-macros-backend/src/module.rs b/pyo3-macros-backend/src/module.rs index 39240aba7e8..4ce3023cbb4 100644 --- a/pyo3-macros-backend/src/module.rs +++ b/pyo3-macros-backend/src/module.rs @@ -286,7 +286,18 @@ pub fn pymodule_module_impl(mut module: syn::ItemMod) -> Result { } } - let initialization = module_initialization(&name, ctx); + let module_def = quote! {{ + use #pyo3_path::impl_::pymodule as impl_; + const INITIALIZER: impl_::ModuleInitializer = impl_::ModuleInitializer(__pyo3_pymodule); + unsafe { + impl_::ModuleDef::new( + __PYO3_NAME, + #doc, + INITIALIZER + ) + } + }}; + let initialization = module_initialization(&name, ctx, module_def); Ok(quote!( #(#attrs)* #vis mod #ident { @@ -294,21 +305,6 @@ pub fn pymodule_module_impl(mut module: syn::ItemMod) -> Result { #initialization - #[allow(unknown_lints, non_local_definitions)] - impl MakeDef { - const fn make_def() -> #pyo3_path::impl_::pymodule::ModuleDef { - use #pyo3_path::impl_::pymodule as impl_; - const INITIALIZER: impl_::ModuleInitializer = impl_::ModuleInitializer(__pyo3_pymodule); - unsafe { - impl_::ModuleDef::new( - __PYO3_NAME, - #doc, - INITIALIZER - ) - } - } - } - fn __pyo3_pymodule(module: &#pyo3_path::Bound<'_, #pyo3_path::types::PyModule>) -> #pyo3_path::PyResult<()> { use #pyo3_path::impl_::pymodule::PyAddToModule; #( @@ -335,7 +331,7 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result let vis = &function.vis; let doc = get_doc(&function.attrs, None, ctx); - let initialization = module_initialization(&name, ctx); + let initialization = module_initialization(&name, ctx, quote! { MakeDef::make_def() }); // Module function called with optional Python<'_> marker as first arg, followed by the module. let mut module_args = Vec::new(); @@ -400,7 +396,7 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result }) } -fn module_initialization(name: &syn::Ident, ctx: &Ctx) -> TokenStream { +fn module_initialization(name: &syn::Ident, ctx: &Ctx, module_def: TokenStream) -> TokenStream { let Ctx { pyo3_path, .. } = ctx; let pyinit_symbol = format!("PyInit_{}", name); let name = name.to_string(); @@ -412,7 +408,7 @@ fn module_initialization(name: &syn::Ident, ctx: &Ctx) -> TokenStream { pub(super) struct MakeDef; #[doc(hidden)] - pub static _PYO3_DEF: #pyo3_path::impl_::pymodule::ModuleDef = MakeDef::make_def(); + pub static _PYO3_DEF: #pyo3_path::impl_::pymodule::ModuleDef = #module_def; /// This autogenerated function is called by the python interpreter when importing /// the module.