Build and imports a c-extension module `modname` from a list of function fragments `functions`. Parameters ---------- functions : list of fragments Each fragment is a sequence of func_name, calling convention, snippet. prologue : string Code to precede the
(
modname, functions, *, prologue="", build_dir=None,
include_dirs=None, more_init="")
| 16 | |
| 17 | |
| 18 | def build_and_import_extension( |
| 19 | modname, functions, *, prologue="", build_dir=None, |
| 20 | include_dirs=None, more_init=""): |
| 21 | """ |
| 22 | Build and imports a c-extension module `modname` from a list of function |
| 23 | fragments `functions`. |
| 24 | |
| 25 | |
| 26 | Parameters |
| 27 | ---------- |
| 28 | functions : list of fragments |
| 29 | Each fragment is a sequence of func_name, calling convention, snippet. |
| 30 | prologue : string |
| 31 | Code to precede the rest, usually extra ``#include`` or ``#define`` |
| 32 | macros. |
| 33 | build_dir : pathlib.Path |
| 34 | Where to build the module, usually a temporary directory |
| 35 | include_dirs : list |
| 36 | Extra directories to find include files when compiling |
| 37 | more_init : string |
| 38 | Code to appear in the module PyMODINIT_FUNC |
| 39 | |
| 40 | Returns |
| 41 | ------- |
| 42 | out: module |
| 43 | The module will have been loaded and is ready for use |
| 44 | |
| 45 | Examples |
| 46 | -------- |
| 47 | >>> functions = [("test_bytes", "METH_O", \"\"\" |
| 48 | if ( !PyBytesCheck(args)) { |
| 49 | Py_RETURN_FALSE; |
| 50 | } |
| 51 | Py_RETURN_TRUE; |
| 52 | \"\"\")] |
| 53 | >>> mod = build_and_import_extension("testme", functions) |
| 54 | >>> assert not mod.test_bytes('abc') |
| 55 | >>> assert mod.test_bytes(b'abc') |
| 56 | """ |
| 57 | if include_dirs is None: |
| 58 | include_dirs = [] |
| 59 | body = prologue + _make_methods(functions, modname) |
| 60 | init = """ |
| 61 | PyObject *mod = PyModule_Create(&moduledef); |
| 62 | #ifdef Py_GIL_DISABLED |
| 63 | PyUnstable_Module_SetGIL(mod, Py_MOD_GIL_NOT_USED); |
| 64 | #endif |
| 65 | """ |
| 66 | if not build_dir: |
| 67 | build_dir = pathlib.Path('.') |
| 68 | if more_init: |
| 69 | init += """#define INITERROR return NULL |
| 70 | """ |
| 71 | init += more_init |
| 72 | init += "\nreturn mod;" |
| 73 | source_string = _make_source(modname, init, body) |
| 74 | mod_so = compile_extension_module( |
| 75 | modname, build_dir, include_dirs, source_string) |
nothing calls this directly
no test coverage detected
searching dependent graphs…