U
    "Iƒb�ž  ã                   @   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
mZ ddlmZ ddlmZmZmZ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! 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* ddl+m,Z, ddl-m.Z. e/Z0e 1d¡Z2e 1dej3¡Z4e 1d¡Z5e 1dej3¡j6Z7d 8¡ Z9ddddgZ:dZ;dZ<e<j=dj=ej>Ž ed�Z?dd„ Z@dd„ ZAdd„ ZBdGd d„ZCdHd!d"„ZDdId#d$„ZEdedfd%d„ZFdJd&d'„ZGd(d)„ ZHe 1d*ej3¡ZIeHd+d,„ ƒZJG d-d.„ d.ƒZKG d/d0„ d0eKƒZLG d1d„ deƒZMe 1d2¡jNZOd3d4„ ZPd5d6„ ZQdKd7d8„ZRd9d:„ ZSG d;d<„ d<ƒZTG d=d>„ d>ejUƒZVejWjXfd?d@„ZYdAdB„ ZZeRe;ƒeYƒZYdCdD„ Z[dEdF„ Z\dS )Lz#PyPI and direct package downloadingé    N©Úwraps)Úsix)ÚurllibÚhttp_clientÚconfigparserÚmap)ÚCHECKOUT_DISTÚDistributionÚBINARY_DISTÚnormalize_pathÚSOURCE_DISTÚEnvironmentÚfind_distributionsÚ	safe_nameÚsafe_versionÚto_filenameÚRequirementÚDEVELOP_DISTÚEGG_DIST)Ússl_support)Úlog)ÚDistutilsError)Ú	translate)Úget_all_headers)Úunescape)ÚWheelz^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   s4   zt  | ¡W S  tk
r.   td| f ƒ‚Y nX d S )Nz1Not a URL, existing file, or requirement spec: %r)r   ÚparseÚ
ValueErrorr   )Úspec© r&   ú</tmp/pip-unpacked-wheel-b_twsu17/setuptools/package_index.pyÚparse_requirement_arg4   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.exeNiöÿÿÿÚwin32z	.win32-pyiðÿÿÿiùÿÿÿéüÿÿÿz.win-amd64.exeiòÿÿÿz	win-amd64z.win-amd64-pyiìÿÿÿ)ÚlowerÚendswithÚ
startswith)Únamer,   ÚbaseÚpy_verÚplatr&   r&   r'   r   =   s$    



c           	      C   sx   t j | ¡}|\}}}}}}t j | d¡d ¡}|dkrX|dkrXt j | d¡d ¡}d|krp| dd¡\}}||fS )Nú/éÿÿÿÿzsourceforge.netÚdownloadéþÿÿÿú#é   )r   r#   ÚurlparseÚunquoteÚsplit)	ÚurlÚpartsÚschemeÚserverÚpathÚ
parametersÚqueryÚfragmentr0   r&   r&   r'   Úegg_info_for_urlU   s    rD   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 URLr8   )Ú
precedenceN)rD   Údistros_for_locationÚEGG_FRAGMENTÚmatchr    Úgroupr	   )r<   Úmetadatar0   rC   ÚdistrH   r&   r&   r'   r   `   s    
   ÿ
c                 C   sä   |  d¡r|dd… }|  d¡r8d|kr8t | ||¡gS |  d¡rxd|krxt|ƒ}| ¡ s^g S t| |j|jtd d�gS |  d	¡rªt|ƒ\}}}|dk	rªt	| |||t
|ƒS tD ]0}|  |¡r®|dt|ƒ … }t	| ||ƒ  S q®g S )
z:Yield egg or source distribution objects based on basenameú.egg.zipNr+   z.eggú-z.whlr8   )ÚlocationÚproject_nameÚversionrE   r)   )r-   r
   Úfrom_locationr   Úis_compatiblerO   rP   r   r   r    r   Ú
EXTENSIONSÚlen)rN   ÚbasenamerJ   ÚwheelZwin_baser1   ÚplatformÚextr&   r&   r'   rF   n   s<    
û
     ÿ
