a
    ʿd                     @   s  d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlZddlmZ ddlZddlmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+ dd	l,m-Z- e.d
Z/e.dej0Z1e.dZ2e.dej0j3Z4d5 Z6g dZ7dZ8dZ9e9j:dj:ej; edZ<dd Z=dd Z>dd Z?dBddZ@dCddZAdDddZBdedfd d!ZCd"d# ZDe.d$ej0ZEeDd%d& ZFG d'd( d(ZGG d)d* d*eGZHG d+d, d,eZIe.d-jJZKd.d/ ZLd0d1 ZMdEd2d3ZNd4d5 ZOG d6d7 d7ZPG d8d9 d9e
jQZRejSjTfd:d;ZUd<d= ZVeNe8eUZUd>d? ZWd@dA ZXdS )Fz$PyPI and direct package downloading.    Nwraps)CHECKOUT_DISTDistributionBINARY_DISTnormalize_pathSOURCE_DISTEnvironmentfind_distributions	safe_namesafe_versionto_filenameRequirementDEVELOP_DISTEGG_DISTparse_version)logDistutilsError)	translate)Wheelunique_everseenz^egg=([-A-Za-z0-9_.+!]+)$zhref\s*=\s*['"]?([^'"> ]+)z<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)href="[^?]+\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\)z([-+.a-z0-9]{2,}):z.tar.gz .tar.bz2 .tar .zip .tgz)PackageIndexdistros_for_urlparse_bdist_wininstinterpret_distro_name   z<setuptools/{setuptools.__version__} Python-urllib/{py_major}z{}.{})Zpy_major
setuptoolsc              
   C   sF   zt | W S  ty@ } ztd| f |W Y d }~n
d }~0 0 d S )Nz1Not a URL, existing file, or requirement spec: %r)r   parse
ValueErrorr   )spece r#   7lib/python3.9/site-packages/setuptools/package_index.pyparse_requirement_argD   s    r%   c                 C   s   |   }d\}}}|dr|dr8| dd }d}nn|ddrb| d	d
 }| dd }d}nD|dr~| dd }d}n(|ddr| d	d
 }| dd }d}|||fS )z=Return (base,pyversion) or (None,None) for possible .exe name)NNN.exez
.win32.exeNiZwin32z	.win32-pyiiz.win-amd64.exeiz	win-amd64z.win-amd64-pyi)lowerendswith
startswith)namer(   basepy_verZplatr#   r#   r$   r   M   s$    



r   c           	      C   sx   t j| }|\}}}}}}t j|dd }|dkrX|dkrXt j|dd }d|v rp|dd\}}||fS )N/zsourceforge.netdownload#   )urllibr   urlparseunquotesplit)	urlpartsschemeserverpath
parametersqueryfragmentr,   r#   r#   r$   egg_info_for_urle   s    r@   c                 c   s\   t | \}}t| ||D ]
}|V  q|rXt|}|rXt| |d|tdD ]
}|V  qLdS )zEYield egg or source distribution objects that might be found at a URLr3   )
precedenceN)r@   distros_for_locationEGG_FRAGMENTmatchr   groupr   )r8   metadatar,   r?   distrD   r#   r#   r$   r   p   s    

r   c                 C   s   | dr|dd }| dr8d|v r8t| ||gS | drxd|v rxt|}| s^g S t| |j|jtd dgS | d	rt|\}}}|durt	| |||t
|S tD ]0}| |r|dt|  }t	| ||  S qg S )
z:Yield egg or source distribution objects based on basename.egg.zipNr'   z.egg-z.whlr3   )locationproject_nameversionrA   r&   )r)   r   Zfrom_locationr   Zis_compatiblerK   rL   r   r   r   r   
EXTENSIONSlen)rJ   basenamerF   ZwheelZwin_baser-   platformZextr#   r#   r$   rB   ~   s4    
	

rB   c                 C   s   t t| tj| |S )zEYield possible egg or source distribution objects based on a filename)rB   r   osr<   rO   )filenamerF   r#   r#   r$   distros_for_filename   s    rS   c              	   c   s   | d}|s,tdd |dd D r,dS tt|D ]}|| dd  r8 q^q8t|}t| |d|d| d||d |||dV  dS )zGenerate the interpretation 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!
    rI   c                 s   s   | ]}t d |V  qdS )z	py\d\.\d$N)rerD   ).0pr#   r#   r$   	<genexpr>       z(interpret_distro_name.<locals>.<genexpr>   Nr3   )
