3
LY                 @   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
 yddlmZ W n  ek
r   ddlmZ Y nX 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/ ej0dZ1ej0dej2Z3ej0dZ4ej0dej2j5Z6dj7 Z8ddddgZ9dZ:dZ;e;j<f dej=dd ie> 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j0d*ej2ZIeHd+d, ZJG d-d. d.eKZLG d/d0 d0eLZMG d1d deZNej0d2jOZPd3d4 ZQd5d6 ZRd7d8 ZSdKd9d:ZTd;d< ZUG d=d> d>eKZVG d?d@ d@ejWZXejYjZfdAdBZ[eTe:e[Z[dCdD Z\dEdF Z]dS )Lz#PyPI and direct package downloading    N)wraps)	splituser)six)urllibhttp_clientconfigparsermap)CHECKOUT_DISTDistributionBINARY_DISTnormalize_pathSOURCE_DISTrequireEnvironmentfind_distributions	safe_namesafe_versionto_filenameRequirementDEVELOP_DIST)ssl_support)log)DistutilsError)	translate)strip_fragment)get_all_headersz^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   c             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%   r/private/var/folders/7d/20zwc49s3kn54d3vgq8bd4640000gn/T/pip-build-an2lx5zf/setuptools/setuptools/package_index.pyparse_requirement_arg6   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   )NNNiiiiiiir/   i)lowerendswith
startswith)namer0   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pathZ
parametersqueryfragmentr4   r%   r%   r&   egg_info_for_urlW   s    rH   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 URLr8   )
precedenceN)rH   distros_for_locationEGG_FRAGMENTmatchr   groupr	   )rA   metadatar4   rG   distrL   r%   r%   r&   r   b   s    

c             C   s   |j dr|dd }|j dr8d|kr8tj| ||gS |j drjt|\}}}|dk	rjt| |||t|S x4tD ],}|j |rp|dt|  }t| ||S qpW g S )z:Yield egg or source distribution objects based on basenamez.egg.zipNr,   z.egg-z.exer/   )r1   r
   from_locationr   r   r   
EXTENSIONSlen)locationbasenamerN   Zwin_baser5   platformextr%   r%   r&   rJ   p   s    



rJ   c             C   s   t t| tjj| |S )zEYield possible egg or source distribution objects based on a filename)rJ   r   osrE   rU   )filenamerN   r%   r%   r&   distros_for_filename   s    rZ   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 )zGenerate alternative interpretations of a source distro name

    Note: if `location` is a filesystem filename, you should call
    ``pkg_resources.normalize_path()`` on it before passing it to this
    routine!
    rP   c             s   s   | ]}t jd |V  qdS )z	py\d\.\d$N)rerL   ).0pr%   r%   r&   	<genexpr>   s    z(interpret_distro_name.<locals>.<genexpr>r:   Nr8   )
py_versionrI   rV   )r@   anyrangerS   r
   join)rT   rU   rN   r_   rI   rV   rB   r]   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    