rF   c                 C   s   t t| ƒtj | ¡|ƒS )zEYield possible egg or source distribution objects based on a filename)rF   r   Úosr@   rU   )ÚfilenamerJ   r&   r&   r'   Údistros_for_filename�   s
     
 ÿr[   c              
   c   s|   |  d¡}|s,tdd„ |dd… D ƒƒr,dS tdt|ƒd ƒD ]8}t| |d |d|… ¡d ||d… ¡|||d�V  q>dS )zØGenerate 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!
    rM   c                 s   s   | ]}t  d |¡V  qdS )z	py\d\.\d$N)ÚrerH   )Ú.0Úpr&   r&   r'   Ú	<genexpr>­   s     z(interpret_distro_name.<locals>.<genexpr>é   Nr8   )Ú
py_versionrE   rW   )r;   ÚanyÚrangerT   r
   Újoin)rN   rU   rJ   ra   rE   rW   r=   r^   r&   r&   r'   r    –   s    
    ýc                 c   sf   t ƒ }|j}|dkr:tj |j| ¡D ]}||ƒ |V  q$n(| D ]"}||ƒ}||kr>||ƒ |V  q>dS )zHList unique elements, preserving order. Remember all elements ever seen.N)ÚsetÚaddr   ÚmovesÚfilterfalseÚ__contains__)ÚiterableÚkeyÚseenZseen_addÚelementÚkr&   r&   r'   Úunique_everseenº   s    
ro   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 ˆ | |ŽƒS ©N)ro   )ÚargsÚkwargs©Úfuncr&   r'   ÚwrapperÒ   s    zunique_values.<locals>.wrapperr   )rt   ru   r&   rs   r'   Úunique_valuesÌ   s    rv   z(<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>c              	   c   sº   t  |¡D ]d}| ¡ \}}tttj| ¡  d¡ƒƒ}d|ksDd|k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homepager5   r8   )z<th>Home Pagez<th>Download URLr4   N)ÚRELÚfinditerÚgroupsre   r   ÚstrÚstripr,   r;   ÚHREFr   r#   ÚurljoinÚ
htmldecoderI   ÚfindÚsearch)r<   ÚpagerH   ÚtagÚrelZrelsÚposr&   r&   r'   Úfind_external_linksÝ   s    
r†   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&   ©r‰   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&   )r‰   ÚreporterÚtemplater&   r&   r'   Úreport  s    zContentChecker.reportN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r‹   r�   r�   r&   r&   r&   r'   r‡   ð   s   r‡   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 rp   )Ú	hash_nameÚhashlibÚnewÚhashÚexpected)r‰   r–   rš   r&   r&   r'   Ú__init__  s    zHashChecker.__init__c                 C   s>   t j |¡d }|stƒ S | j |¡}|s0tƒ S | f | ¡ ŽS )z5Construct a (possibly null) ContentChecker from a URLr4   )r   r#   r9   r‡   Úpatternr�   Ú	groupdict)Úclsr<   rC   rH   r&   r&   r'   Úfrom_url  s    zHashChecker.from_urlc                 C   s   | j  |¡ d S rp   )r™   Úupdaterˆ   r&   r&   r'   r‹     s    zHashChecker.feedc                 C   s   | j  ¡ | jkS rp   )r™   Ú	hexdigestrš   rŒ   r&   r&   r'   r�   "  s    zHashChecker.is_validc                 C   s   || j  }||ƒS rp   )r–   )r‰   rŽ   r�   Úmsgr&   r&   r'   r�   %  s    
zHashChecker.reportN)r‘   r’   r“   r\   Úcompilerœ   r›   ÚclassmethodrŸ   r‹   r�   r�   r&   r&   r&   r'   r•   	  s   ÿ

