a  zeΛ@sdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl ZddlZddlZddlZddlmZddlZddlmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#ddl$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+dd l,m-Z-e.d Z/e.d ej0Z1e.d Z2e.d ej0j3Z4d5Z6gdZ7dZ8dZ9e9j:dj:ej;edZddZ?dBddZ@dCddZAdDddZBdedfd d!ZCd"d#ZDe.d$ej0ZEeDd%d&ZFGd'd(d(ZGGd)d*d*eGZHGd+d,d,eZIe.d-jJZKd.d/ZLd0d1ZMdEd2d3ZNd4d5ZOGd6d7d7ZPGd8d9d9e jQZRejSjTfd:d;ZUdd?ZWd@dAZXdS)Fz#PyPI and direct package downloadingNwraps) CHECKOUT_DIST Distribution BINARY_DISTnormalize_path SOURCE_DIST Environmentfind_distributions safe_name safe_version to_filename Requirement DEVELOP_DISTEGG_DIST)log)DistutilsError) translate)Wheelunique_everseenz^egg=([-A-Za-z0-9_.+!]+)$zhref\s*=\s*['"]?([^'"> ]+)z([^<]+)\n\s+\(md5\)z([-+.a-z0-9]{2,}):z.tar.gz .tar.bz2 .tar .zip .tgz) PackageIndexdistros_for_urlparse_bdist_wininstinterpret_distro_namezdS)zGenerate alternative interpretations of a source distro name Note: if `location` is a filesystem filename, you should call ``pkg_resources.normalize_path()`` on it before passing it to this routine! rIcss|]}td|VqdS)z py\d\.\d$N)rerD).0pr!r!r" z(interpret_distro_name..Nr3) py_versionrArS)r7anyrangerPrjoin)rJrQrFr^rArSr9rZr!r!r"rs $rcstfdd}|S)zs Wrap a function returning an iterable such that the resulting iterable only ever yields unique items. cst|i|SNr)argskwargsfuncr!r"wrapperszunique_values..wrapperr)rfrgr!rer" unique_valuessrhz(<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>c cst|D]d}|\}}tttj|d}d|vsDd|vr t |D]}t j |t |dVqNq dD]@}||}|dkrtt ||}|rtt j |t |dVqtdS)zEFind rel="homepage" and rel="download" links in `page`, yielding URLs,Zhomepager0r3)z Home PagezDownload URLr/N)RELfinditergroupssetmapstrstripr'r7HREFr4rurljoin htmldecoderEfindsearch)r8pagerDtagrelZrelsposr!r!r"find_external_linkss   rzc@s(eZdZdZddZddZddZdS) ContentCheckerzP A null content checker that defines the interface for checking content cCsdS)z3 Feed a block of data to the hash. Nr!selfblockr!r!r"feedszContentChecker.feedcCsdS)zC Check the hash. Return False if validation fails. Tr!r}r!r!r"is_validszContentChecker.is_validcCsdS)zu Call reporter with information about the checker (hash name) substituted into the template. Nr!)r}reportertemplater!r!r"reportszContentChecker.reportN)__name__ __module__ __qualname____doc__rrrr!r!r!r"r{sr{c@sBeZdZedZddZeddZddZ dd Z d d Z d S) HashCheckerzK(?Psha1|sha224|sha384|sha256|sha512|md5)=(?P[a-f0-9]+)cCs||_t||_||_dSrb) hash_namehashlibnewhashexpected)r}rrr!r!r"__init__s zHashChecker.__init__cCsBtj|d}|stS|j|}|s0tS|fi|S)z5Construct a (possibly null) ContentChecker from a URLr/)r4rr5r{patternru groupdict)clsr8r?rDr!r!r"from_urls zHashChecker.from_urlcCs|j|dSrb)rupdater|r!r!r"rszHashChecker.feedcCs|j|jkSrb)r hexdigestrrr!r!r"rszHashChecker.is_validcCs||j}||Srb)r)r}rrmsgr!r!r"rs zHashChecker.reportN) rrrrXcompilerr classmethodrrrrr!r!r!r"rs rcsDeZdZdZdLddZdMd d ZdNd d ZdOd dZddZddZ ddZ ddZ ddZ dPddZ ddZdQfdd Zdd Zd!d"Zd#d$Zd%d&Zd'd(ZdRd)d*ZdSd+d,Zd-d.Zd/Zd0d1Zd2d3ZdTd4d5Zd6d7Zd8d9Zd:d;Zdd?Z e!dUd@dAZ"dBdCZ#dDdEZ$dFdGZ%dHdIZ&dJdKZ'Z(S)Vrz;A distribution index that scans web pages for download URLshttps://pypi.org/simple/*NTcOsrtj|g|Ri||dd|d |_i|_i|_i|_td t t |j |_ g|_tjj|_dS)Nr.|)r rr( index_url scanned_urls fetched_urls package_pagesrXrrarnrrDallowsto_scanr4requesturlopenopener)r}rhostsZ ca_bundleZ verify_sslrckwr!r!r"rszPackageIndex.__init__Fc Cs||jvr|sdSd|j|<t|s2||dStt|}|r\||sPdS|d||sn|rn||jvrtt|j |dS||sd|j|<dS| d|d|j|<d}| |||}|durdSt |t jjr|jdkr| d|jd|j|j<d|jd d vr(|dS|j}|}t |tsvt |t jjrXd }n|jd phd }||d }|t|D](} t j|t| d} |!| q|"|j#rt$|dddkr|%||}dS)z.)filterrUr<rr itertoolsstarmap scan_egg_link)r} search_pathdirsZ egg_linksr!r!r"scan_egg_links|s zPackageIndex.scan_egg_linkscCsttj||&}ttdttj|}Wdn1s>0Yt |dkrXdS|\}}t tj||D]*}tjj|g|R|_ t |_ ||qrdS)Nr])openrUr<rarrrnrorprPr rJrrAr)r}r<rZ raw_lineslinesZegg_pathZ setup_pathrGr!r!r"rs4 zPackageIndex.scan_egg_linkcCsd}||js|Stttjj|t|jdd}t|dksRd|dvrV|St |d}t |d}d|j | i|<t|t|fS)N)NNr.r]r2r3rT)r)rrrnr4rr6rPr7r r r setdefaultr'r )r}rZNO_MATCH_SENTINELr9pkgverr!r!r"_scans   zPackageIndex._scanc Cst|D]:}z"|tj|t|dWq tyBYq 0q ||\}}|s\dSt ||D]H}t |\}}| dr|s|r|d||f7}n | || |qftdd|S)z#Process the contents of a PyPI pager3r.pyz #egg=%s-%scSsd|dddS)Nz%sr3r])rE)mr!r!r"r\z,PackageIndex.process_index..)rqrkrr4rrrrsrErrzr@r(need_version_infoscan_urlPYPI_MD5sub) r}r8rvrDrrnew_urlr+fragr!r!r"rs$"    zPackageIndex.process_indexcCs|d|dS)NzPPage at %s links to .py file(s) without version info; an index scan is required.)scan_allr}r8r!r!r"rszPackageIndex.need_version_infocGs<|j|jvr,|r"|j|g|R|d||jdS)Nz6Scanning index of all packages (this may take a while))rrrrrr}rrcr!r!r"rs zPackageIndex.scan_allcCsz||j|jd|j|js:||j|jd|j|jsR||t|j|jdD]}||qfdS)Nr.r!) rr unsafe_namerrkeyrKnot_found_in_indexr)r} requirementr8r!r!r" find_packagess zPackageIndex.find_packagescsR|||||jD]"}||vr0|S|d||qtt|||S)Nz%s does not match %s)prescanrrrsuperrobtain)r}r installerrG __class__r!r"rs zPackageIndex.obtaincCsL||jd||sH|t|td|jjtj |fdS)z- checker is a ContentChecker zValidating %%s checksum for %sz7%s validation failed for %s; possible download problem?N) rrrrrUunlinkrrr*r<rQ)r}checkerrVtfpr!r!r" check_hashs zPackageIndex.check_hashcCsN|D]D}|jdus0t|r0|ds0tt|r<||q|j|qdS)z;Add `urls` to the list that will be prescanned for searchesNfile:)rrr)rrrappend)r}urlsr8r!r!r"add_find_linkss  zPackageIndex.add_find_linkscCs"|jrtt|j|jd|_dS)z7Scan urls scheduled for prescanning (e.g. --find-links)N)rrrnrrr!r!r"r szPackageIndex.prescancCs<||jr|jd}}n |jd}}|||j|dS)Nz#Couldn't retrieve index page for %rz3Couldn't find index page for %r (maybe misspelled?))rrrrr)r}rmethrr!r!r"rs  zPackageIndex.not_found_in_indexcCs~t|tsjt|}|rR||d||}t|\}}|drN||||}|Stj |rb|St |}t | ||ddS)aLocate and/or download `spec` to `tmpdir`, returning a local path `spec` may be a ``Requirement`` object, or a string containing a URL, an existing local filename, or a project/version requirement spec (i.e. the string form of a ``Requirement`` object). If it is the URL of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is automatically created alongside the downloaded file. If `spec` is a ``Requirement`` object or a string containing a project/version requirement spec, this method returns the location of a matching distribution (possibly after downloading it to `tmpdir`). If `spec` is a locally existing file or directory name, it is simply returned unchanged. If `spec` is a URL, it is downloaded to a subpath of `tmpdir`, and the local filename is returned. Various errors may be raised if a problem occurs during downloading. r3rrJN)rrr _download_urlrEr@r( gen_setuprUr<rr#rfetch_distribution)r}rtmpdirr:foundr+r?r!r!r"r0s    zPackageIndex.downloadc sd|id}d fdd }|rH|||}|s^|dur^|||}|durjdurx||}|dur|s|||}|durdrdpd|nd||j|jd SdS) a|Obtain a distribution suitable for fulfilling `requirement` `requirement` must be a ``pkg_resources.Requirement`` instance. If necessary, or if the `force_scan` flag is set, the requirement is searched for in the (online) package index as well as the locally installed packages. If a distribution matching `requirement` is found, the returned distribution's ``location`` is the value you would have gotten from calling the ``download()`` method with the matching distribution's URL or filename. If no matching distribution is found, ``None`` is returned. If the `source` flag is set, only source distributions and source checkout links will be considered. Unless the `develop_ok` flag is set, development and system eggs (i.e., those using the ``.egg-info`` format) will be ignored. zSearching for %sNcs|dur }||jD]v}|jtkrFsF|vrd|d|<q||vo\|jtkp\ }|r|j}||_tj |jr|SqdS)Nz&Skipping development or system egg: %sr3) rrArrrr0rJdownload_locationrUr<r)reqenvrGtestloc develop_okr}skippedsourcerr!r"rtUs$z-PackageIndex.fetch_distribution..findz:No local packages or working download links found for %s%sza source distribution of rzBest match: %s)rJ)N)rrrrrcloner) r}rr force_scanrrZ local_indexrGrtr!r r"r=s2         zPackageIndex.fetch_distributioncCs"|||||}|dur|jSdS)a3Obtain a file suitable for fulfilling `requirement` DEPRECATED; use the ``fetch_distribution()`` method now instead. For backward compatibility, this routine is identical but returns the ``location`` of the downloaded distribution instead of a distribution object. N)rrJ)r}rrrrrGr!r!r"fetchszPackageIndex.fetchc Cst|}|r*ddt||ddDp,g}t|dkrtj|}tj||krtj ||}ddl m }|||st |||}ttj |dd<} | d|dj|djtj|dfWdn1s0Y|S|rtd ||fntd dS) NcSsg|]}|jr|qSr!)rL)rYdr!r!r" sz*PackageIndex.gen_setup..r3r)samefilezsetup.pywzIfrom setuptools import setup setup(name=%r, version=%r, py_modules=[%r]) zCan't unambiguously interpret project/version identifier %r; any dashes in the name or version should be escaped using underscores. %rzpCan't process plain .py files without an '#egg=name-version' suffix to enable automatic setup script generation.)rCrDrrErPrUr<rQdirnameraZsetuptools.command.easy_installrshutilcopy2rwriterKrLsplitextr) r}rVr?rrDrrQdstrrr!r!r"rs@       "zPackageIndex.gen_setupi c Cs:|d|d}zt|}||}t|tjjrLtd||j |j f|}d}|j }d}d|vr| d} t tt| }||||||t|d`} ||} | r|| | | |d7}||||||qqq|||| Wdn1s0Y|W|r"|Sn|r4|0dS) NzDownloading %szCan't download %s: %s %srr/zcontent-lengthzContent-Lengthwbr3)rrrrrr4rrrrr dl_blocksizeget_allmaxrnint reporthookrrrrrr) r}r8rVfprrblocknumbssizesizesrr~r!r!r" _download_tosD        .zPackageIndex._download_tocCsdSrbr!)r}r8rVr%Zblksizer'r!r!r"r#szPackageIndex.reporthookc Cs|drt|Szt||jWSttjjfy}zHddd|j D}|r`| ||nt d||f|WYd}~n*d}~0t j jy}z|WYd}~Sd}~0t j jy}z4|r| ||jnt d||jf|WYd}~nd}~0tjjyT}z6|r,| ||jnt d||jf|WYd}~n^d}~0tjjtj fy}z2|r| ||nt d||f|WYd}~n d}~00dS)Nr cSsg|] }t|qSr!)ro)rYargr!r!r"rr\z)PackageIndex.open_url..z%s %szDownload error for %s: %sz;%s returned a bad status line. The server might be down, %s)r) local_openopen_with_authrrhttpclient InvalidURLrarcrrr4rrURLErrorreason BadStatusLineline HTTPExceptionsocket)r}r8warningvrr!r!r"rsJ (zPackageIndex.open_urlcCst|\}}|r0d|vr4|dddd}qnd}|drJ|dd}tj||}|dksj|d rv|||S|d ks|d r|||S|d r| ||S|d krt j t j |dS||d|||SdS)Nz...\_Z__downloaded__rHr&svnzsvn+gitzgit+zhg+rr]T)r@replacer(rUr<rar) _download_svn _download_git _download_hgr4r url2pathnamerr5r_attempt_download)r}r:r8rr*r?rVr!r!r"r s$        zPackageIndex._download_urlcCs||ddS)NT)rrr!r!r"r)szPackageIndex.scan_urlcCs6|||}d|ddvr.||||S|SdS)Nrrr)r)rr'_download_html)r}r8rVrr!r!r"rC,s zPackageIndex._attempt_downloadcCsnt|}|D]>}|r td|rF|t||||SqLq |t|td|dS)Nz ([^- ]+ - )?Revision \d+:zUnexpected HTML page found at ) r���rp���rX���ru���r���rU���r���r?��r���)r}���r8���r���rV���r���r4��r!���r!���r"���rD��3��s����   zPackageIndex._download_htmlc�����������������C���s��t�dt�|ddd�}d}|�drd|v�rtj|\}}}}}} |s|drd |d d��v�r|d d��d d\}}t |\} } | rd | v�r| d d\} } d | | f�}nd | �}| }|||||| f}tj |}|� d||�t d|||f��|S�)Nz"SVN download support is deprecatedr2���r3���r���r���zsvn:@z//r.���r]���:z --username=%s --password=%sz --username=z'Doing subversion checkout from %s to %szsvn checkout%s -q %s %s)warningsr��� UserWarningr7���r'���r)���r4���r���r5��� _splituser urlunparser���rU���system)r}���r8���rV���credsr:���netlocr<���rZ���qr���authhostuserpwr9���r!���r!���r"���r?��B��s&����   zPackageIndex._download_svnc�����������������C���sp���t�j|�\}}}}}|ddd�}|ddd�}d�}d|v�rR|dd\}}t�j||||df}�|�|fS�)N+r3���r/���r2���r���rE��r���)r4���r���urlsplitr7���rsplit urlunsplit)r8��� pop_prefixr:���rM��r<���r>���r���revr!���r!���r"���_vcs_split_rev_from_urlX��s����z$PackageIndex._vcs_split_rev_from_urlc�����������������C���sl���|�ddd�}|�j|dd\}}|�d||�td||f��|d�urh|�d|�td ||f��|S�) Nr2���r3���r���TrW��zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %szgit -C %s checkout --quiet %sr7���rY��r���rU���rK��r}���r8���rV���rX��r!���r!���r"���r@��j��s���� zPackageIndex._download_gitc�����������������C���sl���|�ddd�}|�j|dd\}}|�d||�td||f��|d�urh|�d|�td ||f��|S�) Nr2���r3���r���TrZ��zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %szhg --cwd %s up -C -r %s -qr[��r\��r!���r!���r"���rA��z��s���� zPackageIndex._download_hgc�����������������G���s���t�j|g|R���d�S�rb���)r���r���r���r!���r!���r"���r�����s����zPackageIndex.debugc�����������������G���s���t�j|g|R���d�S�rb���)r���r���r���r!���r!���r"���r�����s����zPackageIndex.infoc�����������������G���s���t�j|g|R���d�S�rb���)r���r���r���r!���r!���r"���r�����s����zPackageIndex.warn)r���r���NT)F)F)F)N)N)FFFN)FF)N)F))r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r���r��r���r���r0���r��r��r��r��r)��r#��r���r��r���rC��rD��r?�� staticmethodrY��r@��rA��r���r���r��� __classcell__r!���r!���r���r"���r�����sR�����  5      #�� L )$ # r���z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c�����������������C���s���|��d}t|S�)Nr���)rE���r���unescape)rD���whatr!���r!���r"��� decode_entity��s���� ra��c�����������������C���s ���t�t|�S�)a�� Decode HTML entities in the given text. >>> htmldecode( ... 'https://../package_name-0.1.2.tar.gz' ... '?tokena=A&tokenb=B">package_name-0.1.2.tar.gz') 'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz' ) entity_subra��)textr!���r!���r"���rs�����s���� rs���c��������������������s����fdd}|S�)Nc��������������������s����fdd}|S�)Nc��������������� ������s>���t��}t��z�|�i�|W�t�|�S�t�|�0�d�S�rb���)r6��getdefaulttimeoutsetdefaulttimeout)rc���rd���Z old_timeout)rf���timeoutr!���r"���_socket_timeout��s����  z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr!���)rf���rg��rf��re���r"���rg����s����z'socket_timeout.<locals>._socket_timeoutr!���)rf��rg��r!���rh��r"���socket_timeout��s���� ri��c�����������������C���s2���t�j|�}|�}t|}|�}|ddS�)a9�� Encode auth from a URL suitable for an HTTP header. >>> str(_encode_auth('username%3Apassword')) 'dXNlcm5hbWU6cGFzc3dvcmQ=' Long auth strings should not cause a newline to be inserted. >>> long_auth = 'username:' + 'password'*10 >>> chr(10) in str(_encode_auth(long_auth)) False  r���)r4���r���r6���encodebase64 b64encoder���r>��)rO��Zauth_sZ auth_bytesZ encoded_bytesencodedr!���r!���r"��� _encode_auth��s ����  ro��c�������������������@���s(���e�Zd�ZdZdd�Zdd�Zdd�ZdS�) Credentialz: A username/password pair. Use like a namedtuple. c�����������������C���s���||�_�||�_d�S�rb���usernamepassword)r}���rr��rs��r!���r!���r"���r�����s����zCredential.__init__c�����������������c���s���|�j�V��|�jV��d�S�rb���rq��r���r!���r!���r"���__iter__��s����zCredential.__iter__c�����������������C���s ���dt�|��S�)Nz%(username)s:%(password)s)varsr���r!���r!���r"���__str__��s����zCredential.__str__N)r���r���r���r���r���rt��rv��r!���r!���r!���r"���rp����s���rp��c�������������������@���s0���e�Zd�Zdd�Zedd�Zdd�Zdd�Zd S�) PyPIConfigc�����������������C���sN���t�g�dd}tj|�|�tjtjdd}tj |rJ|� |�dS�)z% Load from ~/.pypirc )rr��rs�� repositoryr���~z.pypircN) dictfromkeys configparserRawConfigParserr���rU���r<���ra��� expanduserr���r���)r}���defaultsrcr!���r!���r"���r�����s ���� zPyPIConfig.__init__c��������������������s&����fdd���D�}tt�j|S�)Nc��������������������s ���g�|�]}��|d��r|qS�)rx��)r���rp���)rY���sectionr���r!���r"���r����s���z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)sectionsrz��rn���_get_repo_cred)r}���Zsections_with_repositoriesr!���r���r"���creds_by_repository��s���� zPyPIConfig.creds_by_repositoryc�����������������C���s6���|��|d�}|t|��|d�|��|d�fS�)Nrx��rr��rs��)r���rp���rp��)r}���r��repor!���r!���r"���r����s ����zPyPIConfig._get_repo_credc�����������������C���s*���|�j��D�]\}}||r |��S�q dS�)z If the URL indicated appears to be a repository defined in this config, return the credential for that repository. N)r��itemsr)���)r}���r8���rx��credr!���r!���r"���find_credential��s���� zPyPIConfig.find_credentialN)r���r���r���r���propertyr��r��r��r!���r!���r!���r"���rw����s ���  rw��c�����������������C���s@��t�j|�}|\}}}}}}|dr2tjd|dv�rHt|\} } nd} | st� |�} | rt | } | j |�f} t j dg| R���| rdt| �} || ||||f} t�j| }t�j|}|d| �n t�j|�}|dt�||}| r<t�j|j\}}}}}}||kr<|| kr<||||||f} t�j| |_|S�) z4Open a urllib2 request, handling HTTP authenticationrF��znonnumeric port: '')r.��httpsNz*Authenticating as %s for %s (from .pypirc)zBasic Authorizationz User-Agent)r4���r���r5���r(���r.��r/��r0��rI��rw��r��ro���rr��r���r���ro��rJ��r���Request add_header user_agentr8���)r8���r���parsedr:���rM��r<���paramsr>���r���rO��addressr��r���r9���r���r���r$��s2h2Zpath2Zparam2Zquery2Zfrag2r!���r!���r"���r-����s8����          r-��c�����������������C���s ���|��d\}}}�|r|nd|�fS�)zNsplituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.rE��N) rpartition)rP��rQ��delimr!���r!���r"���rI��4��s����rI��c�����������������C���s���|�S�rb���r!���)r8���r!���r!���r"��� fix_sf_url?��s����r��c�������������� ���C���s,��t�j|�\}}}}}}t�j|}tj|r<t�j|�S�| drtj |rg�}t |D�]x} tj || } | dkrt | d} | �} W�d���n1�s0����Y���qntj | r| d7�} |dj| d�q`d} | j|�d |d } d \}}n d \}}} d d i}t| }t�j|�||||S�)z7Read a local path, with special support for directoriesr.���z index.htmlrNz<a href="{name}">{name}</a>)r*���zB<html><head><title>{url}{files}rj)r8files)OK)rzPath not foundz Not foundrz text/html)r4rr5rrBrUr<isfilerr(rrrarrrformatioStringIOrr)r8r:r;r<paramr>rrVrrfilepathr$bodyrstatusmessagerZ body_streamr!r!r"r,Cs.    &    r,)N)N)N)r)YrsysrUrXrrr6rlrrrGr|r http.clientr. urllib.parser4urllib.request urllib.error functoolsrr pkg_resourcesrrrrrr r r r r rrr distutilsrdistutils.errorsrfnmatchrZsetuptools.wheelrZ setuptools.extern.more_itertoolsrrrCIrqrrDrr7rO__all__Z_SOCKET_TIMEOUTZ_tmplr version_inforr#rr@rrBrWrrhrjrzr{rrrrbrarsrirorpr}rwrrr-rIrr,r!r!r!r"s <          !  #  !  &/