B
    =)H[jB  ã               @   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m	Z	 d dl
mZmZmZ d dlmZ d dlmZmZ d dlmZ d dlmZmZmZmZmZmZmZmZ d d	lmZ e  e!¡Z"d
d„ Z#dd„ Z$e$dd„ ƒZ%dd„ Z&dd„ Z'G dd„ de(ƒZ)G dd„ de(ƒZ*dS )é    )Úabsolute_importN)Úpkg_resources)ÚWINDOWSÚcache_from_sourceÚuses_pycache)ÚUninstallationError)Úbin_pyÚbin_user)Ú
indent_log)ÚFakeFileÚaskÚdist_in_usersiteÚdist_is_localÚegg_link_pathÚis_localÚnormalize_pathÚrenames)ÚTempDirectoryc             C   sl   t | ƒrt}nt}tj ||¡}|g}trh| |d ¡ | |d ¡ |rZ| |d ¡ n| |d ¡ |S )z‘Create the fully qualified name of the files created by
    {console,gui}_scripts for the given ``dist``.
    Returns the list of file names
    z.exez.exe.manifestz-script.pywz
-script.py)r   r	   r   ÚosÚpathÚjoinr   Úappend)ÚdistÚscript_nameÚis_guiÚbin_dirÚexe_nameÚpaths_to_remove© r   ú`C:\Users\HIRONO~1\AppData\Local\Temp\pip-install-qz7kpjmn\pip\pip\_internal\req\req_uninstall.pyÚ_script_names   s    r    c                s   t  ˆ ¡‡ fdd„ƒ}|S )Nc              ?   s6   t ƒ }x*ˆ | |ŽD ]}||kr| |¡ |V  qW d S )N)ÚsetÚadd)ÚargsÚkwÚseenÚitem)Úfnr   r   Úunique/   s
    
z_unique.<locals>.unique)Ú	functoolsÚwraps)r'   r(   r   )r'   r   Ú_unique.   s    r+   c             c   s~   t  t|  d¡ƒ¡}xd|D ]\}tj | j|d ¡}|V  | d¡rtj 	|¡\}}|dd… }tj ||d ¡}|V  qW dS )a  
    Yield all the uninstallation paths for dist based on RECORD-without-.pyc

    Yield paths to all the files in RECORD. For each .py file in RECORD, add
    the .pyc in the same directory.

    UninstallPathSet.add() takes care of the __pycache__ .pyc.
    ÚRECORDr   z.pyNéýÿÿÿz.pyc)
ÚcsvÚreaderr   Úget_metadata_linesr   r   r   ÚlocationÚendswithÚsplit)r   ÚrÚrowr   Údnr'   Úbaser   r   r   Úuninstallation_paths9   s    


r8   c                sN   t jj‰tƒ }x:t| td�D ]*‰ t‡ ‡fdd„|D ƒƒ}|s| ˆ ¡ qW |S )zÈCompact a path set to contain the minimal number of paths
    necessary to contain all paths in the set. If /a/path/ and
    /a/path/to/a/file.txt are both in the set, leave only the
    shorter path.)Úkeyc             3   s:   | ]2}ˆ   | d ¡¡o0ˆ t| d ¡ ˆ¡ƒ ˆkV  qdS )Ú*N)Ú
startswithÚrstripÚlen)Ú.0Ú	shortpath)r   Úsepr   r   ú	<genexpr>X   s   zcompact.<locals>.<genexpr>)r   r   r@   r!   Úsortedr=   Úanyr"   )ÚpathsÚshort_pathsÚ
should_addr   )r   r@   r   ÚcompactN   s    
rG   c          	   C   sú   t | ƒ}tƒ }tƒ }tƒ }xF|D ]>}| d¡r0q | d¡sBd|krT| tj |¡¡ | |¡ q W t|ƒ}xt|D ]l}xft |¡D ]X\}}}	xL|	D ]D}
|
 d¡r q�tj 	tj 
||
¡¡}tj |¡r�||kr�| |¡ q�W q€W qpW |dd„ |D ƒB }||fS )as  Returns a tuple of 2 sets of which paths to display to user

    The first set contains paths that would be deleted. Files of a package
    are not added and the top-level directory of the package has a '*' added
    at the end - to signify that all it's contents are removed.

    The second set contains files that would have been skipped in the above
    folders.
    z.pycz__init__.pyz
.dist-infoc             S   s   h | ]}t j |d ¡’qS )r:   )r   r   r   )r>   Úfolderr   r   r   ú	<setcomp>ˆ   s   z.compress_for_output_listing.<locals>.<setcomp>)Úlistr!   r2   r"   r   r   ÚdirnamerG   ÚwalkÚnormcaser   Úisfile)rD   Úwill_removeÚ	will_skipÚfoldersÚfilesr   rH   ÚdirpathÚ_ÚdirfilesÚfnameÚfile_r   r   r   Úcompress_for_output_listinga   s,    





rX   c               @   sf   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zddd„Z	dd„ Z
dd„ Zdd„ Zedd„ ƒZdS )ÚUninstallPathSetzMA set of file paths to be removed in the uninstallation of a
    requirement.c             C   s2   t ƒ | _t ƒ | _i | _|| _tdd�| _g | _d S )NÚ	uninstall)Úkind)r!   rD   Ú_refuseÚpthr   r   Úsave_dirÚ_moved_paths)Úselfr   r   r   r   Ú__init__’   s    zUninstallPathSet.__init__c             C   s   t |ƒS )zs
        Return True if the given path is one we are permitted to
        remove/modify, False otherwise.

        )r   )r`   r   r   r   r   Ú