py_versionrA   rP   )r7   anyrangerN   isdigitr   join)rJ   rO   rF   rZ   rA   rP   r9   rV   r#   r#   r$   r      s     

r   c                    s   t   fdd}|S )zs
    Wrap a function returning an iterable such that the resulting iterable
    only ever yields unique items.
    c                     s   t  | i |S Nr   )argskwargsfuncr#   r$   wrapper   s    zunique_values.<locals>.wrapperr   )rc   rd   r#   rb   r$   unique_values   s    re   z3<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>c              	   c   s   t |D ]d}| \}}tttj| d}d|v sDd|v r
t	|D ]}t
j| t|dV  qNq
dD ]@}||}|dkrtt	||}|rtt
j| t|dV  qtdS )zEFind rel="homepage" and rel="download" links in `page`, yielding URLs,Zhomepager0   r3   )z<th>Home Pagez<th>Download URLr/   N)RELfinditergroupssetmapstrstripr(   r7   HREFr4   r   urljoin
htmldecoderE   findsearch)r8   pagerD   tagZrelZrelsposr#   r#   r$   find_external_links   s    
rv   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	ContentCheckerzP
    A null content checker that defines the interface for checking content
    c                 C   s   dS )z3
        Feed a block of data to the hash.
        Nr#   selfblockr#   r#   r$   feed   s    zContentChecker.feedc                 C   s   dS )zC
        Check the hash. Return False if validation fails.
        Tr#   ry   r#   r#   r$   is_valid   s    zContentChecker.is_validc                 C   s   dS )zu
        Call reporter with information about the checker (hash name)
        substituted into the template.
        Nr#   )ry   reportertemplater#   r#   r$   report  s    zContentChecker.reportN)__name__
__module____qualname____doc__r{   r}   r   r#   r#   r#   r$   rw      s   rw   c                   @   sB   e Zd ZedZdd Zedd Zdd Z	dd	 Z
d
d ZdS )HashCheckerzK(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)=(?P<expected>[a-f0-9]+)c                 C   s   || _ t|| _|| _d S r_   )	hash_namehashlibnewhashexpected)ry   r   r   r#   r#   r$   __init__  s    zHashChecker.__init__c                 C   sB   t j|d }|st S | j|}|s0t S | f i | S )z5Construct a (possibly null) ContentChecker from a URLr/   )r4   r   r5   rw   patternrr   	groupdict)clsr8   r?   rD   r#   r#   r$   from_url  s    zHashChecker.from_urlc                 C   s   | j | d S r_   )r   updaterx   r#   r#   r$   r{     s    zHashChecker.feedc                 C   s   | j  | jkS r_   )r   Z	hexdigestr   r|   r#   r#   r$   r}   "  s    zHashChecker.is_validc                 C   s   || j  }||S r_   )r   )ry   r~   r   msgr#   r#   r$   r   %  s    
zHashChecker.reportN)r   r   r   rT   compiler   r   classmethodr   r{   r}   r   r#   r#   r#   r$   r   	  s   