r•   c                       s<  e Zd ZdZdJdd„ZdKd	d
„ZdLdd„ZdMdd„Zdd„ Zdd„ Z	dd„ Z
dd„ ZdNdd„Zdd„ ZdO‡ fdd„	Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ ZdPd'd(„ZdQd)d*„Zd+d,„ Zd-Zd.d/„ Zd0d1„ ZdRd2d3„Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Ze dSd>d?„ƒZ!d@dA„ Z"dBdC„ Z#dDdE„ Z$dFdG„ Z%dHdI„ Z&‡  Z'S )Tr   z;A distribution index that scans web pages for download URLsúhttps://pypi.org/simple/©Ú*NTc                 O   s”   t j| f|ž|Ž |dd | d¡ …  | _i | _i | _i | _t d 	t
t|ƒ¡¡j| _g | _|ortjor|prt ¡ }|r†t |¡| _n
tjj| _d S )Nr3   ú|)r   r›   r-   Ú	index_urlÚscanned_urlsÚfetched_urlsÚpackage_pagesr\   r£   rd   r   r   rH   ÚallowsÚto_scanr   Zis_availableZfind_ca_bundleZ
opener_forÚopenerr   ÚrequestÚurlopen)r‰   r©   ÚhostsZ	ca_bundleZ
verify_sslrq   ÚkwZuse_sslr&   r&   r'   r›   -  s    ÿ
ýzPackageIndex.__init__Fc                 C   sº  || j kr|sdS d| j |< t|ƒs2|  |¡ dS tt|ƒƒ}|r\|  |¡sPdS |  d|¡ |sn|rn|| jkr‚tt| j	|ƒƒ dS |  |¡sšd| j|< dS |  
d|¡ d| j|< d}|  ||| ¡}|dkrÐdS d| j|j< d|j dd¡ ¡ k�r | ¡  dS |j}| ¡ }t|tƒ�sNt|tjjƒ�r0d	}n|j d
¡�p@d	}| |d¡}| ¡  t |¡D ](}	tj |t|	 d¡ƒ¡}
|  |
¡ �q`|  | j!¡�r¶t"|ddƒdk�r¶|  #||¡}dS )z<Evaluate a URL as a possible download, and maybe retrieve itNTzFound link: %sz
Reading %sz<Download error on %s: %%s -- Some packages may not be found!Úhtmlúcontent-typeÚ zlatin-1ÚcharsetÚignorer8   Úcodeé”  )$rª   Ú
URL_SCHEMEÚprocess_filenameÚlistr   Úurl_okÚdebugr«   r   rf   ÚinfoÚopen_urlr<   ÚheadersÚgetr,   ÚcloseÚreadÚ
isinstancer{   r   ÚerrorÚ	HTTPErrorÚ	get_paramÚdecoder}   ry   r#   r~   r   rI   Úprocess_urlr.   r©   ÚgetattrÚprocess_index)r‰   r<   ÚretrieveÚdistsÚtmplÚfr0   r‚   r·   rH   Úlinkr&   r&   r'   rË   B  sP    





 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)rY   r@   ÚexistsÚwarnÚisdirÚrealpathÚlistdirr¼   rd   r[   r¿   r½   r   rf   )r‰   ÚfnÚnestedr@   ÚitemrÏ   r&   r&   r'   r¼   u  s    zPackageIndex.process_filenamec                 C   sb   t |ƒ}|o| d¡ ¡ dk}|s8|  tj |¡d ¡r<dS d}|rRt|| ƒ‚n|  ||¡ d S )Nr8   ÚfileTzN
Note: Bypassing %s (disallowed host; see http://bit.ly/2hrImnY for details).
)	r»   rI   r,   r­   r   r#   r9   r   rÔ   )r‰   r<   Ú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)rY   r×   r-   )r]   r@   Úentryr&   r&   r'   r_   ”  s
    
ýz.PackageIndex.scan_egg_links.<locals>.<genexpr>)ÚfilterrY   r@   rÕ   r½   Ú	itertoolsÚstarmapÚscan_egg_link)r‰   Ú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 5 Q R X t	|ƒdkrDd S |\}}t
tj ||¡ƒD ](}tjj|f|žŽ |_t|_|  |¡ q^d S )Nr`   )ÚopenrY   r@   rd   r½   rà   r   r{   r|   rT   r   rN   r   rE   rf   )r‰   r@   rß   Z	raw_linesÚlinesZegg_pathZ
setup_pathrK   r&   r&   r'   rã   œ  s     zPackageIndex.scan_egg_linkc           
   	      sÎ   ‡ fdd„}t  |¡D ]:}z |tj |t| d¡ƒ¡ƒ W q tk
