B
    ãUvg¯w  ã               @   s¸  d dl m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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m Z  d d
l!m"Z"m#Z#m$Z$m%Z%m&Z& d dl'm(Z(m)Z)m*Z*m+Z+ e�rd dlm,Z- nd dlm-Z- ddddddddddddddddddd d!d"d#d$d%gZ.e /e0¡Z1d&Z2d'Z3d(Z4d)Z5e4e2 e5 e3 Z6e4e5 Z7yd dl8Z8e7e27 Z7W n  e9k
�rÂ   e1 :d*¡ Y nX yd dl;Z;e7e37 Z7W n  e9k
�rø   e1 :d+¡ Y nX d,d-„ Z<d.d!„ Z=d/d„ Z>ed0d1d2�dyd4d„ƒZ?d5d6„ Z@d7d„ ZAdzd9d„ZBd:d;„ ZCd<d„ ZDd=d„ ZEd>d„ ZFd?d„ ZGd@d„ ZHejIfdAdB„ZJdCd„ ZKdDd„ ZLd{dFd„ZMdGd„ ZNdHd„ ZOdIdJ„ ZPdKdL„ ZQdMdN„ ZRdOdP„ ZSdQdR„ ZTdEe+dEd3d3fdSdT„ZUdUdV„ ZVdWdX„ ZWdYdZ„ ZXd|d[d„ZYd\d„ ZZd]d„ Z[d}d_d„Z\d`da„ Z]dbdc„ Z^G ddde„ dee_ƒZ`G dfdg„ dge-ƒZaejbdhdi„ ƒZcdjd „ ZdG dkdl„ dle_ƒZed~dmd$„Zfdndo„ Zgdpdq„ Zhddrds„Zidtdu„ Zjdvd%„ Zkdwdx„ ZldS )€é    )Úabsolute_importN)Údeque)Úpkg_resources)Úretry)ÚPY2)Úinput)Úparse)ÚCommandErrorÚInstallationError)Úrunning_under_virtualenvÚsite_packagesÚ	user_siteÚvirtualenv_no_globalÚwrite_delete_marker_file)ÚWINDOWSÚconsole_to_strÚ
expanduserÚstdlib_pkgs)ÚBytesIO)ÚStringIOÚrmtreeÚdisplay_pathÚ
backup_dirÚaskÚsplitextÚformat_sizeÚis_installable_dirÚis_svn_pageÚfile_contentsÚsplit_leading_dirÚhas_leading_dirÚnormalize_pathÚrenamesÚget_progÚ
unzip_fileÚ
untar_fileÚunpack_fileÚcall_subprocessÚcaptured_stdoutÚ
ensure_dirÚARCHIVE_EXTENSIONSÚSUPPORTED_EXTENSIONSÚget_installed_versionÚremove_auth_from_url)z.tar.bz2z.tbz)z.tar.xzz.txzz.tlzz.tar.lzz	.tar.lzma)z.zipz.whl)z.tar.gzz.tgzz.tarzbz2 module is not availablezlzma module is not availablec             O   s,   yt | ƒS  tk
r&   |||Ž‚Y nX d S )N)Ú
__import__ÚImportError)Úpkg_or_module_stringÚExceptionTypeÚargsÚkwargs© r4   ú9/tmp/pip-install-r_9ig3yj/pip/pip/_internal/utils/misc.pyÚimport_or_raiseO   s    r6   c          
   C   sD   yt  | ¡ W n0 tk
r> } z|jtjkr.‚ W dd}~X Y nX dS )z os.path.makedirs without EEXIST.N)ÚosÚmakedirsÚOSErrorÚerrnoÚEEXIST)ÚpathÚer4   r4   r5   r)   V   s
    c           
   C   sL   y,t j tjd ¡} | dkr&dtj S | S W n tttfk
