U
    +|j¬[  ã                   @   sX  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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mZ d dl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)m*Z* e +e,¡Z-dd„ Z.dd„ Z/e/dd„ ƒZ0dd„ Z1dd„ Z2dd„ Z3G dd„ dƒZ4G dd„ dƒZ5G dd„ dƒZ6dS )é    N)Úcache_from_source)	ÚAnyÚCallableÚDictÚIterableÚIteratorÚListÚOptionalÚSetÚTuple)Úpkg_resources)ÚDistribution)ÚUninstallationError)Úget_bin_prefixÚget_bin_user)ÚWINDOWS)Ú
indent_log)ÚaskÚdist_in_usersiteÚdist_is_localÚegg_link_pathÚis_localÚnormalize_pathÚrenamesÚrmtree)ÚAdjacentTempDirectoryÚTempDirectoryc                 C   sp   t | ƒrtƒ }ntƒ }tj ||¡}|g}trl| |d ¡ | |d ¡ |r^| |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'   úgC:\Users\snmko\Desktop\web_content\django_cbt\venv\Lib\site-packages\pip/_internal/req/req_uninstall.pyÚ_script_names    s    r)   c                    s   t  ˆ ¡‡ fdd„ƒ}|S )Nc                  ?   s2   t ƒ }ˆ | |ŽD ]}||kr| |¡ |V  qd S ©N)ÚsetÚadd)ÚargsÚkwÚseenÚitem©Úfnr'   r(   Úunique8   s
    
z_unique.<locals>.unique)Ú	functoolsÚwraps)r2   r3   r'   r1   r(   Ú_unique6   s    r6   c                 c   sŽ   t  |  d¡¡}|D ]t}tj | j|d ¡}|V  | d¡rtj |¡\}}|dd… }tj ||d ¡}|V  tj ||d ¡}|V  qdS )a  
    Yield all the uninstallation paths for dist based on RECORD-without-.py[co]

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

    UninstallPathSet.add() takes care of the __pycache__ .py[co].
    ÚRECORDr   ú.pyNéýÿÿÿú.pycú.pyo)	ÚcsvÚreaderÚget_metadata_linesr   r   r   ÚlocationÚendswithÚsplit)r!   ÚrÚrowr   Údnr2   Úbaser'   r'   r(   Úuninstallation_pathsC   s    
rF   c                    sJ   t jj‰tƒ }t| td�D ]*‰ t‡ ‡fdd„|D ƒƒ}|s| ˆ ¡ q|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>e   s   þzcompact.<locals>.<genexpr>)r   r   rP   r+   ÚsortedrL   Úanyr,   )ÚpathsÚshort_pathsÚshould_skipr'   rO   r(   Úcompact[   s    ýrW   c           	         sð   dd„ | D ƒ}t |ƒ}tdd„ | ¡ D ƒtd�}t ƒ }dd„ ‰|D ]˜‰t‡fdd	„|D ƒƒr^qBt ƒ }t ƒ }t ˆ¡D ]B\‰ }}| ‡ ‡‡fd
d	„|D ƒ¡ | ‡ ‡‡fdd	„|D ƒ¡ qt|| sB| |¡ | 	ˆtj
 ¡ qBt t|j|ƒƒ|B S )z«Returns a set containing the paths that need to be renamed.

    This set may include directories when the original sequence of paths
    included every file on disk.
    c                 S   s   i | ]}t j |¡|“qS r'   )r   r   Únormcase©rM   Úpr'   r'   r(   Ú
<dictcomp>v   s     
 z'compress_for_rename.<locals>.<dictcomp>c                 S   s   h | ]}t j |¡d  ’qS )r   )r   r   rA   rY   r'   r'   r(   Ú	<setcomp>x   s     z&compress_for_rename.<locals>.<setcomp>rG   c                  W   s   t j t jj| Ž ¡S r*   )r   r   rX   r   )Úar'   r'   r(   Ú	norm_join{   s    z&compress_for_rename.<locals>.norm_joinc                 3   s    | ]}t j ˆ ¡ |¡V  qd S r*   )r   r   rX   rJ   )rM   Úw)Úrootr'   r(   rQ   €   s   ÿz&compress_for_rename.<locals>.<genexpr>c                 3   s   | ]}ˆˆˆ |ƒV  qd S r*   r'   )rM   Úd©Údirnamer^   r`   r'   r(   rQ   ˆ   s   ÿc                 3   s   | ]}ˆˆˆ |ƒV  qd S r*   r'   )rM   Úfrb   r'   r(   rQ   Š   s   ÿ)r+   rR   ÚvaluesrL   rS   r   ÚwalkÚupdateÚdifference_updater,   rP   ÚmapÚ__getitem__)	rT   Úcase_mapÚ	remainingÚ	uncheckedÚ	wildcardsÚ	all_filesÚall_subdirsÚsubdirsÚfilesr'   rb   r(   Úcompress_for_renameo   s.    ÿÿÿ