rN   Y qX q||ƒ\}}|rÆt||ƒD ]H}t	|ƒ\}}	| 
d¡rª|	sª|r |d||f 7 }n
ˆ  |¡ ˆ  |¡ qlt dd„ |¡S dS d	S )
z#Process the contents of a PyPI pagec                    sŒ   |   ˆ j¡rˆtttjj| tˆ jƒd …  d¡ƒƒ}t|ƒdkrˆd|d krˆt	|d ƒ}t
|d ƒ}dˆ j | ¡ i ¡| < t|ƒt|ƒfS dS )Nr3   r`   r7   r8   r   T)NN)r.   r©   r½   r   r   r#   r:   rT   r;   r   r   r¬   Ú
setdefaultr,   r   )rÒ   r=   ÚpkgÚverrŒ   r&   r'   Úscan¯  s     ÿz(PackageIndex.process_index.<locals>.scanr8   ú.pyz
#egg=%s-%sc                 S   s   d|   ddd¡ S )Nz<a href="%s#md5=%s">%s</a>r8   é   r`   )rI   )Úmr&   r&   r'   Ú<lambda>Ò  ó    z,PackageIndex.process_index.<locals>.<lambda>r¶   N)r}   ry   r   r#   r~   r   rI   r$   r†   rD   r-   Úneed_version_infoÚscan_urlÚPYPI_MD5Úsub)
r‰   r<   r‚   rì   rH   rê   rë   Únew_urlr0   Ú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©r‰   r<   r&   r&   r'   rò   ×  s    þzPackageIndex.need_version_infoc                 G   s:   | j | jkr*|r | j|f|žŽ  |  d¡ |  | j ¡ d S )Nz6Scanning index of all packages (this may take a while))r©   r«   rÔ   rÀ   ró   ©r‰   r¢   rq   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 )Nr3   r&   )	ró   r©   Úunsafe_namer¬   rÃ   rk   rO   Únot_found_in_indexr½   )r‰   Úrequirementr<   r&   r&   r'   Úfind_packagesæ  s    
zPackageIndex.find_packagesc                    sR   |   ¡  |  |¡ | |j D ]"}||kr0|  S |  d||¡ qtt| ƒ ||¡S )Nz%s does not match %s)Úprescanrþ   rk   r¿   Úsuperr   Úobtain)r‰   rý   Ú	installerrK   ©Ú	__class__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Ä   rY   Úunlinkr   r™   r/   r@   rU   )r‰   ÚcheckerrZ   Útfpr&   r&   r'   Ú
check_hashþ  s    þ
þÿzPackageIndex.check_hashc                 C   sN   |D ]D}| j dk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)r‰   Úurlsr<   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½   r   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?))rk   rÀ   rÔ   rû   rø   )r‰   rý   Úmethr¢   r&   r&   r'   rü   #  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.
        r8   rí   rN   N)rÆ   r   r»   Ú_download_urlrI   rD   r-   Ú	gen_setuprY   r@   rÓ   r(   rÌ   Úfetch_distribution)r‰   r%   Útmpdirr>   Úfoundr0   rC   r&   r&   r'   r5   -  s    

