Extending and Embedding Python, Release 3.9.5 Chapter 2. Creating extensions without third party tools 10 Note: Unlike our$_{spam}$example,$_{xxmodule}$ uses multi-phase initialization (new in Python 3.5), where a PyMod- uleDef structure is returned from$_{PyInit_spam}$ , and creation of the module is left to the import machinery. For details on multi-phase initialization, see PEP 489 . A more substantial example module is included in the Python source distribution as$_{Modules/xxmodule.c}$ . This file may be used as a template or simply read as an example. Note: Removing entries from$_{sys.modules}$ or importing compiled modules into multiple interpreters within a process (or following a$_{fork()}$ without an intervening$_{exec()}$ ) can create problems for some extension modules. Extension module authors should exercise caution when initializing internal data structures. When embedding Python, the$_{PyInit_spam()}$ function is not called automatically unless there’s an entry in the PyImport_Inittab table. To add the module to the initialization table, use PyImport_AppendInittab() , optionally followed by an import of the module: When the Python program imports module$_{spam}$for the first time,$_{PyInit_spam()}$ is called. (See below for comments about embedding Python.) It calls PyModule_Create() , which returns a module object, and inserts built-in function objects into the newly created module based upon the table (an array of$_{PyMethodDef}$ structures) found in the module definition. PyModule_Create() returns a pointer to the module object that it creates. It may abort with a fatal error for certain errors, or return$_{NULL}$ if the module could not be initialized satisfactorily. The init function must return the module object to its caller, so that it then gets inserted into sys.modules . int main( int argc, char *argv[]) { wchar_t *program =Py_DecodeLocale(argv[ 0],NULL ); if (program==NULL ) { fprintf(stderr, "Fatal error: cannot decode argv[0] "); exit(1); } /* Add a built-in module, before Py_Initialize */ if (PyImport_AppendInittab( "spam", PyInit_spam) ==-1 ) { fprintf(stderr, "Error: could not extend in-built modules table "); exit(1); } /* Pass argv[0] to the Python interpreter */ Py_SetProgramName(program); /* Initialize the Python interpreter. Required. If this step fails, it will be a fatal error. */ Py_Initialize(); /* Optionally import the module; alternatively, import can be deferred until the embedded script imports it. */ PyObject *pmodule=PyImport_ImportModule( "spam"); if (!pmodule) { PyErr_Print(); fprintf(stderr, "Error: could not import module 'spam' "); } ... PyMem_RawFree(program); return 0; }