
    SBgI                     r   S r / SQrSSKrSSKrSSKJrJr   SSKr\c  S r
\
r\
r\
rSSKJr  \rO*SSKJs  Jr  \R,                  " 5       rC\R.                  rS rS r/ S	QrS
 r " S S\5      r " S S\5      r0 rSS jr\b%  S rS r \ " 5       r!S r"S r#S r$S r%S r&SS jrS rgg! \	 a    Sr Nf = f)a7  
============================
``ctypes`` Utility Functions
============================

See Also
--------
load_library : Load a C library.
ndpointer : Array restype/argtype with verification.
as_ctypes : Create a ctypes array from an ndarray.
as_array : Create an ndarray from a ctypes array.

References
----------
.. [1] "SciPy Cookbook: ctypes", https://scipy-cookbook.readthedocs.io/items/Ctypes.html

Examples
--------
Load the C library:

>>> _lib = np.ctypeslib.load_library('libmystuff', '.')     #doctest: +SKIP

Our result type, an ndarray that must be of type double, be 1-dimensional
and is C-contiguous in memory:

>>> array_1d_double = np.ctypeslib.ndpointer(
...                          dtype=np.double,
...                          ndim=1, flags='CONTIGUOUS')    #doctest: +SKIP

Our C-function typically takes an array and updates its values
in-place.  For example::

    void foo_func(double* x, int length)
    {
        int i;
        for (i = 0; i < length; i++) {
            x[i] = i*i;
        }
    }

We wrap it using:

>>> _lib.foo_func.restype = None                      #doctest: +SKIP
>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP

Then, we're ready to call ``foo_func``:

>>> out = np.empty(15, dtype=np.double)
>>> _lib.foo_func(out, len(out))                #doctest: +SKIP

)load_library	ndpointerc_intp	as_ctypesas_arrayas_ctypes_type    N)	_flagdictflagsobjc                      [        S5      e)z
Dummy object that raises an ImportError if ctypes is not available.

Raises
------
ImportError
    If ctypes is not available.

