Source code for hpy/hpymodule.h

/* If 'HPY_EMBEDDED_MODULES' is defined, this means that there will be several embedded HPy modules (and so, several 'HPy_MODINIT' usages) in the same binary. In this case, some restrictions apply: (1) all of the module's methods/member/slots/... must be defined in the same file, and (2) the embedder *MUST* declare the module to be "embeddable" by using macro 'HPY_MOD_EMBEDDABLE(modname)'. */ #ifdef HPY_EMBEDDED_MODULES #define _HPy_CTX_MODIFIER static #define HPY_MOD_EMBEDDABLE(modname) \ _HPy_CTX_MODIFIER HPyContext *_ctx_for_trampolines; #else
[docs]/** * Declares a module to be *embeddable* which means that it and its members can * be compiled/linked into a binary together with other embeddable HPy modules. * * You may declare a module to be *embeddable* if all of its member definitions * are in the same file. */ #define HPY_MOD_EMBEDDABLE(modname)
// this is defined by HPy_MODINIT
extern HPyContext *_ctx_for_trampolines;
[docs]/** * Definition of a Python module. Pointer to this struct is returned from * the HPy initialization function ``HPyInit_{extname}`` and the Python * interpreter creates a Python module from it. HPy supports only the * multi-phase module initialization approach (PEP 451). * * There is no HPy API to create a Python module manually, i.e., equivalent * of ``PyModule_Create`` or ``PyModule_FromDefAndSpec``, for the time being, * but may be added if a use-case arises. * * Note: unlike Python/C API, HPy module definition does not specify module * name. The name if always taken from the ModuleSpec, which is also the case * in multi-phase module initialization on Python/C API. */ typedef struct {
[docs] /** Docstring of the type (UTF-8 encoded; may be ``NULL``) */ const char* doc;
[docs] /** * The size (in bytes) of the module state structure. If set to zero, * then the module will not get allocated and assigned any HPy module state. * Negative size, unlike in Python/C API, does not have any specific meaning * and will produce a runtime error. */ HPy_ssize_t size;
[docs] /** * ``NULL``-terminated list of legacy module-level methods. * In order to enable incremental migration * from C API to HPy, it is possible to still add *legacy* method * definitions. Those methods have a C API signature which means that they * still receive ``PyObject *`` and similar arguments. If legacy methods * are defined, you cannot create a *universal binary* (i.e. a binary that * will run on all Python engines). */ cpy_PyMethodDef *legacy_methods;
[docs] /** * Pointer to a ``NULL``-terminated array of pointers to HPy defines (i.e. * ``HPyDef *``). Note, that some kinds of HPy definitions don't make sense * for a module. In particular, anything else than methods. */ HPyDef **defines;
[docs] /** * Pointer to a ``NULL``-terminated array of pointers to * :c:struct:`HPyGlobal` variables. For details, see :doc:`hpy-global`. */ HPyGlobal **globals;
} HPyModuleDef;
#if defined(__cplusplus) # define HPy_EXPORTED_FUNC extern "C" HPy_EXPORTED_SYMBOL #else /* __cplusplus */
#endif /* __cplusplus */ #ifdef HPY_ABI_CPYTHON // helpers provided by HPy runtime: #include "hpy/runtime/ctx_module.h" // module initialization in the CPython case #define HPy_MODINIT(ext_name, mod_def) \ PyMODINIT_FUNC \ PyInit_##ext_name(void) \ { \ return _HPyModuleDef_AsPyInit(&mod_def); \ } #else // HPY_ABI_CPYTHON // module initialization in the universal and hybrid case
[docs]/** * Convenience macro for generating the module initialization code. This will * generate three functions that are used by to verify an initialize the module * when loading: * * ``get_required_hpy_major_version_<modname>`` * The HPy major version this module was built with. * * ``get_required_hpy_minor_version_<modname>`` * The HPy minor version this module was built with. * * ``HPyModuleDef* HPyInit_<extname>`` * The init function that will be called by the interpreter. This function * does not have an access to HPyContext and thus cannot call any HPy APIs. * The purpose of this function is to return a pointer to a HPyModuleDef * structure that will serve as a specification of the module that should be * created by the interpreter. HPy supports only multi-phase module * initialization (PEP 451). Any module initialization code can be added * to the HPy_mod_exec slot of the module if needed. * * Example: * * .. code-block:: c * * HPy_MODINIT(myextension_shared_library_filename, my_hpy_module_def) */ #define HPy_MODINIT(ext_name, mod_def) \ HPy_EXPORTED_FUNC uint32_t \ get_required_hpy_major_version_##ext_name() \ { \ return HPY_ABI_VERSION; \ } \ HPy_EXPORTED_FUNC uint32_t \ get_required_hpy_minor_version_##ext_name() \ { \ return HPY_ABI_VERSION_MINOR; \ } \ _HPy_CTX_MODIFIER HPyContext *_ctx_for_trampolines; \ HPy_EXPORTED_FUNC void \ HPyInitGlobalContext_##ext_name(HPyContext *ctx) \ { \ _ctx_for_trampolines = ctx; \ } \ HPy_EXPORTED_FUNC HPyModuleDef* \ HPyInit_##ext_name() \ { \ return &mod_def; \ }
// Implementation note: the global HPyContext is used by the CPython // trampolines generated by the HPyDef_XXX macros #endif // HPY_ABI_CPYTHON #endif // HPY_UNIVERSAL_HPYMODULE_H