U
    ,d	                    @   sV  d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlm	Z	 d dl
Z
d dlmZ d dlmZmZmZmZmZmZmZ ejZejZejZejZG dd deZe Ze Z e Z!ej"Z#e j"Z$e!j"Z%G d	d
 d
ed
dZ&G dd deddZ'G dd deddZ(G dd deZ)G dd deZ*eddZ+G dd deZ,G dd dZ-dS )    )
namedtupleN)ir)Constant)
_helperlib)typesutilsconfigloweringcgutilsimputils	serializec                   @   s&   e Zd Zdd Zdd ZdddZdS )		_Registryc                 C   s
   i | _ d S N)	functionsself r   8/tmp/pip-unpacked-wheel-eu7e0c37/numba/core/pythonapi.py__init__   s    z_Registry.__init__c                    s"   t tjst fdd}|S )Nc                    s&    j krtdf |  j < | S )Nzduplicate registration for %s)r   KeyError)funcr   	typeclassr   r   	decorator   s    

z%_Registry.register.<locals>.decorator)
issubclassr   TypeAssertionError)r   r   r   r   r   r   register   s    z_Registry.registerNc                 C   s<   t |tjst|jD ] }| j|}|d k	r|  S q|S r   )r   r   r   r   __mro__r   get)r   r   defaultclsr   r   r   r   lookup$   s    

z_Registry.lookup)N)__name__
__module____qualname__r   r   r"   r   r   r   r   r      s   	r   c                   @   s   e Zd ZdZdZdd ZdS )_BoxContextz<
    The facilities required by boxing implementations.
    r   c                 C   s   | j ||| jS r   pyapifrom_native_valueenv_managerr   typvalr   r   r   box<   s    z_BoxContext.boxN)r#   r$   r%   __doc__	__slots__r.   r   r   r   r   r&   5   s   r&   )contextbuilderr(   r*   c                   @   s   e Zd ZdZdZdd ZdS )_UnboxContextz>
    The facilities required by unboxing implementations.
    r   c                 C   s   | j ||S r   )r(   to_native_value)r   r,   objr   r   r   unboxG   s    z_UnboxContext.unboxN)r#   r$   r%   r/   r0   r6   r   r   r   r   r3   @   s   r3   )r1   r2   r(   c                   @   s,   e Zd ZdZdZdd Zdd Zdd Zd	S )
_ReflectContextz@
    The facilities required by reflection implementations.
    r   c                 C   s   | j | jtj d S r   )r2   storeis_errorr
   Ztrue_bitr   r   r   r   	set_errorT   s    z_ReflectContext.set_errorc                 C   s   | j ||| jS r   r'   r+   r   r   r   r.   W   s    z_ReflectContext.boxc                 C   s   | j ||| jS r   )r(   reflect_native_valuer*   r+   r   r   r   reflectZ   s    z_ReflectContext.reflectN)r#   r$   r%   r/   r0   r:   r.   r<   r   r   r   r   r7   K   s
   r7   )r1   r2   r(   r*   r9   c                   @   s   e Zd ZdZdddZdS )NativeValuez
    Encapsulate the result of converting a Python object to a native value,
    recording whether the conversion was successful and how to cleanup.
    Nc                 C   s$   || _ |d k	r|ntj| _|| _d S r   )valuer
   	false_bitr9   cleanup)r   r>   r9   r@   r   r   r   r   d   s    zNativeValue.__init__)NN)r#   r$   r%   r/   r   r   r   r   r   r=   ^   s   r=   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )EnvironmentManagerc                 C   s,   t |tjst|| _|| _|| _|| _d S r   )
isinstancer	   Environmentr   r(   envenv_bodyenv_ptr)r   r(   rD   rE   rF   r   r   r   r   l   s
    zEnvironmentManager.__init__c                 C   sT   t |trt|}t| jjD ]\}}||kr  qPq t| jj}| jj| |S )zF
        Add a constant to the environment, return its index.
        )	rB   strsysintern	enumeraterD   constslenappend)r   constindexr-   r   r   r   	add_consts   s    

zEnvironmentManager.add_constc              
   C   s   |t | jjk st| jj}| jj}tj|| jj	dd}|
t||R\}}|  | j||}||| W 5 Q R X | | jdd W 5 Q R X W 5 Q R X ||S )z
        Look up constant number *index* inside the environment body.
        A borrowed reference is returned.

        The returned LLVM value may have NULL value at runtime which indicates
        an error at runtime.
        TzfillPyExc_RuntimeErrorz$`env.consts` is NULL in `read_const`)rL   rD   rK   r   r(   r2   rE   r
   alloca_oncepyobjif_elseis_not_nulllist_getitemr8   err_set_stringload)r   rO   r2   rK   retZbr_not_nullZbr_nullgetitemr   r   r   
read_const   s    zEnvironmentManager.read_constN)r#   r$   r%   r   rP   r]   r   r   r   r   rA   j   s   rA   _IteratorLoop)r>   do_breakc                   @   sp  e Zd ZdZdd Zdd ZdWdd	Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdXdd Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* ZejdYd+d,Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 ZdZd:d;Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+dRdS Z,dTdU Z-dVdW Z.dXdY Z/dZd[ Z0d\d] Z1d^d_ Z2d[d`daZ3d\dbdcZ4d]dddeZ5d^dfdgZ6d_dhdiZ7d`djdkZ8dadldmZ9dbdndoZ:dcdpdqZ;dddrdsZ<dedtduZ=dfdvdwZ>dgdxdyZ?dhdzd{Z@d|d} ZAd~d ZBdd ZCdd ZDdd ZEdd ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdiddZZdd Z[dd Z\dd Z]dd Z^dd Z_ejdd Z`dd Zadd Zbdd ZcddÄ Zdddń ZeddǄ ZfddɄ Zgdd˄ Zhdd̈́ ZidjddЄZjdkdd҄ZkddԄ Zlddք Zmdd؄ Znddڄ Zodd܄ Zpddބ Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|dd Z}dd Z~dd Zdd Zdd Zdd  Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zejdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zdld5d6Zdmd7d8Zd9d: Zdnd;d<Zd=d> Zd?d@ ZdAdB ZdCdD ZdEdF ZdGdH ZdIdJ ZdKdL ZdMdN ZdOdP ZdQdR ZdSdT ZdUdV ZdS (o  	PythonAPIz^
    Code generation facilities to call into the CPython C API (and related
    helpers).
    c                 C   s0  || _ || _|jjj| _z| jj W n tk
r@   i | j_Y nX | j tj	| _
| j
 | _ttd| _tttjd | _| j| _tttjd | _| j| _t | _| j tj| _ttd| _ttj d | _!t"tdtj#| _$| j| _%tj&| _&tj'| _'tj(| _(tj)| _)dS )zL
        Note: Maybe called multiple times when lowering a function
           N)*r1   r2   Zbasic_blockfunctionmodule_PythonAPI__serializedAttributeErrorZget_argument_typer   pyobjectrU   