zctypes is not available.)ImportError)argskwdss     1/usr/lib/python3/dist-packages/numpy/ctypeslib.py_dummyr   A   s     455    )intpc                 r   [         R                  " U 5      n [         R                  " U5      n[         R                  R                  U 5      S   nU(       d  SSKnSSKnSnUR                  R                  S5      (       a  SnO"UR                  R                  S5      (       a  SnX-   /nUR                  S	5      nXu:X  d  UR                  SX-   5        OU /n[         R                  R                  U5      n[         R                  R                  U5      (       d   [         R                  R                  U5      nOUnU H\  n	[         R                  R                  X5      n
[         R                  R                  U
5      (       d  MH   [        R                   U
   s  $    [#        S
5      e! ["         a    e f = f)aB  
It is possible to load a library using

>>> lib = ctypes.cdll[<full_path_name>] # doctest: +SKIP

But there are cross-platform considerations, such as library file extensions,
plus the fact Windows will just load the first library it finds with that name.
NumPy supplies the load_library function as a convenience.

.. versionchanged:: 1.20.0
    Allow libname and loader_path to take any
    :term:`python:path-like object`.

Parameters
----------
libname : path-like
    Name of the library, which can have 'lib' as a prefix,
    but without an extension.
loader_path : path-like
    Where the library can be found.

Returns
-------
ctypes.cdll[libpath] : library object
   A ctypes library object

Raises
------
OSError
    If there is no library with the expected extension, or the
    library is defective and cannot be loaded.
   r   Nz.sodarwinz.dylibwinz.dll
EXT_SUFFIXzno file with expected extension)osfsdecodepathsplitextsys	sysconfigplatform
startswithget_config_varinsertabspathisdirdirnamejoinexistsctypescdllOSError)libnameloader_pathextr   r   base_extlibname_extso_extlibdirlnlibpaths              r   r   r   X   s[   D ++g&kk+.ggw'* H||&&x00#((//!"-.K--l;F%""1g&67")Kggook2ww}}[))WW__[1F FBggll6.Gww~~g&&!;;w//	  788	  s   F**F6c                 4    SnU  H  nU[         U   -  nM     U$ Nr   )r	   )flaglistnumvals      r   _num_fromflagsr8      s$    
Cy~ Jr   )C_CONTIGUOUSF_CONTIGUOUSALIGNED	WRITEABLEOWNDATAWRITEBACKIFCOPYc                 n    / n[          H(  n[        U   nX-  (       d  M  UR                  U5        M*     U$ N)
_flagnamesr	   append)r6   reskeyvalues       r   _flags_fromnumrF      s3    
C#KKJJsO  Jr   c                   $    \ rS rSr\S 5       rSrg)_ndptr   c                    [        U[        R                  5      (       d  [        S5      eU R                  b2  UR
                  U R                  :w  a  [        SU R                  -  5      eU R                  b2  UR                  U R                  :w  a  [        SU R                  -  5      eU R                  b;  UR                  U R                  :w  a!  [        S[        U R                  5      -  5      eU R                  bR  UR                  R                  U R                  -  U R                  :w  a!  [        S[        U R                  5      -  5      eUR                  $ )Nzargument must be an ndarrayzarray must have data type %szarray must have %d dimension(s)zarray must have shape %szarray must have flags %s)
isinstancenpndarray	TypeError_dtype_dtype_ndim_ndim_shape_shapestr_flags_flagsr6   rF   r'   )clsobjs     r   
from_param_ndptr.from_param   s   #rzz**9::;;"99+:S[[HII::!88szz)=

JKK;;"99+6S[[9IIJJ;;"YY]]S[[0S[[@6"3;;/0 1 1zzr    N)__name__
__module____qualname____firstlineno__classmethodrZ   __static_attributes__r\   r   r   rH   rH      s     r   rH   c                   .    \ rS rSrSrS r\S 5       rSrg)_concrete_ndptr   z
Like _ndptr, but with `_shape_` and `_dtype_` specified.

Notably, this means the pointer has enough information to reconstruct
the array, which is not generally true.
c                     U R                   $ )z
This method is called when this class is used as the .restype
attribute for a shared-library function, to automatically wrap the
pointer into an array.
)contents)selfs    r   _check_retval__concrete_ndptr._check_retval_   s     }}r   c                 @   [         R                  " U R                  U R                  45      n[        R
                  UR                  -  n[        R                  " U [        R                  " U5      5      R                  n[         R                  " X1S9R                  SS9$ )z
Get an ndarray viewing the data pointed to by this pointer.

This mirrors the `contents` attribute of a normal ctypes pointer
rP   r   )axis)rL   rP   rO   rS   r'   c_charitemsizecastPOINTERrg   
frombuffersqueeze)rh   
full_dtype
full_ctypebuffers       r   rg   _concrete_ndptr.contents   so     XXt||T\\:;
]]Z%8%88
T6>>*#=>GG}}V6>>A>FFr   r\   N)	r]   r^   r_   r`   __doc__ri   propertyrg   rb   r\   r   r   rd   rd      s"     	G 	Gr   rd   c           	         U b  [         R                  " U 5      n SnUb  [        U[        5      (       a  UR	                  S5      nO_[        U[
        [         R                  45      (       a  Un[        U5      nO,[        U[        5      (       a  UR                  n[        U5      nUc9   U Vs/ s H   oUR                  5       R                  5       PM"     nn[        U5      nUb   [        U5      nXX$4n [         U   $ s  snf ! [         a  n[        S5      UeSnAff = f! [         a    U4n N@f = f! ["         a     Of = fU c  SnO.U R$                  b  [        ['        U 5      5      nOU R                  nUb  USU-  -  nUb  USSR)                  S U 5       5      -   -  nUb  USSR)                  U5      -   -  nU b
  Ub  [*        n	O[,        n	[/        S	U-  U	4U UUUS
.5      n
U
[         U'   U
$ )a  
Array-checking restype/argtypes.

An ndpointer instance is used to describe an ndarray in restypes
and argtypes specifications.  This approach is more flexible than
using, for example, ``POINTER(c_double)``, since several restrictions
can be specified, which are verified upon calling the ctypes function.
These include data type, number of dimensions, shape and flags.  If a
given array does not satisfy the specified restrictions,
a ``TypeError`` is raised.

Parameters
----------
dtype : data-type, optional
    Array data-type.
ndim : int, optional
    Number of array dimensions.
shape : tuple of ints, optional
    Array shape.
flags : str or tuple of str
    Array flags; may be one or more of:

    - C_CONTIGUOUS / C / CONTIGUOUS
    - F_CONTIGUOUS / F / FORTRAN
    - OWNDATA / O
    - WRITEABLE / W
    - ALIGNED / A
    - WRITEBACKIFCOPY / X

Returns
-------
klass : ndpointer type object
    A type object, which is an ``_ndtpr`` instance containing
    dtype, ndim, shape and flags information.

Raises
------
TypeError
    If a given array does not satisfy the specified restrictions.

Examples
--------
>>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64,
...                                                  ndim=1,
...                                                  flags='C_CONTIGUOUS')]
... #doctest: +SKIP
>>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64))
... #doctest: +SKIP

N,zinvalid flags specificationanyz_%dd_xc              3   8   #    U  H  n[        U5      v   M     g 7fr@   )rU   ).0r~   s     r   	<genexpr>ndpointer.<locals>.<genexpr>J  s     3USVVUs   zndpointer_%s)rO   rS   rQ   rV   )rL   rP   rK   rU   splitintintegerrF   r
   r6   stripupper	ExceptionrN   r8   tuple_pointer_type_cacheKeyErrornamesidr%   rd   rH   type)rP   rR   rT   rW   r6   r~   e	cache_keynamebaseklasss              r   r   r      s
   j  CeS!!KK$ERZZ011C"3'Ex(())C"3'E;F49:Eq*E: !'C 	%LE
 e)I"9--! ; F =>AEF  	HE	   }		 2e9~yyCHH3U3333CHHUO##U.$tg"#!!#$E
 &+	"LsN   )D -'C>D %D! 5D4 >D 
DDD!D10D14
E Ec                 :    USSS2    H  nX -  n SU l         M     U $ )z6Create an ndarray of the given element type and shape N)r^   )element_typerT   dims      r   _ctype_ndarrayr   ]  s,    2;C-L&*L#  r   c                     [         n U R                  U R                  U R                  U R                  U R
                  U R                  U R                  U R                  U R                  U R                  U R                  U R                  U R                  /nU Vs0 s H  n[        R                  " U5      U_M     sn$ s  snf )zH
Return a dictionary mapping native endian scalar dtype to ctypes types
)r'   c_bytec_shortc_intc_long
c_longlongc_ubytec_ushortc_uintc_ulongc_ulonglongc_floatc_doublec_boolrL   rP   )ctsimple_typesctypes      r   _get_scalar_type_mapr   f  s     IIrzz288RYYJJRYY

BNNJJII	
 5AAL5&LAAAs   !C c                 J   U R                  S5      R                  S5      nU R                  S5      n [        U   nUR
                  S:X  a  UR                  nU$ UR
                  S:X  a  UR                  nU$ ! [         a   n[        SR	                  U 5      5      S eS nAff = f)NS=z Converting {!r} to a ctypes type><)newbyteorder_scalar_type_mapr   NotImplementedErrorformat	byteorder__ctype_be____ctype_le__)rP   dtype_with_endiandtype_nativer   r   s        r   _ctype_from_dtype_scalarr   w  s    !..s3@@E))#.	$\2E &&#-&&E  ((C/&&E  	%299%@	s   	A8 8
B"BB"c                 J    U R                   u  p[        U5      n[        X25      $ r@   )subdtype_ctype_from_dtyper   )rP   element_dtyperT   r   s       r   _ctype_from_dtype_subarrayr     s#    $~~!-0e++r   c           
         / nU R                    H3  nU R                  U   S S u  p4UR                  XB[        U5      45        M5     [	        US S9n[        U5      S:  a  [        S U 5       5      (       a  Sn/ nU H8  u  pBnUR                  X'45        [        U[        R                  " U5      5      nM:     U R                  U:w  a.  UR                  S[        R                  U R                  -  45        [        S[        R                  4[        USS S	95      $ Sn/ nU Hp  u  pBnXH-
  n	U	S:  a  [        S
5      eU	S:  a$  UR                  S[        R                  U	-  45        UR                  X'45        U[        R                  " U5      -   nMr     U R                  U-
  n	U	S:  a$  UR                  S[        R                  U	-  45        [        S[        R                   4[        USS S	95      $ )N   c                     U S   $ r4   r\   )fs    r   <lambda>._ctype_from_dtype_structured.<locals>.<lambda>  s    adr   )rD   r   c              3   0   #    U  H  u  po1S :H  v   M     g7f)r   Nr\   )r   offsetr   r   s       r   r   /_ctype_from_dtype_structured.<locals>.<genexpr>  s     &Yj7JvU{js   r    union)_fields__pack_r^   zOverlapping fieldsstruct)r   fieldsrB   r   sortedlenallmaxr'   sizeofro   rn   r   Uniondictr   	Structure)
rP   
field_datar   field_dtyper   sizer   r   last_offsetpaddings
             r   _ctype_from_dtype_structuredr     s   
KKD"',,t"4Ra"8Kv->{-KLM  
 JN;
z?Q3&Yj&Y#Y#YDH'1#e.4u!56 (2
 ~~%V]]U^^%C DE &,,$!3   KH'1#e .Q;-.BCCQ;OOR)@$AB.$v}}U';; (2 nn{2G{V]]W%< => 6#3#3"5t!8  r   c                 x    U R                   b  [        U 5      $ U R                  b  [        U 5      $ [	        U 5      $ r@   )r   r   r   r   r   rl   s    r   r   r     s7    <<#/66^^'-e44+E22r   c                 @    [        [        R                  " U 5      5      $ )a  
Convert a dtype into a ctypes type.

Parameters
----------
dtype : dtype
    The dtype to convert

Returns
-------
ctype
    A ctype scalar, union, array, or struct

Raises
------
NotImplementedError
    If the conversion is not possible

Notes
-----
This function does not losslessly round-trip in either direction.

``np.dtype(as_ctypes_type(dt))`` will:

- insert padding fields
- reorder fields to be sorted by offset
- discard field titles

``as_ctypes_type(np.dtype(ctype))`` will:

- discard the class names of `ctypes.Structure`\ s and
  `ctypes.Union`\ s
- convert single-element `ctypes.Union`\ s into single-element
  `ctypes.Structure`\ s
- insert padding fields

Examples
--------
Converting a simple dtype:

>>> dt = np.dtype('int8')
>>> ctype = np.ctypeslib.as_ctypes_type(dt)
>>> ctype
<class 'ctypes.c_byte'>

Converting a structured dtype:

>>> dt = np.dtype([('x', 'i4'), ('y', 'f4')])
>>> ctype = np.ctypeslib.as_ctypes_type(dt)
>>> ctype
<class 'struct'>

)r   rL   rP   rl   s    r   r   r     s    l !%11r   c                    [        U [        R                  5      (       aX  Uc  [        S5      e[        R                  " [        U R                  U5      5      n[        R                  " X5      R                  n [        R                  " U 5      $ )a  
Create a numpy array from a ctypes array or POINTER.

The numpy array shares the memory with the ctypes object.

The shape parameter must be given if converting from a ctypes POINTER.
The shape parameter is ignored if converting from a ctypes array

Examples
--------
Converting a ctypes integer array:

>>> import ctypes
>>> ctypes_array = (ctypes.c_int * 5)(0, 1, 2, 3, 4)
>>> np_array = np.ctypeslib.as_array(ctypes_array)
>>> np_array
array([0, 1, 2, 3, 4], dtype=int32)

Converting a ctypes POINTER:

>>> import ctypes
>>> buffer = (ctypes.c_int * 5)(0, 1, 2, 3, 4)
>>> pointer = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_int))
>>> np_array = np.ctypeslib.as_array(pointer, (5,))
>>> np_array
array([0, 1, 2, 3, 4], dtype=int32)

z=as_array() requires a shape argument when called on a pointer)rK   r'   _PointerrN   rq   r   _type_rp   rg   rL   asarray)rY   rT   
p_arr_types      r   r   r     si    : c6??++}   szz5(IJJ++c.77Czz#r   c                    U R                   nUS   (       a  [        S5      eUS   S:w  a  [        S5      eUS   u  p#U(       a  [        S5      e[        US   5      n[        XAS	   5      nUR	                  U5      nXl        U$ )
a  
Create and return a ctypes object from a numpy array.  Actually
anything that exposes the __array_interface__ is accepted.

Examples
--------
Create ctypes object from inferred int ``np.array``:

>>> inferred_int_array = np.array([1, 2, 3])
>>> c_int_array = np.ctypeslib.as_ctypes(inferred_int_array)
>>> type(c_int_array)
<class 'c_long_Array_3'>
>>> c_int_array[:]
[1, 2, 3]

Create ctypes object from explicit 8 bit unsigned int ``np.array`` :

>>> exp_int_array = np.array([1, 2, 3], dtype=np.uint8)
>>> c_int_array = np.ctypeslib.as_ctypes(exp_int_array)
>>> type(c_int_array)
<class 'c_ubyte_Array_3'>
>>> c_int_array[:]
[1, 2, 3]

strideszstrided arrays not supportedversion   z,only __array_interface__ version 3 supporteddatazreadonly arrays unsupportedtypestrrT   )__array_interface__rN   r   r   from_address__keep)rY   aiaddrreadonlyctype_scalarresult_typeresults          r   r   r   1  s    4 $$i=:;;i=AJKKF9:: &bm4$\g;?))$/r   )NNNNr@   )'rx   __all__r   numpyrL   numpy._core.multiarrayr	   r
   r'   r   r   r   r   r   r   r   object_ndptr_basenumpy._core._internal_core	_internalnic_getintp_ctypec_void_pr8   rA   rF   rH   rd   r   r   r   r   r   r   r   r   r   r   r\   r   r   <module>r      s  2f 
  6 
>
6 LIH$K''!F//KG9T,
[ *Gf G<  rj 
B ,-&,3l362r&R)k   Fs   B+ +B65B6