ó `8(Zc@sŠdZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddlmZddlmZddlmZdd lmZmZmZmZmZmZmZy ejZWnek rejZnXdd fZ ej!d ej"ƒj#Z$d „a%d e&fd„ƒYZ'de(fd„ƒYZ)de j*fd„ƒYZ+dS(sC Operations on existing wheel files, including basic installation. iÿÿÿÿNi(t signatures(treify(tget_install_paths(t get_supported(tread_pkg_info_bytes(turlsafe_b64encodet from_jsonturlsafe_b64decodetnativetbinaryt HashingFilet open_for_csvis‰^(?P(?P.+?)(-(?P\d.+?))?) ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) \.whl|\.dist-info)$cCsByddlmaWn!tk r7ddlmanXt|ƒS(s?Use parse_version from pkg_resources or distutils as available.iÿÿÿÿ(t parse_version(t LooseVersion(t pkg_resourcesR t ImportErrortdistutils.versionR (tversion((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR )s  t BadWheelFilecBseZRS((t__name__t __module__(((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR3st WheelFilecBs[eZdZdZdZdeed„Zd„Z e d„ƒZ e d„ƒZ e d„ƒZ e d„ƒZe d „ƒZeZe d „ƒZe d „ƒZe d „ƒZd „Zd„Ze d„ƒZd„Zd„Zd„Zd„Zd„Zd„Zed„ƒZed„ƒZd„Z ed„ƒZ!eid„Z"dd„Z#RS(sòParse wheel-specific attributes from a wheel (.whl) file and offer basic installation and verification support. WheelFile can be used to simply parse a wheel filename by avoiding the methods that require the actual file contents.tWHEELtRECORDcCs{||_||_||_||_tjj|ƒ}t|ƒ|_|j dƒ sd|jdkrwt d|ƒ‚ndS(s :param fp: A seekable file-like object or None to open(filename). :param append: Open archive in append mode. :param context: Function returning list of supported tags. Wheels must have the same context to be sortable. s.whlsBad filename '%s'N( tfilenametfptappendtcontexttostpathtbasenamet WHEEL_INFO_REtparsed_filenametendswithtNoneR(tselfRRRRR((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__init__As    cCs|jS(N(R(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__repr__UscCsd|jjdƒS(Ns %s.dist-infotnamever(R tgroup(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt distinfo_nameXscCsd|jjdƒS(Ns%s.dataR&(R R'(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt datadir_name\scCsd|j|jfS(Ns%s/%s(R(R(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt record_name`scCsd|j|jfS(Ns%s/%s(R(t WHEEL_INFO(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pytwheelinfo_namedsccs{|jjƒ}xe|djdƒD]P}xG|djdƒD]2}x)|djdƒD]}|||fVqWWq=Wq#WdS(sÎA wheel file is compatible with the Cartesian product of the period-delimited tags in its filename. To choose a wheel file among several candidates having the same distribution version 'ver', an installer ranks each triple of (pyver, abi, plat) that its Python installation can run, sorting the wheels by the best-ranked tag it supports and then by their arity which is just len(list(compatibility_tags)). tpyvert.tabitplatN(R t groupdicttsplit(R#ttagsR-R/R0((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR3hs cCstt|jƒƒS(s4The number of compatibility tags the wheel declares.(tlentlisttcompatibility_tags(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pytarityzscCs|j|jƒƒS(so Lowest index of any of this wheel's tags in self.context(), and the arity e.g. (0, 1) (tcompatibility_rankR(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pytrankscCs|jdtkS(Ni(R9t _big_number(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt compatible‡scCsqg}x?|jD]4}y|j|j|ƒƒWqtk rCqXqWt|ƒrgt|ƒ|jfStdfS(sÑRank the wheel against the supported tags. Smaller ranks are more compatible! :param supported: A list of compatibility tags that the current Python implemenation can run. i(R6Rtindext ValueErrorR4tminR7R:(R#t supportedt preferencesttag((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR8Œs  cCs"|j|kstdƒ‚|jS(Nscontext mismatch(RtAssertionErrorR;(R#tx((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pytsupports_current_pythonŸscCsD|jjdƒt|jjdƒƒtd„|jDƒƒ|jfS(Ntnametvercss|] }| VqdS(N((t.0RC((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pys ®s(R R'R ttupleR9R(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt _sort_keyªscCs|j|jkS(N(R(R#tother((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__eq__±scCs|j|jkS(N(R(R#RJ((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__ne__´scCsV|j|jkr-tdj||ƒƒ‚n|j|jkS|jjdƒ}|jjdƒ}||krw||kSt|jjdƒƒ}t|jjdƒƒ}||kr½||kS|j|jkrêtdj||ƒƒ‚n|j}|j}|dk r*|dk r*||kr*||kS|dkrF|dk rFt S|j |j kS(Ns{0}.context != {1}.contextRERF( Rt TypeErrortformatRIR R'R R9R"tFalseR(R#RJtsntontsvtovtsctoc((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__lt__·s(      $ cCs ||kS(N((R#RJ((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__gt__ÔscCs||kp||kS(N((R#RJ((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__le__×scCs||kp||kS(N((R#RJ((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt__ge__ÚscCsYd}|jrd}nt|jr-|jn|j|ƒ}|jsU|j|ƒn|S(Ntrta(RtVerifyingZipFileRRtverify(R#tmodetvzf((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pytzipfileás  $ cCst|jj|jƒƒS(s+Parse wheel metadata (the .data/WHEEL file)(RR`treadR,(R#((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pytparsed_wheel_infoëscCsD|jd}ttt|jdƒƒƒtkr@tdƒ‚ndS(Ns Wheel-VersionR.sWheel version is too high(RbRHtmaptintR2tVERSION_TOO_HIGHR=(R#R((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt check_versionðs $cCs|jjdƒ}t|ƒS(sc Consult distutils to get the install paths for our dist. A dict with ('purelib', 'platlib', 'headers', 'scripts', 'data'). We use the name from our filename as the dist name, which means headers could be installed in the wrong place if the filesystem-escaped name is different than the Name. Who cares? RE(R R'R(R#RE((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt install_pathsõs c sX‡‡fd†}ˆjddkr4|dƒ}n |dƒ}i}x ˆjjƒD]û}|j}|jdƒrzqVn|jdƒr–|d}n|jdƒ\}} } | r|ˆjkr| jdƒ\} } } | sùtd j |ƒƒ‚n|| ƒ} nd } |} |} t j j t j j | | ƒƒ} | | | | f||siis%s has no hash! t=tsha256sUnsupported hash algorithmN(R"R`tTruetstrictRwR(tset_expected_hashRaRthashlibR«RŒRRtKeyErrorRR]RRNR‘treadert splitlinesRztstderrR„R2RBRR (R#R`tsigR*tsig_nametsmime_sig_nametrecordt record_digesttheaderstpayloadtmsgR±trowRR©talgotdata((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR]~sB       N($RRt__doc__R+RR"RORR$R%tpropertyR(R)R*R,R3R6R7R9R;R8RDRIRKRLRVRWRXRYRR`RbRfRgR¨R](((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR7s>             |R\cBsDeZdZdejed„Zd„Zddd„Z d„Z RS(s´ZipFile that can assert that each of its extracted contents matches an expected sha256 hash. Note that each file must be completly read in order for its hash to be checked.RZcCs>tjj|||||ƒt|_i|_tj|_dS(N( R`tZipFileR$ROR­t_expected_hashesR¯R«t_hash_algorithm(R#tfileR^t compressiont allowZip64((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR$°s  cCs||j|= 2.7)t_eofcsLˆ|ƒˆj|ƒˆjrHˆjƒˆkrHtdˆjƒ‚ndS(NsBad hash for file %r(tupdateRÇRŒRRE(R¾(t_update_crc_origteft expected_hasht running_hash(s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyt _update_crcÓs  csOˆ|d|ƒˆj|ƒ|rKˆjƒˆkrKtdˆjƒ‚ndS(NteofsBad hash for file %r(RÈRŒRRE(R¾RÎ(RÉRÊRËRÌ(s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyRÍÙs sNo expected hash for file %rN(R`RÁR~t isinstancetZipInfoRRÂR"RÍtAttributeErrortwarningstwarnRÃthasattrR­RRE(R#t name_or_infoR^tpwdRERÍ((RÉRÊRËRÌs,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR~Às& "      cCsj|jstdƒ‚n|jƒjƒ}|j|j=|jj|jtj ƒ|jj ƒt |_ dS(sTruncate the last file off this zipfile. Assumes infolist() is in the same order as the files (true for ordinary zip files created by Python)s7Attempt to pop from ZIP archive that was already closedN( Rt RuntimeErrorRstpopt NameToInfoRtseekt header_offsetRtSEEK_SETttruncateR¬t _didModify(R#tlast((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyRØãs    N( RRR¿R`t ZIP_STOREDROR$R®R"R~RØ(((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyR\«s  #(,R¿R‘R¯tos.pathRtreR…RzRÒR`RpRt decoratorRtpathsRt pep425tagsRtpkginfoRtutilRRRRR R R tmaxsizeR:t NameErrortmaxintRetcompiletVERBOSEtmatchRR R=RtobjectRRÁR\(((s,/tmp/pip-build-0nEYGB/wheel/wheel/install.pyts6        4     ÿu