Skip to content

Commit

Permalink
Avoid generating functions that are only ever const evaluated with de…
Browse files Browse the repository at this point in the history
…clarative modules

Refs PyO3#4286
  • Loading branch information
alex committed Jul 1, 2024
1 parent 8f7450e commit d660c5b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 19 deletions.
1 change: 1 addition & 0 deletions newsfragments/4297.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
stop generating code that will never be covered with declarative modules
34 changes: 15 additions & 19 deletions pyo3-macros-backend/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,29 +286,25 @@ pub fn pymodule_module_impl(mut module: syn::ItemMod) -> Result<TokenStream> {
}
}

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 {
#(#items)*

#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;
#(
Expand All @@ -335,7 +331,7 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result<TokenStream>
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();
Expand Down Expand Up @@ -400,7 +396,7 @@ pub fn pymodule_function_impl(mut function: syn::ItemFn) -> Result<TokenStream>
})
}

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();
Expand All @@ -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.
Expand Down

0 comments on commit d660c5b

Please sign in to comment.