rs   c                 C   sü   t | ƒ}t ƒ }t ƒ }t ƒ }|D ]>}| d¡r.q| d¡s@d|krR| tj |¡¡ | |¡ qt ttjj|ƒƒ}t|ƒ}|D ]d}t 	|¡D ]T\}}	}
|
D ]D}| d¡r¨q˜tj 
||¡}tj |¡r˜tj |¡|kr˜| |¡ q˜qŠq||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.
    r:   z__init__.pyú
.dist-infoc                 S   s   h | ]}t j |d ¡’qS )rI   )r   r   r   )rM   Úfolderr'   r'   r(   r\   Â   s    z.compress_for_output_listing.<locals>.<setcomp>)r+   r@   r,   r   r   rc   ri   rX   rW   rf   r   Úisfile)rT   Úwill_removeÚ	will_skipÚfoldersrr   r   Ú_normcased_filesru   ÚdirpathÚ_ÚdirfilesÚfnameÚfile_r'   r'   r(   Úcompress_for_output_listing–   s4    

ÿÿr€   c                   @   sL   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	e
dd„ ƒZdS )ÚStashedUninstallPathSetzWA set of file rename operations to stash files while
    tentatively uninstalling them.c                 C   s   i | _ g | _d S r*   )Ú
_save_dirsÚ_moves©Úselfr'   r'   r(   Ú__init__Ì   s    z StashedUninstallPathSet.__init__c                 C   sD   zt |ƒ}W n tk
r*   tdd�}Y nX || jtj |¡< |jS )z�Stashes a directory.

        Directories are stashed adjacent to their original location if
        possible, or else moved/copied into the user's temp dir.Ú	uninstall©Úkind)r   ÚOSErrorr   r‚   r   r   rX   )r…   r   Úsave_dirr'   r'   r(   Ú_get_directory_stashÕ   s    z,StashedUninstallPathSet._get_directory_stashc                 C   sº   t j |¡}t j |¡d }}d}||krfz| j| }W q†W n tk
rP   Y nX t j |¡| }}q"t j |¡}tdd�}|| j|< t j ||¡}|r´|t jjkr´t j 	|j|¡S |jS )z‚Stashes a file.

        If no root has been provided, one will be created for the directory
        in the user's temp directory.Nr‡   rˆ   )
r   r   rX   rc   r‚   ÚKeyErrorr   ÚrelpathÚcurdirr   )r…   r   ÚheadÚold_headr‹   rŽ   r'   r'   r(   Ú_get_file_stashä   s"    


z'StashedUninstallPathSet._get_file_stashc                 C   sl   t j |¡ot j |¡ }|r*|  |¡}n
|  |¡}| j ||f¡ |r^t j |¡r^t  |¡ t	||ƒ |S )z�Stashes the directory or file and returns its new location.
        Handle symlinks as files to avoid modifying the symlink targets.
        )
