U
    -ºc‰  ã                   @   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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
¡Z0e /dej1¡Z2e /d¡Z3e /dej1¡j4Z5d 6¡ Z7ddddgZ8dZ9dZ:e:j;dj;ej<Ž edZ=dd„ Z>dd„ Z?dd„ Z@dAdd„ZAdBdd„ZBdCdd „ZCdedfd!d„ZDd"d#„ ZEe /d$ej1¡ZFeEd%d&„ ƒZGG d'd(„ d(ƒZHG d)d*„ d*eHƒZIG d+d„ deƒZJe /d,¡jKZLd-d.„ ZMd/d0„ ZNdDd1d2„ZOd3d4„ ZPG d5d6„ d6ƒZQG d7d8„ d8ejRƒZSejTjUfd9d:„ZVd;d<„ ZWeOe9ƒeVƒZVd=d>„ ZXd?d@„ ZYdS )Ez$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   sD   zt  | ¡W S  tk
r> } ztd| f ƒ|‚W 5 d }~X Y nX d S )Nz1Not a URL, existing file, or requirement spec: %r)r   ÚparseÚ
ValueErrorr   )ÚspecÚe© r"   ú</tmp/pip-unpacked-wheel-izj_87as/setuptools/package_index.pyÚparse_requirement_argE   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   N   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éþÿÿÿú#é   )Úurllibr   ÚurlparseÚunquoteÚsplit)	ÚurlÚpartsÚschemeÚserverÚpathÚ
parametersÚqueryÚfragmentr,   r"   r"   r#   Úegg_info_for_urlf   s    rA   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 URLr4   )Ú
precedenceN)rA   Údistros_for_locationÚEGG_FRAGMENTÚmatchr   Úgroupr   )r9   Úmetadatar,   r@   ÚdistrE   r"   r"   r#   r   q   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.whlr4   )ÚlocationÚproject_nameÚversionrB   r%   )r)   r   Úfrom_locationr   Úis_compatiblerL   rM   r   r   r   r   Ú
EXTENSIONSÚlen)rK   ÚbasenamerG   ÚwheelZwin_baser-   ÚplatformÚextr"   r"   r#   rC      s>    
ûÿ	
     ÿ
rC   c                 C   s   t t| ƒtj | ¡|ƒS )zEYield possible egg or source distribution objects based on a filename)rC   r   Úosr=   rR   )ÚfilenamerG   r"   r"   r#   Údistros_for_filename¢   s
     
 ÿrX   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!
    rJ   c                 s   s   | ]}t  d |¡V  qdS )z	py\d\.\d$N)ÚrerE   )Ú.0Úpr"   r"   r#   Ú	<genexpr>¿   s     z(interpret_distro_name.<locals>.<genexpr>é   Nr4   )Ú
py_versionrB   rT   )r8   ÚanyÚrangerQ   r   Újoin)rK   rR   rG   r^   rB   rT   r:   r[   r"   r"   r#   r   ©   s    
ù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 ©Nr   )ÚargsÚkwargs©Úfuncr"   r#   ÚwrapperÕ   s    zunique_values.<locals>.wrapperr   )rf   rg   r"   re   r#   Úunique_valuesÏ   s    rh   z3<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>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homepager1   r4   )z<th>Home Pagez<th>Download URLr0   N)ÚRELÚfinditerÚgroupsÚsetÚmapÚstrÚstripr(   r8   ÚHREFr5   r   ÚurljoinÚ
htmldecoderF   ÚfindÚsearch)r9   ÚpagerE   ÚtagÚrelZrelsÚposr"   r"   r#   Úfind_external_linksâ   s    
rz   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 rb   )Ú	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 URLr0   )r5   r   r6   r{   Úpatternru   Ú	groupdict)Úclsr9   r@   rE   r"   r"   r#   Úfrom_url  s    zHashChecker.from_urlc                 C   s   | j  |¡ d S rb   )r   Úupdater|   r"   r"   r#   r   $  s    zHashChecker.feedc                 C   s   | j  ¡ | jkS rb   )r   Ú	hexdigestrŽ   r€   r"   r"   r#   r   '  s    zHashChecker.is_validc                 C   s   || j  }||ƒS rb   )rŠ   )r}   r‚   rƒ   Úmsgr"   r"   r#   r„   *  s    
zHashChecker.reportN)r…   r†   r‡   rY   Ú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                    sh   t ƒ j||Ž |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_pagesrY   r—   ra   rn   r   rE   ÚallowsÚto_scanr5   ÚrequestÚurlopenÚopener)r}   rž   ÚhostsZ	ca_bundleZ
verify_sslrc   Úkw©Ú	__class__r"   r#   r   2  s    	zPackageIndex.__init__c                    s2   zt |jƒ W n tk
r$   Y d S X tƒ  |¡S rb   )r   rM   Ú	Exceptionr   Úadd)r}   rH   r©   r"   r#   r¬   D  s
    zPackageIndex.addFc                 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 t|tjjƒrø|jdkrø|  
