U
    #c                     @   sF   d dl Z d dlZd dlZd dlmZ ejdd Zejj	dd Z
dS )    N)extbuildc                 C   sd   t jdstd d}dg}d}zddl}|W S  tk
rF   Y nX tjd||t	
 g| |d	S )
z Some codes to generate data and manage temporary buffers use when
    sharing with numpy via the array interface protocol.
    linuxzlink fails on cygwina$  
        #include <Python.h>
        #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
        #include <numpy/arrayobject.h>
        #include <stdio.h>
        #include <math.h>

        NPY_NO_EXPORT
        void delete_array_struct(PyObject *cap) {

            /* get the array interface structure */
            PyArrayInterface *inter = (PyArrayInterface*)
                PyCapsule_GetPointer(cap, NULL);

            /* get the buffer by which data was shared */
            double *ptr = (double*)PyCapsule_GetContext(cap);

            /* for the purposes of the regression test set the elements
               to nan */
            for (npy_intp i = 0; i < inter->shape[0]; ++i)
                ptr[i] = nan("");

            /* free the shared buffer */
            free(ptr);

            /* free the array interface structure */
            free(inter->shape);
            free(inter);

            fprintf(stderr, "delete_array_struct\ncap = %ld inter = %ld"
                " ptr = %ld\n", (long)cap, (long)inter, (long)ptr);
        }
        )new_array_structZMETH_VARARGSa}  

            long long n_elem = 0;
            double value = 0.0;

            if (!PyArg_ParseTuple(args, "Ld", &n_elem, &value)) {
                Py_RETURN_NONE;
            }

            /* allocate and initialize the data to share with numpy */
            long long n_bytes = n_elem*sizeof(double);
            double *data = (double*)malloc(n_bytes);

            if (!data) {
                PyErr_Format(PyExc_MemoryError,
                    "Failed to malloc %lld bytes", n_bytes);

                Py_RETURN_NONE;
            }

            for (long long i = 0; i < n_elem; ++i) {
                data[i] = value;
            }

            /* calculate the shape and stride */
            int nd = 1;

            npy_intp *ss = (npy_intp*)malloc(2*nd*sizeof(npy_intp));
            npy_intp *shape = ss;
            npy_intp *stride = ss + nd;

            shape[0] = n_elem;
            stride[0] = sizeof(double);

            /* construct the array interface */
            PyArrayInterface *inter = (PyArrayInterface*)
                malloc(sizeof(PyArrayInterface));

            memset(inter, 0, sizeof(PyArrayInterface));

            inter->two = 2;
            inter->nd = nd;
            inter->typekind = 'f';
            inter->itemsize = sizeof(double);
            inter->shape = shape;
            inter->strides = stride;
            inter->data = data;
            inter->flags = NPY_ARRAY_WRITEABLE | NPY_ARRAY_NOTSWAPPED |
                           NPY_ARRAY_ALIGNED | NPY_ARRAY_C_CONTIGUOUS;

            /* package into a capsule */
            PyObject *cap = PyCapsule_New(inter, NULL, delete_array_struct);

            /* save the pointer to the data */
            PyCapsule_SetContext(cap, data);

            fprintf(stderr, "new_array_struct\ncap = %ld inter = %ld"
                " ptr = %ld\n", (long)cap, (long)inter, (long)data);

            return cap;
        zimport_array();r   Narray_interface_testing)prologueinclude_dirs	build_dir	more_init)sysplatform
startswithpytestskipr   ImportErrorr   Zbuild_and_import_extensionnpZget_include)Ztmp_pathr   Z	functionsr	   r    r   I/tmp/pip-unpacked-wheel-b2rbor69/numpy/core/tests/test_array_interface.py
get_module   s$    
#@r   c                    sv  G  fddd}t j}d}d}|d |d|}|d |d tj|d	d
}|dt|j  |dt|j  |d |d d }|d t||st	|d |dt|  |d |d ||9 }||9 }|dt|j  |dt|j  |d |d |dt|  |d t||sZt	|d d }|d d S )Nc                       s(   e Zd ZdZdd Ze fddZdS )z!test_cstruct.<locals>.data_sourceaJ  
        This class is for testing the timing of the PyCapsule destructor
        invoked when numpy release its reference to the shared data as part of
        the numpy array interface protocol. If the PyCapsule destructor is
        called early the shared data is freed and invalid memory accesses will
        occur.
        c                 S   s   || _ || _d S N)sizevalue)selfr   r   r   r   r   __init__   s    z*test_cstruct.<locals>.data_source.__init__c                    s     | j| jS r   )r   r   r   )r   r   r   r   __array_struct__   s    z2test_cstruct.<locals>.data_source.__array_struct__N)__name__
__module____qualname____doc__r   propertyr   r   r   r   r   data_source   s   r    go!	g     z+ ---- create an object to share data ---- 
   z ---- OK!

z8 ---- share data via the array interface protocol ---- 
F)copyzarr.__array_interface___ = %s
zarr.base = %s
z0 ---- destroy the object that shared data ---- 
z ---- read shared data ---- 
z	arr = %s
z ---- modify shared data ---- 
z& ---- read modified shared data ---- 
z ---- free shared data ---- 
)
r
   
__stderr__writer   arraystrZ__array_interface__baseZallcloseAssertionError)r   r    stderrZexpected_valueZ
multiplierbufZarrr   r   r   test_cstruct   sH    













r+   )r
   r   Znumpyr   Znumpy.testingr   Zfixturer   markZslowr+   r   r   r   r   <module>   s   
{