rm   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)rm   )argskwargs)funcr%   r&   wrapper   s    zunique_values.<locals>.wrapper)r   )rp   rq   r%   )rp   r&   unique_values   s    rr   z(<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>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homepager9   r8   <th>Home Page<th>Download URLN)rt   ru   r<   )RELfinditergroupsrc   r   strstripr0   r@   HREFr   r"   urljoin
htmldecoderM   findsearch)rA   pagerL   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 URLr8   r<   )r   r"   r>   r   patternr   	groupdict)clsrA   rG   rL   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 }|rtj|| _n
tjj| _d S )Nr7   |)r   r   r1   	index_urlscanned_urlsfetched_urlspackage_pagesr[   r   rb   r   r   rL   allowsto_scanr   Zis_availableZfind_ca_bundleZ
opener_foropenerr   requesturlopen)r   r   hostsZ	ca_bundleZ
verify_sslrn   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rtt| j	| dS | j|sd| j|< dS | j
d| d| j|< d}| j||| }|dkrd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!rt"|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ignorer8   codei  )$r   
URL_SCHEMEprocess_filenamelistr   url_okdebugr   r   rd   infoopen_urlrA   headersgetr0   closeread
isinstancery   r   error	HTTPError	get_paramdecoder{   rw   r"   r|   r}   rM   process_urlr2   r   getattrprocess_index)r   rA   retrievediststmplfr4   r   r   rL   linkr%   r%   r&   r   9  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)rX   rE   existswarnisdirrealpathlistdirr   rb   rZ   r   r   r   rd   )r   fnnestedrE   itemr   r%   r%   r&   r   k  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 )Nr8   fileTzN
Note: Bypassing %s (disallowed host; see http://bit.ly/1dg9ijs for details).
)	r   rM   r0   r   r   r"   r>   r   r   )r   rA   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)rX   r   r1   )r\   rE   entryr%   r%   r&   r^     s   z.PackageIndex.scan_egg_links.<locals>.<genexpr>)filterrX   rE   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:   )openrX   rE   rb   r   r   r   ry   rz   rS   r   rT   r   rI   rd   )r   rE   r   Z	raw_lineslinesZegg_pathZ
setup_pathrO   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 ||\}}|rxXt||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rtttjj| t jd  jd}t|dkrd|d krt	|d }t
|d }d jj|j i | < t|t|fS dS )Nr7   r:   r;   r8   r   T)NN)r2   r   r   r   r   r"   r?   rS   r@   r   r   r   
setdefaultr0   r   )r   rB   pkgver)r   r%   r&   scan  s    "z(PackageIndex.process_index.<locals>.scanr8   z.pyz
#egg=%s-%sc             S   s   d| j ddd S )Nz<a href="%s#md5=%s">%s</a>r8   r!   r:   )rM   )mr%   r%   r&   <lambda>  s    z,PackageIndex.process_index.<locals>.<lambda>r   N)r{   rw   r   r"   r|   r}   rM   r#   r   rH   r1   need_version_infoscan_urlPYPI_MD5sub)
r   rA   r   r   rL   r   r   new_urlr4   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   rA   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   rn   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 )Nr7   )	r   r   unsafe_namer   r   ri   project_namenot_found_in_indexr   )r   requirementrA   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   ri   r   superr   obtain)r   r   	installerrO   )	__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   rX   unlinkr   r   r3   rE   rU   )r   checkerrY   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   r2   r   r   r   append)r   urlsrA   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?))ri   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.
        r8   z.pyrT   N)r   r   r   _download_urlrM   rH   r1   	gen_setuprX   rE   r   r'   r   fetch_distribution)r   r$   tmpdirrC   foundr4   rG   r%   r%   r&   r9      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rdpd| 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}xz|| j  D ]l}|jtkrJ  rJ|krjd| d|< q|| kr|jtksb rj|j|_tj	j
|jr|S qW d S )Nz&Skipping development or system egg: %sr8   )ri   rI   r   r   r   r9   rT   download_locationrX   rE   r   )reqenvrO   )
develop_okr   skippedsourcer  r%   r&   r~   [  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)rT   )N)r   r   r   r   r   cloner  )	r   r   r  
force_scanr  r	  Zlocal_indexrO   r~   r%   )r	  r   r
  r  r  r&   r  B  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  rT   )r   r   r  r  r  rO   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rtjj|}tjj||krtjj	||}ddl
m} |||st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 |rtd	||f ntd
d S )Nc             S   s   g | ]}|j r|qS r%   )version)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])
zCan't unambiguously interpret project/version identifier %r; any dashes in the name or version should be escaped using underscores. %rzpCan't process plain .py files without an '#egg=name-version' suffix to enable automatic setup script generation.)rK   rL   r   rM   rS   rX   rE   rU   dirnamerb   Zsetuptools.command.easy_installr  shutilcopy2r   writer   r  splitextr   )
r   rY   rG   r  rL   r   rU   dstr  r   r%   r%   r&   r    s2    

 zPackageIndex.gen_setupi    c             C   s  | j d| d\}}ztj|}| jt|}t|tjjrRt	d||j