zPackageIndex.downloadc           	         sÜ   ˆ  d|¡ i ‰d}d
‡ ‡‡‡‡fdd„	}|rHˆ ¡  ˆ |¡ ||ƒ}|s^|dk	r^|||ƒ}|dkr€ˆjdk	rxˆ ¡  ||ƒ}|dkrž|sžˆ |¡ ||ƒ}|dkr¾ˆ dˆr´dp¶d|¡ 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 krˆ}|| j  D ]v}|jtkrFˆ sF|ˆkrˆ d|¡ dˆ|< q|| ko\|jtkp\ˆ }|rˆ |jˆ¡}||_tj	 
|j¡r|  S qd S )Nz&Skipping development or system egg: %sr8   )rk   rE   r   rÔ   r   r5   rN   Údownload_locationrY   r@   rÓ   )ÚreqÚenvrK   ÚtestÚloc©Ú
develop_okr‰   ÚskippedÚsourcer  r&   r'   r€   g  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)rN   )N)rÀ   rÿ   rþ   r®   rÔ   Úcloner  )	r‰   rý   r  Ú
force_scanr  r  Zlocal_indexrK   r€   r&   r  r'   r  O  s2    




ýzPackageIndex.fetch_distributionc                 C   s"   |   ||||¡}|dk	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  rN   )r‰   rý   r  r  r  rK   r&   r&   r'   Úfetch›  s    zPackageIndex.fetchc           
   	   C   sü   t  |¡}|r*dd„ t|| d¡d ƒD ƒp,g }t|ƒdkrÚtj |¡}tj |¡|krŠtj 	||¡}ddl
m} |||ƒsŠt ||¡ |}ttj 	|d¡dƒ�2}	|	 d|d j|d jtj |¡d f ¡ W 5 Q R X |S |rðtd	||f ƒ‚ntd
ƒ‚d S )Nc                 S   s   g | ]}|j r|‘qS r&   )rP   )r]   Údr&   r&   r'   Ú
<listcomp>ª  s   ÿz*PackageIndex.gen_setup.<locals>.<listcomp>r8   r   )Úsamefilezsetup.pyÚwzIfrom setuptools import setup
setup(name=%r, version=%r, py_modules=[%r])
z†Can'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.)rG   rH   r    rI   rT   rY   r@   rU   Údirnamerd   Zsetuptools.command.easy_installr!  ÚshutilÚcopy2rç   ÚwriterO   rP   Úsplitextr   )
r‰   rZ   rC   r  rH   rÏ   rU   Údstr!  rÛ   r&   r&   r'   r  ¨  sB    

þý
 þþÿþÿÿzPackageIndex.gen_setupi    c              	   C   s  |   d|¡ d }zît |¡}|  |¡}t|tjjƒrJt	d||j
|jf ƒ‚|  ¡ }d}| j}d}d|kr’t|dƒ}	ttt|	ƒƒ}|  |||||¡ t|dƒ�V}
| |¡}|rà| |¡ |
 |¡ |d7 }|  |||||¡ qžqàqž|  |||
¡ W 5 Q R X |W ¢S |�r| ¡  X d S )	NzDownloading %szCan't download %s: %s %sr   r4   zcontent-lengthzContent-LengthÚwbr8   )rÀ   rÄ   r•   rŸ   rÁ   rÆ   r   rÇ   rÈ   r   r¹   r¢   Údl_blocksizer   Úmaxr   ÚintÚ
reporthookrç   rÅ   r‹   r&  r  )r‰   r<   rZ   Úfpr  rÂ   ÚblocknumÚbsÚsizeZsizesr  rŠ   r&   r&   r'   Ú_download_toÓ  s:    

ÿ



zPackageIndex._download_toc                 C   s   d S rp   r&   )r‰   r<   rZ   r/  Zblksizer1  r&   r&   r'   r-  ÷  s    zPackageIndex.reporthookc              
   C   sš  |  d¡rt|ƒS zt|| jƒW S  ttjfk
