o ;qa@sddlmZddlZddlZddlZddlmZddlZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZddlmZmZmZmZmZddlmZddlmZmZm Z m!Z!dd l"m#Z#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 0e1Z2da3e4ed rd Z5nej67d rdZ5n ej6dkrdZ5ndZ5e8dZ9e9sdej:ddZ9de9Z;e5e9Ze8dZ?e?re?7dre?=dd@ddZ?nddZAeAZ?[Ae Bde jCe jDBZEe Bde jCe jDBZFe BdZGe Bd ZHd!ZId"ZJe jKd#krd$d%ZLnd&d%ZLGd'd(d(eMZNeNZOGd)d*d*eMZPd+d,ZQd-d.ZReRZS[Rd1d/d0ZTdS)2)unicode_literalsN)message_from_file) __version__DistlibException) sysconfigZipFilefsdecode text_typefilter)InstalledDistribution)MetadataMETADATA_FILENAMEWHEEL_METADATA_FILENAMELEGACY_METADATA_FILENAME) FileOperator convert_path CSVReader CSVWriterCachecached_propertyget_cache_base read_exportstempdir get_platform)NormalizedVersionUnsupportedVersionErrorpypy_version_infoppjavajycliipcppy_version_nodotz%s%spy-_.SOABIzcpython-cCsRdtg}tdr|dtdr|dtddkr$|dd |S) Nr#Py_DEBUGd WITH_PYMALLOCmPy_UNICODE_SIZEu) VER_SUFFIXrget_config_varappendjoin)partsr8//usr/lib/python3/dist-packages/distlib/wheel.py _derive_abi<s      r:zz (?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|SNr8or8r8r9^sr?cCs|tjdS)Nr;)replaceossepr=r8r8r9r?`sc@s6eZdZddZddZddZd dd Zd d ZdS) MountercCsi|_i|_dSr<) impure_wheelslibsselfr8r8r9__init__ds zMounter.__init__cCs||j|<|j|dSr<)rDrEupdate)rGpathname extensionsr8r8r9addhs z Mounter.addcCs0|j|}|D] \}}||jvr|j|=qdSr<)rDpoprE)rGrJrKkvr8r8r9removels   zMounter.removeNcCs||jvr |}|Sd}|Sr<)rE)rGfullnamepathresultr8r8r9 find_modulers zMounter.find_modulecCsl|tjvr tj|}|S||jvrtd|t||j|}||_|dd}t|dkr4|d|_ |S)Nzunable to find extension for %sr)rr) sysmodulesrE ImportErrorimp load_dynamic __loader__rsplitlen __package__)rGrQrSr7r8r8r9 load_moduleys      zMounter.load_moduler<)__name__ __module__ __qualname__rHrLrPrTr^r8r8r8r9rCcs   rCc@seZdZdZdZdZd4ddZedd Zed d Z ed d Z e ddZ ddZ e ddZddZd5ddZddZddZddZd6ddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd7d,d-Zd.d/Zd0d1Zd5d2d3ZdS)8Wheelz@ Class to build and install from Wheel files (PEP 427). )rrsha256NFcCs<||_||_d|_tg|_dg|_dg|_t|_ |dur*d|_ d|_ |j |_ dSt|}|rO|d}|d|_ |dd d |_ |d |_|j |_ dStj|\}}t|}|sdtd ||rmtj||_ ||_ |d}|d|_ |d|_ |d |_|d d|_|dd|_|dd|_dS)zB Initialise an instance using a (valid) filename. r2noneanyNdummyz0.1nmvnr(r'bnzInvalid name or filename: %rr&r)biar)sign should_verifybuildverPYVERpyverabiarchrAgetcwddirnamenameversionfilename _filenameNAME_VERSION_REmatch groupdictr@rRsplit FILENAME_RErabspath)rGrwrlverifyr.infortr8r8r9rHsD            zWheel.__init__cCs^|jr d|j}nd}d|j}d|j}d|j}|jdd}d|j|||||fS)zJ Build and return a filename from the various components. r'r2r)r(z%s-%s%s-%s-%s-%s.whl)rnr6rprqrrrvr@ru)rGrnrprqrrrvr8r8r9rws     zWheel.filenamecCstj|j|j}tj|Sr<)rArRr6rtrwisfile)rGrRr8r8r9existss z Wheel.existsccs6|jD]}|jD]}|jD]}|||fVqq qdSr<)rprqrr)rGrprqrrr8r8r9tagss   z Wheel.tagsc Cs2tj|j|j}d|j|jf}d|}td}t |dp}| |}|d dd}t dd |D}t tg} d} | D]=} z2t|| } || } || }t|d } | rb WdWnWdn1slwYWq>ty{Yq>w| std d | Wd| S1swY| S) N%s-%s %s.dist-infoutf-8r Wheel-Versionr)rcSg|]}t|qSr8int.0ir8r8r9 z"Wheel.metadata..)fileobjz8Invalid wheel, because metadata is missing: looked in %sz, )rArRr6rtrwrurvcodecs getreaderrget_wheel_metadatar|tuplerr posixpathopenr KeyError ValueError)rGrJname_verinfo_dirwrapperzfwheel_metadatawv file_versionfnsrSfnmetadata_filenamebfwfr8r8r9metadatasD        zWheel.metadatacCsrd|j|jf}d|}t|d}||}td|}t|}Wdt|S1s0wYt|S)NrrWHEELr) rurvrr6rrrrdict)rGrrrrrrmessager8r8r9rs    zWheel.get_wheel_metadatacCsLtj|j|j}t|d}||}Wd|S1swY|S)Nr)rArRr6rtrwrr)rGrJrrSr8r8r9rs   z Wheel.infoc Cst|}|r?|}|d|||d}}d|vr!t}nt}t|}|r3d|d}nd}||}||}|S|d}|d} |dksQ|| krTd} n|||dd krad } nd} t| |}|S) Nspythonw   rr%s ) SHEBANG_RErzendlowerSHEBANG_PYTHONWSHEBANG_PYTHONSHEBANG_DETAIL_REgroupsfind) rGdatar.rshebangdata_after_shebangshebang_pythonargscrlftermr8r8r9process_shebangs.     zWheel.process_shebangcCsb|dur|j}ztt|}Wn tytd|w||}t|d d}||fS)NzUnsupported hash algorithm: %r=ascii) hash_kindgetattrhashlibAttributeErrorrdigestbase64urlsafe_b64encoderstripdecode)rGrrhasherrSr8r8r9get_hash%s   zWheel.get_hashcCslt|}ttj||}||ddft|}|D]}||qWddS1s/wYdS)Nr2)listto_posixrArRrelpathr5rwriterow)rGrecords record_pathbasepwriterrowr8r8r9 write_record0s  "zWheel.write_recordc Csg}|\}}tt|j}|D]2\}} t| d } | } Wdn1s&wYd|| } tj| } | || | fqtj |d} | || |t tj |d}| || fdS)Nrbz%s=%sRECORD) rrrrreadrrArRgetsizer5r6rr)rGrlibdir archive_pathsrdistinforraprfrrsizer8r8r9 write_records8s     zWheel.write_recordscCs\t|dtj}|D]\}}td|||||q WddS1s'wYdS)NwzWrote %s to %s in wheel)rzipfile ZIP_DEFLATEDloggerdebugwrite)rGrJrrrrr8r8r9 build_zipHs  "zWheel.build_zipc" s|duri}ttfdddd}|dkr#d}tg}tg}tg}n d}tg}d g}d g}|d ||_|d ||_|d ||_ |} d|j |j f} d| } d| } g} dD]}|vrbq[|}t j |rt |D]l\}}}|D]d}tt j ||}t j ||}tt j | ||}| ||f|dkr|dst|d }|}Wdn1swY||}t|d }||Wdn1swYqxqqq[| }d}t |D]W\}}}||krt|D]\}}t|}|drt j ||}||=nq|sJd|D]$}t|dr&qt j ||}tt j ||}| ||fqqt |}|D]!}|dvrgtt j ||}tt j | |}| ||fqGd|po|jdtd|g}|jD]\}}}|d|||fq{t j |d}t|d}|d |Wdn 1swYtt j | d}| ||fd!d"} t| | d#} | || f| | t 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|vSr<r8r=pathsr8r9r?VszWheel.build..)purelibplatlibrrfalsetruerdrerprqrrr%s.datar)rheadersscriptsr.exerwb .dist-infoz(.dist-info directory expected, not found)z.pycz.pyo)r INSTALLERSHAREDrzWheel-Version: %d.%dzGenerator: distlib %szRoot-Is-Purelib: %sz Tag: %s-%s-%srr cSs*|d}|d}d|vr|d7}||fS)Nrr;ri')count)trnr8r8r9sorters  zWheel.build..sorter)key)$rr IMPVERABIARCHrogetrprqrrrurvrArRisdirwalkr r6rrr5endswithrrrr enumeratelistdir wheel_versionrrsortedrrtrwr)"rGrrrlibkeyis_pure default_pyver default_abi default_archrrdata_dirrrrrRrootdirsfilesrrrprrrrrdnrrprqrrrrJr8rr9buildNs             z Wheel.buildcCs |dS)zl Determine whether an archive entry should be skipped when verifying or installing. )r;z /RECORD.jws)r)rGarcnamer8r8r9 skip_entrys zWheel.skip_entrycC KsP|j}|d}|dd}|dd}tj|j|j}d|j|jf} d| } d| } t | t } t | d} t | d }t d }t |d }|| }||}t|}Wd n1scwY|d dd}tdd|D}||jkr|r||j||ddkr|d}n|d}i}||*}t|d}|D] }|d}|||<qWd n1swYWd n1swYt | d}t | d}t | dd}t|d}d|_tj } g}!t}"|"|_d |_zz|D]}#|#j}$t|$tr|$}%n|$d }%| |%rq||%}|dr6t!|#j"|dkr6t#d|%|drr|ddd\}&}'||$ }|$}(Wd n 1sZwY|%|(|&\})}*|*|'krrt#d|$|r|%&||frt'(d |%q|%&|o|%)d! }+|%&|r|%d"d\})},}-tj||,t*|-}.n|%| |fvrqtj|t*|%}.|+sU||$}|+||.Wd n 1swYtjd#krt,|.|#j-d$?d%@|!.|.|s(|dr(t|.d&}|$}(|%|(|&\})}/|/|*krt#d'|.Wd n 1s#wY| rS|.)d(rSz|j/|.|d)}0|!.|0Wqt0yRt'j1d*dd+Yqwqtj2t*|$}1tj|"|1}2||$}|+||2Wd n 1s{wYtj|.\}3}1|3|_|3|1}4|4|4|!5|4q|rt'(d,d }5nMd }6|j6d }|d-kr$t | d.}7zZ||7 }t7|}8Wd n 1swYi}6d/D]9}9d0|9}:|:|8vri|6d1|9<};|8|:8D]}|6d:i}?|>su|?r|dd}@tj>|@st?d;|@|_|>@D]\}:}<|5C||}|r|!.||5D|!|d?||5WWtEF|"Wd St0yt'Gd@|HwtEF|"w1s!wYd S)Aa~ 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. If kwarg ``bytecode_hashed_invalidation`` is True, written bytecode will try to use file-hash based invalidation (PEP-552) on supported interpreter versions (CPython 2.7+). The return value is a :class:`InstalledDistribution` instance unless ``options.lib_only`` is True, in which case the return value is ``None``. warnerlib_onlyFbytecode_hashed_invalidationrrrrrrrNrr)rcSrr8rrr8r8r9rrz!Wheel.install..zRoot-Is-Purelibrrrstreamrr2r)dry_runTr%size mismatch for %s=digest mismatch for %szlib_only: skipping %srr;posixirzdigest mismatch on write for %sz.py)hashed_invalidationzByte-compilation failed)exc_infozlib_only: returning Nonez1.0zentry_points.txt)consoleguiz %s_scriptszwrap_%sz%s:%sz [%s],zAUnable to read legacy script metadata, so cannot generate scriptsrKzpython.commandsz8Unable to read JSON metadata, so cannot generate scripts wrap_consolewrap_guizValid script path not specifiedz%s = %sr%libprefixzinstallation failed.)IrrrArRr6rtrwrurvrrrrrrrr|rrrrrecordrUdont_write_bytecodetempfilemkdtemp source_dir target_dirinfolist isinstancer rrstr file_sizerrr startswithrrrr copy_streamchmod external_attrr5 byte_compile Exceptionwarningbasenamemakeset_executable_modeextendrrvaluesr*suffixflagsjsonloadrritemsr rwrite_shared_locationswrite_installed_filesshutilrmtree exceptionrollback)CrGrmakerkwargsrrrbc_hashed_invalidationrJrrr metadata_namewheel_metadata_name record_namerrbwfrrrrrrrreaderrrdata_pfxinfo_pfx script_pfxfileopbcoutfilesworkdirzinfor u_arcnamekindvaluerr(r is_scriptwhereroutfile newdigestpycrworknamer filenamesdistcommandsepepdatarrNr,rOsconsole_scripts gui_scripts script_dirscriptoptionsr8r8r9installs                                                            F  z Wheel.installcCs8tdurtjttddtjdd}t|atS)Nz dylib-cachez%s.%sr%) cacherArRr6rr3rU version_infor)rGrr8r8r9_get_dylib_caches zWheel._get_dylib_cachec Cstj|j|j}d|j|jf}d|}t|d}t d}g}t |d}z| |r}||} t | } |} | |} tj| j| } tj| sTt| | D]@\}}tj| t|}tj|snd}nt|j}tj|}||}tj|j}||k}|r||| |||fqXWdn1swYWn tyYn wWd|SWd|S1swY|S)Nrr EXTENSIONSrrT)rArRr6rtrwrurvrrrrrrCrDrs prefix_to_dirrrmakedirsrErrstatst_mtimedatetime fromtimestampgetinfo date_timeextractr5r)rGrJrrrrrSrrrrKrqr* cache_baserurdestr} file_timer wheel_timer8r8r9_get_extensionssT                 zWheel._get_extensionscCst|S)zM Determine if a wheel is compatible with the running system. ) is_compatiblerFr8r8r9rszWheel.is_compatiblecCsdS)zP Determine if a wheel is asserted as mountable by its metadata. Tr8rFr8r8r9 is_mountableszWheel.is_mountablecCstjtj|j|j}|sd|}t||s%d|}t||t jvr2t d|dS|r;t j |nt j d||}|r[tt jvrSt j tt||dSdS)Nz)Wheel %s not compatible with this Python.z$Wheel %s is marked as not mountable.z%s already in pathr)rArRr~r6rtrwrrrrUrrr5insertr_hook meta_pathrL)rGr5rJmsgrKr8r8r9mounts$   z Wheel.mountcCs|tjtj|j|j}|tjvrtd|dStj ||t j vr*t |t j s:t tj vr.rrr;..invalid entry in wheel: %rr%rrr)rArRr6rtrwrurvrrrrrrrr|rrr1r2r rrrr3r4rr)rGrJrrrrOrPrQrrrRrrrrrrrSrrr[rr\r]r^rr(rr8r8r9rsn                   $z Wheel.verifyc Ksdd}dd}tj|j|j}d|j|jf}d|}t|d} t} t |dC} i} | D]4} | j}t |t r@|}n| d }|| krJq3d |vrTtd || | | tj| t|}|| |<q3Wd n1srwY|| |\}}|| fi|}|r|| |\}}|r||kr||||d urtjd d| d\}}t|ntj|std|tj||j}t| }tj| |}||f}||| |||||d urt||Wd |SWd |SWd |S1swY|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}||vrd|}||vr ||}t|dj}||fS)Nz%s/%sz %s/PKG-INFOrR)rr rv)path_maprrvrRrr8r8r9 get_version`s  z!Wheel.update..get_versioncSsd}z>t|}|d}|dkrd|}n*dd||dddD}|dd7<d |d|dd d |Df}WntyOtd |Ynw|rot|d }||_| t }|j ||dtd||dSdS)Nr'rz%s+1cSrr8r)rrjr8r8r9rrrz8Wheel.update..update_version..rr)rz%s+%scss|]}t|VqdSr<)r3rr8r8r9 usz7Wheel.update..update_version..z0Cannot update non-compliant (PEP-440) version %rr)rRlegacyzVersion updated from %r to %r) rrr|r6rrrr rvrrr)rvrRupdatedrOrr7mdrr8r8r9update_versionjs4       z$Wheel.update..update_versionrrrrrrrNz.whlz wheel-update-)rAr*dirzNot a directory: %r)rArRr6rtrwrurvrrrr1r2r rrr}rr-mkstempcloserrrErrrHcopyfile)rGmodifierdest_dirrMrrrJrrrQrZrrr[rr\rRoriginal_versionr(modifiedcurrent_versionfdnewpathrrrr8r8r9rIOsr                - - --z Wheel.update)NFFr<)NN)F)r_r`ra__doc__rrrHpropertyrwrrrrrrrrrrrrrrprsrrrrrrrIr8r8r8r9rbsB )        tn "  8rbcCsZddl}|}g}|ddkr+|ddD]}||r#t|ndqt|}|S)Nrglibcrr))platformlibc_verr|r5isdigitrr)rverrSrjr8r8r9_get_glibc_versions rc CsRtg}td}ttjddddD]}|d|t|gqg}tD]\}}}| dr<|| dddq'| t dkrK| dt |dg}tg}tjd krtd t}|r|\} }}} t|}| g} | d vrz| d | d vr| d| dvr| d| dvr| d| dvr| d|dkr| D]} d| ||| f} | tkr|| q|d8}|dks|D]}|D]} |dt|df|| f|dkrMtj drM| dd} t}t|dkrM|dkr |dt|df|d| f|dkr|dt|df|d| f|dkr5|dt|df|d| f|dt|df|d|d|d| ffqqt|D]&\}}|dt|fddf|dkrx|dt|dfddfqSt|D]&\}}|dd |fddf|dkr|dd |dfddfq~t|S)!zG Return (pyver, abi, arch) tuples compatible with this Python. rrrr2z.abir)r%rddarwinz(\w+)_(\d+)_(\d+)_(\w+)$)i386ppcfat)rrx86_64fat3)ppc64rfat64)rrintel)rrrrr universalz %s_%s_%s_%slinuxlinux_)r%z manylinux1_%s)r% zmanylinux2010_%s)r%zmanylinux2014_%szmanylinux_%s_%s_%srer&)r3rangerUrrr5r6r3rX get_suffixesr5r|sortrrrrrerzrr IMP_PREFIXr@rr\rset)versionsmajorminorabisrAr(rSarchesr.rurrmatchesrzrjrqr7rrvr8r8r9compatible_tagss                 rcCs^t|ts t|}d}|durt}|D]\}}}||jvr,||jvr,||jvr,d}|Sq|S)NFT)r2rbCOMPATIBLE_TAGSrprqrr)wheelrrSrrqrrr8r8r9rs rr<)U __future__rrrryemailrrrXrCloggingrArrrHrUr-rr2rrcompatrrr r r databaser rr rrrutilrrrrrrrrrrrvrr getLoggerr_rrqhasattrrrr5r4r3rrrorr@rrr|r:compile IGNORECASEVERBOSEr}ryrrrrrBrobjectrCrrbrrrrr8r8r8r9s   0             #1 P