as_pointerpyobjptrr   PointerTypeIntTypevoidptrctypessizeofc_longlongulongc_ulonglonglonglong	ulonglong
DoubleTypedoubleget_value_typeintp
py_ssize_tcstringr   Zpy_gil_state_size	gil_stateZ	ArrayTypeZpy_buffer_sizepy_buffer_t	py_hash_tpy_unicode_1byte_kindpy_unicode_2byte_kindpy_unicode_4byte_kindpy_unicode_wchar_kind)r   r1   r2   r   r   r   r      s0    
zPythonAPI.__init__c                 C   s   t | |||S r   )rA   )r   rD   rE   rF   r   r   r   get_env_manager   s    zPythonAPI.get_env_managerF c              	   C   s   t | j|}t | j|f |rb| jjjj}|j| jks>t	| 
dd|  | j|   n| jj| jtd| f W 5 Q R X dS )z;Emits LLVM code to ensure the `envptr` is not NULL
        rS   zmissing Environment: N)r
   is_nullr2   Zif_unlikelyrb   typepointeereturn_typerU   r   rY   r[   get_null_objectr1   	call_convZreturn_user_excRuntimeError)r   ZenvptrZreturn_pyobjectZ	debug_msgr   fntyr   r   r   emit_environment_sentry   s      
z!PythonAPI.emit_environment_sentryc                 C   s6   t t  | jg}| j|dd}| j||g d S )NZ	Py_IncRefnamer   FunctionTypeVoidTyperU   _get_functionr2   callr   r5   r   fnr   r   r   incref   s    zPythonAPI.increfc                 C   s6   t t  | jg}| j|dd}| j||g d S )NZ	Py_DecRefr   r   r   r   r   r   decref   s    zPythonAPI.decrefc                 C   s0   t | j| jg}| j|dd}| j||gS )NZnumba_py_typer   r   r   rU   r   r2   r   r   r   r   r   get_type   s    zPythonAPI.get_typec                 G   sl   t t d}t |}| j| j||g}t jt d|dd}	| j|	dd}
| j|
||||gt| S )Nra       TZvar_argZPyArg_ParseTupleAndKeywordsr   	r   ri   rj   rU   r   r   r2   r   list)r   argskwsfmtkeywordsobjscharptrZ
charptraryargtypesr   r   r   r   r   parse_tuple_and_keywords   s    
z"PythonAPI.parse_tuple_and_keywordsc                 G   sX   t t d}| j|g}t jt d|dd}| j|dd}| j|||gt| S )Nra   r   Tr   ZPyArg_ParseTupler   r   )r   r   r   r   r   r   r   r   r   r   r   parse_tuple   s
    
zPythonAPI.parse_tuplec           
      G   s   t t d}| j|| j| jg}t jt d|dd}| j|dd}	t| jt|}t| jt|}t	|t
r| j| jj|}| j|	||||gt| S )Nra   r   Tr   ZPyArg_UnpackTupler   )r   ri   rj   rU   rx   r   r   r   intrB   rG   r1   insert_const_stringr2   rc   r   r   )
r   r   r   Zn_minZn_maxr   r   r   r   r   r   r   r   unpack_tuple  s    
zPythonAPI.unpack_tuplec                 C   s*   t | jd}| j|dd}| j|dS )Nr   ZPyErr_Occurredr   r   r   r   r   r   r   r   err_occurred  s    zPythonAPI.err_occurredc                 C   s,   t t  d}| j|dd}| j|dS )Nr   ZPyErr_Clearr   )r   r   r   r   r2   r   r   r   r   r   	err_clear  s    zPythonAPI.err_clearc                 C   sf   t t  | j| jg}| j|dd}t|tr:| |}t|trT| j	
| j|}| j|||fS )NZPyErr_SetStringr   )r   r   r   rU   ry   r   rB   rG   get_c_objectr1   r   rc   r2   r   )r   exctypemsgr   r   r   r   r   rY     s    


zPythonAPI.err_set_stringc                 G   sr   t jt  | j| jgdd}| j|dd}t|tr>| |}t|trX| j	
| j|}| j|||ft| S )NTr   ZPyErr_Formatr   )r   r   r   rU   ry   r   rB   rG   r   r1   r   rc   r2   r   tuple)r   r   r   Zformat_argsr   r   r   r   r   
err_format(  s    


zPythonAPI.err_formatNc                 C   sB   t t  | jg}| j|dd}|dkr2|  }| j||fS )z
        Raise an arbitrary exception (type or value or (type, args)
        or None - if reraising).  A reference to the argument is consumed.
        Znumba_do_raiser   N)r   r   r   rU   r   	make_noner2   r   )r   excr   r   r   r   r   raise_object1  s
    zPythonAPI.raise_objectc                 C   sL   t t  | j| jg}| j|dd}t|tr:| |}| j	|||fS )NZPyErr_SetObjectr   
r   r   r   rU   r   rB   rG   r   r2   r   )r   r   Zexcvalr   r   r   r   r   err_set_object<  s
    

zPythonAPI.err_set_objectc                 C   sF   t t  | jg}| j|dd}t|tr6| |}| j	||fS )NZPyErr_SetNoner   r   )r   r   r   r   r   r   r   err_set_noneC  s
    

zPythonAPI.err_set_nonec                 C   s2   t t  | jg}| j|dd}| j||fS )NZPyErr_WriteUnraisabler   r   r   r   r   r   err_write_unraisableJ  s    zPythonAPI.err_write_unraisablec                 C   s:   t t  | jgd }| j|dd}| j||||fS )N   ZPyErr_Fetchr   )r   r   r   rh   r   r2   r   )r   ptypvalptbr   r   r   r   r   	err_fetchO  s    zPythonAPI.err_fetchc                 C   s:   t t  | jgd }| j|dd}| j||||fS )Nr   ZPyErr_Restorer   r   )r   tyr-   tbr   r   r   r   r   err_restoreT  s    zPythonAPI.err_restorec              
   #   s    fddt dD \}}} ||| dV   j|} j|} j|}|rt j  } jj|ddV\}	}
|	$  |  |  | W 5 Q R X |
  	||| W 5 Q R X W 5 Q R X n 	||| dS )a  
        Temporarily push the current error indicator while the code
        block is executed.  If *keep_new* is True and the code block
        raises a new error, the new error is kept, otherwise the old
        error indicator is restored at the end of the block.
        c                    s   g | ]}t  j jqS r   )r
   rT   r2   rU   ).0ir   r   r   
<listcomp>a  s   z&PythonAPI.err_push.<locals>.<listcomp>r   NFZlikely)
ranger   r2   rZ   r
   rW   r   rV   r   r   )r   Zkeep_newr   r   r   r   r-   r   Z	new_errorZif_errorZif_okr   r   r   err_pushY  s$    


$zPythonAPI.err_pushc                 C   s   | j j| j| jj|ddS )z
        Get a Python object through its C-accessible *name*
        (e.g. "PyExc_ValueError").  The underlying variable must be
        a `PyObject *`, and the value of that pointer is returned.
        T)Z	dllimport)r1   Zget_c_valuer2   rU   r   )r   r   r   r   r   r   v  s    zPythonAPI.get_c_objectc                 C   s(   d| }| j | j|}| d| d S )Nzglobal name '%s' is not definedPyExc_NameErrorr1   r   rc   rY   r   r   r   cstrr   r   r   raise_missing_global_error  s    z$PythonAPI.raise_missing_global_errorc                 C   s(   d| }| j | j|}| d| d S )Nzname '%s' is not definedr   r   r   r   r   r   raise_missing_name_error  s    z"PythonAPI.raise_missing_name_errorc                 C   sR   t t  | jg}| j|dd}|jd | j| j	|}| j
||f d S )NZPy_FatalErrorr   Znoreturn)r   r   r   ry   r   
attributesaddr1   r   rc   r2   r   )r   r   r   r   r   r   r   r   fatal_error  s
    zPythonAPI.fatal_errorc                 C   sF   t | j| j| jg}| j|dd}| j| j|}| j	|||gS )FLookup name inside dict

        Returns a borrowed reference
        ZPyDict_GetItemStringr   )