r   c                       sT  e Zd ZdZdN fdd	Z fdd	ZdOddZdPddZdQddZdd Z	dd Z
dd Zdd Zdd ZdRddZdd ZdS fdd 	Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* ZdTd+d,ZdUd-d.Zd/d0 Zd1Zd2d3 Zd4d5 ZdVd6d7Zd8d9 Zd:d; Zd<d= Zd>d? Z d@dA Z!e"dWdBdCZ#dDdE Z$dFdG Z%dHdI Z&dJdK Z'dLdM Z(  Z)S )Xr   z;A distribution index that scans web pages for download URLshttps://pypi.org/simple/*NTc                    sl   t  j|i | |dd |d   | _i | _i | _i | _td	t
t|j| _g | _tjj| _d S )Nr.   |)superr   r)   	index_urlscanned_urlsfetched_urlspackage_pagesrT   r   r^   rk   r   rD   allowsto_scanr4   requesturlopenopener)ry   r   ZhostsZ	ca_bundleZ
verify_sslr`   kw	__class__r#   r$   r   -  s    	zPackageIndex.__init__c                    s0   zt |j W n ty"   Y d S 0 t |S r_   )r   rL   	Exceptionr   add)ry   rG   r   r#   r$   r   ?  s
    zPackageIndex.addFc                 C   s  t drtd| || jv r(|s(dS d| j|< t|sH| | dS tt|}|rr| |sfdS | 	d| |s|r|| j
v rtt| j| dS | |sd| j
|< dS | d| d| j
|< d}| ||| }|du rdS t|tjjr|jdkr| d	|j  d| j
|j< d
|jdd vrB|  dS |j}| }t|tst|tjjrrd}n|jdpd}||d}|  t|D ](}	tj !|t"|	#d}
| $|
 q|%| j&rt'|dddkr| (||}dS )z<Evaluate a URL as a possible download, and maybe retrieve itZCONDA_BUILDzkSetuptools downloading is disabled in conda build. Be sure to add all dependencies in the meta.yaml  url=%sNTzFound link: %sz
Reading %sz<Download error on %s: %%s -- Some packages may not be found!i  zAuthentication error: %shtmlcontent-type zlatin-1charsetignorer3   code  ))rQ   getenvRuntimeErrorr   
URL_SCHEMEprocess_filenamelistr   url_okdebugr   rk   r   infoopen_url
isinstancer4   error	HTTPErrorr   r   r8   headersgetr(   closereadrl   Z	get_paramdecodern   rh   r   ro   rp   rE   process_urlr*   r   getattrprocess_index)ry   r8   Zretrievediststmplfr,   rs   r   rD   linkr#   r#   r$   r   H  s\    






 zPackageIndex.process_urlc                 C   s   t j|s| d| d S t j|r^|s^t j|}t |D ]}| t j||d qBt	|}|r| 
d| tt| j| d S )NzNot found: %sTz	Found: %s)rQ   r<   existswarnisdirrealpathlistdirr   r^   rS   r   r   rk   r   )ry   fnnestedr<   itemr   r#   r#   r$   r     s    zPackageIndex.process_filenamec                 C   sb   t |}|o|d dk}|s8| tj|d r<dS d}|rRt|| n| || d S )Nr3   fileTz
Note: Bypassing %s (disallowed host; see https://setuptools.pypa.io/en/latest/deprecated/easy_install.html#restricting-downloads-with-allow-hosts for details).
)	r   rE   r(   r   r4   r   r5   r   r   )ry   r8   Zfatalsis_filer   r#   r#   r$   r     s    zPackageIndex.url_okc                 C   s2   t tjj|}dd |D }tt| j| d S )Nc                 s   s0   | ](}t |D ]}|d r||fV  qqdS )z	.egg-linkN)rQ   r   r)   )rU   r<   entryr#   r#   r$   rW     s   
z.PackageIndex.scan_egg_links.<locals>.<genexpr>)filterrQ   r<   r   r   	itertoolsstarmapscan_egg_link)ry   search_pathdirsZ	egg_linksr#   r#   r$   scan_egg_links  s
    zPackageIndex.scan_egg_linksc                 C   s   t tj||&}ttd ttj|}W d    n1 s>0    Y  t	|dkrXd S |\}}t
tj||D ]*}tjj|g|R  |_t|_| | qrd S )NrY   )openrQ   r<   r^   r   r   rk   rl   rm   rN   r
   rJ   r   rA   r   )ry   r<   r   Z	raw_lineslinesZegg_pathZ
setup_pathrG   r#   r#   r$   r     s    4zPackageIndex.scan_egg_linkc                 C   s   d}| | js|S tttjj|t| jd  d}t|dksRd|d v rV|S t	|d }t
|d }d| j| i |< t|t|fS )N)NNr.   rY   r2   r3   r   T)r*   r   r   rk   r4   r   r6   rN   r7   r   r   r   
setdefaultr(   r   )ry   r   ZNO_MATCH_SENTINELr9   pkgverr#   r#   r$   _scan  s    &zPackageIndex._scanc           	   
   C   s   t |D ]:}z"| tj|t|d W q
 tyB   Y q
0 q
| |\}}|s\dS t	||D ]H}t
|\}}|dr|s|r|d||f 7 }n
| | | | qftdd |S )z#Process the contents of a PyPI pager3   r   .pyz
#egg=%s-%sc                 S   s   d|  ddd S )Nz<a href="%s#md5=%s">%s</a>r3      rY   )rE   )mr#   r#   r$   <lambda>  rX   z,PackageIndex.process_index.<locals>.<lambda>)rn   rh   r   r4   r   ro   rp   rE   r    rv   r@   r)   need_version_infoscan_urlPYPI_MD5sub)	ry   r8   rs   rD   r   r   new_urlr,   fragr#   r#   r$   r     s$    "
zPackageIndex.process_indexc                 C   s   |  d| d S )NzPPage at %s links to .py file(s) without version info; an index scan is required.)scan_allry   r8   r#   r#   r$   r     s    zPackageIndex.need_version_infoc                 G   s<   | j | jvr,|r"| j|g|R   | d | | j  d S )Nz6Scanning index of all packages (this may take a while))r   r   r   r   r   ry   r   r`   r#   r#   r$   r     s
    