rF   Y nX dS )Nr   )z__main__.pyz-cz	%s -m pipÚpip)	r7   r<   ÚbasenameÚsysÚargvÚ
executableÚAttributeErrorÚ	TypeErrorÚ
IndexError)Úprogr4   r4   r5   r#   _   s    
i¸  iô  )Ústop_max_delayÚ
wait_fixedFc             C   s   t j| |td� d S )N)Úignore_errorsÚonerror)Úshutilr   Úrmtree_errorhandler)ÚdirrI   r4   r4   r5   r   l   s    c             C   s2   t  |¡jtj@ r,t  |tj¡ | |ƒ dS ‚ dS )zÑOn Windows, the files in .svn are read-only, so when rmtree() tries to
    remove them, an exception is thrown.  We catch that here, remove the
    read-only attribute, and hopefully continue without problems.N)r7   ÚstatÚst_modeÚS_IREADÚchmodÚS_IWRITE)Úfuncr<   Úexc_infor4   r4   r5   rL   r   s
    rL   c             C   st   t j t j | ¡¡} tjd dkrB|  t ¡ d¡} |  t 	¡ d¡} |  
t  ¡ t jj ¡rpd| tt  ¡ ƒd…  } | S )zTGives the display value for a given path, making it relative to cwd
    if possible.r   é   ÚreplaceÚ.N)r7   r<   ÚnormcaseÚabspathr@   Úversion_infoÚdecodeÚgetfilesystemencodingÚencodeÚgetdefaultencodingÚ
startswithÚgetcwdÚsepÚlen)r<   r4   r4   r5   r   �   s    ú.bakc             C   s:   d}|}x(t j | | ¡r0|d7 }|t|ƒ }q
W | | S )z\Figure out the name of a directory to back up the given dir to
    (adding .bak, .bak2, etc)é   )r7   r<   ÚexistsÚstr)rM   ÚextÚnÚ	extensionr4   r4   r5   r   �   s    c             C   s2   x&t j dd¡ ¡ D ]}||kr|S qW t| |ƒS )NÚPIP_EXISTS_ACTIONÚ )r7   ÚenvironÚgetÚsplitr   )ÚmessageÚoptionsÚactionr4   r4   r5   Úask_path_exists˜   s    rr   c             C   sZ   xTt j d¡rtd|  ƒ‚t| ƒ}| ¡  ¡ }||krNtd|d |¡f ƒ q|S qW dS )z@Ask the message interactively, with the given possible responsesÚPIP_NO_INPUTz7No input was expected ($PIP_NO_INPUT set); question: %sz<Your response (%r) was not one of the expected responses: %sz, N)	r7   rl   rm   Ú	Exceptionr   ÚstripÚlowerÚprintÚjoin)ro   rp   Úresponser4   r4   r5   r   Ÿ   s    c             C   sL   | dkrd| d d  S | dkr,d| d  S | dkr@d| d  S d|  S d S )	Ni@B z%.1fMBg     @�@iè  i'  z%ikBz%.1fkBz%ibytesr4   )Úbytesr4   r4   r5   r   ²   s    c             C   sP   t j | ¡sdS t j | d¡}t j |¡r.dS t j | d¡}t j |¡rLdS dS )zBIs path is a directory containing setup.py or pyproject.toml?
    Fzsetup.pyTzpyproject.toml)r7   r<   Úisdirrx   Úisfile)r<   Úsetup_pyÚpyproject_tomlr4   r4   r5   r   ½   s    c             C   s   t  d| ¡ot  d| t j¡S )zT
    Returns true if the page appears to be the index page of an svn repository
    z<title>[^<]*Revision \d+:z#Powered by (?:<a[^>]*?>)?Subversion)ÚreÚsearchÚI)Úhtmlr4   r4   r5   r   Ë   s    c          	   C   s$   t | dƒ�}| ¡  d¡S Q R X d S )NÚrbzutf-8)ÚopenÚreadr[   )ÚfilenameÚfpr4   r4   r5   r   Ó   s    c             c   s    x|   |¡}|sP |V  qW dS )z7Yield pieces of data from a file-like object until EOF.N)r…   )ÚfileÚsizeÚchunkr4   r4   r5   Úread_chunksØ   s
    
r‹   c             C   sh   |   d¡  d¡} d| krHd| kr4|  d¡|  d¡k s<d| krH|  dd¡S d| kr\|  dd¡S | dfS d S )Nú/ú\rd   rk   )ÚlstripÚfindrn   )r<   r4   r4   r5   r   á   s    $c             C   sD   d}x:| D ]2}t |ƒ\}}|s"dS |dkr0|}q
||kr
dS q
W dS )zyReturns true if all the paths have the same leading path name
    (i.e., everything is in one subdirectory in an archive)NFT)r   )ÚpathsÚcommon_prefixr<   ÚprefixÚrestr4   r4   r5   r    ì   s    