d|j ¡ d| j|j< d|j d	d
¡ ¡ kr(| ¡  dS |j}| ¡ }t|tƒsvt|tjjƒrXd}n|j d¡phd}| |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!i‘  zAuthentication error: %sÚhtmlúcontent-typeÚ zlatin-1ÚcharsetÚignorer4   Úcodeé”  )&rŸ   Ú
URL_SCHEMEÚprocess_filenameÚlistr   Úurl_okÚdebugr    rn   r¬   ÚinfoÚopen_urlÚ
isinstancer5   ÚerrorÚ	HTTPErrorr²   r–   r9   ÚheadersÚgetr(   ÚcloseÚreadro   Ú	get_paramÚdecoderq   rk   r   rr   rs   rF   Úprocess_urlr*   rž   ÚgetattrÚprocess_index)r}   r9   ÚretrieveÚdistsÚtmplÚfr,   rv   r°   rE   Úlinkr"   r"   r#   rÄ   M  sT    





 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)rV   r=   ÚexistsÚwarnÚisdirÚrealpathÚlistdirrµ   ra   rX   r¸   r¶   rn   r¬   )r}   Ú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 )Nr4   ÚfileTzN
Note: Bypassing %s (disallowed host; see http://bit.ly/2hrImnY for details).
)	r´   rF   r(   r¢   r5   r   r6   r   rÍ   )r}   r9   Ú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)rV   rÐ   r)   )rZ   r=   Úentryr"   r"   r#   r\   ¢  s
    
ýz.PackageIndex.scan_egg_links.<locals>.<genexpr>)ÚfilterrV   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]   )ÚopenrV   r=   ra   r¶   rÙ   rn   ro   rp   rQ   r
   rK   r   rB   r¬   )r}   r=   rØ   Z	raw_linesÚlinesZegg_pathZ
setup_pathrH   r"   r"   r#   rÜ   ª  s     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 krV|S t	|d ƒ}t
|d ƒ}d| j | ¡ i ¡|< t|ƒt|ƒfS )N)NNr/   r]   r3   r4   r   T)r*   rž   r¶   rn   r5   r   r7   rQ   r8   r   r   r¡   Ú
setdefaultr(   r   )r}   rË   ZNO_MATCH_SENTINELr:   ÚpkgÚverr"   r"   r#   Ú_scanº  s    &zPackageIndex._scanc           	   
   C   sÂ   t  |¡D ]<}z"|  tj |t| d¡ƒ¡¡ W q
 tk
