3
yYðiÙœ  ã               @   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	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j.dƒZ/ej.dej0ƒZ1ej.dƒZ2ej.dej0ƒj3Z4dj5ƒ Z6ddddgZ7dZ8dZ9e9j:ej;dd… ed�Z<dd„ Z=dd„ Z>dd„ Z?dEd d„Z@dFd!d"„ZAdGd#d$„ZBdedfd%d„ZCdHd&d'„ZDd(d)„ ZEej.d*ej0ƒZFeEd+d,„ ƒZGG d-d.„ d.eHƒZIG d/d0„ d0eIƒZJG d1d„ deƒZKej.d2ƒjLZMd3d4„ ZNd5d6„ ZOdId7d8„ZPd9d:„ ZQG d;d<„ d<eHƒZRG d=d>„ d>ejSƒZTejUjVfd?d@„ZWePe8ƒeWƒZWdAdB„ ZXdCdD„ ZYdS )Jz#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>
\s+\(<a (?:title="MD5 hash"
\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py_majorÚ
setuptoolsc             C   s2   y
t j| ƒ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-build-ue6tjl93/setuptools/setuptools/package_index.pyÚparse_requirement_arg2   s
    
r(   c             C   s°   | j ƒ }d\}}}|jdƒr¦|jdƒr8| dd… }d}nn|jddƒrb| dd… }| dd… }d}nD|jd
ƒr~| dd… }d}n(|jddƒr¦| dd… }| dd… }d}|||fS )z=Return (base,pyversion) or (None,None) for possible .exe nameNz.exez
.win32.exeé
   Úwin32z	.win32-pyé   é   é   z.win-amd64.exeé   z	win-amd64z.win-amd64-pyé   )NNNiöÿÿÿiðÿÿÿiùÿÿÿéüÿÿÿiðÿÿÿiòÿÿÿiìÿÿÿiùÿÿÿr0   iìÿÿÿ)ÚlowerÚendswithÚ
startswith)Únamer1   ÚbaseÚpy_verÚplatr&   r&   r'   r   ;   s$    



c       	      C   sx   t jj| ƒ}|\}}}}}}t jj|jdƒd ƒ}|dkrX|dkrXt jj|jdƒd ƒ}d|krp|jddƒ\}}||fS )	Nú/é   zsourceforge.netÚdownloadé   ú#éÿÿÿÿéþÿÿÿ)r   r#   ÚurlparseÚunquoteÚsplit)	ÚurlÚpartsÚschemeÚserverÚpathÚ
parametersÚqueryÚfragmentr5   r&   r&   r'   Úegg_info_for_urlS   s    rJ   c             c   sd   t | ƒ\}}xt| ||ƒD ]
}|V  qW |r`tj|ƒ}|r`x$t| |jdƒ|td�D ]
}|V  qRW dS )zEYield egg or source distribution objects that might be found at a URLr9   )Ú
precedenceN)rJ   Údistros_for_locationÚEGG_FRAGMENTÚmatchr   Úgroupr   )rB   Úmetadatar5   rI   ÚdistrN   r&   r&   r'   r   ^   s    

c             C   sä   |j dƒr|dd
… }|j dƒr8d|kr8tj| ||ƒgS |j dƒrxd|krxt|ƒ}|jƒ s^g S t| |j|jtd d�gS |j d	ƒrªt|ƒ\}}}|dk	rªt	| |||t
|ƒS x4tD ],}|j |ƒr°|dt|ƒ … }t	| ||ƒS q°W g S )z:Yield egg or source distribution objects based on basenamez.egg.zipNr-   z.eggú-z.whlr9   )ÚlocationÚproject_nameÚversionrK   z.exer0   )r2   r	   Úfrom_locationr   Zis_compatiblerT   rU   r   r   r   r
   Ú
EXTENSIONSÚlen)rS   ÚbasenamerP   ÚwheelZwin_baser6   ÚplatformÚextr&   r&   r'   rL   l   s.    



