U ل=^+@sddlZddlZddlZddlZddlZddlmZddlmZddlm Z ej dkrhddl Z ddZ nddlZd dZ ej d krejZnGd d d ejZGd ddeZdZddZdaddZddZdddZddZddZdS)N)__version_verifier_modules__) ffiplatform)VerificationError)rcCstjjddSN) importlib machineryEXTENSION_SUFFIXESr r /verifier.py_extension_suffixes sr cCsddtDS)NcSs g|]\}}}|tjkr|qSr )impZ C_EXTENSION).0suffix_typer r r s z'_extension_suffixes..)rZ get_suffixesr r r r r srcseZdZfddZZS)NativeIOcs(t|tr|d}tt||dS)Nascii) isinstanceZunicodeencodesuperrwrite)selfs __class__r r rs  zNativeIO.write)__name__ __module__ __qualname__r __classcell__r r rr rsrc@szeZdZdddZd ddZd d Zd d Zd dZddZddZ ddZ ddZ ddZ d!ddZ ddZddZdS)"VerifierNF.cc Ksv|jjrtd|jjf||_||_|s4t| } t||} | ||_|j | | |_ | | | |_ |rz|rxt dndtjddt|| g|j}tjdkr|d}tt|dddd @}|d d }tt|d ddd @}|d d }d||jj||f}td}|p0t|_tj|j|||_ tj|j|||_!||_"d|_#d|_$dS)NzKfeature not supported with ffi.verify(), but only with ffi.set_source(): %sz)can't specify both 'modulename' and 'tag'rrzutf-8rlZ0xLr0z_cffi_%s_%s%s%sF)%Z_parserZ_uses_new_featurerffipreamblerZflatten_locate_engine_class_vengineZpatch_extension_kwdsflagsmake_relative_tokwds TypeErrorjoinsysversionrZ _cdefsources version_inforhexbinasciiZcrc32lstriprstripZ _class_key_get_so_suffixes_caller_dir_pycachetmpdirospathsourcefilenamemodulefilename ext_package _has_source _has_module)rr*r+r<Z modulenamerAtagforce_generic_engineZsource_extensionr. relative_tor0Zflattened_kwdsZ vengine_classkeyZk1Zk2rr r r __init__ sR         zVerifier.__init__c Cs8|jj&|jr |dkr td||W5QRXdS)zkWrite the C source code. It is produced in 'self.sourcefilename', which can be tweaked beforehand.Nzsource code already written)r*_lockrBr _write_sourcerfiler r r write_sourceHs  zVerifier.write_sourcec Cs<|jj*|jrtd|js&||W5QRXdS)zWrite the C source code (if not done already) and compile it. This produces a dynamic link library in 'self.modulefilename'.zmodule already compiledN)r*rIrCrrBrJ_compile_modulerr r r compile_moduleQs  zVerifier.compile_modulec CsR|jj@|js4||js4|js,|||W5QRSQRXdS)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*rIrC_locate_modulerBrJrN _load_libraryrOr r r load_library[s zVerifier.load_librarycCsBtj|j}|ddd}|dr>ttdr>|dd}|S)N.rrZ_dZgettotalrefcount)r=r>basenamer@splitendswithhasattrr3)rrVr r r get_module_nameks  zVerifier.get_module_namec CsVt|js0|jj|js&|W5QRXt|j}|}tj ||f|j Sr) rZ_hack_at_distutilsrBr*rIrJZmaybe_relative_pathr?rZ get_extensionr0)rZ sourcenamemodnamer r r r[vs  zVerifier.get_extensioncCs|jjSr)r-Z_gen_python_modulerOr r r generates_python_modulesz Verifier.generates_python_modulecsz|rvtj|rvtj||}tjD]J}||kr*||}t|ttfsZt d|ffdd|D}|||<q*|S)Nz&keyword '%s' should be a list or tuplecsg|]}tj|qSr )r=r>r2)rfndirnamer r rsz-Verifier.make_relative_to..) r=r>r`copyrZLIST_OF_FILE_NAMESrlisttupler1)rr0rFrGZlstr r_r r/s   zVerifier.make_relative_tocCstj|jsv|jrJzt|jdddg}Wntk r@YdSX|j}nd}|j | |t }|dkrpdS||_|j d|_ dS)N__doc__T)r=r>isfiler@rA __import__ ImportError__path__r- find_modulerZr:Z collect_typesrC)rZpkgr>filenamer r r rQs  zVerifier._locate_modulecCs$||j_z|jW5|j`XdSr)r-Z_fZwrite_source_to_frKr r r _write_source_toszVerifier._write_source_toc Cs|dk r||nt}|||}tj|jrbt|jd}||k }W5QRXnd}|rt |jt|jd}| |W5QRXd|_ dS)NrTw) rkrgetvaluer=r>existsr?openread _ensure_dirrrB)rrLfZ source_datafpZ needs_writtenr r r rJs   zVerifier._write_sourcecCsptj|j}t||}zt||j}Wnt k rHd}YnX|sft |jt ||jd|_ dS)NFT)r=r>r`r?rcompiler[samefiler@OSErrorrrshutilZmoverC)rr<ZoutputfilenameZsamer r r rNs  zVerifier._compile_modulecCs&|jdk r|j|jS|jSdSr)r.r-rSrOr r r rRs zVerifier._load_library)NNNr$Fr%NN)N)N)rr r!rHrMrPrSrZr[r]r/rQrkrJrNrRr r r r r#s( (      r#FcCs|trd}|sPdtjkrd}n4z ddl}Wntk r@d}YnX|j|k rPd}|rfddlm}|jSddlm }|j SdS)NTZ__pypy__r?r) vengine_gen) vengine_cpy) _FORCE_GENERIC_ENGINEr3builtin_module_names _cffi_backendrgZ_backendr$rzZVGenericEnginer{ZVCPythonEngine)r*rEr~rzr{r r r r,s       r,cCsHtrtStjd}|r|Stdjj}tj tj tj |dS)NZ CFFI_TMPDIRr' __pycache__) _TMPDIRr=environgetr3 _getframef_code co_filenamer>abspathr2r`)resultrjr r r r;s r;cCs|adS)z:Set the temporary directory to use instead of __pycache__.N)rr_r r r set_tmpdirsrc Cs$|pt}zt|}Wntk r.YdSX|r:d}ntd}|D]\}|drL||sz|drLzttj ||WqLtk rYqLXqLtj |dg}|D]`}zDt|D]4}tj ||}tj |r| |qt|qWqtk rYqXqdS)z}Clean up the temporary directory by removing all files in it called `_cffi_*.{c,so}` as well as the `build` subdirectory.Nr%rZ_cffi_Zbuild) r;r=listdirrwr:lower startswithrXunlinkr>r2isdirappend)r<Zkeep_soZfilelistrr^Z clean_dirdirr r r cleanup_tmpdirs8     rcCs&t}|s"tjdkrdg}ndg}|S)NZwin32z.pydz.so)r r3platform)suffixesr r r r:$s  r:cCs*tj|}|r&tj|s&t|dSr)r=r>r`rmakedirs)rjr`r r r rr/s rr)NF)r3r=r7rxior$rrerrorrr5Zimportlib.machineryrr rStringIOrBytesIOobjectr#r|r,rr;rrr:rrr r r r s*(      ?