rD   Y q
X q
|  |¡\}}|s^dS t	||ƒD ]H}t
|ƒ\}}| d¡r¦|s¦|rœ|d||f 7 }n
|  |¡ |  |¡ qht dd„ |¡S )z#Process the contents of a PyPI pager4   r¯   ú.pyz
#egg=%s-%sc                 S   s   d|   ddd¡ S )Nz<a href="%s#md5=%s">%s</a>r4   é   r]   )rF   )Úmr"   r"   r#   Ú<lambda>ä  ó    z,PackageIndex.process_index.<locals>.<lambda>)rq   rk   rå   r5   r   rr   rs   rF   r   rz   rA   r)   Úneed_version_infoÚscan_urlÚPYPI_MD5Úsub)	r}   r9   rv   rE   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©r}   r9   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–   rc   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¿   ÚkeyrL   Únot_found_in_indexr¶   )r}   Úrequirementr9   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ø   rõ   r¸   r   r   Úobtain)r}   r÷   Ú	installerrH   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À   rV   Úunlinkr   r   r+   r=   rR   )r}   ÚcheckerrW   Ú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}   Úurlsr9   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¶   rn   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ñ   )r}   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.
        r4   ræ   rK   N)r»   r   r´   Ú_download_urlrF   rA   r)   Ú	gen_setuprV   r=   rÌ   r$   rÅ   Úfetch_distribution)r}   r    Útmpdirr;   Úfoundr,   r@   r"   r"   r#   r1   ;  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: %sr4   )rõ   rB   r   rÍ   r   r1   rK   Údownload_locationrV   r=   rÌ   )ÚreqÚenvrH   ÚtestÚloc©Ú
develop_okr}   ÚskippedÚsourcer  r"   r#   rt   {  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)rK   )N)r¹   rù   rø   r£   rÍ   Úcloner
  )	r}   r÷   r  Ú
force_scanr  r  Zlocal_indexrH   rt   r"   r  r#   r  ]  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  rK   )r}   r÷   r  r  r  rH   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 	||¡}tj 
|¡r~tj ||¡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"   )rM   )rZ   Údr"   r"   r#   Ú
<listcomp>¾  s   þz*PackageIndex.gen_setup.<locals>.<listcomp>r4   zsetup.pyÚwzIfrom setuptools import setup
setup(name=%r, version=%r, py_modules=[%r])
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.)rD   rE   r   rF   rQ   rV   r=   rR   Údirnamera   rÌ   ÚsamefileÚshutilÚcopy2rà   ÚwriterL   rM   Úsplitextr   )	r}   rW   r@   r  rE   rÈ   rR   ÚdstrÔ   r"   r"   r#   r  º  sD    
þÿù
ýþÿ	þÿÿ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’| 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   r0   zcontent-lengthzContent-LengthÚwbr4   )r¹   rÀ   r‰   r“   rº   r»   r5   r¼   r½   r   r²   r–   Údl_blocksizeÚget_allÚmaxrn   ÚintÚ
reporthookrà   rÁ   r   r  rÿ   )r}   r9   rW   Úfprý   r¾   ÚblocknumÚbsÚsizeZsizesrþ   r~   r"   r"   r#   Ú_download_toê  s:    

ÿ