r‚ } z<d dd„ |jD ƒ¡}|r`|  	||¡ nt
d||f ƒ‚W 5 d }~X Y �n tjjk
r® } z| W Y ¢S d }~X Y nè tjjk
� rú } z*|rØ|  	||j¡ nt
d||jf ƒ‚W 5 d }~X Y nœ tjk
�rF } z,|�r$|  	||j¡ nt
d||jf ƒ‚W 5 d }~X Y nP tjtjfk
�r” } z(|�rt|  	||¡ nt
d||f ƒ‚W 5 d }~X Y nX d S )Nr	  ú c                 S   s   g | ]}t |ƒ‘qS r&   )r{   )r]   Úargr&   r&   r'   r      s     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$   r   Ú
InvalidURLrd   rq   rÔ   r   r   rÇ   rÈ   ÚURLErrorÚreasonÚBadStatusLineÚlineÚHTTPExceptionÚsocket)r‰   r<   ÚwarningÚvr¢   r&   r&   r'   rÁ   ú  s>    
"ÿþÿÿzPackageIndex.open_urlc                 C   sæ   t |ƒ\}}|r0d|k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rÊt
j t
j |¡d ¡S |  |d¡ |  ||¡S d S )Nz..Ú.ú\Ú_Z__downloaded__rL   r+   Úsvnzsvn+Úgitzgit+zhg+rÛ   r`   T)rD   Úreplacer-   rY   r@   rd   r.   Ú_download_svnÚ_download_gitÚ_download_hgr   r°   Úurl2pathnamer#   r9   r¾   Ú_attempt_download)r‰   r>   r<   r  r/   rC   rZ   r&   r&   r'   r    s$    

zPackageIndex._download_urlc                 C   s   |   |d¡ d S )NT)rË   rù   r&   r&   r'   ró   :  s    zPackageIndex.scan_urlc                 C   s6   |   ||¡}d| dd¡ ¡ kr.|  |||¡S |S d S )Nr´   rµ   r¶   )r2  rÃ   r,   Ú_download_html)r‰   r<   rZ   rÂ   r&   r&   r'   rJ  =  s    zPackageIndex._attempt_downloadc                 C   sn   t |ƒ}|D ]>}| ¡ rt d|¡rF| ¡  t |¡ |  ||¡  S  qLq| ¡  t |¡ td| ƒ‚d S )Nz <title>([^- ]+ - )?Revision \d+:zUnexpected HTML page found at )	rç   r|   r\   r�   rÄ   rY   r  rF  r   )r‰   r<   rÂ   rZ   rÛ   r;  r&   r&   r'   rK  D  s    

zPackageIndex._download_htmlc                 C   s  t  dt¡ | dd¡d }d}| ¡  d¡râd|krâtj |¡\}}}}}}	|sâ| d¡râd	|d
d … krâ|d
d …  d	d¡\}}t	|ƒ\}
}|
râd|
krº|
 dd¡\}}d||f }nd|
 }|}||||||	f}tj 
|¡}|  d||¡ t d|||f ¡ |S )Nz"SVN download support is deprecatedr7   r8   r   r¶   zsvn:ú@z//r3   r`   ú:z --username=%s --password=%sz --username=z'Doing subversion checkout from %s to %szsvn checkout%s -q %s %s)ÚwarningsrÔ   ÚUserWarningr;   r,   r.   r   r#   r9   Ú
_splituserÚ
urlunparserÀ   rY   Úsystem)r‰   r<   rZ   Úcredsr>   Únetlocr@   r^   ÚqrÑ   ÚauthÚhostÚuserÚpwr=   r&   r&   r'   rF  S  s&    zPackageIndex._download_svnc                 C   sp   t j | ¡\}}}}}| dd¡d }| dd¡d }d }d|krR| dd¡\}}t j ||||df¡} | |fS )Nú+r8   r4   r7   r   rL  r¶   )r   r#   Úurlsplitr;   ÚrsplitÚ
urlunsplit)r<   Ú
pop_prefixr>   rT  r@   rB   r÷   Úrevr&   r&   r'   Ú_vcs_split_rev_from_urli  s    z$PackageIndex._vcs_split_rev_from_urlc                 C   sl   |  dd¡d }| j|dd�\}}|  d||¡ t d||f ¡ |d k	rh|  d|¡ t d	||f ¡ |S )
Nr7   r8   r   T©r^  zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %szgit -C %s checkout --quiet %s©r;   r`  rÀ   rY   rR  ©r‰   r<   rZ   r_  r&   r&   r'   rG  {  s    þzPackageIndex._download_gitc                 C   sl   |  dd¡d }| j|dd�\}}|  d||¡ t d||f ¡ |d k	rh|  d|¡ t d	||f ¡ |S )
Nr7   r8   r   Tra  zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %szhg --cwd %s up -C -r %s -qrb  rc  r&   r&   r'   rH  ‹  s    þzPackageIndex._download_hgc                 G   s   t j|f|žŽ  d S rp   )r   r¿   rú   r&   r&   r'   r¿   ›  s    zPackageIndex.debugc                 G   s   t j|f|žŽ  d S rp   )r   rÀ   rú   r&   r&   r'   rÀ   ž  s    zPackageIndex.infoc                 G   s   t j|f|žŽ  d S rp   )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ü   r5   r  r  r  r*  r2  r-  rÁ   r  ró   rJ  rK  rF  Ústaticmethodr`  rG  rH  r¿   rÀ   rÔ   Ú__classcell__r&   r&   r  r'   r   *  sX         þ

