o
    “Ñ½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r4d dlZdd„ Znd dlZd	d„ Ze j
d
krEe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   ú1usr/lib/python3.10/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)Ú
isinstanceÚ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                   @   s€   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   sx  |j jrtd|j jf ƒ‚|| _|| _|st |¡}t||ƒ}|| ƒ| _| j 	|¡ |	| _
|  ||
¡| _|r=|r<tdƒ‚nSd dtjd d…  t||g|j ¡}tjdkrZ| d¡}tt |dd d… ¡d	@ ƒ}| d
¡ d¡}tt |dd d… ¡d	@ ƒ}| d¡ d¡}d|| jj||f }tƒ d }|p™tƒ | _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)$Ú_parserZ_uses_new_featurer   ÚffiÚpreambler   Ú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/   rA   Z
modulenamerF   ÚtagÚforce_generic_engineZsource_extensionr3   Úrelative_tor5   Zflattened_kwdsZvengine_classÚkeyZk1Zk2r   r   r   r   Ú__init__    sR   ÿÿ


ÿþý


ÿ

zVerifier.__init__c                 C   sN   | j j | jr|du rtdƒ‚|  |¡ W d  ƒ dS 1 s w   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.   Ú_lockrG   r   Ú_write_source©r   Úfiler   r   r   Úwrite_sourceI   s   
ÿ"üzVerifier.write_sourcec                 C   sR   | j j | jrtdƒ‚| js|  ¡  |  ¡  W d  ƒ dS 1 s"w   Y  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.   rN   rH   r   rG   rO   Ú_compile_module©r   r   r   r   Úcompile_moduleR   s   

"ûzVerifier.compile_modulec                 C   s^   | j j! | js|  ¡  | js| js|  ¡  |  ¡  |  ¡ W  d  ƒ S 1 s(w   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.   rN   rH   Ú_locate_modulerG   rO   rS   Ú_load_libraryrT   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   Ú_dÚgettotalrefcountéþÿÿÿ)rB   rC   ÚbasenamerE   ÚsplitÚendswithÚhasattrr8   )r   r]   r   r   r   Úget_module_namel   s
   zVerifier.get_module_namec                 C   sn   t  ¡  | js"| jj | js|  ¡  W d   ƒ n1 sw   Y  t  | j¡}|  ¡ }t j	||fi | j
¤ŽS r   )r   Z_hack_at_distutilsrG   r.   rN   rO   Zmaybe_relative_pathrD   ra   Úget_extensionr5   )r   Z
sourcenameÚmodnamer   r   r   rb   w   s   
€þzVerifier.get_extensionc                 C   s   | j jS r   )r2   Z_gen_python_modulerT   r   r   r   Úgenerates_python_module   s   z Verifier.generates_python_modulec                    sz   |r;t j |¡r;t j |¡‰ | ¡ }tjD ]%}||v r:|| }t|ttfƒs-t	d|f ƒ‚‡ fdd„|D ƒ}|||< q|S )Nz&keyword '%s' should be a list or tuplec                    s   g | ]	}t j ˆ |¡‘qS r   )rB   rC   r7   )r   Úfn©Údirnamer   r   r   Ž   s    z-Verifier.make_relative_to.<locals>.<listcomp>)
rB   rC   rg   Úcopyr   ZLIST_OF_FILE_NAMESr   ÚlistÚtupler6   )r   r5   rK   rL   Úlstr   rf   r   r4   „   s   
ÿ€zVerifier.make_relative_toc                 C   sˆ   t j | j¡s:| jr$zt| jd d dgƒ}W n
 ty   Y d S w |j}nd }| j 	|  
¡ |tƒ ¡}|d u r7d S || _| j ¡  d| _d S )NÚ__doc__T)rB   rC   ÚisfilerE   rF   Ú
__import__ÚImportErrorÚ__path__r2   Úfind_modulera   r?   Zcollect_typesrH   )r   ÚpkgrC   Úfilenamer   r   r   rV   ”   s"   ÿÿ