r   r   rU   ry   r   r1   r   rc   r2   r   )r   dicr   r   r   r   r   r   r   dict_getitem_string  s    zPythonAPI.dict_getitem_stringc                 C   s6   t | j| j| jg}| j|dd}| j|||gS )r   ZPyDict_GetItemr   r   )r   r   r   r   r   r   r   r   dict_getitem  s    zPythonAPI.dict_getitemr   c                 C   sr   |dkr2t | jd}| j|dd}| j|dS t | j| jg}| j|dd}| j|t| jt|gS d S )Nr   r   Z
PyDict_Newr   Z_PyDict_NewPresized)	r   r   rU   r   r2   r   rx   r   r   )r   Zpresizer   r   r   r   r   dict_new  s    zPythonAPI.dict_newc                 C   s@   t t d| j| j| jf}| j|dd}| j||||fS )Nr   ZPyDict_SetItemr   r   r   rj   rU   r   r2   r   )r   dictobjZnameobjvalobjr   r   r   r   r   dict_setitem  s
    zPythonAPI.dict_setitemc                 C   sP   t t d| j| j| jf}| j|dd}| j| j|}| j	
||||fS )Nr   ZPyDict_SetItemStringr   )r   r   rj   rU   ry   r   r1   r   rc   r2   r   )r   r   r   r   r   r   r   r   r   r   dict_setitem_string  s    zPythonAPI.dict_setitem_stringc              	   C   s>   |   }| |" |D ]\}}| ||| qW 5 Q R X |S )zb
        Args
        -----
        keyvalues: iterable of (str, llvm.Value of PyObject*)
        )r   if_object_okr   )r   Z	keyvaluesr   kvr   r   r   	dict_pack  s
    zPythonAPI.dict_packc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyFloat_FromDoubler   )r   r   rU   ru   r   r2   r   )r   Zfvalr   r   r   r   r   float_from_double  s    zPythonAPI.float_from_doublec                 C   s@   t | j| j| jg}| j|dd}| d}| j|||gS )NZPyNumber_AsSsize_tr   ZPyExc_OverflowError)r   r   rx   rU   r   r   r2   r   )r   numobjr   r   	exc_classr   r   r   number_as_ssize_t  s    
zPythonAPI.number_as_ssize_tc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyNumber_Longr   r   r   r   r   r   r   r   r   number_long  s    zPythonAPI.number_longc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyLong_AsUnsignedLongLongr   r   r   rs   rU   r   r2   r   r   r   r   r   long_as_ulonglong  s    zPythonAPI.long_as_ulonglongc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyLong_AsLongLongr   r   r   r   r   r   long_as_longlong  s    zPythonAPI.long_as_longlongc                 C   s0   t | j| jg}| j|dd}| j||gS )z
        Convert the given Python integer to a void*.  This is recommended
        over number_as_ssize_t as it isn't affected by signedness.
        ZPyLong_AsVoidPtrr   r   r   rk   rU   r   r2   r   r   r   r   r   long_as_voidptr  s    zPythonAPI.long_as_voidptrc                 C   sb   t | j|g}| j||d}t| j| j}| j||d}| j| j||g| | j	|S )Nr   )
r   r   rU   r   r
   rT   r2   r8   r   rZ   )r   ival	func_nameZnative_int_typesignedr   r   Zresptrr   r   r   _long_from_native_int  s    zPythonAPI._long_from_native_intc                 C   s4   d}t | j| jg}| j||d}| j||gS )NZPyLong_FromLongr   r   r   rU   ro   r   r2   r   )r   r   r   r   r   r   r   r   long_from_long  s    zPythonAPI.long_from_longc                 C   s   | j |d| jddS )NZPyLong_FromUnsignedLongFr   )r   ro   r   r   r   r   r   long_from_ulong  s     zPythonAPI.long_from_ulongc                 C   s   | j |d| jddS )NZPyLong_FromSsize_tTr   )r   rx   r   r   r   r   long_from_ssize_t	  s     zPythonAPI.long_from_ssize_tc                 C   s   | j |d| jddS )NZPyLong_FromLongLongTr   )r   rr   r   r   r   r   long_from_longlong  s     zPythonAPI.long_from_longlongc                 C   s   | j |d| jddS )NZPyLong_FromUnsignedLongLongFr   )r   rs   r   r   r   r   long_from_ulonglong  s     zPythonAPI.long_from_ulonglongc                 C   s\   |j j}|| jjkr*| | j|| jS || jjkrL| | j|| jS td| dS )zH
        Return a Python integer from any native integer value.
        integer too big (%d bits)N)	r   widthro   r   r2   Zsextrr   r   OverflowErrorr   r   bitsr   r   r   long_from_signed_int  s    zPythonAPI.long_from_signed_intc                 C   s\   |j j}|| jjkr*| | j|| jS || jjkrL| | j|| jS td| dS )zH
        Same as long_from_signed_int, but for unsigned values.
        r   N)	r   r   rp   r   r2   zextrs   r   r   r   r   r   r   long_from_unsigned_int!  s    z PythonAPI.long_from_unsigned_intc                 C   s,   t | j| j| jg}| j|d| d}|S )NzPyNumber_%sr   )r   r   rU   r   )r   r   r   r   r   r   r   _get_number_operator-  s    zPythonAPI._get_number_operatorc                 C   s(   |rd| }|  |}| j|||gS )NZInPlace)r   r2   r   )r   r   lhsrhsinplacer   r   r   r   _call_number_operator2  s    
