a
   Bm7
                   @   s   d dl 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m	Z	 e j
dkrhd dlZdd Znd dlZd	d Ze j
d
krejZnG dd dejZG dd deZdZdd Zdadd Zdd ZdddZdd Zdd ZdS )    N   )__version_verifier_modules__)ffiplatform)VerificationError)   r   c                   C   s   t jjd d  S N)	importlib	machineryEXTENSION_SUFFIXES r   r   1/usr/lib/python3.9/site-packages/cffi/verifier.py_extension_suffixes   s    r   c                   C   s   dd t  D S )Nc                 S   s    g | ]\}}}|t jkr|qS r   )impC_EXTENSION).0suffix_typer   r   r   
<listcomp>   s   
z'_extension_suffixes.<locals>.<listcomp>)r   Zget_suffixesr   r   r   r   r      s    r   c                       s   e Zd Z fddZ  ZS )NativeIOc                    s(   t |tr|d}tt| | d S )Nascii)
isinstanceZunicodeencodesuperr   write)selfs	__class__r   r   r      s    

zNativeIO.write)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s   r   c                   @   sz   e Zd ZdddZd 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dZdd Zdd ZdS )"VerifierN F.cc                 K   sz  |j jrtd|j jf || _|| _|s4t|}t||}|| | _| j	| |	| _
| ||
| _|rz|rxtdnddtjd d  t||g|j }tjdkr|d}tt|dd d d	@ }|d
d}tt|dd d d	@ }|dd}d|| jj||f }t d }|p4t | _tj| j|| | _tj| j|| | _ || _!d| _"d| _#d S )NzKfeature not supported with ffi.verify(), but only with ffi.set_source(): %sz)can't specify both 'modulename' and 'tag' z%d.%d   r   zutf-8r   l    0xLr   0z_cffi_%s_%s%s%sF)$Z_parserZ_uses_new_featurer   ffipreambler   Zflatten_locate_engine_class_vengineZpatch_extension_kwdsflagsmake_relative_tokwds	TypeErrorjoinsysversion_infor   Z_cdefsourcesr   hexbinasciicrc32lstriprstripZ
_class_key_get_so_suffixes_caller_dir_pycachetmpdirospathsourcefilenamemodulefilenameext_package_has_source_has_module)r   r,   r-   r>   Z
modulenamerC   tagforce_generic_engineZsource_extensionr0   relative_tor2   Zflattened_kwdsZvengine_classkeyZk1Zk2r   r   r   r   __init__    sP    







zVerifier.__init__c                 C   sL   | j j0 | jr |du r td| | W d   n1 s>0    Y  dS )zkWrite the C source code.  It is produced in 'self.sourcefilename',
        which can be tweaked beforehand.Nzsource code already written)r,   _lockrD   r   _write_sourcer   filer   r   r   write_sourceI   s    
zVerifier.write_sourcec                 C   sP   | j j4 | jrtd| js&|   |   W d   n1 sB0    Y  dS )zWrite the C source code (if not done already) and compile it.
        This produces a dynamic link library in 'self.modulefilename'.zmodule already compiledN)r,   rK   rE   r   rD   rL   _compile_moduler   r   r   r   compile_moduleR   s    
zVerifier.compile_modulec                 C   s^   | j jB | js4|   | js4| js,|   |   |  W  d   S 1 sP0    Y  dS )a"  Get a C module from this Verifier instance.
        Returns an instance of a FFILibrary class that behaves like the
        objects returned by ffi.dlopen(), but that delegates all
        operations to the C module.  If necessary, the C code is written
        and compiled first.
        N)r,   rK   rE   _locate_modulerD   rL   rP   _load_libraryrQ   r   r   r   load_library\   s    
zVerifier.load_libraryc                 C   sB   t j| j}|ddd }|dr>ttdr>|d d }|S )N.r   r   Z_dZgettotalrefcount)r?   r@   basenamerB   splitendswithhasattrr5   )r   rX   r   r   r   get_module_namel   s
    zVerifier.get_module_namec                 C   sn   t   | jsD| jj | js&|   W d    n1 s:0    Y  t | j}|  }t j	||fi | j