_permittedš   s    zUninstallPathSet._permittedc             C   sˆ   t j |¡\}}t j t|ƒt j |¡¡}t j |¡s:d S |  |¡rR| j 	|¡ n| j
 	|¡ t j |¡d dkr„tr„|  	t|ƒ¡ d S )Né   z.py)r   r   r3   r   r   rM   Úexistsrb   rD   r"   r\   Úsplitextr   r   )r`   r   ÚheadÚtailr   r   r   r"   ¢   s    
zUninstallPathSet.addc             C   sL   t |ƒ}|  |¡r<|| jkr*t|ƒ| j|< | j|  |¡ n| j |¡ d S )N)r   rb   r]   ÚUninstallPthEntriesr"   r\   )r`   Úpth_fileÚentryr   r   r   Úadd_pthµ   s    

zUninstallPathSet.add_pthc             C   s(   t j | jjt j |¡d  t jj¡¡S )Nrc   )r   r   r   r^   Ú
splitdriveÚlstripr@   )r`   r   r   r   r   Ú_stash¾   s    zUninstallPathSet._stashFc          	   C   sÔ   | j st d| jj¡ dS | jjd | jj }t d|¡ tƒ �Š |sP|  |¡rÆ| j 	¡  xBt
t| j ƒƒD ]0}|  |¡}t d|¡ | j |¡ t||ƒ qjW x| j ¡ D ]}| ¡  qªW t d|¡ W dQ R X dS )z[Remove paths in ``self.paths`` with confirmation (unless
        ``auto_confirm`` is True).z7Can't uninstall '%s'. No files were found to uninstall.Nú-zUninstalling %s:zRemoving file or directory %szSuccessfully uninstalled %s)rD   ÚloggerÚinfor   Úproject_nameÚversionr
   Ú_allowed_to_proceedr^   ÚcreaterB   rG   rn   Údebugr_   r   r   r]   ÚvaluesÚremove)r`   Úauto_confirmÚverboseÚdist_name_versionr   Únew_pathr]   r   r   r   rx   Ã   s$    