rL   c             C   s   t t| ƒtjj| ƒ|ƒS )zEYield possible egg or source distribution objects based on a filename)rL   r   ÚosrF   rY   )ÚfilenamerP   r&   r&   r'   Údistros_for_filename�   s    r_   c          
   c   s‚   |j dƒ}| r.tdd„ |dd… D ƒƒr.dS xNtdt|ƒd ƒD ]8}t| |dj|d|… ƒdj||d… ƒ|||d�V  qBW 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!
    rR   c             s   s   | ]}t jd |ƒV  qdS )z	py\d\.\d$N)ÚrerN   )Ú.0Úpr&   r&   r'   ú	<genexpr>«   s    z(interpret_distro_name.<locals>.<genexpr>r;   Nr9   )Ú
py_versionrK   r[   )rA   ÚanyÚrangerX   r	   Újoin)rS   rY   rP   rd   rK   r[   rC   rb   r&   r&   r'   r   ”   s    
 $c             c   sn   t ƒ }|j}|dkr>xTtjj|j| ƒD ]}||ƒ |V  q&W n,x*| D ]"}||ƒ}||krD||ƒ |V  qDW 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    
rr   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)rr   )ÚargsÚkwargs)Úfuncr&   r'   ÚwrapperÐ   s    zunique_values.<locals>.wrapper)r   )ru   rv   r&   )ru   r'   Úunique_valuesÊ   s    rw   z3<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>c             c   sÆ   xvt j|ƒD ]h}|jƒ \}}tttj|jƒ jdƒƒƒ}d|ksFd|krx,t	j|ƒD ]}t
jj| t|jdƒƒƒV  qRW qW xHdD ]@}|j|ƒ}|d	kr~t	j||ƒ}|r~t
jj| t|jdƒƒƒV  q~W dS )
zEFind rel="homepage" and rel="download" links in `page`, yielding URLsú,Zhomepager:   r9   ú<th>Home Pageú<th>Download URLN)ry   rz   r=   )ÚRELÚfinditerÚgroupsrh   r   ÚstrÚstripr1   rA   ÚHREFr   r#   ÚurljoinÚ
htmldecoderO   ÚfindÚsearch)rB   ÚpagerN   Ú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j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j|ƒ| _|| _d S )N)Ú	hash_nameÚhashlibÚnewÚhashÚexpected)r‹   r—   r›   r&   r&   r'   Ú__init__  s    zHashChecker.__init__c             C   s>   t jj|ƒd }|stƒ S | jj|ƒ}|s0tƒ S | f |jƒ ŽS )z5Construct a (possibly null) ContentChecker from a URLr9   r=   )r   r#   r?   rŠ   Úpatternr„   Ú	groupdict)ÚclsrB   rI   rN   r&   r&   r'   Úfrom_url  s    zHashChecker.from_urlc             C   s   | j j|ƒ d S )N)rš   Úupdate)r‹   rŒ   r&   r&   r'   r�     s    zHashChecker.feedc             C   s   | j jƒ | jkS )N)rš   Ú	hexdigestr›   )r‹   r&   r&   r'   rŽ      s    zHashChecker.is_validc             C   s   || j  }||ƒS )N)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dKdd„ZdLd	d
„ZdMdd„ZdNdd„Zdd„ Zdd„ Z	dd„ Z
dd„ ZdOdd„Zdd„ ZdP‡ fdd„	Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zd%d&„ ZdQd'd(„ZdRd)d*„Zd+d,„ Zd-Zd.d/„ Zd0d1„ ZdSd2d3„Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Ze dTd>d?„ƒZ!d@dA„ Z"dBdC„ Z#dDdE„ Z$dFdG„ Z%dHdI„ Z&‡  Z'S )Ur   z;A distribution index that scans web pages for download URLsúhttps://pypi.python.org/simpleÚ*NTc             O   s”   t j| f|ž|Ž |dd |jdƒ …  | _i | _i | _i | _tjdj	t
t|ƒƒƒj| _g | _|ortjor|prtjƒ }|r†tj|ƒ| _n
tjj| _d S )Nr8   ú|)r   rœ   r2   Ú	index_urlÚscanned_urlsÚfetched_urlsÚpackage_pagesr`   r¤   rg   r   r   rN   ÚallowsÚto_scanr   Zis_availableZfind_ca_bundleZ
opener_forÚopenerr   ÚrequestÚurlopen)r‹   r©   ÚhostsZ	ca_bundleZ
verify_sslrs   ÚkwZuse_sslr&   r&   r'   rœ   +  s    zPackageIndex.__init__Fc             C   sÂ  || j kr| rdS d| j |< t|ƒs4| j|ƒ dS tt|ƒƒ}|r^| j|ƒsRdS | jd|ƒ |sr| sr|| jkr†tt| j	|ƒƒ dS | j|ƒsžd| j|< dS | j
d|ƒ d| j|< d}| j||| ƒ}|dkrÔdS d| j|j< d|jjddƒjƒ k�r|jƒ  dS |j}|jƒ }t|tƒ�sRt|tjjƒ�r4d	}n|jjd
ƒ�pDd	}|j|dƒ}|jƒ  x6tj|ƒD ](}	tjj|t|	jdƒƒƒ}
| j|
ƒ �qfW |j | j!ƒ�r¾t"|ddƒdk�r¾| j#||ƒ}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!Úhtmlzcontent-typeÚ zlatin-1ÚcharsetÚignorer9   Úcodei”  )$rª   Ú
URL_SCHEMEÚprocess_filenameÚlistr   Úurl_okÚdebugr«   r   ri   ÚinfoÚopen_urlrB   ÚheadersÚgetr1   ÚcloseÚreadÚ
isinstancer~   r   ÚerrorÚ	HTTPErrorÚ	get_paramÚdecoder€   r|   r#   r�   r‚   rO   Úprocess_urlr3   r©   ÚgetattrÚprocess_index)r‹   rB   ÚretrieveÚdistsÚtmplÚfr5   r…   r¶   rN   Úlinkr&   r&   r'   rÉ   @  sP    





 zPackageIndex.process_urlc             C   s�   t jj|ƒs| jd|ƒ d S t jj|ƒrd| rdt jj|ƒ}x(t j|ƒD ]}| jt jj||ƒdƒ qFW t	|ƒ}|rŒ| j
d|ƒ tt| j|ƒƒ d S )NzNot found: %sTz	Found: %s)r]   rF   ÚexistsÚwarnÚisdirÚrealpathÚlistdirrº   rg   r_   r½   r»   r   ri   )r‹   ÚfnÚnestedrF   ÚitemrÍ   r&   r&   r'   rº   s  s    zPackageIndex.process_filenamec             C   sb   t |ƒ}|o|jdƒjƒ dk}|s8| jtjj|ƒd ƒr<dS d}|rRt|| ƒ‚n| j||ƒ d S )Nr9   ÚfileTzN
Note: Bypassing %s (disallowed host; see http://bit.ly/2hrImnY for details).
)	r¹   rO   r1   r­   r   r#   r?   r   rÒ   )r‹   rB   Ú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| j|ƒƒ d S )Nc             s   s0   | ](}t j|ƒD ]}|jd ƒr||fV  qqdS )z	.egg-linkN)r]   rÕ   r2   )ra   rF   Úentryr&   r&   r'   rc   “  s   z.PackageIndex.scan_egg_links.<locals>.<genexpr>)Úfilterr]   rF   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j||ƒƒ�}ttd ttj|ƒƒƒ}W d Q R X t	|ƒdkrDd S |\}}x>t
tjj||ƒƒD ](}tjj|f|žŽ |_t|_| j|ƒ q`W d S )Nr;   )Úopenr]   rF   rg   r»   rÞ   r   r~   r   rX   r   rS   r   rK   ri   )r‹   rF   rÝ   Z	raw_linesÚlinesZegg_pathZ
setup_pathrQ   r&   r&   r'   rá   š  s     zPackageIndex.scan_egg_linkc       
         sØ   ‡ fdd„}xHt j|ƒD ]:}y |tjj|t|jdƒƒƒƒ W q tk
