B
     ¯]Ç+  ã               @   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rŠe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
   ú,lib/python3.7/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   sv  |j jrtd|j jf ƒ‚|| _|| _|s4t |¡}t||ƒ}|| ƒ| _| j 	|¡ |	| _
|  ||
¡| _|rz|rxtdƒ‚n¢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 }|p0tƒ | _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'ú r   )r   zutf-8r   é   l   ÿÿ Z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Úversionr   Z_cdefsourcesÚversion_infor   ÚhexÚbinasciiZ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
modulenamer?   ÚtagÚforce_generic_engineZsource_extensionr,   Úrelative_tor.   Zflattened_kwdsZvengine_classÚkeyZk1Zk2r   r
   r
   r   Ú__init__    sD    









zVerifier.__init__c          	   C   s8   | j j& | jr |dkr tdƒ‚|  |¡ W dQ R X dS )zkWrite the C source code.  It is produced in 'self.sourcefilename',
        which can be tweaked beforehand.Nzsource code already written)r(   Ú_lockr@   r   Ú_write_source)r   Úfiler
   r
   r   Úwrite_sourceH   s
    
zVerifier.write_sourcec          	   C   s<   | j j* | jrtdƒ‚| js&|  ¡  |  ¡  W dQ R X dS )z„Write 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(   rG   rA   r   r@   rH   Ú_compile_module)r   r
   r
   r   Úcompile_moduleQ   s    
zVerifier.compile_modulec          	   C   sF   | j j4 | js4|  ¡  | js4| js,|  ¡  |  ¡  |  ¡ S Q R X 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(   rG   rA   Ú_locate_moduler@   rH   rK   Ú_load_library)r   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<   Úbasenamer>   ÚsplitÚendswithÚhasattrr1   )r   rR   r
   r
   r   Úget_module_namek   s
    zVerifier.get_module_namec          	   C   sV   t  ¡  | js0| jj | js&|  ¡  W d Q R X t  | j¡}|  ¡ }t j	||f| j
ŽS )N)r   Z_hack_at_distutilsr@   r(   rG   rH   Zmaybe_relative_pathr=   rV   Úget_extensionr.   )r   Z
sourcenameÚmodnamer
   r
   r   rW   v   s    
zVerifier.get_extensionc             C   s   | j jS )N)r+   Z_gen_python_module)r   r
   r
   r   Úgenerates_python_module€   s    z Verifier.generates_python_modulec                s~   |rzt j |¡rzt j |¡‰ | ¡ }xTtjD ]J}||kr,|| }t|ttfƒs\t	d|f ƒ‚‡ fdd„|D ƒ}|||< q,W |S )Nz&keyword '%s' should be a list or tuplec                s   g | ]}t j ˆ |¡‘qS r
   )r;   r<   r0   )r   Úfn)Údirnamer
   r   r      s    z-Verifier.make_relative_to.<locals>.<listcomp>)
r;   r<   r[   Úcopyr   ZLIST_OF_FILE_NAMESr   ÚlistÚtupler/   )r   r.   rD   rE   Zlstr
   )r[   r   r-   ƒ   s    
zVerifier.make_relative_toc             C   sˆ   t j | j¡st| jrHyt| jd d dgƒ}W n tk
r>   d S X |j}nd }| j 	|  
¡ |tƒ ¡}|d krnd S || _| j ¡  d| _d S )NÚ__doc__T)r;   r<   Úisfiler>   r?   Ú
__import__ÚImportErrorÚ__path__r+   Úfind_modulerV   r8   Zcollect_typesrA   )r   Úpkgr<   Úfilenamer
   r
   r   rM   “   s    
