zmc
2023-12-22 9fdbf60165db0400c2e8e6be2dc6e88138ac719a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
U
P±dƒã@sŠdZddlZddlZddlZddlZddgZddgddœdd„Zggfdd„Zd    d
„Zd d „Z    d d„Z
gggfdd„Z dd„Z dd„Z dS)zb
Build a c-extension module on-the-fly in tests.
See build_and_import_extensions for usage hints
 
éNÚbuild_and_import_extensionÚcompile_extension_moduleÚ)ÚprologueÚ    build_dirÚ include_dirsÚ    more_initc
CsÎddlm}|t||ƒ}d}|s,t d¡}|r@|d7}||7}|d7}t|||ƒ}    zt||||    ƒ}
Wn4|k
rš} ztd|›dƒ| ‚W5d    } ~ XYnXdd    l} | 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(u'abc')
    >>> assert mod.test_bytes(b'abc')
    r)Ú CompileErrorz8PyObject *mod = PyModule_Create(&moduledef);
           Ú.z.#define INITERROR return NULL
                z
return mod;zcould not compile in ú:N)Údistutils.errorsr    Ú _make_methodsÚpathlibÚPathÚ _make_sourcerÚ RuntimeErrorZimportlib.utilÚutilÚspec_from_file_locationÚmodule_from_specÚloaderÚ exec_module)ÚmodnameÚ    functionsrrrrr    ÚbodyÚinitÚ source_stringZmod_soÚeÚ    importlibÚspecZfoo©rúVd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\numpy/testing/_private/extbuild.pyrs0' 
 ÿ$  c    CsR| d¡d}||}|jddt||ƒ}|t d¡g}t||||ggdS)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
éÿÿÿÿT)Úexist_okÚ    INCLUDEPY)ÚoutputfilenamerÚ    librariesÚ library_dirs)ÚsplitÚmkdirÚ_convert_str_to_fileÚ    sysconfigÚget_config_varÚ
_c_compile)    ÚnameZbuilddirrrr%r&rÚdirnameÚcfilerrr rPs 
þc    Cs0|d}| d¡}| t|ƒ¡W5QRX|S)zHelper function to create a file ``source.c`` in `dirname` that contains
    the string in `source`. Returns the file name
    zsource.cÚw)ÚopenÚwriteÚstr)Úsourcer.ÚfilenameÚfrrr r)qs r)c Csˆg}g}|D]V\}}}d||f}d|kr0d}nd}| d|||f¡dj|||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Ú    signatureÚcodeÚ
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)ÚappendÚformatÚjoinÚdict) rrZ methods_tableÚcodesÚfuncnameÚflagsr9r7r8Ú    func_coderrrr r {s(  ÿû 
ô r cCsdt|||d}|S)zG Combines the code fragments into source code ready to be compiled
    zn
    #include <Python.h>
 
    %(body)s
 
    PyMODINIT_FUNC
    PyInit_%(name)s(void) {
    %(init)s
    }
    )r-rr)r?)r-rrr9rrr r£s    ÿ÷ rc
Cs0tjdkr(dg}dtj tjd¡g}n&tj d¡rFdddd    g}d}nd}}tjdkrb|d
g}tjd krÊd D]X}|d |kržtj |d ¡rž| |d ¡|d|krptj |d¡rp| |d¡qp|     t
ƒ¡}tj   ¡}zt|||||||ƒW5|  ¡D]&\}    }
tj  |    ¡|
kr|
tj |    <qX|S)NÚwin32z/we4013z    /LIBPATH:ZlibsÚlinuxz-O0z-gz%-Werror=implicit-function-declarationz-fPICz/DEBUGÚdarwin)z/sw/z /opt/local/ÚincludeÚlib)ÚsysÚplatformÚosÚpathr>Ú base_prefixÚ
startswithÚexistsr<Ú with_suffixÚ get_so_suffixÚenvironÚcopyÚitemsÚgetÚbuild) r/r$rr%r&Ú compile_extraÚ
link_extraÚsZ saved_environÚkeyÚvaluerrr r,µsJ
 ÿ
 
 
 ÿ 
ýr,c     s–ddlm}|ddd}| d¡g}    t ¡}
t ˆj¡z2|jtˆj    ƒg||d} |    ‡fdd    „| Dƒ7}    W5t |
¡X|j
|    t|ƒ|||d
d S) z@cd into the directory where the cfile is, use distutils to buildr)Ú new_compileréé)ÚforceÚverboser)rÚ extra_preargscsg|]}tˆj|ƒ‘qSr)r3Úparent)Ú.0Úr©r/rr Ú
<listcomp>íszbuild.<locals>.<listcomp>)r%rar&N) Znumpy.distutils.ccompilerr\Z    customizerKÚgetcwdÚchdirrbÚcompiler3r-Zlink_shared_object) r/r$rWrXrr%r&r\ÚcompilerZobjectsÚoldÚresrrer rVÜs*  
 
ý ürVcCst d¡}|st‚|S)NÚ
EXT_SUFFIX)r*r+ÚAssertionError)Úretrrr rQøs
rQ)Ú__doc__rKrrIr*Ú__all__rrr)r rr,rVrQrrrr Ú<module>s*þ Cþ
!
(ÿ
'