Tc             C   s2   t | ƒ} |rtj | ¡} ntj | ¡} tj | ¡S )zN
    Convert a path to its canonical, case-normalized, absolute version.

    )r   r7   r<   ÚrealpathrY   rX   )r<   Úresolve_symlinksr4   r4   r5   r!   û   s
    c             C   s@   t  | ¡\}}| ¡  d¡r8|dd… | }|dd… }||fS )z,Like os.path.splitext, but take off .tar tooz.taréüÿÿÿN)Ú	posixpathr   rv   Úendswith)r<   Úbaserg   r4   r4   r5   r     s
    c             C   sz   t j |¡\}}|r.|r.t j |¡s.t  |¡ t | |¡ t j | ¡\}}|rv|rvyt  |¡ W n tk
rt   Y nX dS )z7Like os.renames(), but handles renaming across devices.N)	r7   r<   rn   re   r8   rK   ÚmoveÚ
removedirsr9   )ÚoldÚnewÚheadÚtailr4   r4   r5   r"     s    
c             C   sr   t | ƒ} t tjƒ}tƒ r(|  t tjƒ¡S ddlm} |  |¡rjx&|dƒ ¡ D ]}|  t |ƒ¡rLdS qLW dS dS dS )aB  
    Return True if this is a path pip is allowed to modify.

    If we're in a virtualenv, sys.prefix points to the virtualenv's
    prefix; only sys.prefix is considered local.

    If we're not in a virtualenv, in general we can modify anything.
    However, if the OS vendor has configured distutils to install
    somewhere other than sys.prefix (which could be a subdirectory of
    sys.prefix, e.g. /usr/local), we consider sys.prefix itself nonlocal
    and the domain of the OS vendor. (In other words, everything _other
    than_ sys.prefix is considered local.)

    r   )Údistutils_schemerk   TFN)r!   r@   r’   r   r_   Úpip._internal.locationsr    Úvalues)r<   r’   r    Ú
local_pathr4   r4   r5   Úis_local"  s    

r¤   c             C   s   t t| ƒƒS )zh
    Return True if given Distribution object is installed somewhere pip
    is allowed to modify.

    )r¤   Údist_location)Údistr4   r4   r5   Údist_is_localB  s    r§   c             C   s   t t| ƒƒ}| t tƒ¡S )zF
    Return True if given Distribution is installed in user site.
    )r!   r¥   r_   r   )r¦   Ú	norm_pathr4   r4   r5   Údist_in_usersiteK  s    r©   c             C   s   t t| ƒƒ t tƒ¡S )z[
    Return True if given Distribution is installed in
    sysconfig.get_python_lib().
    )r!   r¥   r_   r   )r¦   r4   r4   r5   Údist_in_site_packagesS  s    
rª   c             C   s8   x2t jD ](}tj || jd ¡}tj |¡rdS qW dS )z$Is distribution an editable install?z	.egg-linkTF)r@   r<   r7   rx   Úproject_namer|   )r¦   Ú	path_itemÚegg_linkr4   r4   r5   Údist_is_editable]  s
    r®   c                sl   | r
t ‰ndd„ ‰|r dd„ ‰ ndd„ ‰ |r6dd„ ‰ndd„ ‰|rHt‰nd	d
„ ‰‡ ‡‡‡‡fdd„tjD ƒS )a÷  
    Return a list of installed Distribution objects.

    If ``local_only`` is True (default), only return installations
    local to the current virtualenv, if in a virtualenv.

    ``skip`` argument is an iterable of lower-case project names to
    ignore; defaults to stdlib_pkgs

    If ``include_editables`` is False, don't report editables.

    If ``editables_only`` is True , only report editables.

    If ``user_only`` is True , only report installations in the user
    site directory.

    c             S   s   dS )NTr4   )Údr4   r4   r5   Ú
local_test  s    z/get_installed_distributions.<locals>.local_testc             S   s   dS )NTr4   )r¯   r4   r4   r5   Úeditable_testƒ  s    z2get_installed_distributions.<locals>.editable_testc             S   s
   t | ƒ S )N)r®   )r¯   r4   r4   r5   r±   †  s    c             S   s   t | ƒS )N)r®   )r¯   r4   r4   r5   Úeditables_only_testŠ  s    z8get_installed_distributions.<locals>.editables_only_testc             S   s   dS )NTr4   )r¯   r4   r4   r5   r²   �  s    c             S   s   dS )NTr4   )r¯   r4   r4   r5   Ú	user_test“  s    z.get_installed_distributions.<locals>.user_testc                s:   g | ]2}ˆ|ƒr|j ˆkrˆ |ƒrˆ|ƒrˆ|ƒr|‘qS r4   )Úkey)Ú.0r¯   )r±   r²   r°   Úskipr³   r4   r5   ú
