a
    hÝEbˆ  ã                   @   sŠ   d Z ddlZddlZddlZddlZddgZddg ddœdd„Zg g fdd„Zd	d
„ Zdd„ Z	dd„ Z
g g g fdd„Zdd„ Zdd„ ZdS )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             
   C   sÐ   ddl m} |t|| ƒ }d}|s,t d¡}|r@|d7 }||7 }|d7 }t| ||ƒ}	zt| |||	ƒ}
W n6 |yœ } ztd|› d�ƒ|‚W Y d	}~n
d	}~0 0 dd	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 preceed 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;zcould not compile in ú:N)Údistutils.errorsr	   Ú_make_methodsÚpathlibÚPathÚ_make_sourcer   ÚRuntimeErrorÚimportlib.utilÚutilÚspec_from_file_locationÚmodule_from_specÚloaderÚexec_module)ÚmodnameÚ	functionsr   r   r   r   r	   ÚbodyÚinitÚsource_stringZmod_soÚeÚ	importlibÚspecZfoo© r    ú_/home/ja/django-apps/lartica_env/lib/python3.9/site-packages/numpy/testing/_private/extbuild.pyr      s*    '
ÿ(c           	      C   sR   |   d¡d }||  }|jdd� t||ƒ}t d¡g| }t||| |g g d�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)	ÚnameZbuilddirr   r   r&   r'   r   ÚdirnameÚcfiler    r    r!   r   P   s    
þc                 C   sD   |d }|  d¡�}| t| ƒ¡ W d  ƒ n1 s60    Y  |S )zHelper function to create a file ``source.c`` in `dirname` that contains
    the string in `source`. Returns the file name
    zsource.cÚwN)ÚopenÚwriteÚstr)Úsourcer/   ÚfilenameÚfr    r    r!   r*   q   s    ,r*   c                 C   sˆ   g }g }| D ]V\}}}d||f }d|v r0d}nd}|  d|||f ¡ dj|||d�}	|  |	¡ qd |¡d	td |¡|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)r   r   Zmethods_tableÚcodesÚfuncnameÚflagsr:   r8   r9   Ú	func_coder   r    r    r!   r   {   s$    ÿû
ôr   c                 C   s   dt | ||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.   r   r   )r@   )r.   r   r   r:   r    r    r!   r   £   s    	ÿ÷r   c              
   C   sX  t jdkr(dg}dtj t jd¡ g}n"t j d¡rBg d¢}d }nd  }}t jdkr^|dg }t jdkrÆd	D ]X}|d
 |vrštj |d
 ¡rš| |d
 ¡ |d |vrltj |d ¡rl| |d ¡ ql| 	t
ƒ ¡}tj ¡ }zDt| ||||||ƒ W | ¡ D ]"\}	}
tj |	¡|
krü|
tj|	< qün2| ¡ D ]&\}	}
tj |	¡|
k�r*|
tj|	< �q*0 |S )NÚwin32z/we4013z	/LIBPATH:ZlibsÚlinux)z-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ÚbuildÚitemsÚget)r0   r%   r   r&   r'   Úcompile_extraÚ
link_extraÚsZsaved_environÚkeyÚvaluer    r    r!   r-   µ   s@    



ÿ
ýþr-   c              	      s    ddl m} |ddd�}| d¡ g }	t ¡ }
t ˆ j¡ z<|jtˆ j	ƒg||d�}|	‡ fdd	„|D ƒ7 }	W t |
¡ nt |
¡ 0 |j
|	t|ƒ|||d
� dS )z@cd into the directory where the cfile is, use distutils to buildr   )Únew_compileré   é   )ÚforceÚverboser   )r   Úextra_preargsc                    s   g | ]}t ˆ j| ƒ‘qS r    )r4   Úparent)Ú.0Úr©r0   r    r!   Ú
<listcomp>í   ó    zbuild.<locals>.<listcomp>)r&   rb   r'   N)Znumpy.distutils.ccompilerr]   Z	customizerL   ÚgetcwdÚchdirrc   Úcompiler4   r.   Zlink_shared_object)r0   r%   rX   rY   r   r&   r'   r]   ÚcompilerÚobjectsÚoldÚresr    rf   r!   rU   Ü   s(    

ýürU   c                  C   s   t  d¡} | sJ ‚| S )NÚ
EXT_SUFFIX)r+   r,   )Úretr    r    r!   rR   ø   s    
rR   )Ú__doc__rL   r   rJ   r+   Ú__all__r   r   r*   r   r   r-   rU   rR   r    r    r    r!   Ú<module>   s$   þCþ
!
(ÿ
'