zVerifier._locate_modulec                 C   s(   || j _z| j  ¡  W | j `d S | j `w r   )r2   Z_fZwrite_source_to_frP   r   r   r   Ú_write_source_to§   s   zVerifier._write_source_toc                 C   sÊ   |d ur|   |¡ d S tƒ }|   |¡ | ¡ }tj | j¡r<t| jdƒ}| ¡ |k }W d   ƒ n1 s6w   Y  nd}|r`t	| jƒ t| jdƒ}| 
|¡ W d   ƒ n1 s[w   Y  d| _d S )NÚrTÚw)rt   r   ÚgetvaluerB   rC   ÚexistsrD   ÚopenÚreadÚ_ensure_dirr   rG   )r   rQ   ÚfZsource_dataÚfpZneeds_writtenr   r   r   rO   ®   s"   
ÿ€
ÿ
zVerifier._write_sourcec                 C   sn   t j | j¡}t ||  ¡ ¡}z	t || j¡}W n t	y#   d}Y nw |s2t
| jƒ t || j¡ d| _d S )NFT)rB   rC   rg   rD   r   Úcompilerb   ÚsamefilerE   ÚOSErrorr{   ÚshutilÚmoverH   )r   rA   ZoutputfilenameZsamer   r   r   rS   Ç   s   ÿ

zVerifier._compile_modulec                 C   s,   | j sJ ‚| jd ur| j | j¡S | j ¡ S r   )rH   r3   r2   rX   rT   r   r   r   rW   Ô   s   


zVerifier._load_library)NNNr&   Fr'   NNr   )r!   r"   r#   rM   rR   rU   rX   ra   rb   rd   r4   rV   rt   rO   rS   rW   r   r   r   r   r%      s"    
þ
)	


r%   Fc                 C   sv   t rd}|s'dtjv rd}nzdd l}W n ty   d}Y nw | j|ur'd}|r2ddlm} |jS ddlm	} |j
S )NTZ__pypy__r   ú?r   )Úvengine_gen)Úvengine_cpy)Ú_FORCE_GENERIC_ENGINEr8   Úbuiltin_module_namesÚ_cffi_backendro   Z_backendr&   r„   ZVGenericEnginer…   ZVCPythonEngine)r.   rJ   rˆ   r„   r…   r   r   r   r1   ß   s"   
ÿ
r1   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__)Ú_TMPDIRrB   ÚenvironÚgetr8   Ú	_getframeÚf_codeÚco_filenamerC   Úabspathr7   rg   )Úresultrs   r   r   r   r@   ÷   s   ÿr@   c                 C   s   | a dS )z:Set the temporary directory to use instead of __pycache__.N)rŠ   rf   r   r   r   Ú
set_tmpdir  s   r’   c              	   C   s  | pt ƒ } zt | ¡}W n
 ty   Y dS w |rd}ntƒ d  ¡ }|D ]-}| ¡  d¡rR| ¡  |¡s<| ¡  d¡rRzt tj	 
| |¡¡ W q% tyQ   Y q%w q%tj	 
| d¡g}|D ]-}z"t |¡D ]}tj	 
||¡}tj	 |¡rz| |¡ qet |¡ qeW q] tyŠ   Y 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.Nr'   r   Z_cffi_Úbuild)r@   rB   Úlistdirr€   r?   ÚlowerÚ
startswithr_   ÚunlinkrC   r7   ÚisdirÚappend)rA   Zkeep_soÚfilelistr   re   Z	clean_dirÚdirr   r   r   Úcleanup_tmpdir  sD   
ÿÿÿÿ€ûÿørœ   c                  C   s(   t ƒ } | stjdkrdg} | S dg} | S )NÚwin32z.pydz.so)r   r8   Úplatform)Úsuffixesr   r   r   r?   %  s   
þr?   c                 C   s2   t j | ¡}|rt j |¡st  |¡ d S d S d S r   )rB   rC   rg   r˜   Úmakedirs)rs   rg   r   r   r   r{   0  s   ÿr{   )NF)r8   rB   r;   r   Úior&   r   r   Úerrorr   r9   Zimportlib.machineryr   r   r   ÚStringIOr   ÚBytesIOÚobjectr%   r†   r1   rŠ   r@   r’   rœ   r?   r{   r   r   r   r   Ú<module>   s,   (


 @