zPackageIndex._download_toc                 C   s   d S rb   r"   )r}   r9   rW   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k
r† } z>d dd„ |j	D ƒ¡}|rb|  
||¡ 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jk
rP } z.|r,|  
||j¡ ntd||jf ƒ|‚W 5 d }~X Y nT tjjtjfk
r¢ } z*|r€|  
||¡ ntd||f ƒ|‚W 5 d }~X Y nX d S )Nr   ú c                 S   s   g | ]}t |ƒ‘qS r"   )ro   )rZ   Ú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   ÚhttpÚclientÚ
InvalidURLra   rc   rÍ   r   r5   r¼   r½   ÚURLErrorÚreasonÚBadStatusLineÚlineÚHTTPExceptionÚsocket)r}   r9   ÚwarningÚvr–   r"   r"   r#   rº     sB    
$ÿþÿÿý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__rI   r'   Úsvnzsvn+Úgitzgit+zhg+rÔ   r]   T)rA   Úreplacer)   rV   r=   ra   r*   Ú_download_svnÚ_download_gitÚ_download_hgr5   r¤   Úurl2pathnamer   r6   r·   Ú_attempt_download)r}   r;   r9   r  r+   r@   rW   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¡ ¡ kr.|  |||¡S |S d S )Nr­   r®   r¯   )r*  r¿   r(   Ú_download_html)r}   r9   rW   r¾   r"   r"   r#   rD  T  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à   rp   rY   ru   rÀ   rV   rü   r@  r   )r}   r9   r¾   rW   rÔ   r5  r"   r"   r#   rE  [  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 deprecatedr3   r4   r   r¯   zsvn:ú@z//r/   r]   ú:z --username=%s --password=%sz --username=z'Doing subversion checkout from %s to %szsvn checkout%s -q %s %s)ÚwarningsrÍ   ÚUserWarningr8   r(   r*   r5   r   r6   Ú
_splituserÚ
urlunparser¹   rV   Úsystem)r}   r9   rW   Úcredsr;   Únetlocr=   r[   ÚqrÊ   ÚauthÚhostÚuserÚpwr:   r"   r"   r#   r@  j  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ú+r4   r0   r3   r   rF  r¯   )r5   r   Úurlsplitr8   ÚrsplitÚ
urlunsplit)r9   Ú
pop_prefixr;   rN  r=   r?   rð   Úrevr"   r"   r#   Ú_vcs_split_rev_from_url€  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 )
Nr3   r4   r   T©rX  zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %szgit -C %s checkout --quiet %s©r8   rZ  r¹   rV   rL  ©r}   r9   rW   rY  r"   r"   r#   rA  ’  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 )
Nr3   r4   r   Tr[  zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %szhg --cwd %s up -C -r %s -qr\  r]  r"   r"   r#   rB  ¥  s    þÿÿzPackageIndex._download_hgc                 G   s   t j|f|žŽ  d S rb   )r   r¸   ró   r"   r"   r#   r¸   ¸  s    zPackageIndex.debugc                 G   s   t j|f|žŽ  d S rb   )r   r¹   ró   r"   r"   r#   r¹   »  s    zPackageIndex.infoc                 G   s   t j|f|žŽ  d S rb   )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ö   r1   r  r  r  r!  r*  r%  rº   r  rì   rD  rE  r@  ÚstaticmethodrZ  rA  rB  r¸   r¹   rÍ   Ú__classcell__r"   r"   r©   r#   r   /  s\       û	
5



	&    ù
P
.$
"z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c                 C   s   |   d¡}t |¡S )Nr   )rF   r­   Úunescape)rE   Úwhatr"   r"   r#   Údecode_entityÇ  s    
rb  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_subrb  )Útextr"   r"   r#   rs   Ì  s    	rs   c                    s   ‡ fdd„}|S )Nc                    s   ‡ ‡fdd„}|S )Nc               	      s2   t  ¡ }t  ˆ¡ zˆ | |ŽW ¢S t  |¡ X d S rb   )r7  ÚgetdefaulttimeoutÚsetdefaulttimeout)rc   rd   Zold_timeout)rf   Útimeoutr"   r#   Ú_socket_timeoutÚ  s
    
z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr"   )rf   rh  ©rg  re   r#   rh  Ù  s    z'socket_timeout.<locals>._socket_timeoutr"   )rg  rh  r"   ri  r#   Úsocket_timeoutØ  s    rj  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¯   )r5   r   r7   ÚencodeÚbase64Ú	b64encoderÃ   r?  )rP  Zauth_sZ
auth_bytesZencoded_bytesÚencodedr"   r"   r#   Ú_encode_authç  s
    
rp  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 rb   ©ÚusernameÚpassword)r}   rs  rt  r"   r"   r#   r     s    zCredential.__init__c                 c   s   | j V  | jV  d S rb   rr  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   ru  rw  r"   r"   r"   r#   rq  ü  s   rq  c                       s8   e Zd Z‡ fdd„Zedd„ ƒZdd„ Zdd„ Z‡  ZS )	Ú
PyPIConfigc                    sN   t  dddgd¡}tƒ  |¡ tj tj d¡d¡}tj |¡rJ|  	|¡ dS )z%
        Load from ~/.pypirc
        rs  rt  Ú