|jf |j  }d}| j}d	}	d|krt|d}
ttt|
}	| j|||||	 t|dZ}xD|j|}|r|j| |j| |d7 }| j|||||	 qP qW | j||| W d Q R X |S |r|j  X d S )
NzDownloading %szCan't download %s: %s %sr   r8   zcontent-lengthzContent-Lengthwb)NNr<   )r   r   r   r   r   r   r   r   r   r   r   r   dl_blocksizer   maxr   int
reporthookr   r   r   r  r   r   )r   rA   rY   fpr   r   r   blocknumbssizesizesr   r   r%   r%   r&   _download_to  s:    




zPackageIndex._download_toc             C   s   d S )Nr%   )r   rA   rY   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 nJ tjk
r } z*|r`| j	|| nt
d||f W Y d d }~X nX d S )Nzfile: c             S   s   g | ]}t |qS r%   )ry   )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)r2   
local_openopen_with_authr   r#   r   
InvalidURLrb   rn   r   r   r   r   r   URLErrorreasonBadStatusLinelineHTTPException)r   rA   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rt
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:   Tr/   )rH   replacer1   rX   rE   rb   r2   _download_svn_download_git_download_hgr   r   url2pathnamer"   r>   r   _attempt_download)r   rC   rA   r  r3   rG   rY   r%   r%   r&   r  
  s$    


zPackageIndex._download_urlc             C   s   | j |d d S )NT)r   )r   rA   r%   r%   r&   r   '  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   r0   _download_html)r   rA   rY   r   r%   r%   r&   r;  *  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   rz   r[   r   r   rX   r   r7  r   )r   rA   r   rY   r   r-  r%   r%   r&   r<  1  s    


zPackageIndex._download_htmlc             C   s   |j ddd }d}|j jdrd|krtjj|\}}}}}}	| r|jdrd|d	d  kr|d	d  j dd\}}t|\}
}|
rd
|
kr|
j d
d\}}d||f }nd|
 }|}||||||	f}tjj|}| jd|| t	j
d|||f  |S )Nr;   r8   r   r   zsvn:@z//r7   r:   :z --username=%s --password=%sz --username=z'Doing subversion checkout from %s to %szsvn checkout%s -q %s %s)r@   r0   r2   r   r"   r>   r   
urlunparser   rX   system)r   rA   rY   credsrC   netlocrE   r]   qr   authhostuserpwrB   r%   r%   r&   r7  @  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+r8   r;   r   r=  r   r<   )r   r"   urlsplitr@   rsplit
urlunsplit)rA   
pop_prefixrC   rB  rE   rF   r   revr%   r%   r&   _vcs_split_rev_from_urlU  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;   r8   r   T)rL  zDoing git clone from %s to %szgit clone --quiet %s %szChecking out %sz"(cd %s && git checkout --quiet %s))r@   rN  r   rX   r@  )r   rA   rY   rM  r%   r%   r&   r8  g  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;   r8   r   T)rL  zDoing hg clone from %s to %szhg clone --quiet %s %szUpdating to %sz(cd %s && hg up -C -r %s >&-))r@   rN  r   rX   r@  )r   rA   rY   rM  r%   r%   r&   r9  w  s    
zPackageIndex._download_hgc             G   s   t j|f|  d S )N)r   r   )r   r   rn   r%   r%   r&   r     s    zPackageIndex.debugc             G   s   t j|f|  d S )N)r   r   )r   r   rn   r%   r%   r&   r     s    zPackageIndex.infoc             G   s   t j|f|  d S )N)r   r   )r   r   rn   r%   r%   r&   r     s    zPackageIndex.warnr   )r   rO  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   r9   r  r  r  r  r$  r  r   r  r   r;  r<  r7  staticmethodrN  r8  r9  r   r   r   __classcell__r%   r%   )r   r&   r   !  sL    

2


+
			# 
D
)$
#z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c             C   s(   t | ts| S | dkr tj| S t| S )N   )r   r  r   unichrchr)cr%   r%   r&   uchr  s
    

rV  c             C   sd   | j d}|jdr(t|dd  d}n4|jdrDt|dd  }ntjjjj|| j d}t|S )Nr8   z#xr:   r*   r;   r   )	rM   r2   r  r   re   html_entitiesname2codepointr   rV  )rL   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)socketgetdefaulttimeoutsetdefaulttimeout)rn   ro   Zold_timeout)rp   timeoutr%   r&   _socket_timeout  s
    

z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr%   )rp   ra  )r`  )rp   r&   ra    s    z'socket_timeout.<locals>._socket_timeoutr%   )r`  ra  r%   )r`  r&   socket_timeout  s    rb  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   r6  )rD  Zauth_sZ
auth_bytesZencoded_bytesencodedr%   r%   r&   _encode_auth  s
    