r   r   ÚisdirÚislinkrŒ   r’   rƒ   r    Úrmdirr   )r…   r   Úpath_is_dirÚnew_pathr'   r'   r(   Ústash   s    


zStashedUninstallPathSet.stashc                 C   s,   | j  ¡ D ]\}}| ¡  q
g | _i | _ dS )z0Commits the uninstall by removing stashed files.N)r‚   ÚitemsÚcleanuprƒ   )r…   r|   r‹   r'   r'   r(   Úcommit  s    
zStashedUninstallPathSet.commitc                 C   sÆ   | j D ]}tjd|žŽ  q| j D ]˜\}}zTt d||¡ tj |¡sPtj |¡r\t |¡ ntj 	|¡rpt
|ƒ t||ƒ W q  tk
r¶ } zt d|¡ t d|¡ W 5 d}~X Y q X q |  ¡  dS )z2Undoes the uninstall by moving stashed files back.úMoving to %s
 from %szReplacing %s from %szFailed to restore %szException: %sN)rœ   )rƒ   ÚloggerÚinfoÚdebugr   r   rv   r”   Úunlinkr“   r   r   rŠ   Úerrorr›   )r…   rZ   r—   r   Úexr'   r'   r(   Úrollback  s    
 z StashedUninstallPathSet.rollbackc                 C   s
   t | jƒS r*   )Úboolrƒ   r„   r'   r'   r(   Úcan_rollback2  s    z$StashedUninstallPathSet.can_rollbackN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r†   rŒ   r’   r˜   r›   r£   Úpropertyr¥   r'   r'   r'   r(   r�   É   s   	r�   c                   @   s^   e Zd Z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   s(   t ƒ | _t ƒ | _i | _|| _tƒ | _d S r*   )r+   rT   Ú_refuseÚpthr!   r�   Ú_moved_paths)r…   r!   r'   r'   r(   r†   ;  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(   Ú
_permittedC  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|ƒ¡ d S )Né   r8   )r   r   rA   r   r   rX   Úexistsr¯   rT   r,   r¬   Úsplitextr   )r…   r   r�   Útailr'   r'   r(   r,   L  s    
zUninstallPathSet.addc                 C   sL   t |ƒ}|  |¡r<|| jkr*t|ƒ| j|< | j|  |¡ n| j |¡ d S r*   )r   r¯   r­   ÚUninstallPthEntriesr,   r¬   )r…   Úpth_fileÚentryr'   r'   r(   Úadd_pth`  s    

zUninstallPathSet.add_pthFc              	   C   sº   | j st d| jj¡ dS | jjd | jj }t d|¡ tƒ �p |sP|  |¡r¬| j}t	| j ƒ}t
t|ƒƒD ]}| |¡ t d|¡ ql| j ¡ D ]}| ¡  q’t d|¡ W 5 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)rT   r�   rž   r!   Úproject_nameÚversionr   Ú_allowed_to_proceedr®   rs   rR   rW   r˜   rŸ   r­   re   Úremove)r…   Úauto_confirmÚverboseÚdist_name_versionÚmovedÚ
for_renamer   r­   r'   r'   r(   r¼   j  s&    þÿ


zUninstallPathSet.removec                 C   sn   dd„ }|st | jƒ\}}nt| jƒ}tƒ }|d|ƒ |d|ƒ |d| jƒ |r`|dt| jƒƒ tddƒd	kS )
zIDisplay which files would be deleted and prompt for confirmation
        c              	   S   sD   |sd S t  | ¡ tƒ �" tt|ƒƒD ]}t  |¡ q&W 5 Q R X d S r*   )r�   rž   r   rR   rW   )ÚmsgrT   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Will actually move:zProceed (y/n)? )ÚyÚnrÄ   )r€   rT   r+   r¬   rs   r   )r…   r¾   rÃ   rw   rx   r'   r'   r(   r»   Š  s    



