@@ -15,7 +15,7 @@ use crate::{
1515 get_doc,
1616 pyclass:: PyClassPyO3Option ,
1717 pyfunction:: { impl_wrap_pyfunction, PyFunctionOptions } ,
18- utils:: { has_attribute, has_attribute_with_namespace, Ctx , IdentOrStr , LitCStr } ,
18+ utils:: { has_attribute, has_attribute_with_namespace, Ctx , IdentOrStr , LitCStr , PythonDoc } ,
1919} ;
2020use proc_macro2:: { Span , TokenStream } ;
2121use quote:: quote;
@@ -389,27 +389,14 @@ pub fn pymodule_module_impl(
389389 let introspection_id = quote ! { } ;
390390
391391 let gil_used = options. gil_used . map_or ( true , |op| op. value . value ) ;
392- let num_slots: usize = 2 ; // initializer + gil_used
393392
394- let module_def = quote ! { {
395- use #pyo3_path:: impl_:: pymodule as impl_;
396-
397- unsafe extern "C" fn __pyo3_module_exec( module: * mut #pyo3_path:: ffi:: PyObject ) -> :: std:: os:: raw:: c_int {
398- #pyo3_path:: impl_:: trampoline:: module_exec( module, |m| __pyo3_pymodule( m) )
399- }
400-
401- static SLOTS : impl_:: PyModuleSlots <{ #num_slots + 1 } > = impl_:: PyModuleSlotsBuilder :: new( )
402- . with_mod_exec( __pyo3_module_exec)
403- . with_gil_used( #gil_used)
404- . build( ) ;
405- impl_:: ModuleDef :: new( __PYO3_NAME, #doc, & SLOTS )
406- } } ;
407393 let initialization = module_initialization (
408394 & name,
409395 ctx,
410- module_def ,
396+ quote ! { __pyo3_pymodule } ,
411397 options. submodule . is_some ( ) ,
412- true , // FIXME remove this
398+ gil_used,
399+ doc,
413400 ) ;
414401
415402 let module_consts_names = module_consts. iter ( ) . map ( |i| i. unraw ( ) . to_string ( ) ) ;
@@ -462,8 +449,14 @@ pub fn pymodule_function_impl(
462449
463450 let gil_used = options. gil_used . map_or ( true , |op| op. value . value ) ;
464451
465- let initialization =
466- module_initialization ( & name, ctx, quote ! { MakeDef :: make_def( ) } , false , gil_used) ;
452+ let initialization = module_initialization (
453+ & name,
454+ ctx,
455+ quote ! { ModuleExec :: __pyo3_module_exec } ,
456+ false ,
457+ gil_used,
458+ doc,
459+ ) ;
467460
468461 #[ cfg( feature = "experimental-inspect" ) ]
469462 let introspection =
@@ -496,24 +489,9 @@ pub fn pymodule_function_impl(
496489 // (and `super` doesn't always refer to the outer scope, e.g. if the `#[pymodule] is
497490 // inside a function body)
498491 #[ allow( unknown_lints, non_local_definitions) ]
499- impl #ident:: MakeDef {
500- const fn make_def( ) -> #pyo3_path:: impl_:: pymodule:: ModuleDef {
501- use #pyo3_path:: impl_:: pymodule as impl_;
502-
503- unsafe extern "C" fn __pyo3_module_exec( module: * mut #pyo3_path:: ffi:: PyObject ) -> :: std:: os:: raw:: c_int {
504- #pyo3_path:: impl_:: trampoline:: module_exec( module, |module| #ident( #( #module_args) , * ) )
505- }
506-
507- static SLOTS : impl_:: PyModuleSlots <4 > = impl_:: PyModuleSlotsBuilder :: new( )
508- . with_mod_exec( __pyo3_module_exec)
509- . with_gil_used( #gil_used)
510- . build( ) ;
511-
512- impl_:: ModuleDef :: new(
513- #ident:: __PYO3_NAME,
514- #doc,
515- & SLOTS
516- )
492+ impl #ident:: ModuleExec {
493+ fn __pyo3_module_exec( module: & #pyo3_path:: Bound <' _, #pyo3_path:: types:: PyModule >) -> #pyo3_path:: PyResult <( ) > {
494+ #ident( #( #module_args) , * )
517495 }
518496 }
519497 } )
@@ -522,9 +500,10 @@ pub fn pymodule_function_impl(
522500fn module_initialization (
523501 name : & syn:: Ident ,
524502 ctx : & Ctx ,
525- module_def : TokenStream ,
503+ module_exec : TokenStream ,
526504 is_submodule : bool ,
527505 gil_used : bool ,
506+ doc : PythonDoc ,
528507) -> TokenStream {
529508 let Ctx { pyo3_path, .. } = ctx;
530509 let pyinit_symbol = format ! ( "PyInit_{name}" ) ;
@@ -535,9 +514,27 @@ fn module_initialization(
535514 #[ doc( hidden) ]
536515 pub const __PYO3_NAME: & ' static :: std:: ffi:: CStr = #pyo3_name;
537516
538- pub ( super ) struct MakeDef ;
517+ // This structure exists for `fn` modules declared within `fn` bodies, where due to the hidden
518+ // module (used for importing) the `fn` to initialize the module cannot be seen from the #module_def
519+ // declaration just below.
539520 #[ doc( hidden) ]
540- pub static _PYO3_DEF: #pyo3_path:: impl_:: pymodule:: ModuleDef = #module_def;
521+ pub ( super ) struct ModuleExec ;
522+
523+ #[ doc( hidden) ]
524+ pub static _PYO3_DEF: #pyo3_path:: impl_:: pymodule:: ModuleDef = {
525+ use #pyo3_path:: impl_:: pymodule as impl_;
526+
527+ unsafe extern "C" fn __pyo3_module_exec( module: * mut #pyo3_path:: ffi:: PyObject ) -> :: std:: os:: raw:: c_int {
528+ #pyo3_path:: impl_:: trampoline:: module_exec( module, #module_exec)
529+ }
530+
531+ static SLOTS : impl_:: PyModuleSlots <4 > = impl_:: PyModuleSlotsBuilder :: new( )
532+ . with_mod_exec( __pyo3_module_exec)
533+ . with_gil_used( #gil_used)
534+ . build( ) ;
535+
536+ impl_:: ModuleDef :: new( __PYO3_NAME, #doc, & SLOTS )
537+ } ;
541538 #[ doc( hidden) ]
542539 // so wrapped submodules can see what gil_used is
543540 pub static __PYO3_GIL_USED: bool = #gil_used;
0 commit comments