rh  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   rj  rk  r%   r%   r&   r     s    zCredential.__init__c             c   s   | j V  | jV  d S )N)rj  rk  )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   rl  rn  r%   r%   r%   r&   ri    s   ri  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
        rj  rk  
repositoryr   ~z.pypircN)dictfromkeysr   RawConfigParserr   rX   rE   rb   
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 )rp  )r   rz   )r\   section)r   r%   r&   r    s    z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)sectionsrr  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 )Nrp  rj  rk  )r   rz   ri  )r   rx  repor%   r%   r&   rz    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)r{  itemsr2   )r   rA   rp  credr%   r%   r&   find_credential  s    
zPyPIConfig.find_credentialN)r   r   r   r   propertyr{  rz  r  r%   r%   r%   r&   ro    s   	ro  c             C   s6  t jj| \}}}}}}|jdr,tjd|d
krBt|\}}	nd}|szt j| }
|
rzt	|
}|
j
| f}tjd|  |rdt| }||	||||f}t jj|}t jj|}|jd| nt jj| }|jd	t ||}|r2t jj|j\}}}}}}||kr2||	kr2||||||f}t jj||_|S )z4Open a urllib2 request, handling HTTP authenticationr>  znonnumeric port: ''httphttpsN*Authenticating as %s for %s (from .pypirc)zBasic Authorizationz
User-Agent)r  r  )r  )r   r"   r>   r1   r   r)  r   ro  r  ry   rj  r   r   rh  r?  r   Request
add_header
user_agentrA   )rA   r   rC   rB  rE   paramsrF   r   rD  rE  r~  r   rB   r   r   r  s2h2path2Zparam2Zquery2Zfrag2r%   r%   r&   r(    s6    


r(  c             C   s   | S )Nr%   )rA   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rtjj
|rg }xtj|D ]b}	tjj||	}
|	dkrt|
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 directoriesr7   z
index.htmlrNz<a href="{name}">{name}</a>)r3   zB<html><head><title>{url}</title></head><body>{files}</body></html>rc  )rA   files   OK  Path not found	Not foundzcontent-typez	text/html)r  r  )r  r  r  )r   r"   r>   r   r:  rX   rE   isfiler   r1   r   r   rb   r   r   r   formatr   StringIOr   r   )rA   rC   rD   rE   paramrF   r   rY   r  r   filepathr  bodyr   statusmessager   Zbody_streamr%   r%   r&   r'  @  s,    


r'  )N)N)N)N)r    )^r   sysrX   r[   r  r]  re  r   r   	functoolsr   urllib.parser   ImportErrorurllib2Zsetuptools.externr   Zsetuptools.extern.six.movesr   r   r   r   
setuptoolspkg_resourcesr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   	distutilsr   Zdistutils.errorsr   fnmatchr   Zsetuptools.py26compatr   Zsetuptools.py27compatr   r   rK   Ir{   r   rL   r   r@   rR   __all__Z_SOCKET_TIMEOUTZ_tmplr  r  globalsr  r'   r   rH   r   rJ   rZ   r   rm   rr   rv   r   objectr   r   r   r   r[  rV  rZ  r}   rb  rh  ri  rt  ro  r   r   r(  r  r'  r%   r%   r%   r&   <module>   s   <
 	


"
!    v
&.