3


+
		
#      þ
L
)$
#z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c                 C   s   |   d¡}t|ƒS )Nr   )rI   r   )rH   Úwhatr&   r&   r'   Údecode_entityª  s    
rg  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_subrg  )Útextr&   r&   r'   r   ¯  s    	r   c                    s   ‡ fdd„}|S )Nc                    s   ‡ ‡fdd„}|S )Nc               	      s2   t  ¡ }t  ˆ¡ zˆ | |ŽW ¢S t  |¡ X d S rp   )r=  ÚgetdefaulttimeoutÚsetdefaulttimeout)rq   rr   Zold_timeout)rt   Útimeoutr&   r'   Ú_socket_timeout½  s
    
z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr&   )rt   rm  ©rl  rs   r'   rm  ¼  s    z'socket_timeout.<locals>._socket_timeoutr&   )rl  rm  r&   rn  r'   Úsocket_timeout»  s    ro  c                 C   s2   t j | ¡}| ¡ }t |¡}| ¡ }| dd¡S )aq  
    A function compatible with Python 2.3-3.3 that will 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¶   )r   r#   r:   ÚencodeÚbase64Ú	b64encoderÊ   rE  )rV  Zauth_sZ
auth_bytesZencoded_bytesÚencodedr&   r&   r'   Ú_encode_authÊ  s
    
ru  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 rp   ©ÚusernameÚpassword)r‰   rx  ry  r&   r&   r'   r›   å  s    zCredential.__init__c                 c   s   | j V  | jV  d S rp   rw  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›   rz  r|  r&   r&   r&   r'   rv  à  s   rv  c                   @   s0   e Zd Zdd„ Zedd„ ƒZdd„ Zdd„ Zd	S )
Ú
PyPIConfigc                 C   sP   t  dddgd¡}tj | |¡ tj tj d¡d¡}tj 	|¡rL|  
|¡ dS )z%
        Load from ~/.pypirc
        rx  ry  Ú
repositoryr¶   ú~z.pypircN)ÚdictÚfromkeysr   ÚRawConfigParserr›   rY   r@   rd   Ú
expanduserrÓ   rÅ   )r‰   ÚdefaultsÚ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 )r~  )rÃ   r|   )r]   ÚsectionrŒ   r&   r'   r   ÿ  s   ÿz2PyPIConfig.creds_by_repository.<locals>.<listcomp>)Úsectionsr€  r   Ú_get_repo_cred)r‰   Zsections_with_repositoriesr&   rŒ   r'   Úcreds_by_repositoryý  s    
ÿzPyPIConfig.creds_by_repositoryc                 C   s6   |   |d¡ ¡ }|t|   |d¡ ¡ |   |d¡ ¡ ƒfS )Nr~  rx  ry  )rÃ   r|   rv  )r‰   r†  Úrepor&   r&   r'   rˆ    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)r‰  Úitemsr.   )r‰   r<   r~  Úcredr&   r&   r'   Úfind_credential  s    
zPyPIConfig.find_credentialN)r‘   r’   r“   r›   Úpropertyr‰  rˆ  r�  r&   r&   r&   r'   r}  ñ  s
   