z$UninstallPathSet._allowed_to_proceedc                 C   sR   | j jst d| jj¡ dS t d| jj¡ | j  ¡  | j 	¡ D ]}| ¡  q@dS )z1Rollback the changes previously made by remove().z'Can't roll back %s; was not uninstalledNzRolling back uninstall of %s)
r®   r¥   r�   r¡   r!   r¹   rž   r£   r­   re   )r…   r­   r'   r'   r(   r£   ©  s    þ
zUninstallPathSet.rollbackc                 C   s   | j  ¡  dS )z?Remove temporary save dir: rollback will no longer be possible.N)r®   r›   r„   r'   r'   r(   r›   ·  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| d
¡ ¡ D ]&}tj tj |j|¡¡}	| |	¡ qôn�| d¡�râ| d¡�rB| d¡‰ ng ‰ ‡ fdd„| d¡ ¡ D ƒD ]J}
tj |j|
¡}	| |	¡ | |	d ¡ | |	d ¡ | |	d ¡ �qb�n0|�rÌtd |j¡ƒ‚�n|j d¡�r"| |j¡ tj |j¡d }tj tj |j¡d¡}| |d| ¡ nÀ|�rR|j d¡�rRt |ƒD ]}	| |	¡ �q>n�|�rÒt!|ƒ�}tj "| #¡  $¡ ¡}W 5 Q R X ||jk�s¢t%d ||j|j¡ƒ‚| |¡ tj tj |¡d¡}| ||j¡ nt &d||j¡ | d¡�rV| 'd¡�rV| (d¡D ]P}t)|ƒ�rt*ƒ }nt+ƒ }| tj ||¡¡ t,�r| tj ||¡d ¡ �qg }|j-dd�}| .¡ D ]}| /t0||dƒ¡ �qn|j-dd�}| .¡ D ]}| /t0||d ƒ¡ �qœ|D ]}| |¡ �qº|S )!Nz1Not uninstalling %s at %s, outside environment %sc                 S   s   h | ]}|r|’qS r'   r'   rY   r'   r'   r(   r\   É  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'   rY   ©Ú
namespacesr'   r(   Ú
<listcomp>ñ  s    þz.UninstallPathSet.from_dist.<locals>.<listcomp>r8   r:   r;   z©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.eggr°   zeasy-install.pthz./rt   z;Egg-link {} does not match installed location of {} (at {})z)Not sure how to uninstall: %s - Check: %sÚscriptsz.batÚconsole_scripts)ÚgroupFÚgui_scriptsT)1r   r?   r   r�   rž   rH   ÚsysÚprefixÚ	sysconfigÚget_pathr   Úformatr   Úto_filenamer¹   Úegg_infor   r   r±   ÚgetattrÚ	_providerr@   r,   Úhas_metadataÚget_metadataÚ
splitlinesÚnormpathr   r   rA   rc   r·   rF   ÚopenrX   ÚreadlineÚstripÚAssertionErrorrŸ   Ú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)r¦   r§   r¨   r©   r†   r¯   r,   r·   r¼   r»   r£   r›   Úclassmethodrõ   r'   r'   r'   r(   r«   8  s   	

 r«   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
r´   c                 C   s   || _ tƒ | _d | _d S r*   )Úfiler+   ÚentriesÚ_saved_lines)r…   rµ   r'   r'   r(   r†   B  s    zUninstallPthEntries.__init__c                 C   s<   t j |¡}tr,t j |¡d s,| dd¡}| j |¡ d S )Nr   ú\ú/)r   r   rX   r   Ú
splitdriveÚreplacerø   r,   )r…   r¶   r'   r'   r(   r,   H  s    
zUninstallPthEntries.addc              	   C   s
  t  d| j¡ tj | j¡s.t  d| j¡ d S t| jdƒ�}| ¡ }|| _	W 5 Q R X t
dd„ |D ƒƒrld}nd}|rž|d  | d	¡¡sž|d | d	¡ |d< | jD ]>}z$t  d
|¡ | ||  d	¡¡ W q¤ tk
rà   Y q¤X q¤t| jdƒ�}| |¡ W 5 Q R X d S )NzRemoving pth entries from %s:z.Cannot remove entries from nonexistent file %sÚrbc                 s   s   | ]}d |kV  qdS )s   
Nr'   )rM   Úliner'   r'   r(   rQ   f  s     z-UninstallPthEntries.remove.<locals>.<genexpr>z
Ú
éÿÿÿÿzutf-8zRemoving entry: %sÚwb)r�   rŸ   r÷   r   r   rv   ÚwarningrÜ   Ú	readlinesrù   rS   r@   Úencoderø   r¼   Ú
ValueErrorÚ
writelines)r…   rï   ÚlinesÚendliner¶   r'   r'   r(   r¼   X  s.     ÿ
zUninstallPthEntries.removec              	   C   sR   | j d krt d| j¡ dS t d| j¡ t| jdƒ�}| | j ¡ W 5 Q R X dS )Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous stater  T)rù   r�   r¡   r÷   rŸ   rÜ   r  )r…   rï   r'   r'   r(   r£   v  s    
 ÿzUninstallPthEntries.rollbackN)r¦   r§   r¨   r†   r,   r¼   r£   r'   r'   r'   r(   r´   A  s   r´   )7r<   r4   Úloggingr   rÏ   rÑ   Úimportlib.utilr   Útypingr   r   r   r   r   r   r	   r
   r   Úpip._vendorr   Úpip._vendor.pkg_resourcesr   Úpip._internal.exceptionsr   Úpip._internal.locationsr   r   Úpip._internal.utils.compatr   Úpip._internal.utils.loggingr   Úpip._internal.utils.miscr   r   r   r   r   r   r   r   Úpip._internal.utils.temp_dirr   r   Ú	getLoggerr¦   r�   r)   r6   rF   rW   rs   r€   r�   r«   r´   r'   r'   r'   r(   Ú<module>   s8   ,(


'3o  