zPythonAPI._call_number_operatorc                 C   s   | j d|||dS )NZAddr   r   r   r   r   r   r   r   r   
number_add8  s    zPythonAPI.number_addc                 C   s   | j d|||dS )NZSubtractr  r  r  r   r   r   number_subtract;  s    zPythonAPI.number_subtractc                 C   s   | j d|||dS )NZMultiplyr  r  r  r   r   r   number_multiply>  s    zPythonAPI.number_multiplyc                 C   s   | j d|||dS )NZ
TrueDivider  r  r  r   r   r   number_truedivideA  s    zPythonAPI.number_truedividec                 C   s   | j d|||dS )NZFloorDivider  r  r  r   r   r   number_floordivideD  s    zPythonAPI.number_floordividec                 C   s   | j d|||dS )NZ	Remainderr  r  r  r   r   r   number_remainderG  s    zPythonAPI.number_remainderc                 C   s   | j d|||dS )NZMatrixMultiplyr  r  r  r   r   r   number_matrix_multiplyJ  s    z PythonAPI.number_matrix_multiplyc                 C   s   | j d|||dS )NZLshiftr  r  r  r   r   r   number_lshiftM  s    zPythonAPI.number_lshiftc                 C   s   | j d|||dS )NZRshiftr  r  r  r   r   r   number_rshiftP  s    zPythonAPI.number_rshiftc                 C   s   | j d|||dS )NAndr  r  r  r   r   r   
number_andS  s    zPythonAPI.number_andc                 C   s   | j d|||dS )NOrr  r  r  r   r   r   	number_orV  s    zPythonAPI.number_orc                 C   s   | j d|||dS )NZXorr  r  r  r   r   r   
number_xorY  s    zPythonAPI.number_xorc                 C   sF   t | j| jgd }|rdnd}| ||}| j||||  gS )Nr   ZPyNumber_InPlacePowerZPyNumber_Power)r   r   rU   r   r2   r   borrow_none)r   r   r   r   r   fnamer   r   r   r   number_power\  s    zPythonAPI.number_powerc                 C   s0   t | j| jg}| j|dd}| j||fS )NZPyNumber_Negativer   r   r   r   r   r   number_negativeb  s    zPythonAPI.number_negativec                 C   s0   t | j| jg}| j|dd}| j||fS )NZPyNumber_Positiver   r   r   r   r   r   number_positiveg  s    zPythonAPI.number_positivec                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyNumber_Floatr   r   )r   r-   r   r   r   r   r   number_floatl  s    zPythonAPI.number_floatc                 C   s0   t | j| jg}| j|dd}| j||fS )NZPyNumber_Invertr   r   r   r   r   r   number_invertq  s    zPythonAPI.number_invertc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyFloat_AsDoubler   )r   r   ru   rU   r   r2   r   )r   Zfobjr   r   r   r   r   float_as_doublev  s    zPythonAPI.float_as_doublec                 C   s   | j || j}| |S )z8
        Get a Python bool from a LLVM boolean.
        )r2   r   ro   bool_from_long)r   ZbvalZlongvalr   r   r   bool_from_bool{  s    zPythonAPI.bool_from_boolc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyBool_FromLongr   r   )r   r   r   r   r   r   r   r    s    zPythonAPI.bool_from_longc                 C   s:   t | jt  t  g}| j|dd}| j|||gS )NZPyComplex_FromDoublesr   )r   r   rU   rt   r   r2   r   )r   ZrealvalZimagvalr   r   r   r   r   complex_from_doubles  s    zPythonAPI.complex_from_doublesc                 C   s2   t t  | jg}| j|dd}| j||gS )NZPyComplex_RealAsDoubler   r   r   rt   rU   r   r2   r   r   cobjr   r   r   r   r   complex_real_as_double  s    z PythonAPI.complex_real_as_doublec                 C   s2   t t  | jg}| j|dd}| j||gS )NZPyComplex_ImagAsDoubler   r  r  r   r   r   complex_imag_as_double  s    z PythonAPI.complex_imag_as_doublec                 C   s   t | j| j}t | j| j}t | j| j}ttd| jg| j gd  }| j	|dd}| j
|||||f}| j|}| j|}	| j|}
t | j|||	|
fS )z
        Read the members of a slice of integers.

        Returns a (ok, start, stop, step) tuple where ok is a boolean and
        the following members are pointer-sized ints.
        r   r   Znumba_unpack_slicer   )r
   rT   r2   rx   r   r   rj   rU   rg   r   r   rZ   r   )r   r5   ZpstartZpstopZpstepr   r   resstartstopstepr   r   r   slice_as_ints  s    zPythonAPI.slice_as_intsc                 C   s<   t | j| j| j| jg}| j|dd}| j||||fS )NZPySequence_GetSlicer   r   r   rU   rx   r   r2   r   )r   r5   r#  r$  r   r   r   r   r   sequence_getslice  s
    zPythonAPI.sequence_getslicec                 C   s0   t | j| jg}| j|dd}| j||gS )NZPySequence_Tupler   r   r   r   r   r   sequence_tuple  s    zPythonAPI.sequence_tuplec                 C   s6   t | j| j| jg}| j|dd}| j|||gS )NZPySequence_Concatr   r   )r   Zobj1obj2r   r   r   r   r   sequence_concat  s    zPythonAPI.sequence_concatc                 C   s0   t | j| jg}| j|dd}| j||gS )NZ
PyList_Newr   r'  )r   Zszvalr   r   r   r   r   list_new  s    zPythonAPI.list_newc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyList_Sizer   r   r   rx   rU   r   r2   r   )r   lstr   r   r   r   r   	list_size  s    zPythonAPI.list_sizec                 C   s:   t t d| j| jg}| j|dd}| j|||gS )Nr   ZPyList_Appendr   r   )r   r.  r-   r   r   r   r   r   list_append  s    zPythonAPI.list_appendc                 C   s@   t t d| j| j| jg}| j|dd}| j||||gS )z6
        Warning: Steals reference to ``val``
        r   ZPyList_SetItemr   )r   r   rj   rU   rx   r   r2   r   )r   r.  idxr-   r   r   r   r   r   list_setitem  s
    zPythonAPI.list_setitemc                 C   sP   t | j| j| jg}| j|dd}t|tr>| jt	j
|}| j|||gS )z/
        Returns a borrowed reference.
        ZPyList_GetItemr   )r   r   rU   rx   r   rB   r   r1   get_constantr   rw   r2   r   )r   r.  r1  r   r   r   r   r   rX     s
    
zPythonAPI.list_getitemc                 C   sV   |d kr|   }ttd| j| j| j| jg}| j|dd}| j|||||fS )Nr   ZPyList_SetSlicer   )	r   r   r   rj   rU   rx   r   r2   r   )r   r.  r#  r$  r5   r   r   r   r   r   list_setslice  s     zPythonAPI.list_setslicec                 C   sF   t | j| j| jg}| j|dd}| jtj|}| j	
|||gS )z"
        Borrow reference
        ZPyTuple_GetItemr   )r   r   rU   rx   r   r1   r3  r   rw   r2   r   )r   tupr1  r   r   r   r   r   tuple_getitem  s    zPythonAPI.tuple_getitemc                 C   sV   t j| j| jgdd}| j|dd}| jtjt	|}|g}|
| | j||S )NTr   ZPyTuple_Packr   )r   r   rU   rx   r   r1   r3  r   rw   rL   extendr2   r   )r   itemsr   r   nr   r   r   r   
tuple_pack  s    
zPythonAPI.tuple_packc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyTuple_Sizer   r-  )r   r5  r   r   r   r   r   
tuple_size   s    zPythonAPI.tuple_sizec                 C   s@   t | jt dg}| j|dd}| j|| jt	j
|gS )Nr   ZPyTuple_Newr   )r   r   rU   rj   r   r2   r   r1   r3  r   int32)r   countr   r   r   r   r   	tuple_new  s
    zPythonAPI.tuple_newc                 C   sX   t t d| jt d| jg}| j|dd}| jtj|}| j	
||||g dS )z/
        Steals a reference to `item`.
        r   ZPyTuple_SetItemr   N)r   r   rj   rU   r   r1   r3  r   r<  r2   r   )r   Z	tuple_valrO   itemr   Z
setitem_fnr   r   r   tuple_setitem  s    "zPythonAPI.tuple_setitemc                 C   s@   |d kr|   }t| j| jg}| j|dd}| j||gS )NZ	PySet_Newr   r   r   r   rU   r   r2   r   )r   iterabler   r   r   r   r   set_new  s
    zPythonAPI.set_newc                 C   s:   t t d| j| jg}| j|dd}| j|||gS )Nr   Z	PySet_Addr   r   )r   setr>   r   r   r   r   r   set_add  s    zPythonAPI.set_addc                 C   s4   t t d| jg}| j|dd}| j||gS )Nr   ZPySet_Clearr   r   r   rD  r   r   r   r   r   	set_clear$  s    zPythonAPI.set_clearc                 C   s0   t | j| jg}| j|dd}| j||gS )NZ
