Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid generating functions that are only ever const evaluated with declarative modules #4297

Merged
merged 1 commit into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading