3

gb                 @   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mZ d dlmZ d dlmZ d dl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#m$Z$m%Z% d dl&m'Z'm(Z(m)Z)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0 er4d dlm1Z2 nd dlm2Z2 e,rd dl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< d dl=m>Z> e;e?e?e?f Z@ddddddddddddd d!gZAejBeCZDd"d# ZEd$d% ZFd&d ZGd'd ZHed(d)d*dd,dZId-d. ZJd/d0 ZKd1d ZLdd3dZMd4d5 ZNd6d7 ZOd8d ZPd9d: ZQd;d< ZRd=d ZSd>d ZTejUfd?d@ZVddBdZWdCd ZXdDd ZYdEdF ZZdGdH Z[dIdJ Z\dKdL Z]dMdN Z^dAe)dAd+d+dfdOdPZ_dQdR Z`dSdT ZadUdV ZbG dWdX dXecZdG dYdZ dZe2Zeejfd[d\ Zgd]d Zhd^d_ ZiG d`da daecZjddbd Zkdcdd Zldedf Zmdgdh ZnddjdkZodldm Zpdndo Zqdpdq Zrdrds Zsdtdu Ztdvdw Zudxdy Zvdzd! Zwd{d| ZxG d}d~ d~ecZydd Zzdd Z{dd Z|dd Z}dddZ~dd ZdS )    )absolute_importN)deque)pkg_resources)retry)PY2	text_type)input)parse)unquote)__version__)CommandError)get_major_minor_versionsite_packages	user_site)WINDOWS
expanduserstdlib_pkgsstr_to_display)MYPY_CHECK_RUNNINGcast)running_under_virtualenvvirtualenv_no_global)BytesIO)StringIO)	AnyAnyStr	ContainerIterableListOptionalTextTupleUnion)Distributionrmtreedisplay_path
backup_dirasksplitextformat_sizeis_installable_dirnormalize_pathrenamesget_progcaptured_stdout
ensure_dirget_installed_versionremove_auth_from_urlc              C   s4   t jjt jjtdd} t jj| } djt| t S )Nz..zpip {} from {} (python {}))	ospathjoindirname__file__abspathformatr   r   )pip_pkg_dir r:   </tmp/pip-unpacked-wheel-v59g9nu1/pip/_internal/utils/misc.pyget_pip_versionK   s    r<   c             C   sD   t | dk r"| dt |  d 7 } nt | dkr:| dd } td| S )ax  
    Convert a tuple of ints representing a Python version to one of length
    three.

    :param py_version_info: a tuple of ints representing a Python version,
        or None to specify no version. The tuple can have any length.

    :return: a tuple of length three if `py_version_info` is non-None.
        Otherwise, return `py_version_info` unchanged (i.e. None).
       r   NVersionInfo)r   )lenr   )py_version_infor:   r:   r;   normalize_version_infoW   s
    rA   c             C   sP   yt j|  W n< tk
rJ } z |jtjkr:|jtjkr: W Y dd}~X nX dS )z os.path.makedirs without EEXIST.N)r2   makedirsOSErrorerrnoEEXIST	ENOTEMPTY)r3   er:   r:   r;   r/   k   s
    c              C   sL   y,t j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   __main__.py-cz	%s -m pippip)rH   rI   )	r2   r3   basenamesysargv
executableAttributeError	TypeError
IndexError)progr:   r:   r;   r-   v   s    
i  i  )stop_max_delay
wait_fixedFc             C   s   t j| |td d S )N)ignore_errorsonerror)shutilr$   rmtree_errorhandler)dirrU   r:   r:   r;   r$      s    c             C   sV   yt j|jtj@  }W n ttfk
r0   dS X |rPt j|tj | | dS  dS )zOn 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)r2   statst_modeS_IWRITEIOErrorrC   chmod)funcr3   exc_infohas_attr_readonlyr:   r:   r;   rX      s    rX   c             C   sd   | dkrdS t | tr| S y| jtj d}W n0 tk
r^   trRtdj| }nt	| }Y nX |S )z
    Convert a bytes (or text) path to text (unicode in Python 2) for display
    and logging purposes.

    This function should never error out. Also, this function is mainly needed
    for Python 2 since in Python 3 str paths are already text.
    Nstrictzb{!r})

isinstancer   decoderL   getfilesystemencodingUnicodeDecodeErrorr   r   r8   ascii)r3   r%   r:   r:   r;   path_to_display   s    	
rh   c             C   st   t jjt jj| } tjd dkrB| jtj d} | jtj	 d} | j
t j t jj rpd| tt j d  } | S )zTGives the display value for a given path, making it relative to cwd
    if possible.r      replace.N)r2   r3   normcaser7   rL   version_inford   re   encodegetdefaultencoding
startswithgetcwdsepr?   )r3   r:   r:   r;   r%      s    .bakc             C   s:   d}|}x(t j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)   )r2   r3   existsstr)rY   extn	extensionr:   r:   r;   r&      s    c             C   s2   x&t jjddj D ]}||kr|S qW t| |S )NPIP_EXISTS_ACTION )r2   environgetsplitr'   )messageoptionsactionr:   r:   r;   ask_path_exists   s    r   c             C   s   t jjdrtd|  dS )z&Raise an error if no input is allowed.PIP_NO_INPUTz7No input was expected ($PIP_NO_INPUT set); question: %sN)r2   r|   r}   	Exception)r   r:   r:   r;   _check_no_input   s    r   c             C   sJ   xDt |  t| }|j j }||kr>td|dj|f  q|S qW dS )z@Ask the message interactively, with the given possible responsesz<Your response (%r) was not one of the expected responses: %sz, N)r   r   striplowerprintr4   )r   r   responser:   r:   r;   r'      s    c             C   s   t |  t| S )zAsk for input interactively.)r   r   )r   r:   r:   r;   	ask_input   s    r   c             C   s   t |  tj| S )z!Ask for a password interactively.)r   getpass)r   r:   r:   r;   ask_password  s    r   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  z%.1f MBg     @@
   z%i kBz%.1f kBz%i bytesi@B i'  r:   )bytesr:   r:   r;   r)   
  s    c             C   sP   t jj| sdS t jj| d}t jj|r.dS t jj| d}t jj|rLdS dS )zBIs path is a directory containing setup.py or pyproject.toml?
    Fzsetup.pyTzpyproject.toml)r2   r3   isdirr4   isfile)r3   setup_pypyproject_tomlr:   r:   r;   r*     s    c             c   s    x| j |}|sP |V  qW dS )z7Yield pieces of data from a file-like object until EOF.N)read)filesizechunkr:   r:   r;   read_chunks%  s
    
r   Tc             C   s2   t | } |rtjj| } ntjj| } tjj| S )zN
    Convert a path to its canonical, case-normalized, absolute version.

    )r   r2   r3   realpathr7   rl   )r3   resolve_symlinksr:   r:   r;   r+   .  s
    c             C   s@   t j| \}}|j jdr8|dd | }|dd }||fS )z,Like os.path.splitext, but take off .tar tooz.tar   Nr   )	posixpathr(   r   endswith)r3   baserw   r:   r:   r;   r(   <  s
    c             C   s|   t jj|\}}|r0|r0t jj| r0t j| tj| | t jj| \}}|rx|rxyt j| W n tk
rv   Y nX dS )z7Like os.renames(), but handles renaming across devices.N)	r2   r3   r~   ru   rB   rW   move
removedirsrC   )oldnewheadtailr:   r:   r;   r,   F  s    
c             C   s   t  s
dS | jttjS )z
    Return True if path is within sys.prefix, if we're running in a virtualenv.

    If we're not in a virtualenv, all paths are considered "local."

    Caution: this function assumes the head of path has been normalized
    with normalize_path.
    T)r   rp   r+   rL   prefix)r3   r:   r:   r;   is_localX  s    
r   c             C   s   t t| S )z
    Return True if given Distribution object is installed locally
    (i.e. within current virtualenv).

    Always True if we're not in a virtualenv.

    )r   dist_location)distr:   r:   r;   dist_is_localg  s    	r   c             C   s   t | jttS )zF
    Return True if given Distribution is installed in user site.
    )r   rp   r+   r   )r   r:   r:   r;   dist_in_usersites  s    r   c             C   s   t | jttS )z[
    Return True if given Distribution is installed in
    sysconfig.get_python_lib().
    )r   rp   r+   r   )r   r:   r:   r;   dist_in_site_packages{  s    r   c             C   s8   x2t jD ](}tjj|| jd }tjj|rdS qW dS )zC
    Return True if given Distribution is an editable install.
    z	.egg-linkTF)rL   r3   r2   r4   project_namer   )r   	path_itemegg_linkr:   r:   r;   dist_is_editable  s
    r   c                s   |rt j|}nt j}| r tndd |r6dd  ndd  |rLdd ndd |r^tnd	d
  fdd|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.

    If ``paths`` is set, only report the distributions present at the
    specified list of locations.
    c             S   s   dS )NTr:   )dr:   r:   r;   
local_test  s    z/get_installed_distributions.<locals>.local_testc             S   s   dS )NTr:   )r   r:   r:   r;   editable_test  s    z2get_installed_distributions.<locals>.editable_testc             S   s
   t |  S )N)r   )r   r:   r:   r;   r     s    c             S   s   t | S )N)r   )r   r:   r:   r;   editables_only_test  s    z8get_installed_distributions.<locals>.editables_only_testc             S   s   dS )NTr:   )r   r:   r:   r;   r     s    c             S   s   dS )NTr:   )r   r:   r:   r;   	user_test  s    z.get_installed_distributions.<locals>.user_testc                s:   g | ]2}|r|j kr |r|r|r|qS r:   )key).0r   )r   r   r   skipr   r:   r;   
<listcomp>  s    
z/get_installed_distributions.<locals>.<listcomp>)r   
WorkingSetworking_setr   r   )
local_onlyr   include_editableseditables_only	user_onlypathsr   r:   )r   r   r   r   r   r;   get_installed_distributions  s     

r   c             C   sz   g }t  r,|jt t  rDtrD|jt ntr:|jt |jt x0|D ](}tjj|| jd }tjj	|rJ|S qJW 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   appendr   r   r   r2   r3   r4   r   r   )r   sitessiteegglinkr:   r:   r;   egg_link_path  s    



r   c             C   s   t | }|rt|S t| jS )aO  
    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.

    The returned location is normalized (in particular, with symlinks removed).
    )r   r+   location)r   r   r:   r:   r;   r     s    
r   c             G   s   t j| f|  d S )N)loggerinfo)msgargsr:   r:   r;   write_output  s    r   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 )Nr:   )r   lr:   r:   r;   	<genexpr>  s    z$FakeFile.__init__.<locals>.<genexpr>)_gen)selflinesr:   r:   r;   __init__  s    zFakeFile.__init__c             C   sD   y*y
t | jS  tk
r&   | jj  S X W n tk
r>   dS X d S )Nr{   )nextr   	NameErrorStopIteration)r   r:   r:   r;   readline  s    
zFakeFile.readlinec             C   s   | j S )N)r   )r   r:   r:   r;   __iter__  s    zFakeFile.__iter__N)__name__
__module____qualname____doc__r   r   r   r:   r:   r:   r;   r     s   	r   c               @   s$   e Zd Zedd Zedd ZdS )StreamWrapperc             C   s   || _ |  S )N)orig_stream)clsr   r:   r:   r;   from_stream"  s    zStreamWrapper.from_streamc             C   s   | j jS )N)r   encoding)r   r:   r:   r;   r   (  s    zStreamWrapper.encodingN)r   r   r   classmethodr   propertyr   r:   r:   r:   r;   r      s   r   c             c   s@   t t| }tt| tj| zt t| V  W dtt| | X dS )zReturn 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)getattrrL   setattrr   r   )stream_nameorig_stdoutr:   r:   r;   captured_output-  s
    
r   c               C   s   t dS )zCapture 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.
    stdout)r   r:   r:   r:   r;   r.   <  s    	c               C   s   t dS )z 
    See captured_stdout().
    stderr)r   r:   r:   r:   r;   captured_stderrH  s    r   c               @   s    e Zd ZdZdd Zdd ZdS )cached_propertyzA 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   )r   r   r_   )r   r_   r:   r:   r;   r   W  s    zcached_property.__init__c             C   s(   |d kr| S | j | }|j| j j< |S )N)r_   __dict__r   )r   objr   valuer:   r:   r;   __get__[  s    zcached_property.__get__N)r   r   r   r   r   r   r:   r:   r:   r;   r   O  s   r   c             C   s4   t jj| }|dkrt j }|j|}|r0|jS dS )zCGet the installed version of dist_name avoiding pkg_resources cacheN)r   Requirementr	   r   findversion)	dist_namer   reqr   r:   r:   r;   r0   c  s
    
c             C   s   t | dd dS )zConsume an iterable at C speed.r   )maxlenN)r   )iteratorr:   r:   r;   consumeu  s    r   c              O   s@   t t| tt| f|}dd |j D }||d< tdf |S )Nc             S   s   i | ]\}}||qS r:   r:   )r   r   r   r:   r:   r;   
<dictcomp>}  s    zenum.<locals>.<dictcomp>reverse_mappingEnum)dictzipranger?   itemstype)
sequentialnamedenumsreverser:   r:   r;   enum{  s    r  c             C   s*   |dkr| S d| krdj | } dj | |S )z.
    Build a netloc from a host-port pair
    N:z[{}]z{}:{})r8   )hostportr:   r:   r;   build_netloc  s
    
r  httpsc             C   s4   | j ddkr(d| kr(d| kr(dj| } dj|| S )z)
    Build a full URL from a netloc.
    r  ri   @[z[{}]z{}://{})countr8   )netlocschemer:   r:   r;   build_url_from_netloc  s    
r  c             C   s   t | }tj|}|j|jfS )z2
    Return the host-port pair from a netloc.
    )r  urllib_parseurlparsehostnamer  )r  urlparsedr:   r:   r;   parse_netloc  s    
r  c             C   sX   d| kr| dfS | j dd\}} d|kr6|jdd}n|df}tdd |D }| |fS )zp
    Parse out and remove the auth information from a netloc.

    Returns: (netloc, (username, password)).
    r
  Nrt   r  c             s   s"   | ]}|d krd nt |V  qd S )N)urllib_unquote)r   xr:   r:   r;   r     s    z)split_auth_from_netloc.<locals>.<genexpr>)NN)rsplitr~   tuple)r  auth	user_passr:   r:   r;   split_auth_from_netloc  s    r  c             C   sL   t | \} \}}|dkr| S |dkr.d}d}ntj|}d}dj||| dS )z
    Replace the sensitive data in a netloc with "****", if it exists.

    For example:
        - "user:pass@example.com" returns "user:****@example.com"
        - "accesstoken@example.com" returns "****@example.com"
    Nz****r{   z:****z{user}{password}@{netloc})userpasswordr  )r  r  quoter8   )r  r  r  r:   r:   r;   redact_netloc  s    	
r   c             C   s@   t j| }||j}|j|d |j|j|jf}t j|}||fS )aR  Transform and replace netloc in a url.

    transform_netloc is a function taking the netloc and returning a
    tuple. The first element of this tuple is the new netloc. The
    entire tuple is returned.

    Returns a tuple containing the transformed url as item 0 and the
    original tuple returned by transform_netloc as item 1.
    r   )r  urlsplitr  r  r3   queryfragment
urlunsplit)r  transform_netlocpurlnetloc_tuple
url_piecessurlr:   r:   r;   _transform_url  s
    



r*  c             C   s   t | S )N)r  )r  r:   r:   r;   _get_netloc  s    r+  c             C   s
   t | fS )N)r   )r  r:   r:   r;   _redact_netloc  s    r,  c             C   s   t | t\}\}}|||fS )z
    Parse a url into separate netloc, auth, and url with no auth.

    Returns: (url_without_auth, netloc, (username, password))
    )r*  r+  )r  url_without_authr  r  r:   r:   r;   split_auth_netloc_from_url  s    r.  c             C   s   t | td S )z7Return a copy of url with 'username:password@' removed.r   )r*  r+  )r  r:   r:   r;   r1     s    c             C   s   t | td S )z.Replace the password in a given url with ****.r   )r*  r,  )r  r:   r:   r;   redact_auth_from_url  s    r/  c               @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )
HiddenTextc             C   s   || _ || _d S )N)secretredacted)r   r1  r2  r:   r:   r;   r     s    zHiddenText.__init__c             C   s   dj t| S )Nz<HiddenText {!r}>)r8   rv   )r   r:   r:   r;   __repr__  s    zHiddenText.__repr__c             C   s   | j S )N)r2  )r   r:   r:   r;   __str__  s    zHiddenText.__str__c             C   s    t | t |krdS | j|jkS )NF)r   r1  )r   otherr:   r:   r;   __eq__  s    zHiddenText.__eq__c             C   s
   | |k S )Nr:   )r   r5  r:   r:   r;   __ne__*  s    zHiddenText.__ne__N)r   r   r   r   r3  r4  r6  r7  r:   r:   r:   r;   r0    s
   	r0  c             C   s   t | ddS )Nz****)r2  )r0  )r   r:   r:   r;   
hide_value/  s    r8  c             C   s   t | }t| |dS )N)r2  )r/  r0  )r  r2  r:   r:   r;   hide_url4  s    r9  c             C   sz   ddj tjd dj tjdd  g}| oBtoBtjjtjd |k}|rvtjddgtjd	d  }t	d
j dj
|dS )zProtection 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{}.{}.exeNri   z-mrJ   rt   z3To modify pip, please run the following command:
{} )r8   rL   rm   r   r2   r3   rK   rM   rN   r   r4   )modifying_pip	pip_namesshould_show_use_python_msgnew_commandr:   r:   r;   (protect_pip_from_modification_on_windows:  s    
r?  c               C   s   t jdk	ot jj S )z!Is this console interactive?
    N)rL   stdinisattyr:   r:   r:   r;   is_console_interactiveX  s    rB  rt      c             C   sV   t j }d}t| d2}x*t||dD ]}|t|7 }|j| q&W W dQ R X ||fS )z:Return (hash, length) for path using hashlib.sha256()
    r   rb)r   N)hashlibsha256openr   r?   update)r3   	blocksizehlengthfblockr:   r:   r;   	hash_file_  s    rN  c              C   s&   yddl } W n tk
r    dS X dS )z8
    Return whether the wheel package is installed.
    r   NFT)wheelImportError)rO  r:   r:   r;   is_wheel_installedm  s
    rQ  )F)rs   )T)N)r	     )rR  )
__future__r   
contextlibrD   r   rE  iologgingr2   r   rW   rZ   rL   collectionsr   pip._vendorr   pip._vendor.retryingr   pip._vendor.sixr   r   Zpip._vendor.six.movesr   pip._vendor.six.moves.urllibr	   r  "pip._vendor.six.moves.urllib.parser
   r  rJ   r   pip._internal.exceptionsr   pip._internal.locationsr   r   r   pip._internal.utils.compatr   r   r   r   pip._internal.utils.typingr   r   pip._internal.utils.virtualenvr   r   r   r   typingr   r   r   r   r   r   r    r!   r"   Zpip._vendor.pkg_resourcesr#   intr>   __all__	getLoggerr   r   r<   rA   r/   r-   r$   rX   rh   r%   r&   r   r   r'   r   r   r)   r*   DEFAULT_BUFFER_SIZEr   r+   r(   r,   r   r   r   r   r   r   r   r   r   objectr   r   contextmanagerr   r.   r   r   r0   r   r  r  r  r  r  r   r*  r+  r,  r.  r1   r/  r0  r8  r9  r?  rB  rN  rQ  r:   r:   r:   r;   <module>   s   ,

"

	

	>$


#