PySet_Sizer   r-  rF  r   r   r   set_size)  s    zPythonAPI.set_sizec                 C   s:   t t d| j| jg}| j|dd}| j|||gS )Nr   Z_PySet_Updater   r   )r   rD  rB  r   r   r   r   r   
set_update.  s    zPythonAPI.set_updatec                 C   sR   t t d| j| j | j | j g}| j|dd}| j	|||||fS )Nr   Z_PySet_NextEntryr   )
r   r   rj   rU   rx   rg   r|   r   r2   r   )r   rD  posptrkeyptrhashptrr   r   r   r   r   set_next_entry3  s     zPythonAPI.set_next_entryc           	   
   #   s   | j tj| jdd}tj| jdd}tjt| jddd}d}d 	|  fdd	}
|b | ||||}t|}j|d
d 	  W 5 Q R X t||V  	| W 5 Q R X   d S )NrL  r   rK  r   rJ  bb_bodybb_endc                      s      d S r   )branchr   rO  r2   r   r   r_   H  s    z'PythonAPI.set_iterate.<locals>.do_breakFr   )r2   r
   rT   r|   rU   alloca_once_valuer   rx   append_basic_blockrP  Z
goto_blockrM  r   if_thenr^   rZ   position_at_end)	r   rD  rL  rK  rJ  rN  r_   rfinishedr   rQ  r   set_iterate:  s&    



zPythonAPI.set_iteratec                 C   sN   t | j}t t  |g}| |d}t| j| j}| j	||g |S )zk
        Ensure the GIL is acquired.
        The returned value must be consumed by gil_release().
        Znumba_gil_ensure)
r   ri   rz   r   r   r   r
   rT   r2   r   )r   gilptrtyr   r   Zgilptrr   r   r   
gil_ensureY  s    zPythonAPI.gil_ensurec                 C   s:   t | j}t t  |g}| |d}| j||gS )zg
        Release the acquired GIL by gil_ensure().
        Must be paired with a gil_ensure().
        Znumba_gil_release)r   ri   rz   r   r   r   r2   r   )r   ZgilrY  r   r   r   r   r   gil_releasee  s    zPythonAPI.gil_releasec                 C   s*   t | jg }| j|dd}| j|g S )zj
        Release the GIL and return the former thread state
        (an opaque non-NULL pointer).
        ZPyEval_SaveThreadr   )r   r   rk   r   r2   r   r   r   r   r   save_threado  s    zPythonAPI.save_threadc                 C   s6   t t  | jg}| j|dd}| j||g dS )zH
        Restore the given thread state by reacquiring the GIL.
        ZPyEval_RestoreThreadr   N)r   r   r   rk   r   r2   r   )r   Zthread_stater   r   r   r   r   restore_threadx  s    zPythonAPI.restore_threadc                 C   s0   t | j| jg}| j|dd}| j||fS )NZnumba_get_pyobject_private_datar   r   r   r   r   r   object_get_private_data  s    z!PythonAPI.object_get_private_datac                 C   s8   t t  | j| jg}| j|dd}| j|||fS )NZnumba_set_pyobject_private_datar   )r   r   r   rU   rk   r   r2   r   )r   r5   ptrr   r   r   r   r   object_set_private_data  s    z!PythonAPI.object_set_private_datac                 C   s2   t t  | jg}| j|dd}| j||fS )NZ!numba_reset_pyobject_private_datar   r   r   r   r   r   object_reset_private_data  s    z#PythonAPI.object_reset_private_datac                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyImport_ImportModuleNoBlockr   r   r   rU   ry   r   r2   r   )r   modnamer   r   r   r   r   import_module_noblock  s    zPythonAPI.import_module_noblockc                 C   sT   t j| j| jgdd}| j|dd}|gt| }|| jtj	 | j
||S )NTr   ZPyObject_CallFunctionObjArgsr   )r   r   rU   r   r   rM   r1   get_constant_nullr   rf   r2   r   )r   calleeobjargsr   r   r   r   r   r   call_function_objargs  s
    zPythonAPI.call_function_objargsr   c           
      C   s   | j | j|}tj| j| j| j| jgdd}| j|dd}dt| }| j | j|}|||g}	|rp|		| |	
| j tj | j||	S )NTr   ZPyObject_CallMethodr   O)r1   r   rc   r   r   rU   ry   r   rL   r7  rM   re  r   rf   r2   r   )
r   rf  methodrg  cnamer   r   r   Zcfmtr   r   r   r   call_method  s    

zPythonAPI.call_methodc                 C   sX   |d kr|   }|d kr |   }t| j| jgd }| j|dd}| j||||fS )Nr   ZPyObject_Callr   rA  )r   rf  r   r   r   r   r   r   r   r     s    zPythonAPI.callc                 C   s0   t | j| jg}| j|dd}| j||fS )zJEmit a call to ``PyObject_Type(obj)`` to get the type of ``obj``.
        ZPyObject_Typer   r   r   r   r   r   object_type  s    zPythonAPI.object_typec                 C   s4   t t d| jg}| j|dd}| j||gS )Nr   ZPyObject_IsTruer   r   r   r   r   r   object_istrue  s    zPythonAPI.object_istruec                 C   s4   t t d| jg}| j|dd}| j||gS )Nr   ZPyObject_Notr   r   r   r   r   r   
object_not  s    zPythonAPI.object_notc              	   C   s  ddddddg}||krr| |}t| j| j| jtdg}| j|dd	}| jtj	|}| j
||||fS |d
kr| j
d||}	| |	S |dkr| j
d||}	| |	S |dkrttd| j| jg}| j|dd	}| j
|||f}
| jtj	d}| j
d|
|}t| j
t| jd}t| j
|D |dkrV| j
|
}
| j
|
td}| j
| || W 5 Q R X | j
|S tdj|ddS )zd
        Refer to Python source Include/object.h for macros definition
        of the opid.
        <z<=z==!=>z>=r   ZPyObject_RichComparer   iszis not)innot inZPySequence_ContainsNru     zUnknown operator {op!r})op)rO   r   r   rU   rj   r   r1   r3  r   r<  r2   r   icmp_unsignedr  r
   rR  r   	if_likelynot_truncr8   rZ   NotImplementedErrorformat)r   r   r   ZopstropsZopidr   r   ZlopidZbitflagstatusZnegoneZis_goodZoutptrZ	truncatedr   r   r   object_richcompare  sB    





zPythonAPI.object_richcomparec                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyIter_Nextr   r   )r   Ziterobjr   r   r   r   r   	iter_next  s    zPythonAPI.iter_nextc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyObject_GetIterr   r   r   r   r   r   object_getiter  s    zPythonAPI.object_getiterc                 C   sF   | j | j|}t| j| j| jg}| j|dd}| j	|||gS )NZPyObject_GetAttrStringr   )
r1   r   rc   r   r   rU   ry   r   r2   r   )r   r5   attrr   r   r   r   r   r   object_getattr_string  s    zPythonAPI.object_getattr_stringc                 C   s6   t | j| j| jg}| j|dd}| j|||gS )NZPyObject_GetAttrr   r   )r   r5   r  r   r   r   r   r   object_getattr  s    zPythonAPI.object_getattrc                 C   sP   | j | j|}ttd| j| j| jg}| j|dd}| j	
||||gS )Nr   ZPyObject_SetAttrStringr   )r1   r   rc   r   r   rj   rU   ry   r   r2   r   )r   r5   r  r-   r   r   r   r   r   r   object_setattr_string
  s    zPythonAPI.object_setattr_stringc                 C   s@   t t d| j| j| jg}| j|dd}| j||||gS )Nr   ZPyObject_SetAttrr   r   )r   r5   r  r-   r   r   r   r   r   object_setattr  s    zPythonAPI.object_setattrc                 C   s   |  |||  S r   )r  r   r   r5   r  r   r   r   object_delattr_string  s    zPythonAPI.object_delattr_stringc                 C   s   |  |||  S r   )r  r   r  r   r   r   object_delattr  s    zPythonAPI.object_delattrc                 C   s6   t | j| j| jg}| j|dd}| j|||fS )z!
        Return obj[key]
        ZPyObject_GetItemr   r   r   r5   keyr   r   r   r   r   object_getitem  s    zPythonAPI.object_getitemc                 C   s@   t t d| j| j| jg}| j|dd}| j||||fS )z 
        obj[key] = val
        r   ZPyObject_SetItemr   r   )r   r5   r  r-   r   r   r   r   r   object_setitem'  s    zPythonAPI.object_setitemc                 C   s:   t t d| j| jg}| j|dd}| j|||fS )z
        del obj[key]
        r   ZPyObject_DelItemr   r   r  r   r   r   object_delitem/  s    zPythonAPI.object_delitemc                 C   s4   t | j| jg}d}| j||d}| j||gS )NZPyUnicode_AsUTF8r   )r   r   ry   rU   r   r2   r   )r   strobjr   r  r   r   r   r   string_as_string7  s    zPythonAPI.string_as_stringc                 C   sx   t | j| j}t| j| j| j g}d}| j	||d}| j
|||g}| jdt|jd|}||| j|fS )z
        Returns a tuple of ``(ok, buffer, length)``.
        The ``ok`` is i1 value that is set if ok.
        The ``buffer`` is a i8* of the output buffer.
        The ``length`` is a i32/i64 (py_ssize_t) of the length of the buffer.
        ZPyUnicode_AsUTF8AndSizer   rq  N)r
   rT   r2   rx   r   r   ry   rU   rg   r   r   ry  r   r   rZ   )r   r  p_lengthr   r  r   bufferokr   r   r   string_as_string_and_size=  s    
z#PythonAPI.string_as_string_and_sizec              	   C   s   t | j| j}t | jtd}t | jtd}t | j| j}t| j| j	| j
 td
 td
 | j
 g}d}| j||d}| j||||||g}	| jdt|	jd|	}
|
|	| j|| j|| j|| j|fS )a  
        Returns a tuple of ``(ok, buffer, length, kind)``.
        The ``ok`` is i1 value that is set if ok.
        The ``buffer`` is a i8* of the output buffer.
        The ``length`` is a i32/i64 (py_ssize_t) of the length of the buffer.
        The ``kind`` is a i32 (int32) of the Unicode kind constant
        The ``hash`` is a long/uint64_t (py_hash_t) of the Unicode constant hash
        r   Znumba_extract_unicoder   rq  N)r
   rT   r2   rx   r   rj   r|   r   ry   rU   rg   r   r   ry  r   r   rZ   )r   r  r  Zp_kindZp_asciiZp_hashr   r  r   r  r  r   r   r   string_as_string_size_and_kindQ  s2    	 

 

z(PythonAPI.string_as_string_size_and_kindc                 C   s:   t | j| j| jg}d}| j||d}| j|||gS )NZPyString_FromStringAndSizer   r   r   rU   ry   rx   r   r2   r   r   stringsizer   r  r   r   r   r   string_from_string_and_sizeo  s    z%PythonAPI.string_from_string_and_sizec                 C   s4   t | j| jg}d}| j||d}| j||gS )NZPyUnicode_FromStringr   rb  )r   r  r   r  r   r   r   r   string_from_stringu  s    zPythonAPI.string_from_stringc                 C   sD   t | jt d| j| jg}d}| j||d}| j||||gS )Nr   ZPyUnicode_FromKindAndDatar   )	r   r   rU   rj   ry   rx   r   r2   r   )r   kindr  r  r   r  r   r   r   r   string_from_kind_and_data{  s    z#PythonAPI.string_from_kind_and_datac                 C   s:   t | j| j| jg}d}| j||d}| j|||gS )NZPyBytes_FromStringAndSizer   r  r  r   r   r   bytes_from_string_and_size  s    z$PythonAPI.bytes_from_string_and_sizec                 C   s4   t | j| jg}d}| j||d}| j||gS )NZPyObject_Hashr   )r   r   r|   rU   r   r2   r   )r   r5   r   r  r   r   r   r   object_hash  s    zPythonAPI.object_hashc                 C   s0   t | j| jg}| j|dd}| j||gS )NZPyObject_Strr   r   r   r   r   r   
object_str  s    zPythonAPI.object_strc                 C   s   |   }| | |S r   )r  r   r   r5   r   r   r   r     s    
zPythonAPI.make_nonec                 C   s
   |  dS )NZ_Py_NoneStruct)r   r   r   r   r   r    s    zPythonAPI.borrow_nonec                 G   s:   t jt  | jgdd}| j|dd}| j||f| S )NTr   ZPySys_FormatStdoutr   )r   r   r   ry   r   r2   r   )r   r   r   r   r   r   r   r   sys_write_stdout  s    zPythonAPI.sys_write_stdoutc                 C   s2   t t  | jg}| j|dd}| j||fS )zL
        Dump a Python object on C stderr.  For debugging purposes.
        Z_PyObject_Dumpr   r   r   r   r   r   object_dump  s    zPythonAPI.object_dumpc                 C   s   | j jstdtd}| | |j}t| j	| j
| j	||| j	g}| j|dd}|jd d | j tj|j}| j tjt|j}	t| j|}
| j|| j|
| j
|||	|gS )NzNRT requiredr   Z"NRT_adapt_ndarray_to_python_acqrefr   r   	nocapture)r1   
enable_nrtr   r   rj   unserializeserialize_objectZbox_typer   rU   rk   r   r   add_attributer3  r   r<  ndimr   Zmutabler
   rR  r2   r   bitcast)r   ZarytyaryZdtypeptrZinttyZserial_aryty_pytyper   r   r  writableZaryptrr   r   r   nrt_adapt_ndarray_to_python  s&    
  z%PythonAPI.nrt_adapt_ndarray_to_pythonc                 C   sj   | j j}ttjtjtjg}t||d}|jd d |jd d |j	d | j 
|||gS )za
        Allocate a new MemInfo with data payload borrowed from a python
        object.
        ZNRT_meminfo_new_from_pyobjectr   r  rw  noalias)r2   rc   r   r   r
   	voidptr_tget_or_insert_functionr   r  return_valuer   )r   datarU   modr   r   r   r   r   nrt_meminfo_new_from_pyobject  s    
z'PythonAPI.nrt_meminfo_new_from_pyobjectc                 C   sD   | j j}t| jtjg}t||d}|j	d | j 
||gS )NZNRT_meminfo_as_pyobjectr  )r2   rc   r   r   rU   r
   r  r  r  r  r   )r   Zmiptrr  r   r   r   r   r   nrt_meminfo_as_pyobject  s    z!PythonAPI.nrt_meminfo_as_pyobjectc                 C   sD   | j j}ttj| jg}t||d}|j	d | j 
||gS )NZNRT_meminfo_from_pyobjectr  )r2   rc   r   r   r
   r  rU   r  r  r  r   )r   Zmiobjr  r   r   r   r   r   nrt_meminfo_from_pyobject  s    z#PythonAPI.nrt_meminfo_from_pyobjectc                 C   sf   | j jstttd| j| jg}| j|dd}|j	d 
d |j	d 
d | j|||fS )Nr   ZNRT_adapt_ndarray_from_pythonr   r   r  rw  r1   r  r   r   r   rj   rU   rk   r   r   r  r2   r   r   r  r_  r   r   r   r   r   nrt_adapt_ndarray_from_python  s    z'PythonAPI.nrt_adapt_ndarray_from_pythonc                 C   sj   | j jsttt t| j| jg}| j	|dd}|j
d d |j
d d | j|||fS )NZNRT_adapt_buffer_from_pythonr   r   r  rw  )r1   r  r   r   r   r   ri   r{   rk   r   r   r  r2   r   r   bufr_  r   r   r   r   r   nrt_adapt_buffer_from_python  s    z&PythonAPI.nrt_adapt_buffer_from_pythonc                 C   s   t | j||S r   )r
   r  rc   )r   r   r   r   r   r   r     s    zPythonAPI._get_functionc                 C   s   | j | jS r   )r2   ZallocarU   r   r   r   r   
alloca_obj  s    zPythonAPI.alloca_objc                 C   s   t | jt| jd}|S )zT
        Return a pointer to a stack-allocated, zero-initialized Py_buffer.
        N)r
   rR  r2   r   r{   )r   r_  r   r   r   alloca_buffer	  s    
zPythonAPI.alloca_bufferc              	   c   s.   t | jt | j| d V  W 5 Q R X d S r   )r
   rz  r2   rW   r  r   r   r   r     s    zPythonAPI.if_object_okc                 C   s>   |  |}| |}| j| jd}| || | | d S )Nz%s)r  r  r1   r   rc   r  r   )r   r5   r  r   r   r   r   r   print_object  s
    

zPythonAPI.print_objectc                 C   s   | j | j|}| | d S r   )r1   r   rc   r  )r   textr   r   r   r   print_string  s    zPythonAPI.print_stringc                 C   s   t | jd S r   )r   rU   r   r   r   r   r   #  s    zPythonAPI.get_null_objectc                 C   s   |   }| j| d S r   )r   r2   r[   )r   noner   r   r   return_none&  s    zPythonAPI.return_nonec              	   C   sv   t |}| | jtj|}| |D t|D ]4}| jtj|}| ||  | 	||||  q2W 5 Q R X |S r   )
rL   r,  r1   r3  r   rw   r   r   r   r2  )r   r8  r9  seqr   r1  r   r   r   	list_pack*  s    zPythonAPI.list_packc                 C   s   t | j| jt d| jf}| j|dd}| j| j|d}| j| j|d}| j| j|d}| j	||||fS )zx
        Unserialize some data.  *structptr* should be a pointer to
        a {i8* data, i32 length} structure.
        r   Znumba_unpickler   r   rw     )
r   r   rU   rk   rj   r   r2   Zextract_valuerZ   r   )r   Z	structptrr   r   r_  r9  hashedr   r   r   r  4  s    zPythonAPI.unserializec           	      C   s   t |}t|dk stdtjdkr.t|nd }t|}tt	
| }| j| j||}| j| j| d|}t|| jttd|jjj|| jg}|S )z
        Same as serialize_object(), but don't create a global variable,
        simply return a literal {i8* data, i32 length, i8* hashbuf} structure.
        l        z.const.pickledata.%sr   DIFF_IRz.sha1r   )r   dumpsrL   r   r   r  idr
   Zmake_bytearrayhashlibsha1digestr1   insert_unique_constrc   r   Zliteral_structr  rk   r   rj   r   r   r=  )	r   r5   r  r   Zbdatar  ZarrZhasharrstructr   r   r   serialize_uncachedA  s"    

  

zPythonAPI.serialize_uncachedc                 C   sl   z| j j| }W nV tk
rf   | |}dtjdkr>t|nd }| j| j ||}|| j j|< Y nX |S )z
        Serialize the given object in the bitcode, and return it
        as a pointer to a {i8* data, i32 length}, structure constant
        (suitable for passing to unserialize()).
        z.const.picklebuf.%sr   r  )	rc   rd   r   r  r   r  r  r1   r  )r   r5   gvr  r   r   r   r   r  [  s    
zPythonAPI.serialize_objectc                 C   s   t | j|  S r   )r
   rW   r2   r   r   r   r   r   c_api_errork  s    zPythonAPI.c_api_errorc                 C   s6   ddl m} t|j|}t| j| j| }||||S )zn
        Unbox the Python object as the given Numba type.
        A NativeValue instance is returned.
        r   )unbox_unsupported)numba.core.boxingr  	_unboxersr"   	__class__r3   r1   r2   )r   r,   r5   r  implcr   r   r   r4   n  s    zPythonAPI.to_native_valuec                 C   s&   t |tjrtd| |||}|S )Nz;callconv should have prevented the return of optional value)rB   r   Optionalr   r)   )r   r,   r-   r*   outr   r   r   from_native_returny  s    zPythonAPI.from_native_returnc                 C   s8   ddl m} t|j|}t| j| j| |}||||S )z
        Box the native value of the given Numba type.  A Python object
        pointer is returned (NULL if an error occurred).
        This method steals any native (NRT) reference embedded in *val*.
        r   )box_unsupported)r  r  _boxersr"   r  r&   r1   r2   )r   r,   r-   r*   r  r  r  r   r   r   r)     s    zPythonAPI.from_native_valuec                 C   sX   t |j}|dkrtjS t| jtj}t| j| j| ||}|||| | j	|j
S )z
        Reflect the native value onto its Python original, if any.
        An error bit (as an LLVM value) is returned.
        N)_reflectorsr"   r  r
   r?   rR  r2   r7   r1   rZ   r9   )r   r,   r-   r*   r  r9   r  r   r   r   r;     s    zPythonAPI.reflect_native_valuec                 C   s,   t | j|}| j| j||}t|S )zy
        Extract the generator structure pointer from a generator *obj*
        (a _dynfunc.Generator instance).
        )r   ri   r1   get_data_typeZget_generator_stater2   r=   )r   r5   r,   Z
gen_ptr_tyr>   r   r   r   to_native_generator  s    zPythonAPI.to_native_generatorc              	   C   s   | j |}|jrt| j |}| j |}t| j| j| j| jg}| j	||j
d}tt | jg}	|jr| j	|	|jd}
ntt|	d}
t| j| j| jt|t|	| jg}| j	|dd}t| j|}| j|| j}|dkr|  }| j|| j}| j|||||
|fS )z
        Make a Numba generator (a _dynfunc.Generator instance) from a
        generator structure pointer *val*.
        *env* is an optional _dynfunc.Environment instance to be wrapped
        in the generator.
        r   NZnumba_make_generator)r1   r  Z