r}  c                 C   s:  t j | ¡}|\}}}}}}| d¡r0t d¡‚|dkrFt|ƒ\}	}
nd}	|	s~tƒ  | ¡}|r~t	|ƒ}	|j
| f}tjd	|žŽ  |	rÄdt|	ƒ }	||
||||f}t j |¡}t j |¡}| d|	¡ nt j | ¡}| dt¡ ||ƒ}|	�r6t j |j¡\}}}}}}||k�r6||
k�r6||||||f}t j |¡|_|S )
z4Open a urllib2 request, handling HTTP authenticationrM  znonnumeric port: '')ÚhttpÚhttpsNú*Authenticating as %s for %s (from .pypirc)zBasic ÚAuthorizationz
User-Agent)r‘  )r   r#   r9   r-   r   r7  rP  r}  r�  r{   rx  r   rÀ   ru  rQ  r°   ÚRequestÚ
add_headerÚ
user_agentr<   )r<   r¯   Úparsedr>   rT  r@   ÚparamsrB   r÷   rV  ÚaddressrŒ  rÀ   r=   rö   r°   r.  Ús2Úh2Úpath2Zparam2Zquery2Zfrag2r&   r&   r'   r6    s8    


r6  c                 C   s    |   d¡\}}} |r|nd| fS )zJsplituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.rL  N)Ú
rpartition)rW  rX  Údelimr&   r&   r'   rP  F  s    rP  c                 C   s   | S rp   r&   )r<   r&   r&   r'   Ú
fix_sf_urlP  s    rž  c              
   C   s  t j | ¡\}}}}}}t j |¡}tj |¡r<t j | ¡S | 	d¡rètj 
|¡règ }t |¡D ]d}	tj ||	¡}
|	dkržt|
dƒ�}| ¡ }W 5 Q R X  qÞn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 directoriesr3   z
index.htmlÚrz<a href="{name}">{name}</a>)r/   zB<html><head><title>{url}</title></head><body>{files}</body></html>rp  )r<   Úfiles)éÈ   ÚOK)rº   zPath not foundz	Not foundrµ   z	text/html)r   r#   r9   r°   rI  rY   r@   Úisfiler±   r-   rÕ   r×   rd   rç   rÅ   r
  Úformatr   ÚStringIOrÇ   rÈ   )r<   r>   r?   r@   ÚparamrB   r÷   rZ   r   rÑ   Úfilepathr.  ÚbodyrÐ   ÚstatusÚmessagerÂ   Zbody_streamr&   r&   r'   r5  T  s.    ÿ


r5  )N)N)N)N)r!   )]r”   ÚsysrY   r\   r$  r=  rr  r—   rá   rN  Ú	functoolsr   Zsetuptools.externr   Zsetuptools.extern.six.movesr   r   r   r   r"   Úpkg_resourcesr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   Ú	distutilsr   Údistutils.errorsr   Úfnmatchr   Zsetuptools.py27compatr   Zsetuptools.py33compatr   Zsetuptools.wheelr   ÚtypeÚ__metaclass__r£   rG   ÚIr}   rô   rH   r»   r;   rS   Ú__all__Z_SOCKET_TIMEOUTZ_tmplr¤  Úversion_infor•  r(   r   rD   r   rF   r[   r    ro   rv   rx   r†   r‡   r•   r   rõ   rh  rg  r   ro  ru  rv  r‚  r}  r°   r±   r6  rP  rž  r5  r&   r&   r&   r'   Ú<module>   s�   <
ÿ  þ	

!
 þ
$

!     
&/