zUninstallPathSet.removec             C   sZ   dd„ }|st | jƒ\}}nt| jƒ}tƒ }|d|ƒ |d|ƒ |d| jƒ tddƒdkS )	zIDisplay which files would be deleted and prompt for confirmation
        c          	   S   sH   |sd S t  | ¡ tƒ �& xtt|ƒƒD ]}t  |¡ q(W W d Q R X d S )N)rp   rq   r
   rB   rG   )ÚmsgrD   r   r   r   r   Ú_displayå   s    
z6UninstallPathSet._allowed_to_proceed.<locals>._displayzWould remove:z+Would not remove (might be manually added):z%Would not remove (outside of prefix):zProceed (y/n)? )ÚyÚnr   )rX   rD   rJ   r!   r\   r   )r`   rz   r~   rO   rP   r   r   r   rt   á   s    	


z$UninstallPathSet._allowed_to_proceedc             C   s€   | j jdkr t d| jj¡ dS t d| jj¡ x.| jD ]$}|  |¡}t 	d|¡ t
||ƒ q8W x| j ¡ D ]}| ¡  qlW dS )z1Rollback the changes previously made by remove().Nz'Can't roll back %s; was not uninstalledFzRolling back uninstall of %szReplacing %s)r^   r   rp   Úerrorr   rr   rq   r_   rn   rv   r   r]   rw   Úrollback)r`   r   Útmp_pathr]   r   r   r   r‚   ü   s    