S r   )r   Z_hack_at_distutilsrD   r,   rK   rL   Zmaybe_relative_pathrA   r\   get_extensionr2   )r   Z
sourcenamemodnamer   r   r   r]   w   s    
&zVerifier.get_extensionc                 C   s   | j jS r   )r/   Z_gen_python_modulerQ   r   r   r   generates_python_module   s    z Verifier.generates_python_modulec                    sz   |rvt j|rvt j| | }tjD ]J}||v r*|| }t|ttfsZt	d|f  fdd|D }|||< q*|S )Nz&keyword '%s' should be a list or tuplec                    s   g | ]}t j |qS r   )r?   r@   r4   )r   fndirnamer   r   r          z-Verifier.make_relative_to.<locals>.<listcomp>)
r?   r@   rb   copyr   ZLIST_OF_FILE_NAMESr   listtupler3   )r   r2   rH   rI   Zlstr   ra   r   r1      s    

zVerifier.make_relative_toc                 C   s   t j| jst| jrHzt| jd d dg}W n ty>   Y d S 0 |j}nd }| j	| 
 |t }|d u rnd S || _| j  d| _d S )N__doc__T)r?   r@   isfilerB   rC   
__import__ImportError__path__r/   find_moduler\   r<   Zcollect_typesrE   )r   pkgr@   filenamer   r   r   rS      s     
zVerifier._locate_modulec                 C   s*   || j _z| j   W | j `n| j `0 d S r   )r/   Z_fZwrite_source_to_frM   r   r   r   _write_source_to   s    zVerifier._write_source_toc                 C   s   |d ur|  | nt }|  | | }tj| jrvt| jd}| |k }W d    qz1 sj0    Y  nd}|rt	| j t| jd}|
| W d    n1 s0    Y  d| _d S )NrTw)ro   r   getvaluer?   r@   existsrA   openread_ensure_dirr   rD   )r   rN   fZsource_datafpZneeds_writtenr   r   r   rL      s    
.
(zVerifier._write_sourcec                 C   sn   t j| j}t||  }zt|| j}W n t	yF   d}Y n0 |sdt
| j t|| j d| _d S )NFT)r?   r@   rb   rA   r   compiler]   samefilerB   OSErrorrv   shutilmoverE   )r   r>   ZoutputfilenameZsamer   r   r   rP      s    

zVerifier._compile_modulec                 C   s0   | j s
J | jd ur"| j| jS | j S d S r   )rE   r0   r/   rU   rQ   r   r   r   rT      s    

zVerifier._load_library)NNNr%   Fr&   NN)N)N)r    r!   r"   rJ   rO   rR   rU   r\   r]   r_   r1   rS   ro   rL   rP   rT   r   r   r   r   r$      s       
)
	


r$   Fc                 C   sz   t rd}|sNdtjv rd}n2zdd l}W n ty>   d}Y n0 | j|urNd}|rdddlm} |jS ddlm	} |j
S d S )NTZ__pypy__r   ?r   )vengine_gen)vengine_cpy)_FORCE_GENERIC_ENGINEr5   builtin_module_names_cffi_backendrj   Z_backendr%   r   ZVGenericEnginer   ZVCPythonEngine)r,   rG   r   r   r   r   r   r   r.      s     


r.   c                  C   sH   t rt S tjd} | r| S tdjj}tj	tj
tj|dS )NZCFFI_TMPDIRr(   __pycache__)_TMPDIRr?   environgetr5   	_getframef_codeco_filenamer@   abspathr4   rb   )resultrn   r   r   r   r=      s    r=   c                 C   s   | a dS )z:Set the temporary directory to use instead of __pycache__.N)r   ra   r   r   r   
set_tmpdir  s    r   c              	   C   s  | pt  } zt| }W n ty,   Y dS 0 |r8d}nt d  }|D ]Z}| drJ| |sx| drJzttj	
| | W qJ ty   Y qJ0 qJtj	
| dg}|D ]^}zDt|D ]4}tj	
||}tj	|r|| qt| qW q ty   Y q0 qdS )z}Clean up the temporary directory by removing all files in it
    called `_cffi_*.{c,so}` as well as the `build` subdirectory.Nr&   r   Z_cffi_Zbuild)r=   r?   listdirr{   r<   lower
startswithrZ   unlinkr@   r4   isdirappend)r>   Zkeep_soZfilelistr   r`   Z	clean_dirdirr   r   r   cleanup_tmpdir  s8    
r   c                  C   s&   t  } | s"tjdkrdg} ndg} | S )Nwin32z.pydz.so)r   r5   platform)suffixesr   r   r   r<   %  s    
r<   c                 C   s*   t j| }|r&t j|s&t | d S r   )r?   r@   rb   r   makedirs)rn   rb   r   r   r   rv   0  s    rv   )NF)r5   r?   r8   r|   ior%   r   r   errorr   r6   importlib.machineryr   r   r   StringIOr   BytesIOobjectr$   r   r.   r   r=   r   r   r<   rv   r   r   r   r   <module>   s*   (


 @