zPackageIndex.scan_allc                 C   sz   |  | j|j d  | j|js:|  | j|j d  | j|jsR| | t| j|jdD ]}|  | qfd S )Nr.   r#   )	r   r   unsafe_namer   r   keyrK   not_found_in_indexr   )ry   requirementr8   r#   r#   r$   find_packages  s    
zPackageIndex.find_packagesc                    sR   |    | | | |j D ]"}||v r0|  S | d|| qtt| ||S )Nz%s does not match %s)prescanr   r   r   r   r   obtain)ry   r   Z	installerrG   r   r#   r$   r     s    
zPackageIndex.obtainc                 C   sL   | | jd|  | sH|  t| td|jjtj	
|f dS )z-
        checker is a ContentChecker
        zValidating %%s checksum for %sz7%s validation failed for %s; possible download problem?N)r   r   r}   r   rQ   unlinkr   r   r+   r<   rO   )ry   checkerrR   tfpr#   r#   r$   
check_hash  s    
zPackageIndex.check_hashc                 C   sN   |D ]D}| j du s0t|r0|ds0tt|r<| | q| j | qdS )z;Add `urls` to the list that will be prescanned for searchesNfile:)r   r   r*   r   r   r   append)ry   Zurlsr8   r#   r#   r$   add_find_links  s    
zPackageIndex.add_find_linksc                 C   s"   | j rtt| j| j  d| _ dS )z7Scan urls scheduled for prescanning (e.g. --find-links)N)r   r   rk   r   r|   r#   r#   r$   r   *  s    zPackageIndex.prescanc                 C   s<   | |j  r| jd }}n| jd }}|||j |   d S )Nz#Couldn't retrieve index page for %rz3Couldn't find index page for %r (maybe misspelled?))r   r   r   r   r   )ry   r   methr   r#   r#   r$   r   0  s    
zPackageIndex.not_found_in_indexc                 C   s~   t |tsjt|}|rR| |d||}t|\}}|drN| |||}|S tj	
|rb|S t|}t| ||ddS )a  Locate 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.
        r3   r   rJ   N)r   r   r   _download_urlrE   r@   r)   	gen_setuprQ   r<   r   r%   r   fetch_distribution)ry   r!   tmpdirr:   foundr,   r?   r#   r#   r$   r0   ;  s    

zPackageIndex.downloadc           	         s    d| i d}d
 fdd	}|rH  | ||}|s^|dur^|||}|du rjdurx  ||}|du r|s| ||}|du rdrdpd| n d| |j|jd	S dS )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.
        zSearching for %sNc                    s   |d u r}|| j  D ]v}|jtkrF sF|vrd| d|< q|| v o\|jtkp\ }|r|j}||_tj	
