Skip to content
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/5753.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Module initialization uses the PyModExport and PyABIInfo APIs on python 3.15 and newer.
20 changes: 18 additions & 2 deletions pyo3-macros-backend/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ fn module_initialization(
) -> Result<TokenStream> {
let Ctx { pyo3_path, .. } = ctx;
let pyinit_symbol = format!("PyInit_{name}");
let pymodexport_symbol = format!("PyModExport_{name}");
let pyo3_name = LitCStr::new(&CString::new(full_name).unwrap(), Span::call_site());
let doc = if let Some(doc) = doc {
doc.to_cstr_stream(ctx)?
Expand All @@ -544,23 +545,38 @@ fn module_initialization(
#pyo3_path::impl_::trampoline::module_exec(module, #module_exec)
}

static SLOTS: impl_::PyModuleSlots<4> = impl_::PyModuleSlotsBuilder::new()
// The full slots, used for the PyModExport initializaiton
static SLOTS: impl_::PyModuleSlots = impl_::PyModuleSlotsBuilder::new()
.with_mod_exec(__pyo3_module_exec)
.with_abi_info()
.with_gil_used(#gil_used)
.with_name(__PYO3_NAME)
.with_doc(#doc)
.build();

// Since the macros need to be written agnostic to the Python version
// we need to explicitly pass the name and docstring for PyModuleDef
// initializaiton.
impl_::ModuleDef::new(__PYO3_NAME, #doc, &SLOTS)
};
};
if !is_submodule {
result.extend(quote! {
/// This autogenerated function is called by the python interpreter when importing
/// the module.
/// the module on Python 3.14 and older.
#[doc(hidden)]
#[export_name = #pyinit_symbol]
pub unsafe extern "C" fn __pyo3_init() -> *mut #pyo3_path::ffi::PyObject {
_PYO3_DEF.init_multi_phase()
}

/// This autogenerated function is called by the python interpreter when importing
/// the module on Python 3.15 and newer.
#[doc(hidden)]
#[export_name = #pymodexport_symbol]
pub unsafe extern "C" fn __pyo3_export() -> *mut #pyo3_path::ffi::PyModuleDef_Slot {
_PYO3_DEF.get_slots()
}
});
}
Ok(result)
Expand Down
Loading
Loading