<listcomp>–  s    
z/get_installed_distributions.<locals>.<listcomp>)r§   r©   r   Úworking_set)Ú
local_onlyr¶   Úinclude_editablesÚeditables_onlyÚ	user_onlyr4   )r±   r²   r°   r¶   r³   r5   Úget_installed_distributionsf  s    

r½   c             C   s„   g }t ƒ r6tƒ r| t¡ qN| t¡ trN| t¡ ntrD| t¡ | t¡ x0|D ](}tj || j¡d }tj 	|¡rT|S qTW dS )a  
    Return the path for the .egg-link file if it exists, otherwise, None.

    There's 3 scenarios:
    1) not in a virtualenv
       try to find in site.USER_SITE, then site_packages
    2) in a no-global virtualenv
       try to find in site_packages
    3) in a yes-global virtualenv
       try to find in site_packages, then site.USER_SITE
       (don't look in global location)

    For #1 and #3, there could be odd cases, where there's an egg-link in 2
    locations.

    This method will just return the first one found.
    z	.egg-linkN)
r   r   Úappendr   r   r7   r<   rx   r«   r|   )r¦   ÚsitesÚsiteÚegglinkr4   r4   r5   Úegg_link_pathŸ  s    



rÂ   c             C   s   t | ƒ}|r|S | jS )zÿ
    Get the site-packages location of this distribution. Generally
    this is dist.location, except in the case of develop-installed
    packages, where dist.location is the source code location, and we
    want to know where the egg-link file is.

    )rÂ   Úlocation)r¦   r­   r4   r4   r5   r¥   Ä  s    r¥   c              C   s   t  d¡} t  | ¡ | S )zBGet the current umask which involves having to set it temporarily.r   )r7   Úumask)Úmaskr4   r4   r5   Úcurrent_umaskÒ  s    

rÆ   c             C   s  t |ƒ t| dƒ}zòtj|dd�}t| ¡ ƒo0|}xÎ| ¡ D ]Â}|j}| |¡}|}	|rdt	|ƒd }	t
j ||	¡}	t
j |	¡}
|	 d¡s’|	 d¡rœt |	ƒ q<t |
ƒ t|	dƒ}z| |¡ W d| ¡  |jd	? }|rüt |¡rü|d
@ rüt
 |	dtƒ  d
B ¡ X q<W W d| ¡  X dS )aŸ  
    Unzip the file (with path `filename`) to the destination `location`.  All
    files are written based on system defaults and umask (i.e. permissions are
    not preserved), except that regular file members with any execute
    permissions (user, group, or world) have "chmod +x" applied after being
    written. Note that for windows, any execute changes using os.chmod are
    no-ops per the python docs.
    rƒ   T)Ú
allowZip64rd   rŒ   r�   ÚwbNé   éI   iÿ  )r)   r„   ÚzipfileÚZipFiler    ÚnamelistÚinfolistr†   r…   r   r7   r<   rx   Údirnamer˜   ÚwriteÚcloseÚexternal_attrrN   ÚS_ISREGrQ   rÆ   )r†   rÃ   ÚflattenÚzipfpÚzipÚleadingÚinfoÚnameÚdataÚfnrM   r‡   Úmoder4   r4   r5   r$   Ù  s0    	




 c             C   s  t |ƒ |  ¡  d¡s$|  ¡  d¡r*d}nL|  ¡  t¡r>d}n8|  ¡  t¡rRd}n$|  ¡  d¡rfd}nt d| ¡ d	}t | |¡}�zxt	d