zUninstallPathSet.rollbackc             C   s   | j  ¡  g | _dS )z?Remove temporary save dir: rollback will no longer be possible.N)r^   Úcleanupr_   )r`   r   r   r   Úcommit  s    
zUninstallPathSet.commitc          	      sê  t |jƒ}t|ƒs.t d|j|tj¡ | |ƒS |dd„ t 	d¡t 	d¡hD ƒkrht d|j|¡ | |ƒS | |ƒ}t
|ƒ}d t |j¡¡}|joœtj |j¡}t|jdd ƒ}|�rº|j d	¡�rº|j |¡�sº| |j¡ | d
¡�r"xÎ| d
¡ ¡ D ]&}tj tj |j|¡¡}	| |	¡ qöW n”| d¡�rð| d¡�rF| d¡‰ ng ‰ xj‡ fdd„| d¡ ¡ D ƒD ]J}
tj |j|
¡}	| |	¡ | |	d ¡ | |	d ¡ | |	d ¡ �qhW �n6|�rÔtd |j¡ƒ‚�n|j d¡�r*| |j¡ tj |j¡d }tj tj |j¡d¡}| |d| ¡ nÆ|�r^|j d¡�r^x°t |ƒD ]}	| |	¡ �qHW n’|�ràt!|dƒ�}tj "| #¡  $¡ ¡}W d Q R X ||jk�s°t%d||j|jf ƒ‚| |¡ tj tj |¡d¡}| ||j¡ nt &d||j¡ | d¡�rd| 'd¡�rdxZ| (d¡D ]L}t)|ƒ�r(t*}nt+}| tj ||¡¡ t,�r| tj ||¡d ¡ �qW g }|j-dd�}x$| .¡ D ]}| /t0||dƒ¡ �q~W |j-d d�}x$| .¡ D ]}| /t0||d!ƒ¡ �q°W x|D ]}| |¡ �qÒW |S )"Nz1Not uninstalling %s at %s, outside environment %sc             S   s   h | ]}|r|’qS r   r   )r>   Úpr   r   r   rI     s    z-UninstallPathSet.from_dist.<locals>.<setcomp>ÚstdlibÚ
platstdlibz<Not uninstalling %s at %s, as it is in the standard library.z{}.egg-infor   z	.egg-infozinstalled-files.txtztop_level.txtznamespace_packages.txtc                s   g | ]}|r|ˆ kr|‘qS r   r   )r>   r†   )Ú
namespacesr   r   ú
<listcomp>F  s    z.UninstallPathSet.from_dist.<locals>.<listcomp>z.pyz.pycz.pyoz©Cannot uninstall {!r}. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.z.eggrc   zeasy-install.pthz./z
.dist-infor4   z;Egg-link %s does not match installed location of %s (at %s)z)Not sure how to uninstall: %s - Check: %sÚscriptsz.batÚconsole_scripts)ÚgroupFÚgui_scriptsT)1r   r1   r   rp   rq   r9   ÚsysÚprefixÚ	sysconfigÚget_pathr   Úformatr   Úto_filenamerr   Úegg_infor   r   rd   ÚgetattrÚ	_providerr2   r"   Úhas_metadataÚget_metadataÚ
splitlinesÚnormpathr   r   r3   rK   rk   r8   ÚopenrM   ÚreadlineÚstripÚAssertionErrorrv   Úmetadata_isdirÚmetadata_listdirr   r	   r   r   Úget_entry_mapÚkeysÚextendr    )Úclsr   Ú	dist_pathr   Údevelop_egg_linkÚdevelop_egg_link_egg_infoÚegg_info_existsÚdistutils_egg_infoÚinstalled_filer   Útop_level_pkgÚeasy_install_eggÚeasy_install_pthÚfhÚlink_pointerÚscriptr   Ú_scripts_to_removerŒ   ÚnamerŽ   Úsr   )r‰   r   Ú	from_dist  s¬    






zUninstallPathSet.from_distN)FF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ra   rb   r"   rk   rn   rx   rt   r‚   r…   Úclassmethodrµ   r   r   r   r   rY   �   s   	
rY   c               @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
rh   c             C   s0   t j |¡std| ƒ‚|| _tƒ | _d | _d S )Nz.Cannot remove entries from nonexistent file %s)r   r   rN   r   Úfiler!   ÚentriesÚ_saved_lines)r`   ri   r   r   r   ra   •  s    
zUninstallPthEntries.__init__c             C   s<   t j |¡}tr,t j |¡d s,| dd¡}| j |¡ d S )Nr   ú\ú/)r   r   rM   r   rl   Úreplacer¼   r"   )r`   rj   r   r   r   r"   ž  s    zUninstallPthEntries.addc          	   C   sî   t  d| j¡ t| jdƒ�}| ¡ }|| _W d Q R X tdd„ |D ƒƒrLd}nd}|r~|d  | d¡¡s~|d | d¡ |d< xH| j	D ]>}y$t  d	|¡ | 
||  d¡¡ W q† tk
rÂ   Y q†X q†W t| jd
ƒ�}| |¡ W d Q R X d S )NzRemoving pth entries from %s:Úrbc             s   s   | ]}d |kV  qdS )s   
Nr   )r>   Úliner   r   r   rA   ®  s    z-UninstallPthEntries.remove.<locals>.<genexpr>z
Ú
éÿÿÿÿzutf-8zRemoving entry: %sÚwb)rp   rv   r»   rœ   Ú	readlinesr½   rC   r2   Úencoder¼   rx   Ú
ValueErrorÚ
writelines)r`   r¯   ÚlinesÚendlinerj   r   r   r   rx   ¨  s"    
zUninstallPthEntries.removec          	   C   sR   | j d krt d| j¡ dS t d| j¡ t| jdƒ�}| | j ¡ W d Q R X dS )Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous staterÅ   T)r½   rp   r�   r»   rv   rœ   rÉ   )r`   r¯   r   r   r   r‚   ¾  s    

zUninstallPthEntries.rollbackN)r¶   r·   r¸   ra   r"   rx   r‚   r   r   r   r   rh   ”  s   	
rh   )+Ú
__future__r   r.   r)   Úloggingr   r�   r‘   Úpip._vendorr   Úpip._internal.compatr   r   r   Úpip._internal.exceptionsr   Úpip._internal.locationsr   r	   Úpip._internal.utils.loggingr
   Úpip._internal.utils.miscr   r   r   r   r   r   r   r   Úpip._internal.utils.temp_dirr   Ú	getLoggerr¶   rp   r    r+   r8   rG   rX   ÚobjectrY   rh   r   r   r   r   Ú<module>   s.   (
.  