zVerifier._locate_modulec             C   s$   || j _z| j  ¡  W d | j `X d S )N)r+   Z_fZwrite_source_to_f)r   rI   r
   r
   r   Ú_write_source_to¦   s    zVerifier._write_source_toc          	   C   s    |d k	r|   |¡ nˆtƒ }|   |¡ | ¡ }tj | j¡rbt| jdƒ}| ¡ |k }W d Q R X nd}|r–t	| jƒ t| jdƒ}| 
|¡ W d Q R X d| _d S )NÚrTÚw)rg   r   Úgetvaluer;   r<   Úexistsr=   ÚopenÚreadÚ_ensure_dirr   r@   )r   rI   ÚfZsource_dataÚfpZneeds_writtenr
   r
   r   rH   ­   s    

zVerifier._write_sourcec             C   sp   t j | j¡}t ||  ¡ ¡}yt || j¡}W n t	k
rH   d}Y nX |sft
| jƒ t || j¡ d| _d S )NFT)r;   r<   r[   r=   r   ÚcompilerW   Úsamefiler>   ÚOSErrorrn   ÚshutilZmoverA   )r   r:   ZoutputfilenameZsamer
   r
   r   rK   Æ   s    

zVerifier._compile_modulec             C   s0   | j s
t‚| jd k	r"| j | j¡S | j ¡ S d S )N)rA   ÚAssertionErrorr,   r+   rO   )r   r
   r
   r   rN   Ó   s    

zVerifier._load_library)NNNr"   Fr#   NN)N)N)r   r   r   rF   rJ   rL   rO   rV   rW   rY   r-   rM   rg   rH   rK   rN   r
   r
   r
   r   r!      s     
&
	


r!   Fc             C   s|   t rd}|sPdtjkrd}n4ydd l}W n tk
r@   d}Y nX | j|k	rPd}|rfddlm} |jS ddlm	} |j
S d S )NTZ__pypy__r   ú?r   )Úvengine_gen)Úvengine_cpy)Ú_FORCE_GENERIC_ENGINEr1   Úbuiltin_module_namesÚ_cffi_backendrb   Z_backendr"   rw   ZVGenericEnginerx   ZVCPythonEngine)r(   rC   r{   rw   rx   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Úgetr1   Ú	_getframeÚf_codeÚco_filenamer<   Úabspathr0   r[   )Úresultrf   r
   r
   r   r9   ö   s    r9   c             C   s   | a dS )z:Set the temporary directory to use instead of __pycache__.N)r}   )r[   r
   r
   r   Ú
set_tmpdir   s    r…   c          	   C   s0  | pt ƒ } yt | ¡}W n tk
r,   dS X |r8d}ntƒ d  ¡ }xd|D ]\}| ¡  d¡rL| ¡  |¡sz| ¡  d¡rLyt tj	 
| |¡¡ W qL tk
r¦   Y qLX qLW tj	 
| d¡g}xn|D ]f}yJxDt |¡D ]6}tj	 
||¡}tj	 |¡r | |¡ qÔt |¡ qÔW W qÂ tk
r&   Y qÂX qÂW dS )z}Clean up the temporary directory by removing all files in it
    called `_cffi_*.{c,so}` as well as the `build` subdirectory.Nz.cr   Z_cffi_Zbuild)r9   r;   Úlistdirrs   r8   ÚlowerÚ
startswithrT   Úunlinkr<   r0   ÚisdirÚappend)r:   Zkeep_soZfilelistr   rZ   Z	clean_dirÚdirr
   r
   r   Úcleanup_tmpdir  s2    



r   c              C   s&   t ƒ } | s"tjdkrdg} ndg} | S )NZwin32z.pydz.so)r   r1   Úplatform)Úsuffixesr
   r
   r   r8   $  s    
r8   c             C   s*   t j | ¡}|r&t j |¡s&t  |¡ d S )N)r;   r<   r[   rŠ   Úmakedirs)rf   r[   r
   r
   r   rn   /  s    rn   )NF)r1   r;   r5   rt   Úior"   r   r   Úerrorr   r3   Úimportlib.machineryr   r   r   ÚStringIOr   ÚBytesIOÚobjectr!   ry   r*   r}   r9   r…   r   r8   rn   r
   r
   r
   r   Ú<module>   s*   (


 ?

