a :jgP@sdZddlZddlZddlZddlZddlZddlZddgZddgddddZggfddZ d d Z d d Z d dZ gggfddZ ddZddZdS)zb Build a c-extension module on-the-fly in tests. See build_and_import_extensions for usage hints Nbuild_and_import_extensioncompile_extension_module)prologue build_dir include_dirs more_initc Cs|t||}d}|s td}|r4|d7}||7}|d7}t|||}zt||||} Wn6ty} ztd|d| WYd} ~ n d} ~ 00ddl} | j || } | j | } | j | | S) a 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 rest, usually extra ``#include`` or ``#define`` macros. build_dir : pathlib.Path Where to build the module, usually a temporary directory include_dirs : list Extra directories to find include files when compiling more_init : string Code to appear in the module PyMODINIT_FUNC Returns ------- out: module The module will have been loaded and is ready for use Examples -------- >>> functions = [("test_bytes", "METH_O", """ if ( !PyBytesCheck(args)) { Py_RETURN_FALSE; } Py_RETURN_TRUE; """)] >>> mod = build_and_import_extension("testme", functions) >>> assert not mod.test_bytes('abc') >>> assert mod.test_bytes(b'abc') z8PyObject *mod = PyModule_Create(&moduledef); .z.#define INITERROR return NULL z return mod;zcould not compile in :Nr) _make_methodspathlibPath _make_sourcer Exception RuntimeErrorimportlib.utilutilspec_from_file_locationmodule_from_specloader exec_module)modname functionsrrrrbodyinit source_stringZmod_soe importlibspecZfoorI/usr/local/lib/python3.9/site-packages/numpy/testing/_private/extbuild.pyrs('  (  c CsR|dd}||}|jddt||}|tdg}t||||ggdS)aH Build an extension module and return the filename of the resulting native code file. Parameters ---------- name : string name of the module, possibly including dots if it is a module inside a package. builddir : pathlib.Path Where to build the module, usually a temporary directory include_dirs : list Extra directories to find include files when compiling libraries : list Libraries to link into the extension module library_dirs: list Where to find the libraries, ``-L`` passed to the linker r Texist_ok INCLUDEPY)outputfilenamer libraries library_dirs)splitmkdir_convert_str_to_file sysconfigget_config_var _c_compile) nameZbuilddirrrr&r'rdirnamecfilerrr rPs  cCsD|d}|d}|t|Wdn1s60Y|S)zHelper function to create a file ``source.c`` in `dirname` that contains the string in `source`. Returns the file name zsource.cwN)openwritestr)sourcer/filenamefrrr r*qs ,r*c Csg}g}|D]V\}}}d||f}d|vr0d}nd}|d|||fdj|||d} || q d|d td||d } | S) z Turns the name, signature, code in functions into complete functions and lists them in a methods_table. Then turns the methods_table into a ``PyMethodDef`` structure and returns the resulting code fragment ready for compilation z%s_%sZ METH_KEYWORDSz2(PyObject *self, PyObject *args, PyObject *kwargs)z (PyObject *self, PyObject *args)z{"%s", (PyCFunction)%s, %s},z^ static PyObject* {cfuncname}{signature} {{ {code} }} ) cfuncname signaturecode a6 static PyMethodDef methods[] = { %(methods)s { NULL } }; static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "%(modname)s", /* m_name */ NULL, /* m_doc */ -1, /* m_size */ methods, /* m_methods */ }; )methodsr)appendformatjoindict) rrZ methods_tablecodesfuncnameflagsr:r8r9 func_coderrrr r {s$     r cCsdt|||d}|S)zG Combines the code fragments into source code ready to be compiled zn #include %(body)s PyMODINIT_FUNC PyInit_%(name)s(void) { %(init)s } )r.rr)r@)r.rrr:rrr rs   rcCstjdkr(dg}dtjtjdg}n"tjdrBgd}g}ng}}tjdkr^|dg}tjdkrd D]X}|d |vrtj|d r||d |d |vrltj|d rl||d ql| t }t ||||||||S) Nwin32z/we4013z /LIBPATH:Zlibslinux)z-O0z-gz%-Werror=implicit-function-declarationz-fPICz/DEBUGdarwin)z/sw/z /opt/local/includelib) sysplatformospathr? base_prefix startswithexistsr= with_suffix get_so_suffixbuild)r0r%rr&r' compile_extra link_extrasrrr r-s0       r-c Cs|jd}tj|dd|jd}t|jddn} dd|D} d d|D} | td |d |jdd | d |d| d |d|dWdn1s0Ytj dkrt j gd|dnt j gd|dt j ddg|dt t ||d|j|dS)zuse meson to buildrSTr"r!z meson.buildwtcSsg|] }d|qS)z-Ir.0drrr zbuild..cSsg|] }d|qS)z-LrrXrrr r[r\z; project('foo', 'c') shared_module('z', 'z', c_args: z + z, link_args: z, link_with: z_, name_prefix: '', name_suffix: 'dummy', ) NrE)mesonsetupz--buildtype=release--vsenv..)cwd)r]r^r_r`r]compilez.dummy)parentrLmakedirspartsr2r3textwrapdedentrJrK subprocess check_callrenamer4) r0r%rTrUrr&r'rZso_nameZfidZincludesZ link_dirsrrr rSs<   *   rScCstd}|sJ|S)N EXT_SUFFIX)r+r,)retrrr rRs rR)__doc__rLr rhrJr+rf__all__rrr*r rr-rSrRrrrr s( A ! ( !