rP   Y qX qW ||ƒ\}}|rÐxXt||ƒD ]J}t	|ƒ\}}	|j
dƒr²|	 r²|r¨|d||f 7 }n
ˆ j|ƒ ˆ j|ƒ qrW tjdd„ |ƒS dS d	S )
z#Process the contents of a PyPI pagec                sŒ   | j ˆ jƒrˆtttjj| tˆ jƒd … jdƒƒƒ}t|ƒdkrˆd|d krˆt	|d ƒ}t
|d ƒ}dˆ jj|jƒ i ƒ| < t|ƒt|ƒfS dS )Nr8   r;   r<   r9   r   T)NN)r3   r©   r»   r   r   r#   r@   rX   rA   r   r   r¬   Ú
setdefaultr1   r   )rÐ   rC   ÚpkgÚver)r‹   r&   r'   Úscan­  s    "z(PackageIndex.process_index.<locals>.scanr9   z.pyz
#egg=%s-%sc             S   s   d| j dddƒ S )Nz<a href="%s#md5=%s">%s</a>r9   r!   r;   )rO   )Úmr&   r&   r'   Ú<lambda>Ð  s    z,PackageIndex.process_index.<locals>.<lambda>rµ   N)r€   r|   r   r#   r�   r‚   rO   r$   r‰   rJ   r2   Úneed_version_infoÚscan_urlÚPYPI_MD5Úsub)
r‹   rB   r…   rê   rN   rè   ré   Únew_urlr5   Úfragr&   )r‹   r'   rË   ª  s$     

zPackageIndex.process_indexc             C   s   | j d|ƒ d S )NzPPage at %s links to .py file(s) without version info; an index scan is required.)Úscan_all)r‹   rB   r&   r&   r'   rí   Õ  s    zPackageIndex.need_version_infoc             G   s:   | j | jkr*|r | j|f|žŽ  | jdƒ | j| j ƒ d S )Nz6Scanning index of all packages (this may take a while))r©   r«   rÒ   r¾   rî   )r‹   r£   rs   r&   r&   r'   ró   Û  s    zPackageIndex.scan_allc             C   s~   | j | j|j d ƒ | jj|jƒs:| j | j|j d ƒ | jj|jƒsR| j|ƒ x&t| jj|jf ƒƒD ]}| j |ƒ qhW d S )Nr8   )	rî   r©   Úunsafe_namer¬   rÁ   rn   rT   Únot_found_in_indexr»   )r‹   ÚrequirementrB   r&   r&   r'   Úfind_packagesä  s    
zPackageIndex.find_packagesc                sR   | j ƒ  | j|ƒ x,| |j D ]}||kr.|S | jd||ƒ qW tt| ƒj||ƒS )Nz%s does not match %s)Úprescanr÷   rn   r½   Úsuperr   Úobtain)r‹   rö   Ú	installerrQ   )Ú	__class__r&   r'   rú   ó  s    
zPackageIndex.obtainc             C   sL   |j | jd| ƒ |jƒ sH|jƒ  tj|ƒ td|jjtj	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Â   r]   Úunlinkr   rš   r4   rF   rY   )r‹   Úcheckerr^   Útfpr&   r&   r'   Ú
check_hashü  s    

zPackageIndex.check_hashc             C   sT   xN|D ]F}| j dks4t|ƒ s4|jdƒs4tt|ƒƒr@| j|ƒ q| j j|ƒ qW dS )z;Add `urls` to the list that will be prescanned for searchesNzfile:)r®   r¹   r3   r»   r   rî   Úappend)r‹   ÚurlsrB   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ƒ | jƒ  d S )Nz#Couldn't retrieve index page for %rz3Couldn't find index page for %r (maybe misspelled?))rn   r¾   rÒ   rô   ró   )r‹   rö   Úmethr£   r&   r&   r'   rõ   !  s    
zPackageIndex.not_found_in_indexc             C   s~   t |tƒsjt|ƒ}|rR| j|jdƒ||ƒ}t|ƒ\}}|jdƒrN| j|||ƒ}|S tj	j
|ƒrb|S t|ƒ}t| j||ƒ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.
        r9   z.pyrS   N)rÄ   r   r¹   Ú_download_urlrO   rJ   r2   Ú	gen_setupr]   rF   rÑ   r(   rÊ   Úfetch_distribution)r‹   r%   ÚtmpdirrD   Úfoundr5   rI   r&   r&   r'   r:   +  s    