repositoryr¯   ú~z.pypircN)
ÚdictÚfromkeysr   r   rV   r=   ra   Ú
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 )ry  )r¿   rp   )rZ   Úsectionr€   r"   r#   r    s   þz2PyPIConfig.creds_by_repository.<locals>.<listcomp>)Úsectionsr{  rn   Ú_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 )Nry  rs  rt  )r¿   rp   rq  )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}   r9   ry  Úcredr"   r"   r#   Úfind_credential*  s    
zPyPIConfig.find_credential)	r…   r†   r‡   r   Úpropertyrƒ  r‚  r‡  r_  r"   r"   r©   r#   rx    s
   
	rx  c                 C   s<  t j | ¡}|\}}}}}}| d¡r2tj d¡‚|dkrHt|ƒ\}	}
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¡ ||ƒ}|	r8t j |j¡\}}}}}}||kr8||
kr8||||||f}t j |¡|_|S )
z4Open a urllib2 request, handling HTTP authenticationrG  znonnumeric port: '')r/  ÚhttpsNú*Authenticating as %s for %s (from .pypirc)zBasic ÚAuthorizationz
User-Agent)rŠ  )r5   r   r6   r)   r/  r0  r1  rJ  rx  r‡  ro   rs  r   r¹   rp  rK  r¤   ÚRequestÚ
add_headerÚ
user_agentr9   )r9   r¦   Úparsedr;   rN  r=   Úparamsr?   rð   rP  Úaddressr†  r¹   r:   rï   r¤   r&  Ús2Úh2Úpath2Zparam2Zquery2Zfrag2r"   r"   r#   r.  4  s8    

r.  c                 C   s    |   d¡\}}} |r|nd| fS )zNsplituser('user[:passwd]@host[:port]')
    --> 'user[:passwd]', 'host[:port]'.rF  N)Ú
rpartition)rQ  rR  Údelimr"   r"   r#   rJ  c  s    rJ  c                 C   s   | S rb   r"   )r9   r"   r"   r#   Ú
fix_sf_urln  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 directoriesr/   z
index.htmlÚrz<a href="{name}">{name}</a>)r+   zB<html><head><title>{url}</title></head><body>{files}</body></html>rk  )r9   Úfiles)éÈ   ÚOK)r³   zPath not foundz	Not foundr®   z	text/html)r5   r   r6   r¤   rC  rV   r=   Úisfiler¥   r)   rÎ   rÐ   ra   rà   rÁ   r  ÚformatÚioÚStringIOr¼   r½   )r9   r;   r<   r=   Úparamr?   rð   rW   r™  rÊ   Úfilepathr&  ÚbodyrÉ   ÚstatusÚmessager¾   Zbody_streamr"   r"   r#   r-  r  s.    ÿ


r-  )N)N)N)r   )Zrˆ   ÚsysrV   rY   rž  r  r7  rm  r‹   rÚ   rH  Úconfigparserr­   Úhttp.clientr/  Úurllib.parser5   Úurllib.requestÚurllib.errorÚ	functoolsr   r   Úpkg_resourcesr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   Ú	distutilsr   Údistutils.errorsr   Úfnmatchr   Zsetuptools.wheelr   Z setuptools.extern.more_itertoolsr   r—   rD   ÚIrq   rí   rE   r´   r8   rP   Ú__all__Z_SOCKET_TIMEOUTZ_tmplr  Úversion_inforŽ  r$   r   rA   r   rC   rX   r   rh   rj   rz   r{   r‰   r   rî   rc  rb  rs   rj  rp  rq  ÚRawConfigParserrx  r¤   r¥   r.  rJ  r—  r-  r"   r"   r"   r#   Ú<module>   s˜   @
ÿü
 ÿ	

#
  ÿ
&
!     
'/