|jr|  S qd S )Nz&Skipping development or system egg: %sr3   )r   rA   r   r   r   r0   rJ   download_locationrQ   r<   r   )ZreqenvrG   testZloc
develop_okry   Zskippedsourcer   r#   r$   rq   {  s"    z-PackageIndex.fetch_distribution.<locals>.findz:No local packages or working download links found for %s%sza source distribution of r   zBest match: %s)rJ   )N)r   r   r   r   r   Zcloner   )	ry   r   r   
force_scanr  r  Zlocal_indexrG   rq   r#   r  r$   r   ]  s2    




zPackageIndex.fetch_distributionc                 C   s"   |  ||||}|dur|jS dS )a3  Obtain 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)r   rJ   )ry   r   r   r  r  rG   r#   r#   r$   fetch  s    zPackageIndex.fetchc           	   	   C   s  t |}|r*dd t||dd D p,g }t|dkrtj|}tj||krtj	||}tj
|r~tj||st|| |}ttj	|dd<}|d|d j|d jtj|d f  W d    n1 s0    Y  |S |r
td||f ntd	d S )
Nc                 S   s   g | ]}|j r|qS r#   )rL   )rU   dr#   r#   r$   
<listcomp>  s   z*PackageIndex.gen_setup.<locals>.<listcomp>r3   zsetup.pywzIfrom setuptools import setup
setup(name=%r, version=%r, py_modules=[%r])
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.)rC   rD   r   rE   rN   rQ   r<   rO   dirnamer^   r   samefileshutilZcopy2r   writerK   rL   splitextr   )	ry   rR   r?   r   rD   r   rO   Zdstr   r#   r#   r$   r     sD    

"	zPackageIndex.gen_setupi    c                 C   s:  |  d| d }zt|}| |}t|tjjrLtd||j	|j
f |  }d}| j}d}d|v r|d}	ttt|	}| ||||| t|d`}
||}|r|| |
| |d7 }| ||||| qqq| |||
 W d    n1 s0    Y  |W |r"|  S n|r4|  0 d S )	NzDownloading %szCan't download %s: %s %sr   r/   zcontent-lengthzContent-Lengthwbr3   )r   r   r   r   r   r4   r   r   r   r   r   dl_blocksizeZget_allmaxrk   int
reporthookr   r   r{   r  r   r   )ry   r8   rR   fpr   r   blocknumZbssizeZsizesr   rz   r#   r#   r$   _download_to  sD    





. zPackageIndex._download_toc                 C   s   d S r_   r#   )ry   r8   rR   r  Zblksizer  r#   r#   r$   r    s    zPackageIndex.reporthookc              
   C   s  | drt|S zt|| jW S  ttjjfy } zHddd |j	D }|r`| 