zPackageIndex.downloadc       	         sà   ˆj d|ƒ i ‰d}d
‡ ‡‡‡‡fdd„	}|rHˆjƒ  ˆj|ƒ ||ƒ}| r`|dk	r`|||ƒ}|dkr‚ˆjdk	rzˆjƒ  ||ƒ}|dkr¢| r¢ˆj|ƒ ||ƒ}|dkrÂˆjdˆr¸dpºd|ƒ nˆj 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ˆ}x‚|| j  D ]t}|jtkrJˆ  rJ|ˆkrˆjd|ƒ dˆ|< q|| ko`|jtkp`ˆ }|rˆj|jˆƒ}||_tj	j
|jƒr|S qW d S )Nz&Skipping development or system egg: %sr9   )rn   rK   r   rÒ   r   r:   rS   Údownload_locationr]   rF   rÑ   )ÚreqÚenvrQ   ÚtestÚloc)Ú
develop_okr‹   ÚskippedÚsourcer  r&   r'   rƒ   e  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)rS   )N)r¾   rø   r÷   r®   rÒ   Úcloner
  )	r‹   rö   r  Ú
force_scanr  r  Zlocal_indexrQ   rƒ   r&   )r  r‹   r  r  r  r'   r  M  s0    




zPackageIndex.fetch_distributionc             C   s"   | j ||||ƒ}|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  rS   )r‹   rö   r  r  r  rQ   r&   r&   r'   Úfetch™  s    zPackageIndex.fetchc       
      C   sü   t j|ƒ}|r*dd„ t||jdƒd ƒD ƒp,g }t|ƒdkrÚtjj|ƒ}tjj|ƒ|krŠtjj	||ƒ}ddl
m} |||ƒsŠtj||ƒ |}ttjj	|dƒdƒ�2}	|	jd|d j|d jtjj|ƒd f ƒ W d Q R X |S |rðtd	||f ƒ‚ntd
ƒ‚d S )Nc             S   s   g | ]}|j r|‘qS r&   )rU   )ra   Údr&   r&   r'   ú
<listcomp>©  s    z*PackageIndex.gen_setup.<locals>.<listcomp>r9   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.)rM   rN   r   rO   rX   r]   rF   rY   Údirnamerg   Zsetuptools.command.easy_installr  ÚshutilÚcopy2rå   ÚwriterT   rU   Úsplitextr   )
r‹   r^   rI   r  rN   rÍ   rY   Údstr  rÙ   r&   r&   r'   r  ¦  s2    

 zPackageIndex.gen_setupi    c             C   s  | j d|ƒ d }zîtj|ƒ}| j|ƒ}t|tjjƒrJtd||j	|j
f ƒ‚|j ƒ }d}| j}d}d|kr’t|dƒ}	ttt|	ƒƒ}| j|||||ƒ t|dƒ�Z}
xD|j|ƒ}|rÞ|j|ƒ |
j|ƒ |d7 }| j|||||ƒ q P q W | j|||
ƒ W d Q R X |S |�r|jƒ  X d S )	NzDownloading %szCan't download %s: %s %sr   r9   zcontent-lengthzContent-LengthÚwbr=   )r¾   r–   r    r¿   rÄ   r   rÅ   rÆ   r   r¸   r£   Údl_blocksizer   Úmaxr   ÚintÚ
reporthookrå   rÃ   r�   r  r   rÂ   )r‹   rB   r^   Úfprþ   rÀ   ÚblocknumÚbsÚsizeÚsizesrÿ   rŒ   r&   r&   r'   Ú_download_toÑ  s:    