d„ | 
¡ D ƒƒ}�xZ| 
¡ D �]L}|j}|dkr¾q¨|rÎt|ƒd }tj ||¡}| ¡ rît |ƒ q¨| ¡ �rDy| ||¡ W n8 tk
�r@ } zt d| |j|¡ w¨W dd}~X Y nX q¨y| |¡}	W n< ttfk
�rŽ } zt d| |j|¡ w¨W dd}~X Y nX t tj |¡ƒ t|dƒ�}
t |	|
¡ W dQ R X |	 ¡  | ||¡ |jd@ r¨t |dtƒ  dB ¡ q¨W W d| ¡  X dS )aŸ  
    Untar the file (with path `filename`) to the destination `location`.
    All files are written based on system defaults and umask (i.e. permissions
    are not preserved), except that regular file members with any execute
    permissions (user, group, or world) have "chmod +x" applied after being
    written.  Note that for windows, any execute changes using os.chmod are
    no-ops per the python docs.
    z.gzz.tgzzr:gzzr:bz2zr:xzz.tarÚrz-Cannot determine compression type for file %szr:*c             S   s   g | ]}|j d kr|j ‘qS )Úpax_global_header)rÙ   )rµ   Úmemberr4   r4   r5   r·     s    zuntar_file.<locals>.<listcomp>rÞ   rd   z/In the tar file %s the member %s is invalid: %sNrÈ   rÊ   iÿ  )r)   rv   r˜   ÚBZ2_EXTENSIONSÚXZ_EXTENSIONSÚloggerÚwarningÚtarfiler„   r    Ú
getmembersrÙ   r   r7   r<   rx   r{   ÚissymÚ_extract_memberrt   ÚextractfileÚKeyErrorrC   rÏ   rK   ÚcopyfileobjrÑ   ÚutimerÜ   rQ   rÆ   )r†   rÃ   rÜ   Útarr×   rß   rÛ   r<   Úexcr‡   Údestfpr4   r4   r5   r%     s`    	


c             C   sÔ   t j | ¡} |dks,|  ¡  t¡s,t | ¡rDt| ||  d¡ d� nŒ|dkslt	 
| ¡sl|  ¡  tt t ¡rxt| |ƒ nX|r´| d¡r´tt| ƒƒr´ddlm} |d|j ƒ |¡ nt d	| ||¡ td
| ƒ‚d S )Nzapplication/zipz.whl)rÔ   zapplication/x-gzipz	text/htmlr   )Ú
Subversionzsvn+zZCannot unpack file %s (downloaded from %s, content-type: %s); cannot detect archive formatz%Cannot determine archive format of %s)r7   r<   r”   rv   r˜   ÚZIP_EXTENSIONSrË   Ú
is_zipfiler$   rä   Ú
is_tarfileÚTAR_EXTENSIONSrà   rá   r%   r_   r   r   Úpip._internal.vcs.subversionrï   ÚurlÚunpackrâ   Úcriticalr
   )r†   rÃ   Úcontent_typeÚlinkrï   r4   r4   r5   r&   P  s,    


Úraisec          
   C   s|  |dkrg }|rd}nt j}|dkrzg }	xF| D ]>}
d|
ksRd|
ksRd|
ksRd|
krbd|
 dd¡ }
|	 |
¡ q.W d |	¡}t d|¡ tj 	¡ }|rž| 
|¡ x|D ]}| |d¡ q¤W y(t j| t jt j|||d	�}|j ¡  W n4 tk
�r } zt d
||¡ ‚ W dd}~X Y nX g }|dk	�r†x`t|j ¡ ƒ}|�s<P | ¡ }| |d ¡ t ¡ tjk�rnt |¡ n|dk	�r&| ¡  �q&W z| ¡  W d|j�r¦|j ¡  X |dk	�rÐ|j�rÆ| d¡ n
| d¡ |j�rh|dk�r.t ¡ tjk�r|�st d|¡ t d |¡d ¡ td||j|f ƒ‚n:|dk�rLt d||j|¡ n|dk�rXnt dt!|ƒ ƒ‚|�sxd |¡S dS )z„
    Args:
      unset_environ: an iterable of environment variable names to unset
        prior to calling subprocess.Popen().
    Nú Ú
ú"ú'z"%s"z\"zRunning command %s)ÚstderrÚstdinÚstdoutÚcwdÚenvz#Error %s while executing command %sÚerrorÚdonerú   z Complete output from command %s:rk   z)
----------------------------------------z,Command "%s" failed with error code %s in %sÚwarnz$Command "%s" had error code %s in %sÚignorezInvalid value: on_returncode=%s)"Ú
subprocessÚPIPErV   r¾   rx   râ   Údebugr7   rl   ÚcopyÚupdateÚpopÚPopenÚSTDOUTr   rÑ   rt   r÷   r   r  ÚreadlineÚrstripÚgetEffectiveLevelÚstd_loggingÚDEBUGÚspinÚwaitÚ
returncodeÚfinishrØ   r
   rã   Ú