|| ntd||f |W Y d }~n*d }~0  tjjy } z|W  Y d }~S d }~0  tjjy } z4|r| 
||j ntd||jf |W Y d }~nd }~0  tjjyT } z6|r,| 
||j ntd||jf |W Y d }~n^d }~0  tjjtjfy } z2|r| 
|| ntd||f |W Y d }~n
d }~0 0 d S )Nr    c                 S   s   g | ]}t |qS r#   )rl   )rU   argr#   r#   r$   r	    rX   z)PackageIndex.open_url.<locals>.<listcomp>z%s %szDownload error for %s: %sz;%s returned a bad status line. The server might be down, %s)r*   
local_openopen_with_authr   r    httpclient
InvalidURLr^   r`   r   r   r4   r   r   ZURLErrorreasonZBadStatusLinelineZHTTPExceptionsocket)ry   r8   Zwarningvr   r#   r#   r$   r     sB    
(zPackageIndex.open_urlc                 C   s   t |\}}|r0d|v r4|dddd}qnd}|drJ|d d }tj||}|dksj|d	rv| ||S |d
ks|dr| ||S |dr| 	||S |dkrt
jt
j|d S | |d | ||S d S )Nz...\_Z__downloaded__rH   r'   Zsvnzsvn+Zgitzgit+zhg+r   rY   T)r@   replacer)   rQ   r<   r^   r*   _download_svn_download_git_download_hgr4   r   url2pathnamer   r5   r   _attempt_download)ry   r:   r8   r   r+   r?   rR   r#   r#   r$   r   4  s$    

zPackageIndex._download_urlc                 C   s   |  |d d S )NT)r   r   r#   r#   r$   r   Q  s    zPackageIndex.scan_urlc                 C   s6   |  ||}d|dd v r.| |||S |S d S )Nr   r   r   )r  r   r(   _invalid_download_html)ry   r8   rR   r   r#   r#   r$   r,  T  s    zPackageIndex._attempt_downloadc                 C   s   t | td| d S )NzUnexpected HTML page found at )rQ   r   r   )ry   r8   r   rR   r#   r#   r$   r-  [  s    
z#PackageIndex._invalid_download_htmlc                 C   s   t d| d S )Nz/Invalid config, SVN download is not supported: r   )ry   r8   Z	_filenamer#   r#   r$   r(  _  s    zPackageIndex._download_svnc                 C   sp   t j| \}}}}}|ddd }|ddd }d }d|v rR|dd\}}t j||||df} | |fS )N+r3   r/   r2   r   @r   )r4   r   Zurlsplitr7   rsplitZ
urlunsplit)r8   
pop_prefixr:   netlocr<   r>   r   revr#   r#   r$   _vcs_split_rev_from_urlb  s    z$PackageIndex._vcs_split_rev_from_urlc                 C   sl   | ddd }| j|dd\}}| d|| td||f  |d urh| d| td	||f  |S )
Nr2   r3   r   Tr1  zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %szgit -C %s checkout --quiet %sr7   r4  r   rQ   systemry   r8   rR   r3  r#   r#   r$   r)  t  s    zPackageIndex._download_gitc                 C   sl   | ddd }| j|dd\}}| d|| td||f  |d urh| d| td	||f  |S )
Nr2   r3   r   Tr5  zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %szhg --cwd %s up -C -r %s -qr6  r8  r#   r#   r$   r*    s    zPackageIndex._download_hgc                 G   s   t j|g|R   d S r_   )r   r   r   r#   r#   r$   r     s    zPackageIndex.debugc                 G   s   t j|g|R   d S r_   )r   r   r   r#   r#   r$   r     s    zPackageIndex.infoc                 G   s   t j|g|R   d S r_   )r   r   r   r#   r#   r$   r     s    zPackageIndex.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   r   r0   r   r  r   r  r  r  r   r   r   r,  r-  r(  staticmethodr4  r)  r*  r   r   r   __classcell__r#   r#   r   r$   r   *  s\       	
9



	&    
P
.$
"r   z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c                 C   s   |  d}t|S )Nr   )rE   r   Zunescape)rD   Zwhatr#   r#   r$   decode_entity  s    
r;  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&amp;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_subr;  )textr#   r#   r$   rp     s    	rp   c                    s    fdd}|S )Nc                    s    fdd}|S )Nc               	      s>   t  }t  z | i |W t | S t | 0 d S r_   )r"  ZgetdefaulttimeoutZsetdefaulttimeout)r`   ra   Zold_timeout)rc   timeoutr#   r$   _socket_timeout  s    

z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr#   )rc   r?  r>  rb   r$   r?    s    z'socket_timeout.<locals>._socket_timeoutr#   )r>  r?  r#   r@  r$   socket_timeout  s    rA  c                 C   s2   t j| }| }t|}| }|ddS )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   encodebase64Z	b64encoder   r'  )authZauth_sZ
auth_bytesZencoded_bytesZencodedr#   r#   r$   _encode_auth  s
    
rF  c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	
Credentialz:
    A username/password pair. Use like a namedtuple.
    c                 C   s   || _ || _d S r_   usernamepassword)ry   rI  rJ  r#   r#   r$   r     s    zCredential.__init__c                 c   s   | j V  | jV  d S r_   rH  r|   r#   r#   r$   __iter__  s    zCredential.__iter__c                 C   s   dt |  S )Nz%(username)s:%(password)s)varsr|   r#   r#   r$   __str__  s    zCredential.__str__N)r   r   r   r   r   rK  rM  r#   r#   r#   r$   rG    s   rG  c                       s8   e Zd Z fddZedd Zdd Zdd Z  ZS )	
PyPIConfigc                    sL   t g dd}t | tjtjdd}tj|rH| 	| dS )z%
        Load from ~/.pypirc
        )rI  rJ  
