U
    O8c                     @   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 n4 |k
r } ztd| d|W 5 d	}~X Y nX 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 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;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    C/tmp/pip-unpacked-wheel-fd_gsd75/numpy/testing/_private/extbuild.pyr      s0    '
   $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   s0   |d }| d}|t|  W 5 Q R X |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w)openwritestr)sourcer/   filenamefr    r    r!   r*   q   s    r*   c                 C   s   g }g }| D ]V\}}}d||f }d|k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   s0  t jdkr(dg}dtjt jd g}n&t jdrFdddd	g}d }nd  }}t jdkrb|d
g }t jdkrdD ]X}|d |krtj|d r||d  |d |krptj|d rp||d  qp|	t
 }tj }zt| |||||| W 5 | D ]&\}	}
tj|	|
kr|
tj|	< qX |S )Nwin32z/we4013z	/LIBPATH:Zlibs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)r0   r%   r   r&   r'   compile_extra
link_extrasZsaved_environkeyvaluer    r    r!   r-      sJ    
   



    r-   c              	      s   ddl m} |ddd}|d g }	t }
t j z2|jt j	g||d}|	 fdd	|D 7 }	W 5 t|
 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_preargsc                    s   g | ]}t  j| qS r    )r4   parent).0rr0   r    r!   
<listcomp>   s     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]   compilerZobjectsoldresr    rf   r!   rW      s*    

 rW   c                  C   s   t d} | st| S )N
EXT_SUFFIX)r+   r,   AssertionError)retr    r    r!   rR      s    
rR   )__doc__rL   r   rJ   r+   __all__r   r   r*   r   r   r-   rW   rR   r    r    r    r!   <module>   s*     C 
!
(
'