ValueErrorÚrepr)ÚcmdÚshow_stdoutr  Úon_returncodeÚcommand_descÚextra_environÚunset_environÚspinnerr  Ú	cmd_partsÚpartr  rÙ   Úprocrí   Ú
all_outputÚliner4   r4   r5   r'   q  sŠ    	
 












c          	   C   sx   t | dƒ�}| ¡ }W dQ R X dt d¡dg}x4|D ],}y| |¡}W n tk
r\   w4Y nX P q4W t|ƒtkstt‚|S )aR  Return the contents of *filename*.

    Try to decode the file contents with utf-8, the preferred system encoding
    (e.g., cp1252 on some Windows machines), and latin1, in that order.
    Decoding a byte string with latin1 will never raise an error. In the worst
    case, the returned string will contain some garbage characters.

    rƒ   Nzutf-8FÚlatin1)	r„   r…   ÚlocaleÚgetpreferredencodingr[   ÚUnicodeDecodeErrorÚtyperz   ÚAssertionError)r†   r‡   rÚ   Ú	encodingsÚencr4   r4   r5   Úread_text_fileâ  s    	
r/  c             C   s   t  | ¡ t| ƒ d S )N)r7   r8   r   )Ú	build_dirr4   r4   r5   Ú_make_build_dirú  s    
r1  c               @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚFakeFilezQWrap a list of lines in an object with readline() to make
    ConfigParser happy.c             C   s   dd„ |D ƒ| _ d S )Nc             s   s   | ]
}|V  qd S )Nr4   )rµ   Úlr4   r4   r5   ú	<genexpr>  s    z$FakeFile.__init__.<locals>.<genexpr>)Ú_gen)ÚselfÚlinesr4   r4   r5   Ú__init__  s    zFakeFile.__init__c             C   sD   y*y
t | jƒS  tk
r&   | j  ¡ S X W n tk
r>   dS X d S )Nrk   )Únextr5  Ú	NameErrorÚStopIteration)r6  r4   r4   r5   r    s    
zFakeFile.readlinec             C   s   | j S )N)r5  )r6  r4   r4   r5   Ú__iter__  s    zFakeFile.__iter__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r8  r  r<  r4   r4   r4   r5   r2  ÿ  s   	r2  c               @   s$   e Zd Zedd„ ƒZedd„ ƒZdS )ÚStreamWrapperc             C   s   || _ | ƒ S )N)Úorig_stream)ÚclsrB  r4   r4   r5   Úfrom_stream  s    zStreamWrapper.from_streamc             C   s   | j jS )N)rB  Úencoding)r6  r4   r4   r5   rE    s    zStreamWrapper.encodingN)r=  r>  r?  ÚclassmethodrD  ÚpropertyrE  r4   r4   r4   r5   rA    s   rA  c          
   c   s@   t t| ƒ}tt| t |¡ƒ zt t| ƒV  W dtt| |ƒ X dS )zËReturn a context manager used by captured_stdout/stdin/stderr
    that temporarily replaces the sys stream *stream_name* with a StringIO.

    Taken from Lib/support/__init__.py in the CPython repo.
    N)Úgetattrr@   ÚsetattrrA  rD  )Ústream_nameÚorig_stdoutr4   r4   r5   Úcaptured_output  s
    
rL  c               C   s   t dƒS )zÜCapture the output of sys.stdout:

       with captured_stdout() as stdout:
           print('hello')
       self.assertEqual(stdout.getvalue(), 'hello
')

    Taken from Lib/support/__init__.py in the CPython repo.
    r  )rL  r4   r4   r4   r5   r(   .  s    	c               @   s    e Zd ZdZdd„ Zdd„ ZdS )Úcached_propertyzôA property that is only computed once per instance and then replaces
       itself with an ordinary attribute. Deleting the attribute resets the
       property.

       Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175
    c             C   s   t |dƒ| _|| _d S )Nr@  )rH  r@  rS   )r6  rS   r4   r4   r5   r8  B  s    zcached_property.__init__c             C   s(   |d kr| S |   |¡ }|j| j j< |S )N)rS   Ú__dict__r=  )r6  ÚobjrC  Úvaluer4   r4   r5   Ú__get__F  s    zcached_property.__get__N)r=  r>  r?  r@  r8  rQ  r4   r4   r4   r5   rM  :  s   rM  c             C   s4   t j | ¡}|dkrt  ¡ }| |¡}|r0|jS dS )zCGet the installed version of dist_name avoiding pkg_resources cacheN)r   ÚRequirementr   Ú