repositoryr   ~z.pypircN)
dictfromkeysr   r   rQ   r<   r^   
expanduserr   r   )ry   defaultsZrcr   r#   r$   r     s
    zPyPIConfig.__init__c                    s&    fdd   D }tt j|S )Nc                    s    g | ]}  |d  r|qS )rO  )r   rm   )rU   sectionr|   r#   r$   r	    s   z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)ZsectionsrQ  rk   _get_repo_cred)ry   Zsections_with_repositoriesr#   r|   r$   creds_by_repository  s    
zPyPIConfig.creds_by_repositoryc                 C   s6   |  |d }|t|  |d |  |d fS )NrO  rI  rJ  )r   rm   rG  )ry   rU  Zrepor#   r#   r$   rV    s
    zPyPIConfig._get_repo_credc                 C   s*   | j  D ]\}}||r
|  S q
dS )z
        If the URL indicated appears to be a repository defined in this
        config, return the credential for that repository.
        N)rW  itemsr*   )ry   r8   rO  credr#   r#   r$   find_credential  s    
zPyPIConfig.find_credential)	r   r   r   r   propertyrW  rV  rZ  r:  r#   r#   r   r$   rN    s
   
	rN  c                 C   s@  t j| }|\}}}}}}|dr2tjd|dv rHt|\}	}
nd}	|	st 	| }|rt
|}	|j| f}tjdg|R   |	rdt|	 }	||
||||f}t j|}t j|}|d|	 nt j| }|dt ||}|	r<t j|j\}}}}}}||kr<||
kr<||||||f}t j||_|S )	z4Open a urllib2 request, handling HTTP authentication:znonnumeric port: '')r  ZhttpsNz*Authenticating as %s for %s (from .pypirc)zBasic ZAuthorizationz
User-Agent)r4   r   r5   r)   r  r  r  
_splituserrN  rZ  rl   rI  r   r   rF  Z
urlunparser   ZRequestZ
add_header
user_agentr8   )r8   r   Zparsedr:   r2  r<   paramsr>   r   rE  ZaddressrY  r   r9   r   r   r  s2Zh2Zpath2Zparam2Zquery2Zfrag2r#   r#   r$   r    s8    

r  c                 C   s    |  d\}}} |r|nd| fS )zNsplituser('user[:passwd]@host[:port]')
    --> 'user[:passwd]', 'host[:port]'.r/  N)
rpartition)ZhostuserZdelimr#   r#   r$   r]  E  s    r]  c                 C   s   | S r_   r#   )r8   r#   r#   r$   
fix_sf_urlP  s    rc  c              	   C   s,  t j| \}}}}}}t j|}tj|r<t j| S |	drtj
|rg }t|D ]x}	tj||	}
|	dkrt|
d}| }W d   n1 s0    Y   qntj
|
r|	d7 }	|dj|	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.htmlrNz<a href="{name}">{name}</a>)r+   zB<html><head><title>{url}</title></head><body>{files}</body></html>rB  )r8   files)   ZOK)r   zPath not foundz	Not foundr   z	text/html)r4   r   r5   r   r+  rQ   r<   isfiler   r)   r   r   r^   r   r   r   formatioStringIOr   r   )r8   r:   r;   r<   Zparamr>   r   rR   re  r   filepathr  bodyr   Zstatusmessager   Zbody_streamr#   r#   r$   r  T  s.    &


r  )N)N)N)r   )Yr   sysrQ   rT   ri  r  r"  rD  r   r   Zconfigparserr   Zhttp.clientr  Zurllib.parser4   Zurllib.requestZurllib.error	functoolsr   r   Zpkg_resourcesr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   	distutilsr   Zdistutils.errorsr   Zfnmatchr   Zsetuptools.wheelr   Z setuptools.extern.more_itertoolsr   r   rC   Irn   r   rD   r   r7   rM   __all__Z_SOCKET_TIMEOUTZ_tmplrh  version_infor^  r%   r   r@   r   rB   rS   r   re   rg   rv   rw   r   r   r   r<  r;  rp   rA  rF  rG  ZRawConfigParserrN  r   r   r  r]  rc  r  r#   r#   r#   r$   <module>   s   @
	

#

"
!     
'/