zPackageIndex._download_toc             C   s   d S )Nr&   )r‹   rB   r^   r%  Zblksizer'  r&   r&   r'   r#  õ  s    zPackageIndex.reporthookc             C   sŒ  |j dƒrt|ƒS yt|| jƒS  ttjfk
r€ } z>djdd„ |jD ƒƒ}|r^| j	||ƒ nt
d||f ƒ‚W Y d d }~X �n tjjk
r¢ } z|S d }~X næ tjjk
rì } z,|rÊ| j	||jƒ nt
d||jf ƒ‚W Y d d }~X nœ tjk
�r8 } z.|�r| j	||jƒ nt
d||jf ƒ‚W Y d d }~X nP tjtjfk
�r† } z*|�rf| j	||ƒ nt
d||f ƒ‚W Y d d }~X nX d S )Nzfile:ú c             S   s   g | ]}t |ƒ‘qS r&   )r~   )ra   Ú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)r3   Ú
local_openÚopen_with_authr¯   r$   r   Ú
InvalidURLrg   rs   rÒ   r   r   rÅ   rÆ   ÚURLErrorÚreasonÚBadStatusLineÚlineÚHTTPExceptionÚsocket)r‹   rB   ÚwarningÚvr£   r&   r&   r'   r¿   ø  s6    
"zPackageIndex.open_urlc             C   sê   t |ƒ\}}|r4x&d|kr0|jddƒjddƒ}qW nd}|jdƒrN|d d… }tjj||ƒ}|dksn|jd	ƒrz| j||ƒS |d
ksŒ|jdƒr˜| j||ƒS |jdƒr®| j	||ƒS |dkrÎt
jjt
jj|ƒd ƒS | j|dƒ | j||ƒS d S )Nz..Ú.ú\Ú_Z__downloaded__z.egg.zipr-   Úsvnzsvn+Úgitzgit+zhg+rÙ   r;   Tr0   )rJ   Úreplacer2   r]   rF   rg   r3   Ú_download_svnÚ_download_gitÚ_download_hgr   r°   Úurl2pathnamer#   r?   r¼   Ú_attempt_download)r‹   rD   rB   r  r4   rI   r^   r&   r&   r'   r    s$    


