@@ -87,6 +87,17 @@ def preprocess_ast(self) -> None:
8787 capsule_types = capsule_types , registered_types = registered_types ,
8888 requires_status = requires_status )
8989
90+ def generate_pyinit (self ) -> Generator [str , None , None ]:
91+ yield '#include <Python.h>'
92+ yield ''
93+ mangled_module_name = _generate_mangled_name_for_module (
94+ self ._module_path )
95+ yield f'extern "C" PyObject* GooglePyInit_{ mangled_module_name } ();'
96+ yield ''
97+ yield f'extern "C" PyObject* PyInit_{ self ._module_name } () {{'
98+ yield I + f'return GooglePyInit_{ mangled_module_name } ();'
99+ yield '}'
100+
90101 def generate_header (self ,
91102 ast : ast_pb2 .AST ) -> Generator [str , None , None ]:
92103 """Generates pybind11 bindings code from CLIF ast."""
@@ -148,31 +159,55 @@ def generate_from(self, ast: ast_pb2.AST):
148159 yield ''
149160 yield from type_casters .generate_from (ast , self ._include_paths )
150161
151- mangled_module_name = _generate_mangled_name_for_module (
152- self ._module_path )
153- yield (f'GOOGLE_PYBIND11_MODULE({ self ._module_name } , '
154- f'{ mangled_module_name } , m) {{' )
155- yield from self ._generate_import_modules (ast )
156- yield I + ('m.doc() = "CLIF-generated pybind11-based module for '
157- f'{ ast .source } ";' )
162+ yield 'namespace {'
163+ yield ''
164+ yield 'PyObject * this_module_init() noexcept {'
165+ yield I + 'PYBIND11_CHECK_PYTHON_VERSION'
166+ yield I + 'PYBIND11_ENSURE_INTERNALS_READY'
167+ yield I + ('static pybind11::module_::module_def '
168+ f'module_def_{ self ._module_name } ;' )
169+ yield I + ('auto m = pybind11::module_::create_extension_module('
170+ f'"{ self ._module_name } ", nullptr, '
171+ f'&module_def_{ self ._module_name } );' )
172+ yield I + 'try {'
173+ for s in self ._generate_import_modules (ast ):
174+ yield I + s
175+ yield I + I + ('m.doc() = "CLIF-generated pybind11-based module for '
176+ f'{ ast .source } ";' )
158177 if self ._codegen_info .requires_status :
159- yield I + 'pybind11::module_::import("util.task.python.error");'
160- yield I + 'pybind11_protobuf::ImportNativeProtoCasters();'
178+ yield I + I + ('pybind11::module_::import('
179+ '"util.task.python.error");' )
180+ yield I + I + 'pybind11_protobuf::ImportNativeProtoCasters();'
161181
162182 for decl in ast .decls :
163183 if decl .decltype == ast_pb2 .Decl .Type .FUNC :
164184 for s in function .generate_from (
165185 'm' , decl .func , self ._codegen_info , None ):
166- yield I + s
186+ yield I + I + s
167187 elif decl .decltype == ast_pb2 .Decl .Type .CONST :
168- yield from consts .generate_from ('m' , decl .const )
188+ for s in consts .generate_from ('m' , decl .const ):
189+ yield I + s
169190 elif decl .decltype == ast_pb2 .Decl .Type .CLASS :
170- yield from classes .generate_from (
171- decl , 'm' , trampoline_class_names , self ._codegen_info )
191+ for s in classes .generate_from (
192+ decl , 'm' , trampoline_class_names , self ._codegen_info ):
193+ yield I + s
172194 elif decl .decltype == ast_pb2 .Decl .Type .ENUM :
173- yield from enums .generate_from ('m' , decl .enum )
195+ for s in enums .generate_from ('m' , decl .enum ):
196+ yield I + s
197+ yield I + I + 'return m.ptr();'
198+ yield I + '}'
199+ yield I + 'PYBIND11_CATCH_INIT_EXCEPTIONS'
200+ yield '}'
201+ yield ''
202+ yield '} // namespace'
203+ yield ''
204+ mangled_module_name = _generate_mangled_name_for_module (
205+ self ._module_path )
206+ yield f'extern "C" PyObject* GooglePyInit_{ mangled_module_name } () {{'
207+ yield I + 'return this_module_init();'
174208 yield '}'
175209 yield ''
210+
176211 for namespace , typedefs in itertools .groupby (
177212 self ._types , lambda gen_type : gen_type .cpp_namespace ):
178213 namespace = namespace .strip (':' ) or 'clif'
0 commit comments