is_pointerr   Zget_abi_sizeofZget_generator_descr   r   rU   r   Zllvm_cpython_wrapper_namer   rk   Zhas_finalizerZllvm_finalizer_namer   ri   rx   r2   r  r   r   )r   r-   r,   rD   ZlltyZgen_struct_sizeZgendescZgenfntyZgenfnZfinalizerty	finalizerr   r   Z
state_sizeZinitial_stater   r   r   from_native_generator  s2    
zPythonAPI.from_native_generatorc                 C   sf   | j jrtttd| j| jg}| j|dd}|j	d 
d |j	d 
d | j|||fS )Nr   Znumba_adapt_ndarrayr   r   r  rw  r  r  r   r   r   numba_array_adaptor  s    zPythonAPI.numba_array_adaptorc                 C   s^   t t  t | j| jg}| j|dd}|jd d |jd d | j	
|||fS )NZnumba_adapt_bufferr   r   r  rw  )r   r   r   ri   r{   rk   r   r   r  r2   r   r  r   r   r   numba_buffer_adaptor  s    
zPythonAPI.numba_buffer_adaptorc                 C   s:   t t d| j|jg}| j|dd}| j|||gS )Nr   Znumba_complex_adaptorr   )r   r   rj   rU   r   r   r2   r   )r   r  Zcmplxr   r   r   r   r   complex_adaptor  s    zPythonAPI.complex_adaptorc                 C   s<   t | j| jt | jg}| j|dd}| j|||gS )NZnumba_extract_record_datar   )	r   r   rk   rU   ri   r{   r   r2   r   r   r5   pbufr   r   r   r   r   extract_record_data  s
    zPythonAPI.extract_record_datac                 C   s@   t t d| jt | jg}| j|dd}| j|||gS )Nr   Znumba_get_bufferr   )	r   r   rj   rU   ri   r{   r   r2   r   r  r   r   r   
get_buffer  s
    zPythonAPI.get_bufferc                 C   s8   t t  t | jg}| j|dd}| j||gS )NZnumba_release_bufferr   )r   r   r   ri   r{   r   r2   r   )r   r  r   r   r   r   r   release_buffer  s    zPythonAPI.release_bufferc                 C   s4   t t d| jg}| j|dd}| j||gS )N@   Znumba_extract_np_datetimer   r   r   r   r   r   extract_np_datetime  s    zPythonAPI.extract_np_datetimec                 C   s4   t t d| jg}| j|dd}| j||gS )Nr  Znumba_extract_np_timedeltar   r   r   r   r   r   extract_np_timedelta  s    zPythonAPI.extract_np_timedeltac                 C   sR   t tdt|}t| jtdtdg}| j|dd}| j|||gS )Nr   r  Znumba_create_np_datetimer   	r   r   rj   r   r   rU   r   r2   r   r   r-   Z	unit_coder   r   r   r   r   create_np_datetime  s    zPythonAPI.create_np_datetimec                 C   sR   t tdt|}t| jtdtdg}| j|dd}| j|||gS )Nr   r  Znumba_create_np_timedeltar   r  r  r   r   r   create_np_timedelta  s    zPythonAPI.create_np_timedeltac                 C   sZ   t | jt t dt d| jg}| j|dd}|||}| j	||||gS )Nra   r   Znumba_recreate_recordr   )
r   r   rU   ri   rj   r   r]   rP   r2   r   )r   Zpdatar  Zdtyper*   r   r   Z	dtypeaddrr   r   r   recreate_record  s     zPythonAPI.recreate_recordc                 C   s0   | j | j|}| j tjt|}| ||S r   )r1   r   rc   r3  r   rw   rL   r  )r   r  r   szr   r   r   string_from_constant_string  s    z%PythonAPI.string_from_constant_stringc              
   C   s$  | j }| j|||}|jj}|j}||krDtd| d| d| j||j||\}}	t	j
|t	jdd}
| j|j}t	j
||dd}||jj\}}|& ||j|
 | jj|| | W 5 Q R X |& t| j||||	}	||	| W 5 Q R X W 5 Q R X ||
}||}	||	fS )aP  Calls into Numba jitted code and propagate error using the Python
        calling convention.

        Parameters
        ----------
        func : function
            The Python function to be compiled. This function is compiled
            in nopython-mode.
        sig : numba.typing.Signature
            The function signature for *func*.
        args : Sequence[llvmlite.binding.Value]
            LLVM values to use as arguments.

        Returns
        -------
        (is_error, res) :  2-tuple of llvmlite.binding.Value.
            is_error : true iff *func* raised an exception.
            res : Returned value from *func* iff *is_error* is false.

        If *is_error* is true, this method will adapt the nopython exception
        into a Python exception. Caller should return NULL to Python to
        indicate an error.
        zmismatching signature z != z.
TrQ   )r2   r1   Zcompile_subroutine	signaturer   errorsZLoweringErrorZcall_internal_no_propagateZfndescr
   rT   Zbool_trv   rV   r9   r8   r   Zraise_errorr   Zfix_returning_optionalrZ   )r   r   sigr   r2   ZcresZ	got_rettyZrettyr  r"  Zis_error_ptrZres_typeZres_ptrZhas_errZno_errr9   r   r   r   call_jit_code  sB            

zPythonAPI.call_jit_code)Fr   )N)F)r   )F)F)F)F)F)F)F)F)F)F)F)F)F)F)N)r   )NN)N)N)N)r#   r$   r%   r/   r   r   r   r   r   r   r   r   r   r   r   rY   r   r   r   r   r   r   r   
contextlibcontextmanagerr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r	  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r!  r&  r(  r)  r+  r,  r/  r0  r2  rX   r4  r6  r:  r;  r>  r@  rC  rE  rG  rH  rI  rM  rX  rZ  r[  r\  r]  r^  r`  ra  rd  rh  rl  r   rm  rn  ro  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r   r  r  r   r  r  r   r  r  r  r  r  r  r4   r  r)   r;   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r   r   r   r`      s\  ! 
			
		
	
	

	
	)
	
	)r`   c                   @   s,   e Zd ZdZdd Zdd Zedd ZdS )	ObjModeUtilszHInternal utils for calling objmode dispatcher from within NPM code.
    c                 C   s
   || _ d S r   )r(   )r   r(   r   r   r   r   X  s    zObjModeUtils.__init__c              	   C   s  | j j}| j j}|j}tj|| j j|dd}|j	d |_
d|_|d}t|jr| j |jt|f}| j |}	t||	}
||
 || W 5 Q R X ||}|t|| t|jrt| }| j | j |j}| j ||	g}| j | | j |	 n$|jt|}|j|t|dd}| j | ||| W 5 Q R X || | | ||}|S )NZcached_objmode_dispatcherr   ZinternalrO  Zwith_objectmode)info)!r(   r2   r1   rc   r   ZGlobalVariablerU   Zget_unique_namer   r   ZinitializerlinkagerS  r   Zis_serialiable
dispatcherr  r   r  r
   r   rT  rP  rZ   _call_objmode_dispatcherrh  r   compileZadd_dynamic_addrr  r   r8   rU  )r   r   r   r2   Ztyctxmr  rO  Zserialized_dispatchercompile_argsZfailed_unsercachedr!   compilerrf  Zentry_ptr   r   r   load_dispatcher[  sX     

   


zObjModeUtils.load_dispatcherc                 C   s   | \}}| |}|S r   )r  )r  r   r   Zentryptr   r   r   r    s    
z%ObjModeUtils._call_objmode_dispatcherN)r#   r$   r%   r/   r   r  staticmethodr  r   r   r   r   r  U  s
   7r  ).collectionsr   r  pickler  rH   Zllvmliter   Zllvmlite.irr   rl   Znumbar   Z
numba.corer   r   r   r	   r
   r   r   r}   ZPY_UNICODE_1BYTE_KINDr~   ZPY_UNICODE_2BYTE_KINDr   ZPY_UNICODE_4BYTE_KINDr   ZPY_UNICODE_WCHAR_KINDobjectr   r  r  r  r   r.   r6   r<   r&   r3   r7   r=   rA   r^   r`   r  r   r   r   r   <module>   sZ   $4
           ?