zPackageIndex._download_urlc             C   s   | j |dƒ d S )NT)rÉ   )r‹   rB   r&   r&   r'   rî   8  s    zPackageIndex.scan_urlc             C   s6   | j ||ƒ}d|jddƒjƒ kr.| j|||ƒS |S d S )Nr´   zcontent-typerµ   )r)  rÁ   r1   Ú_download_html)r‹   rB   r^   rÀ   r&   r&   r'   rA  ;  s    zPackageIndex._attempt_downloadc             C   sl   t |ƒ}x@|D ]8}|jƒ rtjd|ƒrD|jƒ  tj|ƒ | j||ƒS P qW |jƒ  tj|ƒ td| ƒ‚d S )Nz <title>([^- ]+ - )?Revision \d+:zUnexpected HTML page found at )	rå   r   r`   r„   rÂ   r]   rý   r=  r   )r‹   rB   rÀ   r^   rÙ   r2  r&   r&   r'   rB  B  s    


zPackageIndex._download_htmlc             C   s  |j ddƒd }d}|jƒ jdƒrÜd|krÜtjj|ƒ\}}}}}}	| rÜ|jdƒrÜd|d	d … krÜ|d	d … j ddƒ\}}tjj|ƒ\}
}|
rÜd
|
kr´|
j d
dƒ\}}d||f }nd|
 }|}||||||	f}tjj|ƒ}| jd||ƒ t	j
d|||f ƒ |S )Nr<   r9   r   rµ   zsvn:ú@z//r8   r;   ú:z --username=%s --password=%sz --username=z'Doing subversion checkout from %s to %szsvn checkout%s -q %s %s)rA   r1   r3   r   r#   r?   Ú	splituserÚ
urlunparser¾   r]   Úsystem)r‹   rB   r^   ÚcredsrD   ÚnetlocrF   rb   ÚqrÏ   ÚauthÚhostÚuserÚpwrC   r&   r&   r'   r=  Q  s$     zPackageIndex._download_svnc             C   sp   t jj| ƒ\}}}}}|jddƒd }|jddƒd }d }d|krR|jddƒ\}}t jj||||dfƒ} | |fS )Nú+r9   r<   r   rC  rµ   r=   )r   r#   ÚurlsplitrA   ÚrsplitÚ
urlunsplit)rB   Ú
pop_prefixrD   rI  rF   rH   rò   Úrevr&   r&   r'   Ú_vcs_split_rev_from_urlf  s    z$PackageIndex._vcs_split_rev_from_urlc             C   sl   |j ddƒd }| j|dd�\}}| jd||ƒ tjd||f ƒ |d k	rh| jd|ƒ tjd	||f ƒ |S )
Nr<   r9   r   T)rS  zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %sz"(cd %s && git checkout --quiet %s))rA   rU  r¾   r]   rG  )r‹   rB   r^   rT  r&   r&   r'   r>  x  s    
zPackageIndex._download_gitc             C   sl   |j ddƒd }| j|dd�\}}| jd||ƒ tjd||f ƒ |d k	rh| jd|ƒ tjd	||f ƒ |S )
Nr<   r9   r   T)rS  zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %sz(cd %s && hg up -C -r %s -q))rA   rU  r¾   r]   rG  )r‹   rB   r^   rT  r&   r&   r'   r?  ˆ  s    
zPackageIndex._download_hgc             G   s   t j|f|žŽ  d S )N)r   r½   )r‹   r£   rs   r&   r&   r'   r½   ˜  s    zPackageIndex.debugc             G   s   t j|f|žŽ  d S )N)r   r¾   )r‹   r£   rs   r&   r&   r'   r¾   ›  s    zPackageIndex.infoc             G   s   t j|f|žŽ  d S )N)r   rÒ   )r‹   r£   rs   r&   r&   r'   rÒ   ž  s    zPackageIndex.warn©r§   )r¦   rV  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  r  r  r   r)  r#  r¿   r  rî   rA  rB  r=  ÚstaticmethodrU  r>  r?  r½   r¾   rÒ   Ú__classcell__r&   r&   )rü   r'   r   (  sL    

3


+
		
# 
J
)$
#z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c             C   s   | j dƒ}t|ƒS )Nr9   )rO   r   )rN   Úwhatr&   r&   r'   Údecode_entity§  s    
rZ  c             C   s
   t t| ƒS )z'Decode HTML entities in the given text.)Ú
entity_subrZ  )Útextr&   r&   r'   r‚   ¬  s    r‚   c                s   ‡ fdd„}|S )Nc                s   ‡ ‡fdd„}|S )Nc                 s.   t jƒ }t jˆƒ z
ˆ | |ŽS t j|ƒ X d S )N)r4  ÚgetdefaulttimeoutÚsetdefaulttimeout)rs   rt   Zold_timeout)ru   Útimeoutr&   r'   Ú_socket_timeout³  s
    

z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr&   )ru   r`  )r_  )ru   r'   r`  ²  s    z'socket_timeout.<locals>._socket_timeoutr&   )r_  r`  r&   )r_  r'   Úsocket_timeout±  s    ra  c             C   s2   t jj| ƒ}|jƒ }tj|ƒ}|jƒ }|j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ÚencodestringrÈ   r<  )rK  Zauth_sZ
auth_bytesZencoded_bytesÚencodedr&   r&   r'   Ú_encode_authÀ  s
    
rg  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 )N)ÚusernameÚpassword)r‹   ri  rj  r&   r&   r'   rœ   Ü  s    zCredential.__init__c             c   s   | j V  | jV  d S )N)ri  rj  )r‹   r&   r&   r'   Ú__iter__à  s    zCredential.__iter__c             C   s   dt | ƒ S )Nz%(username)s:%(password)s)Úvars)r‹   r&   r&   r'   Ú__str__ä  s    zCredential.__str__N)r’   r“   r”   r•   rœ   rk  rm  r&   r&   r&   r'   rh  ×  s   rh  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 jdddgdƒ}tjj| |ƒ tjjtjjdƒdƒ}tjj	|ƒrL| j
|ƒ dS )z%
        Load from ~/.pypirc
        ri  rj  Ú
repositoryrµ   ú~z.pypircN)ÚdictÚfromkeysr   ÚRawConfigParserrœ   r]   rF   rg   Ú
expanduserrÑ   rÃ   )r‹   ÚdefaultsÚrcr&   r&   r'   rœ   é  s
    zPyPIConfig.__init__c                s&   ‡ fdd„ˆ j ƒ D ƒ}ttˆ j|ƒƒS )Nc                s    g | ]}ˆ j |d ƒjƒ r|‘qS )ro  )rÁ   r   )ra   Úsection)r‹   r&   r'   r  ÷  s    z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)Úsectionsrq  r   Ú_get_repo_cred)r‹   Zsections_with_repositoriesr&   )r‹   r'   Úcreds_by_repositoryô  s    zPyPIConfig.creds_by_repositoryc             C   s6   | j |dƒjƒ }|t| j |dƒjƒ | j |dƒjƒ ƒfS )Nro  ri  rj  )rÁ   r   rh  )r‹   rw  Úrepor&   r&   r'   ry  ý  s    zPyPIConfig._get_repo_credc             C   s*   x$| j jƒ D ]\}}|j|ƒr|S qW dS )zŒ
        If the URL indicated appears to be a repository defined in this
        config, return the credential for that repository.
        N)rz  Úitemsr3   )r‹   rB   ro  Úcredr&   r&   r'   Úfind_credential  s    
zPyPIConfig.find_credentialN)r’   r“   r”   rœ   Úpropertyrz  ry  r~  r&   r&   r&   r'   rn  è  s   	rn  c             C   s:  t jj| ƒ\}}}}}}|jdƒr,tjdƒ‚|d
krFt jj|ƒ\}}	nd}|s~tƒ j| ƒ}
|
r~t	|
ƒ}|
j
| f}tjd|žŽ  |rÄdt|ƒ }||	||||f}t jj|ƒ}t jj|ƒ}|jd|ƒ nt jj| ƒ}|jd	tƒ ||ƒ}|�r6t jj|jƒ\}}}}}}||k�r6||	k�r6||||||f}t jj|ƒ|_|S )z4Open a urllib2 request, handling HTTP authenticationrD  znonnumeric port: ''ÚhttpÚhttpsNú*Authenticating as %s for %s (from .pypirc)zBasic ÚAuthorizationz
User-Agent)r€  r�  )r‚  )r   r#   r?   r2   r   r.  rE  rn  r~  r~   ri  r   r¾   rg  rF  r°   ÚRequestÚ
add_headerÚ
user_agentrB   )rB   r¯   rD   rI  rF   ÚparamsrH   rò   rK  rL  r}  r¾   rC   rñ   r°   r$  Ús2Úh2Úpath2Zparam2Zquery2Zfrag2r&   r&   r'   r-    s6    


r-  c             C   s   | S )Nr&   )rB   r&   r&   r'   Ú
fix_sf_url?  s    r‹  c             C   s  t jj| ƒ\}}}}}}t jj|ƒ}tjj|ƒr<t jj| ƒS |j	dƒrêtjj
|ƒrêg }xˆtj|ƒD ]b}	tjj||	ƒ}
|	dkržt|
dƒ�}|jƒ }W dQ R X P ntjj
|
ƒr²|	d7 }	|jdj|	d�ƒ qbW d}|j| dj|ƒd	�}d\}}n
d\}}}ddi}tj|ƒ}t jj| ||||ƒS )z7Read a local path, with special support for directoriesr8   z
index.htmlÚrNz<a href="{name}">{name}</a>)r4   zB<html><head><title>{url}</title></head><body>{files}</body></html>rb  )rB   ÚfileséÈ   ÚOKé”  úPath not foundú	Not foundzcontent-typez	text/html)rŽ  r�  )r�  r‘  r’  )r   r#   r?   r°   r@  r]   rF   Úisfiler±   r2   rÓ   rÕ   rg   rå   rÃ   r  Úformatr   ÚStringIOrÅ   rÆ   )rB   rD   rE   rF   ÚparamrH   rò   r^   r�  rÏ   Úfilepathr$  ÚbodyrÎ   ÚstatusÚmessagerÀ   Zbody_streamr&   r&   r'   r,  C  s,    


r,  )N)N)N)N)r    )Zr•   Úsysr]   r`   r  r4  rd  r˜   rß   Ú	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   Zdistutils.errorsr   Úfnmatchr   Zsetuptools.py27compatr   Zsetuptools.py33compatr   Zsetuptools.wheelr   r¤   rM   ÚIr€   rï   rN   r¹   rA   rW   Ú__all__Z_SOCKET_TIMEOUTZ_tmplr”  rU   r†  r(   r   rJ   r   rL   r_   r   rr   rw   r{   r‰   ÚobjectrŠ   r–   r   rð   r[  rZ  r‚   ra  rg  rh  rs  rn  r°   r±   r-  r‹  r,  r&   r&   r&   r'   Ú<module>   s|   <
	

!
"
!     
&.