3 Pf˘@sddlmZddlZddlZddlZddlZddlmZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlmZmZddlmZmZmZmZmZddlmZddlm Z m!Z!dd l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+dd l,m-Z-m.Z.e j/e0Z1da2e3ed r4d Z4n*ej5j6d rHdZ4nej5dkrZdZ4ndZ4ej7dZ8e8sdej9ddZ8de8Z:e4e8Z;ej"j<j=ddj=ddZ>ej7dZ?e?re?j6dre?j=ddZ?nddZ@e@Z?[@ejAdejBejCBZDejAdejBejCBZEejAdZFejAd ZGd!ZHd"ZIe jJd#kr>d$d%ZKnd&d%ZKGd'd(d(eLZMeMZNGd)d*d*eLZOd+d,ZPePZQ[Pd/d-d.ZRdS)0)unicode_literalsN)message_from_file) __version__DistlibException) sysconfigZipFilefsdecode text_typefilter)InstalledDistribution)MetadataMETADATA_FILENAME) FileOperator convert_path CSVReader CSVWriterCachecached_propertyget_cache_base read_exportstempdir)NormalizedVersionUnsupportedVersionErrorZpypy_version_infoZppjavaZjyZcliZipcppy_version_nodotz%s%spy-_.SOABIzcpython-cCsRdtg}tjdr|jdtjdr0|jdtjddkrH|jdd j|S) NrPy_DEBUGd WITH_PYMALLOCmZPy_UNICODE_SIZEu) VER_SUFFIXrget_config_varappendjoin)partsr//usr/lib/python3.6/wheel.py _derive_abi;s     r1zz (?P[^-]+) -(?P\d+[^-]*) (-(?P\d+[^-]*))? -(?P\w+\d+(\.\w+\d+)*) -(?P\w+) -(?P\w+(\.\w+)*) \.whl$ z7 (?P[^-]+) -(?P\d+[^-]*) (-(?P\d+[^-]*))?$ s \s*#![^\r\n]*s^(\s*#!("[^"]+"|\S+))\s+(.*)$s#!pythons #!pythonw/cCs|S)Nr/)or/r/r0]sr4cCs|jtjdS)Nr2)replaceossep)r3r/r/r0r4_sc@s6eZdZddZddZddZd dd Zd d ZdS) MountercCsi|_i|_dS)N) impure_wheelslibs)selfr/r/r0__init__cszMounter.__init__cCs||j|<|jj|dS)N)r9r:update)r;pathname extensionsr/r/r0addgs z Mounter.addcCs4|jj|}x"|D]\}}||jkr|j|=qWdS)N)r9popr:)r;r>r?kvr/r/r0removeks  zMounter.removeNcCs||jkr|}nd}|S)N)r:)r;fullnamepathresultr/r/r0 find_moduleqs zMounter.find_modulecCsj|tjkrtj|}nP||jkr,td|tj||j|}||_|jdd}t|dkrf|d|_ |S)Nzunable to find extension for %sr!rr) sysmodulesr: ImportErrorimpZ load_dynamic __loader__rsplitlen __package__)r;rErGr.r/r/r0 load_modulexs       zMounter.load_module)N)__name__ __module__ __qualname__r<r@rDrHrQr/r/r/r0r8bs  r8c@seZdZdZd2ZdZd3ddZedd Zed d Z ed d Z e ddZ ddZ e ddZddZd4ddZddZddZddZd5ddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd6d*d+Zd,d-Zd.d/Zd7d0d1ZdS)8Wheelz@ Class to build and install from Wheel files (PEP 427). rZsha256NFcCs8||_||_d|_tg|_dg|_dg|_tj|_ |dkrRd|_ d|_ |j |_ ntj|}|r|jd}|d|_ |djd d |_ |d |_|j |_ ntjj|\}}tj|}|std ||rtjj||_ ||_ |jd}|d|_ |d|_ |d |_|d jd|_|djd|_|djd|_dS)zB Initialise an instance using a (valid) filename. r)noneanyNZdummyz0.1ZnmZvnr rZbnzInvalid name or filename: %rrr!Zbiar)signZ should_verifybuildverPYVERpyverabiarchr6getcwddirnamenameversionfilenameZ _filenameNAME_VERSION_REmatch groupdictr5rFsplit FILENAME_RErabspath)r;rcrYverifyr&infor`r/r/r0r<sB            zWheel.__init__cCs^|jrd|j}nd}dj|j}dj|j}dj|j}|jjdd}d|j|||||fS)zJ Build and return a filename from the various components. rr)r!r z%s-%s%s-%s-%s-%s.whl)rZr-r\r]r^rbr5ra)r;rZr\r]r^rbr/r/r0rcs     zWheel.filenamecCstjj|j|j}tjj|S)N)r6rFr-r`rcisfile)r;rFr/r/r0existssz Wheel.existsccs@x:|jD]0}x*|jD] }x|jD]}|||fVq WqWqWdS)N)r\r]r^)r;r\r]r^r/r/r0tagss   z Wheel.tagscCstjj|j|j}d|j|jf}d|}tjd}t |d}|j |}|dj dd}t dd |D}|d krzd } nt } y8tj|| } |j| } || } t| d } WdQRXWn tk rtd | YnXWdQRX| S)Nz%s-%sz %s.dist-infozutf-8rz Wheel-Versionr!rcSsg|] }t|qSr/)int).0ir/r/r0 sz"Wheel.metadata..ZMETADATA)Zfileobjz$Invalid wheel, because %s is missing)rr)r6rFr-r`rcrarbcodecs getreaderrget_wheel_metadatargtupler posixpathopenr KeyError ValueError)r;r>name_verinfo_dirwrapperzfwheel_metadatawv file_versionfnmetadata_filenamebfwfrGr/r/r0metadatas(     zWheel.metadatac CsXd|j|jf}d|}tj|d}|j|}tjd|}t|}WdQRXt|S)Nz%s-%sz %s.dist-infoWHEELzutf-8) rarbrxr-ryrtrurdict)r;rr|r}rrrmessager/r/r0rvs  zWheel.get_wheel_metadatac Cs6tjj|j|j}t|d}|j|}WdQRX|S)Nro)r6rFr-r`rcrrv)r;r>rrGr/r/r0rks z Wheel.infoc Cstj|}|r||j}|d|||d}}d|jkrBt}nt}tj|}|rfd|jd }nd}||}||}nT|jd}|jd} |dks|| krd} n|||dd krd } nd} t| |}|S) Nspythonw r  rrs ) SHEBANG_REreendlowerSHEBANG_PYTHONWSHEBANG_PYTHONSHEBANG_DETAIL_REgroupsfind) r;datar&rZshebangZdata_after_shebangZshebang_pythonargsZcrZlfZtermr/r/r0process_shebangs,       zWheel.process_shebangc Csh|dkr|j}ytt|}Wn tk r<td|YnX||j}tj|jdj d}||fS)NzUnsupported hash algorithm: %r=ascii) hash_kindgetattrhashlibAttributeErrorrdigestbase64Zurlsafe_b64encoderstripdecode)r;rrhasherrGr/r/r0get_hashs zWheel.get_hashc Csbt|}ttjj||}|j|ddf|jt|}x|D]}|j|qBWWdQRXdS)Nr)) listto_posixr6rFrelpathr,sortrZwriterow)r;recordsZ record_pathbasepwriterrowr/r/r0 write_record's  zWheel.write_recordc Csg}|\}}tt|j}xX|D]P\}} t| d} | j} WdQRXd|j| } tjj| } |j || | fqWtjj |d} |j || |t tjj |d}|j || fdS)Nrbz%s=%sRECORD) rrrryreadrr6rFgetsizer,r-rr)r;rklibdir archive_pathsrdistinfor}raprfrrsizer/r/r0 write_records0s   zWheel.write_recordsc CsJt|dtj2}x*|D]"\}}tjd|||j||qWWdQRXdS)NwzWrote %s to %s in wheel)rzipfileZ ZIP_DEFLATEDloggerdebugwrite)r;r>rrrrr/r/r0 build_zip@szWheel.build_zipc!s|dkr i}ttfddd%d}|dkrFd}tg}tg}tg}nd}tg}d g}d g}|jd ||_|jd ||_|jd ||_ |} d|j |j f} d| } d| } g} xd&D]}|krq|}t j j|rxt j|D]\}}}x|D]}tt j j||}t j j||}tt j j| ||}| j||f|dkr|jd rt|d}|j}WdQRX|j|}t|d}|j|WdQRXqWqWqW| }d}xt j|D]\}}}||kr"x@t|D]4\}}t|}|jdrt j j||}||=PqW|s"tdxP|D]H}t|jd'r@q(t j j||}tt j j||}| j||fq(WqWt j|}xJ|D]B}|d(krtt j j||}tt j j| |}| j||fqWd|p|jd td!|g}x*|jD] \}}}|jd"|||fqWt j j|d}t|d#}|jd$j|WdQRXtt j j| d}| j||f|j || f| | t j j|j!|j"} |j#| | | S))z Build a wheel from files in specified paths, and use any specified tags when determining the name of the wheel. Ncs|kS)Nr/)r3)pathsr/r0r4NszWheel.build..purelibplatlibrZfalsetruerVrWr\r]r^z%s-%sz%s.dataz %s.dist-inforheadersscriptsz.exerwbz .dist-infoz(.dist-info directory expected, not found.pyc.pyor INSTALLERSHAREDrzWheel-Version: %d.%dzGenerator: distlib %szRoot-Is-Purelib: %sz Tag: %s-%s-%sr )rr)rrr)rr)rrrr)$rr IMPVERABIARCHr[getr\r]r^rarbr6rFisdirwalkr r-rrr,endswithryrrr enumerateAssertionErrorlistdir wheel_versionrrnrr`rcr)!r;rrnrZlibkeyZis_pureZ default_pyverZ default_abiZ default_archrr|data_dirr}rkeyrFrootdirsfilesrrrprrrrrrdnrr\r]r^r>r/)rr0buildFs      "         z Wheel.buildcBIKs`|j}|jd}|jdd}tjj|j|j}d|j|jf}d|} d|} t j| t } t j| d} t j| d} t j d }t |d }|j| }||}t|}Wd QRX|d jd d}tdd|D}||jkr|r||j||ddkr|d}n|d}i}|j| <}t|d&}x|D]}|d}|||<q.WWd QRXWd QRXt j| d}t j| d}t j| dd}t|d}d|_tj }g} tj}!|!|_d |_zy^x|jD]}"|"j}#t|#tr|#}$n |#jd }$|$j drq||$}|dr0t!|"j"|dkr0t#d|$|dr|djdd\}%}&|j|#}|j$}'Wd QRX|j%|'|%\}(})|)|&krt#d|#|r|$j&||frt'j(d |$q|$j&|o|$j d! }*|$j&|r|$jd"d\}(}+},tjj||+t)|,}-n$|$| | fkrqtjj|t)|$}-|*s|j|#}|j*||-Wd QRX| j+|-| r|drt|-d#4}|j$}'|j%|'|%\}(}.|.|)krt#d$|-Wd QRX|rx|-j d%rxy|j,|-}/| j+|/Wn$t-k rt'j.d&dd'YnXnttjj/t)|#}0tjj|!|0}1|j|#}|j*||1Wd QRXtjj|-\}2}0|2|_|j0|0}3|j1|3| j2|3qW|rt'j(d(d }4n~d }5|j3d }|d)kr~t j| d*}6y|j|6}t4|}7Wd QRXi}5xxd|=s |>r|jdd}?tjj;|?s.tW|>rd,di}Ax8|>j=D],\}9};d8|9|;f}@|j0|@|A}3|j1|3qWtjj|| }t>|}4t?|}|d=|d=||d9<|4j@||}|r| j+||4jA| |d:||4St-k r@t'jBd;|jCYnXWd tDjE|!XWd QRXd S)=a Install a wheel to the specified paths. If kwarg ``warner`` is specified, it should be a callable, which will be called with two tuples indicating the wheel version of this software and the wheel version in the file, if there is a discrepancy in the versions. This can be used to issue any warnings to raise any exceptions. If kwarg ``lib_only`` is True, only the purelib/platlib files are installed, and the headers, scripts, data and dist-info metadata are not written. The return value is a :class:`InstalledDistribution` instance unless ``options.lib_only`` is True, in which case the return value is ``None``. warnerlib_onlyFz%s-%sz%s.dataz %s.dist-inforrzutf-8roNz Wheel-Versionr!rcSsg|] }t|qSr/)rp)rqrrr/r/r0rssz!Wheel.install..zRoot-Is-Purelibrrr)streamrr)r)dry_runTz /RECORD.jwsrzsize mismatch for %s=zdigest mismatch for %szlib_only: skipping %sz.exer2rzdigest mismatch on write for %sz.pyzByte-compilation failed)exc_infozlib_only: returning Nonez1.0zentry_points.txtconsoleguiz %s_scriptszwrap_%sz%s:%sz %szAUnable to read legacy script metadata, so cannot generate scriptsr?zpython.commandsz8Unable to read JSON metadata, so cannot generate scriptsZ wrap_consoleZwrap_guizValid script path not specifiedz%s = %slibprefixzinstallation failed.)rr)Frrr6rFr-r`rcrarbrxrrtrurryrrgrwrrrrecordrIdont_write_bytecodetempfileZmkdtempZ source_dirZ target_dirinfolist isinstancer rrstr file_sizerrr startswithrrrZ copy_streamr,Z byte_compile ExceptionZwarningbasenameZmakeZset_executable_modeextendrkrvaluesrsuffixflagsjsonloadrr{itemsr rZwrite_shared_locationsZwrite_installed_filesZ exceptionZrollbackshutilZrmtree)Br;rZmakerkwargsrrrr>r|rr} metadata_namewheel_metadata_name record_namer~rbwfrrrrrrrreaderrrZdata_pfxZinfo_pfxZ script_pfxZfileopZbcZoutfilesworkdirzinfoarcname u_arcnamekindvaluerr rZ is_scriptwhererZoutfileZ newdigestZpycrZworknamer filenamesZdistZcommandsZepZepdatarrBr$rCsZconsole_scriptsZ gui_scriptsZ script_dirZscriptZoptionsr/r/r0installsB            "                                          z Wheel.installcCs4tdkr0tjjttdtjdd}t|atS)Nz dylib-cache) cacher6rFr-rrrIrbr)r;rr/r/r0_get_dylib_caches zWheel._get_dylib_cachecCsltjj|j|j}d|j|jf}d|}tj|d}tj d}g}t |d}y|j |}||} t j | } |j} | j|} tjj| j| } tjj| stj| x| jD]\}}tjj| t|}tjj|sd}n6tj|j}tjj|}|j|}tj|j}||k}|r(|j|| |j||fqWWdQRXWntk r\YnXWdQRX|S)Nz%s-%sz %s.dist-infoZ EXTENSIONSzutf-8roT)r6rFr-r`rcrarbrxrtrurryrrrZ prefix_to_dirrrmakedirsrrrmstatst_mtimedatetimeZ fromtimestampZgetinfoZ date_timeextractr,rz)r;r>r|r}rr~rGrrrr?rrZ cache_baserardestrZ file_timerkZ wheel_timer/r/r0_get_extensionss>              zWheel._get_extensionscCst|S)zM Determine if a wheel is compatible with the running system. ) is_compatible)r;r/r/r0rszWheel.is_compatiblecCsdS)zP Determine if a wheel is asserted as mountable by its metadata. Tr/)r;r/r/r0 is_mountableszWheel.is_mountablecCstjjtjj|j|j}|js2d|}t||jsJd|}t||t jkrbt j d|nN|rtt jj |nt jj d||j}|rtt jkrt jj ttj||dS)Nz)Wheel %s not compatible with this Python.z$Wheel %s is marked as not mountable.z%s already in pathr)r6rFrir-r`rcrrrrIrrr,insertr_hook meta_pathr@)r;r,r>msgr?r/r/r0mounts"   z Wheel.mountcCsrtjjtjj|j|j}|tjkr2tjd|nr/r/r0unmounts     z Wheel.unmountc'Cstjj|j|j}d|j|jf}d|}d|}tj|t}tj|d}tj|d}t j d}t |d} | j |} || } t | } WdQRX| djd d } td d | D}i}| j |:}t|d $}x|D]}|d}|||<qWWdQRXWdQRXx| jD]}|j}t|tr*|}n |jd}d|krJtd||jdrZq||}|drt|j|dkrtd||d r|d jdd \}}| j |}|j}WdQRX|j||\}}||krtd|qWWdQRXdS)Nz%s-%sz%s.dataz %s.dist-inforrzutf-8roz Wheel-Versionr!rcSsg|] }t|qSr/)rp)rqrrr/r/r0rssz Wheel.verify..)rrz..zinvalid entry in wheel: %rz /RECORD.jwsrzsize mismatch for %srzdigest mismatch for %s)r6rFr-r`rcrarbrxrrtrurryrrgrwrrrr rrrrrrr)r;r>r|rr}rrrr~rrrrrrrrrrrrrrrrrr rr/r/r0rjsT                z Wheel.verifycKsdd}dd}tjj|j|j}d|j|jf}d|}tj|d} t} t |d} i} xt| j D]h} | j}t |t r|}n |j d }|| krqjd |krtd || j| | tjj| t|}|| |<qjWWd QRX|| |\}}|| f|}|r|| |\}}|r(||kr(||||d krRtjd d| d\}}tj|n*tjj|sltd|tjj||j}t| j}tjj| |}||f}|j|| ||j|||d krtj||Wd QRX|S)a Update the contents of a wheel in a generic way. The modifier should be a callable which expects a dictionary argument: its keys are archive-entry paths, and its values are absolute filesystem paths where the contents the corresponding archive entries can be found. The modifier is free to change the contents of the files pointed to, add new entries and remove entries, before returning. This method will extract the entire contents of the wheel to a temporary location, call the modifier, and then use the passed (and possibly updated) dictionary to write a new wheel. If ``dest_dir`` is specified, the new wheel is written there -- otherwise, the original wheel is overwritten. The modifier should return True if it updated the wheel, else False. This method returns the same value the modifier returns. cSsHd}}d|tf}||kr$d|}||kr@||}t|dj}||fS)Nz%s/%sz %s/PKG-INFO)rF)rr rb)path_mapr}rbrFrr/r/r0 get_version1s  z!Wheel.update..get_versionc Ssd}y|t|}|jd}|dkr*d|}nTdd||ddjdD}|dd7<d|d|djd d |Df}Wn tk rtjd |YnX|rt|d }||_|j t  }|j ||d tjd||dS)Nrrz%s+1cSsg|] }t|qSr/)rp)rqr r/r/r0rsCsz8Wheel.update..update_version..rr!z%s+%scss|]}t|VqdS)N)r)rqrrr/r/r0 Fsz7Wheel.update..update_version..z0Cannot update non-compliant (PEP-440) version %r)rF)rFlegacyzVersion updated from %r to %rr) rrrgr-rrrr rbrrr)rbrFupdatedrCrrr.Zmdr"r/r/r0update_version;s(       z$Wheel.update..update_versionz%s-%sz %s.dist-inforrozutf-8z..zinvalid entry in wheel: %rNz.whlz wheel-update-)rrdirzNot a directory: %r)r6rFr-r`rcrarbrxrrrrr rrrrrZmkstempcloserrrrrrZcopyfile)r;ZmodifierZdest_dirrr r$r>r|r}rrrrrrrrFZoriginal_versionr ZmodifiedZcurrent_versionfdnewpathrrrkr/r/r0r= sX                z Wheel.update)rr)NFF)N)NN)F)N)rRrSrT__doc__rrr<propertyrcrmrnrrrvrkrrrrrrr rrrrrrrjr=r/r/r/r0rUs4 )        he "  6rUcCstg}td}x6ttjddddD]}|jdj|t|gq&Wg}x6tjD]*\}}}|j drT|j|j dddqTW|j t dkr|j dt |jdg}tg}tjdkrtjd t}|r|j\} }}} t|}| g} | dkr| jd | dkr| jd| dkr*| jd| dkr>| jd| dkrR| jdxL|dkrx2| D]*} d| ||| f} | tkrd|j| qdW|d8}qTWx<|D]4}x,|D]$} |jdjt|df|| fqWqWxXt|D]L\}}|jdjt|fddf|dkr|jdjt|dfddfqWxXt|D]L\}}|jdjd|fddf|dkrB|jdjd|dfddfqBWt|S)zG Return (pyver, abi, arch) tuples compatible with this Python. rrr)z.abir!rrVdarwinz(\w+)_(\d+)_(\d+)_(\w+)$i386ppcZfatx86_64Zfat3ppc64Zfat64intelZ universalz %s_%s_%s_%srWrrr)r,r-)r,r-r.)r/r.)r,r.)r,r.r0r-r/)r*rangerI version_infor,r-rrLZ get_suffixesrrgrrrrplatformrererrp IMP_PREFIXrset)ZversionsmajorminorZabisrr rGZarchesr&rar^Zmatchesrer r]rrrbr/r/r0compatible_tagss`                    * $ $r9cCs^t|tst|}d}|dkr"t}x6|D].\}}}||jkr(||jkr(||jkr(d}Pq(W|S)NFT)rrUCOMPATIBLE_TAGSr\r]r^)ZwheelrnrGZverr]r^r/r/r0rs r)N)SZ __future__rrrtrZdistutils.utilZ distutilsZemailrrrLrZloggingr6rxr4rrIrrr)rrcompatrrr r r Zdatabaser rr rutilrrrrrrrrrrbrrZ getLoggerrRrrhasattrr5r3rr+r*r2r[r get_platformr5rrr1compile IGNORECASEVERBOSErhrdrrrrr7robjectr8rrUr9r:rr/r/r/r0s   ,          #>