WorkingSetr�   Úversion)Ú	dist_namer¸   Úreqr¦   r4   r4   r5   r,   N  s
    
c             C   s   t | dd� dS )zConsume an iterable at C speed.r   )ÚmaxlenN)r   )Úiteratorr4   r4   r5   Úconsume`  s    rY  c              O   s@   t t| tt| ƒƒƒf|Ž}dd„ | ¡ D ƒ}||d< tdd|ƒS )Nc             S   s   i | ]\}}||“qS r4   r4   )rµ   r´   rP  r4   r4   r5   ú
<dictcomp>h  s    zenum.<locals>.<dictcomp>Úreverse_mappingÚEnumr4   )ÚdictrÖ   Úrangerb   Úitemsr+  )Ú
sequentialÚnamedÚenumsÚreverser4   r4   r5   Úenumf  s    rd  c             C   s$   d  | ||¡}|r |d  |¡7 }|S )zˆ
    Return the URL for a VCS requirement.

    Args:
      repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+").
    z{}@{}#egg={}z&subdirectory={})Úformat)Úrepo_urlÚrevÚegg_project_nameÚsubdirrV  r4   r4   r5   Úmake_vcs_requirement_urlm  s    rj  c             C   sJ   d| kr| dfS |   dd¡\}} d|kr:t| dd¡ƒ}n|df}| |fS )zp
    Parse out and remove the auth information from a netloc.

    Returns: (netloc, (username, password)).
    ú@)NNrd   ú:N)ÚrsplitÚtuplern   )ÚnetlocÚauthÚ	user_passr4   r4   r5   Úsplit_auth_from_netloc{  s    rr  c             C   s<   t  | ¡}t|jƒ\}}|j||j|j|jf}t  |¡}|S )N)	Úurllib_parseÚurlsplitrr  ro  Úschemer<   ÚqueryÚfragmentÚ
urlunsplit)rõ   Úpurlro  rq  Ú
url_piecesÚsurlr4   r4   r5   r-   “  s
    

c             C   sz   dd  tjd ¡dj tjdd… Ž g}| oBtoBtj tjd ¡|k}|rvtjddgtjd	d…  }t	d
  d 
|¡¡ƒ‚dS )z�Protection of pip.exe from modification on Windows

    On Windows, any operation modifying pip should be run as:
        python -m pip ...
    zpip.exez	pip{}.exer   zpip{}.{}.exeNrU   z-mr>   rd   z3To modify pip, please run the following command:
{}rû   )re  r@   rZ   r   r7   r<   r?   rA   rB   r	   rx   )Úmodifying_pipÚ	pip_namesÚshould_show_use_python_msgÚnew_commandr4   r4   r5   Ú(protect_pip_from_modification_on_windows¤  s    
r€  )F)rc   )T)T)TNrú   NNNN)N)N)mÚ
__future__r   Ú
contextlibr:   Úior(  Úloggingr  r7   r—   r   rK   rN   r  r@   rä   rË   Úcollectionsr   Úpip._vendorr   Zpip._vendor.retryingr   Zpip._vendor.sixr   Zpip._vendor.six.movesr   Zpip._vendor.six.moves.urllibr   rs  Úpip._internal.exceptionsr	   r
   r¡   r   r   r   r   r   Úpip._internal.utils.compatr   r   r   r   r   r   Ú__all__Ú	getLoggerr=  râ   rà   rá   rð   ró   r*   r+   Úbz2r/   r
  Úlzmar6   r)   r#   r   rL   r   r   rr   r   r   r   r   r   ÚDEFAULT_BUFFER_SIZEr‹   r   r    r!   r   r"   r¤   r§   r©   rª   r®   r½   rÂ   r¥   rÆ   r$   r%   r&   r'   r/  r1  Úobjectr2  rA  ÚcontextmanagerrL  r(   rM  r,   rY  rd  rj  rr  r-   r€  r4   r4   r4   r5   Ú<module>   sØ   
	

	
	 	
	5%
+L!   
n

