ó â\e[c@s dZddlmZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddlmZddlmZddlmZdd lmZmZmZmZmZmZmZy e jZWnek re jZnXdd fZ ej!d ej"ƒj#Z$d „a%d e&fd„ƒYZ'de(fd„ƒYZ)de&fd„ƒYZ*de j+fd„ƒYZ,dS(sC Operations on existing wheel files, including basic installation. iÿÿÿÿ(tprint_functionNi(t signatures(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[a-z].+?)-(?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-install-0xiv62/wheel/wheel/install.pyR (s  treifycBs#eZdZd„Zdd„ZRS(sÁPut the result of a method which uses this (non-data) descriptor decorator in the instance dict after the first call, effectively replacing the decorator with an instance variable. cCs||_|j|_dS(N(twrappedt__doc__(tselfR((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__init__8s cCs9|dkr|S|j|ƒ}t||jj|ƒ|S(N(tNoneRtsetattrt__name__(Rtinsttobjtypetval((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__get__<s  N(Rt __module__RRRR(((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyR2s t BadWheelFilecBseZRS((RR(((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyRDst 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_filenametendswithRR(RR#R$R%R&R)((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyRRs    cCs|jS(N(R#(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__repr__fscCsd|jjdƒS(Ns %s.dist-infotnamever(R+tgroup(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt distinfo_nameiscCsd|jjdƒS(Ns%s.dataR.(R+R/(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt datadir_namemscCsd|j|jfS(Ns%s/%s(R0R"(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt record_nameqscCsd|j|jfS(Ns%s/%s(R0t WHEEL_INFO(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pytwheelinfo_nameusccs{|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(RttagsR5R7R8((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyR;ys cCstt|jƒƒS(s4The number of compatibility tags the wheel declares.(tlentlisttcompatibility_tags(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pytarity‹scCs|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-install-0xiv62/wheel/wheel/install.pytrankscCs|jdtkS(Ni(RAt _big_number(R((s./tmp/pip-install-0xiv62/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(R>R%tindext ValueErrorR<tminR?RB(Rt supportedt preferencesttag((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyR@s  cCs"|j|kstdƒ‚|jS(Nscontext mismatch(R&tAssertionErrorRC(Rtx((s./tmp/pip-install-0xiv62/wheel/wheel/install.pytsupports_current_python°scCsD|jjdƒt|jjdƒƒtd„|jDƒƒ|jfS(Ntnametvercss|] }| VqdS(N((t.0RK((s./tmp/pip-install-0xiv62/wheel/wheel/install.pys ¿s(R+R/R ttupleRAR#(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt _sort_key»scCs|j|jkS(N(R#(Rtother((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__eq__ÂscCs|j|jkS(N(R#(RRR((s./tmp/pip-install-0xiv62/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}.contextRMRN( R&t TypeErrortformatRQR+R/R RARtFalseR#(RRRtsntontsvtovtsctoc((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__lt__Ès(      $ cCs ||kS(N((RRR((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__gt__åscCs||kp||kS(N((RRR((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__le__èscCs||kp||kS(N((RRR((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt__ge__ëscCsYd}|jrd}nt|jr-|jn|j|ƒ}|jsU|j|ƒn|S(Ntrta(R%tVerifyingZipFileR$R#tverify(Rtmodetvzf((s./tmp/pip-install-0xiv62/wheel/wheel/install.pytzipfileòs  $ cCst|jj|jƒƒS(s+Parse wheel metadata (the .data/WHEEL file)(RRhtreadR4(R((s./tmp/pip-install-0xiv62/wheel/wheel/install.pytparsed_wheel_infoüscCsD|jd}ttt|jdƒƒƒtkr@tdƒ‚ndS(Ns Wheel-VersionR6sWheel version is too high(RjRPtmaptintR:tVERSION_TOO_HIGHRE(RR((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt check_versions $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? RM(R+R/R(RRM((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt install_pathss c sb‡‡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!tfilet=tsha256sUnsupported hash algorithmN(RRhtTruetstrictRR0tset_expected_hashRiRthashlibRµR•RRtKeyErrorRReRRVRštreadert splitlinestprintR‚tstderrR:RJRR (RRhtsigR2tsig_nametsmime_sig_nametrecordt record_digesttheaderstpayloadtmsgR»trowR#R²talgotdata((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyResB       N($RRRR3R"RRWRRR-tpropertyR0R1R2R4R;R>R?RARCR@RLRQRSRTR^R_R`RaRRhRjRnRoR±Re(((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyR Hs>             |RdcBsDeZdZdejed„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 completely read in order for its hash to be checked.RbcCsAtt|ƒj||||ƒt|_i|_tj|_dS(N( tsuperRdRRWR·t_expected_hashesR¹Rµt_hash_algorithm(RR³Rft compressiont allowZip64((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyRÂs  cCs||j|= 2.7)t_eofcsLˆ|ƒˆj|ƒˆjrHˆjƒˆkrHtdˆjƒ‚ndS(NsBad hash for file %r(tupdateRÐR•RRM(RÉ(t_update_crc_origteft expected_hasht running_hash(s./tmp/pip-install-0xiv62/wheel/wheel/install.pyt _update_crcås  csOˆ|d|ƒˆj|ƒ|rKˆjƒˆkrKtdˆjƒ‚ndS(NteofsBad hash for file %r(RÑR•RRM(RÉR×(RÒRÓRÔRÕ(s./tmp/pip-install-0xiv62/wheel/wheel/install.pyRÖës sNo expected hash for file %rN(RËRdR†t isinstanceRhtZipInfoR#RÌRRÖtAttributeErrortwarningstwarnRÍthasattrR·RRM(Rt name_or_infoRftpwdRMRÖ((RÒRÓRÔRÕs./tmp/pip-install-0xiv62/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( R$t RuntimeErrorR{tpopt NameToInfoR#tseekt header_offsetR'tSEEK_SETttruncateR¶t _didModify(Rtlast((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyRáõs    N( RRRRht ZIP_STOREDR¶RR¸RR†Rá(((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyRd½s  #(-Rt __future__RRšR¹tos.pathR'treRR‚RÛRhRxRtpathsRt pep425tagsRtpkginfoRtutilRRRRR R R tmaxsizeRBt NameErrortmaxintRmtcompiletVERBOSEtmatchR*R tobjectRRERR tZipFileRd(((s./tmp/pip-install-0xiv62/wheel/wheel/install.pyts8        4     ÿv