a
    hbòf]  ã                   @   s¶  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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& ee'ƒZ(e)e)e*ee) dœdd„Z+edee f edee f dœdd„Z,e,eee) dœdd„ƒZ-e
e) ee) dœdd„Z.e
e) ee) dœdd„Z/e
e) eee) ee) f dœdd„Z0G dd„ dƒZ1G dd „ d ƒZ2G d!d"„ d"ƒZ3dS )#é    N)Úcache_from_source)	ÚAnyÚCallableÚDictÚIterableÚIteratorÚListÚOptionalÚSetÚTuple)ÚUninstallationError)Úget_bin_prefixÚget_bin_user)ÚBaseDistribution)ÚWINDOWS)Úegg_link_path_from_location)Ú	getLoggerÚ
indent_log)ÚaskÚis_localÚnormalize_pathÚrenamesÚrmtree)ÚAdjacentTempDirectoryÚTempDirectory)Úbin_dirÚscript_nameÚis_guiÚreturnc                 c   sV   t j | |¡}|V  tsdS |› d�V  |› d�V  |rF|› d�V  n|› d�V  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
    Nz.exez.exe.manifestz-script.pywz
-script.py)ÚosÚpathÚjoinr   )r   r   r   Úexe_name© r#   ú\/home/httpd/docs/test/DocsMgr/lib/python3.9/site-packages/pip/_internal/req/req_uninstall.pyÚ_script_names   s    r%   .)Úfnr   c                    s(   t  ˆ ¡tttt dœ‡ fdd„ƒ}|S )N)ÚargsÚkwr   c                  ?   s6   t ƒ }ˆ | i |¤ŽD ]}||vr| |¡ |V  qd S ©N)ÚsetÚadd)r'   r(   ÚseenÚitem©r&   r#   r$   Úunique&   s
    
z_unique.<locals>.unique)Ú	functoolsÚwrapsr   r   )r&   r/   r#   r.   r$   Ú_unique%   s    r2   ©Údistr   c                 c   sò   | j }|dusJ dƒ‚|  ¡ }|du rzdj| d�}| j}|rD|dkrdd | j| j¡}|d |¡7 }n|d |¡7 }t|ƒ‚|D ]n}tj 	||¡}|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].

    If RECORD is not found, raises UninstallationError,
    with possible information from the INSTALLER file.

    https://packaging.python.org/specifications/recording-installed-packages/
    Nznot installedz/Cannot uninstall {dist}, RECORD file not found.)r4   Úpipz{}=={}zZ You might be able to recover from this via: 'pip install --force-reinstall --no-deps {}'.z' Hint: The package was installed by {}.ú.pyéýÿÿÿú.pycú.pyo)ÚlocationÚiter_declared_entriesÚformatÚ	installerÚraw_nameÚversionr   r   r    r!   ÚendswithÚsplit)r4   r:   ÚentriesÚmsgr=   ÚdepÚentryr    Údnr&   Úbaser#   r#   r$   Úuninstallation_paths1   s2    ÿÿ
rH   )Úpathsr   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>f   s   þzcompact.<locals>.<genexpr>)r   r    rS   r*   ÚsortedrO   Úanyr+   )rI   Úshort_pathsÚshould_skipr#   rR   r$   Úcompact]   s    ýrY   c           	         sø   dd„ | D ƒ}t |ƒ}tdd„ | ¡ D ƒtd�}t ƒ }ttdœdd„‰|D ]˜‰t‡fd	d
„|D ƒƒrfqJt ƒ }t ƒ }t ˆ¡D ]B\‰ }}| ‡ ‡‡fdd
„|D ƒ¡ | ‡ ‡‡fdd
„|D ƒ¡ q||| sJ| 	|¡ | 
ˆtj ¡ qJt 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©rP   Úpr#   r#   r$   Ú
<dictcomp>v   ó    z'compress_for_rename.<locals>.<dictcomp>c                 S   s   h | ]}t j |¡d  ’qS )r   )r   r    rA   r[   r#   r#   r$   Ú	<setcomp>x   r^   z&compress_for_rename.<locals>.<setcomp>rJ   )Úar   c                  W   s   t j t jj| Ž ¡S r)   )r   r    rZ   r!   )r`   r#   r#   r$   Ú	norm_join{   s    z&compress_for_rename.<locals>.norm_joinc                 3   s    | ]}t j ˆ ¡ |¡V  qd S r)   )r   r    rZ   rM   )rP   Úw)Úrootr#   r$   rT      r^   z&compress_for_rename.<locals>.<genexpr>c                 3   s   | ]}ˆˆˆ |ƒV  qd S r)   r#   )rP   Úd©Údirnamera   rc   r#   r$   rT   †   r^   c                 3   s   | ]}ˆˆˆ |ƒV  qd S r)   r#   )rP   Úfre   r#   r$   rT   ‡   r^   )r*   rU   ÚvaluesrO   ÚstrrV   r   ÚwalkÚupdateÚdifference_updater+   rS   ÚmapÚ__getitem__)	rI   Úcase_mapÚ	remainingÚ	uncheckedÚ	wildcardsÚ	all_filesÚall_subdirsÚsubdirsÚfilesr#   re   r$   Úcompress_for_renamep   s"    
rw   c                 C   sü   t | ƒ}t ƒ }t ƒ }t ƒ }|D ]>}| d¡r.q| d¡s@d|v 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 |¡|v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.
    r8   z__init__.pyz
.dist-infoc                 S   s   h | ]}t j |d ¡’qS )rL   )r   r    r!   )rP   Úfolderr#   r#   r$   r_   ¿   r^   z.compress_for_output_listing.<locals>.<setcomp>)r*   r@   r+   r   r    rf   rm   rZ   rY   rj   r!   Úisfile)rI   Úwill_removeÚ	will_skipÚfoldersrv   r    Ú_normcased_filesrx   ÚdirpathÚ_ÚdirfilesÚfnameÚfile_r#   r#   r$   Úcompress_for_output_listing’   s2    


ÿþrƒ   c                   @   s|   e Zd ZdZddœdd„Zeedœdd„Zeedœd	d
„Zeedœdd„Zddœdd„Z	ddœdd„Z
eedœdd„ƒZdS )ÚStashedUninstallPathSetzWA set of file rename operations to stash files while
    tentatively uninstalling them.N©r   c                 C   s   i | _ g | _d S r)   )Ú
_save_dirsÚ_moves©Úselfr#   r#   r$   Ú__init__È   s    z StashedUninstallPathSet.__init__©r    r   c                 C   sB   zt |ƒ}W n ty(   tdd�}Y n0 || 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    rZ   )r‰   r    Úsave_dirr#   r#   r$   Ú_get_directory_stashÐ   s    z,StashedUninstallPathSet._get_directory_stashc                 C   s¸   t j |¡}t j |¡d }}d}||krdz| j| }W q„W n tyN   Y n0 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    rZ   rf   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‡   ÚappendÚ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g|¢R Ž  q| j D ]š\}}zTt d||¡ tj |¡sTtj |¡r`t |¡ ntj 	|¡rtt
|ƒ t||ƒ W q$ ty¼ } z$t d|¡ t d|¡ W Y d}~q$d}~0 0 q$|  ¡  dS )z2Undoes the uninstall by moving stashed files back.zMoving to %s
 from %szReplacing %s from %szFailed to restore %szException: %sN)r‡   ÚloggerÚinfoÚdebugr   r    ry   r™   Úunlinkr˜   r   r   r�   Úerrorr¡   )r‰   r\   r�   r    Úexr#   r#   r$   Úrollback  s    
$z StashedUninstallPathSet.rollbackc                 C   s
   t | jƒS r)   )Úboolr‡   rˆ   r#   r#   r$   Úcan_rollback(  s    z$StashedUninstallPathSet.can_rollback)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rŠ   ri   r‘   r—   rž   r¡   r¨   Úpropertyr©   rª   r#   r#   r#   r$   r„   Ä   s   r„   c                   @   s¦   e Zd ZdZeddœdd„Zeedœdd„Zeddœd	d
„Z	eeddœdd„Z
deeddœdd„Zeedœdd„Zddœdd„Zddœdd„Zeed dœdd„ƒZdS )ÚUninstallPathSetzMA set of file paths to be removed in the uninstallation of a
    requirement.Nr3   c                 C   s(   t ƒ | _t ƒ | _i | _|| _tƒ | _d S r)   )r*   Ú_pathsÚ_refuseÚ_pthÚ_distr„   Ú_moved_paths)r‰   r4   r#   r#   r$   rŠ   1  s
    zUninstallPathSet.__init__r‹   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$   Ú
_permitted8  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é   r6   )r   r    rA   r!   r   rZ   Úexistsr¶   r±   r+   r²   Úsplitextr   )r‰   r    r•   Útailr#   r#   r$   r+   @  s    
zUninstallPathSet.add)Úpth_filerE   r   c                 C   sL   t |ƒ}|  |¡r<|| jvr*t|ƒ| j|< | j|  |¡ n| j |¡ d S r)   )r   r¶   r³   ÚUninstallPthEntriesr+   r²   )r‰   r»   rE   r#   r#   r$   Úadd_pthS  s    

zUninstallPathSet.add_pthF)Úauto_confirmÚverboser   c                 C   sÐ   | j st d| jj¡ dS | jj› d| jj› �}t d|¡ tƒ �z |sR|  |¡r®| j}t	| j ƒ}t
t|ƒƒD ]}| |¡ t d|¡ qn| j ¡ D ]}| ¡  q”t d|¡ W d  ƒ n1 sÂ0    Y  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)r±   r¢   r£   r´   r>   r?   r   Ú_allowed_to_proceedrµ   rw   rU   rY   rž   r¿   r³   rh   Úremove)r‰   r¾   r¿   Údist_name_versionÚmovedÚ
for_renamer    Úpthr#   r#   r$   rÂ   \  s$    þ


zUninstallPathSet.remove)r¿   r   c                 C   s|   t tt  ddœdd„}|s*t| jƒ\}}nt| jƒ}tƒ }|d|ƒ |d|ƒ |d| jƒ |rn|dt| jƒƒ td	d
ƒdkS )z@Display which files would be deleted and prompt for confirmationN)rC   rI   r   c                 S   sX   |sd S t  | ¡ tƒ �, tt|ƒƒD ]}t  |¡ q&W d   ƒ n1 sJ0    Y  d S r)   )r¢   r£   r   rU   rY   )rC   rI   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ÚnÚ rÉ   )ri   r   rƒ   r±   r*   r²   rw   r   )r‰   r¿   rÇ   rz   r{   r#   r#   r$   rÁ   y  s    	


z$UninstallPathSet._allowed_to_proceedr…   c                 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³   rh   )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®  |j }|j}|d u r*t d|j¡ | |ƒS t|ƒ}|jsTt d|j|tj¡ | |ƒS |dd„ t	 
d¡t	 
d¡hD ƒv rŽt d|j|¡ | |ƒS | |ƒ}t|jƒ}|joÌ|d uoÌtj |¡oÌ| |j› d�¡ }|�rÈ|d uræ| |¡ | ¡ }|d u�r|D ]}	| tj ||	¡¡ qün¬| d	¡�rúz| d
¡}
W n t�yJ   g ‰ Y n0 |
jdd�‰ ‡ fdd„| d	¡ ¡ D ƒD ]N}tj ||¡}| |¡ | |› d�¡ | |› d�¡ | |› d�¡ �qt�n2|j�rätd |j¡ƒ‚�n|j�r.| |¡ tj |¡d }tj tj |¡d¡}|  |d| ¡ nÌ|j!�rRt"|ƒD ]}| |¡ �q>n¨|�rìt#|ƒ�$}tj $| %¡  &¡ ¡}W d   ƒ n1 �sŒ0    Y  ||k�s¾J d|› d|j› d|› d�ƒ‚| |¡ tj tj |¡d¡}|  ||¡ nt 'd||¡ |j(�r
t)ƒ }nt*ƒ }zN| +d¡D ]>}| tj ||j,¡¡ t-�r| tj ||j,› d�¡¡ �qW n tt.f�yv   Y n0 t/t0t1t0 dœdd„}|||ƒD ]}| |¡ �q˜|S ) Nz-Not uninstalling %s since it is not installedz1Not uninstalling %s at %s, outside environment %sc                 S   s   h | ]}|r|’qS r#   r#   r[   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-infoztop_level.txtznamespace_packages.txtF)Úkeependsc                    s   g | ]}|r|ˆ vr|‘qS r#   r#   r[   ©Ú
namespacesr#   r$   Ú
<listcomp>é  s   þz.UninstallPathSet.from_dist.<locals>.<listcomp>r6   r8   r9   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.r·   zeasy-install.pthz./z	Egg-link z& does not match installed location of z (at ú)z)Not sure how to uninstall: %s - Check: %sÚscriptsz.bat)r4   r   r   c                 s   sP   |   ¡ D ]B}|jdkr,t||jdƒE d H  q|jdkrt||jdƒE d H  qd S )NÚconsole_scriptsFÚgui_scriptsT)Úiter_entry_pointsÚgroupr%   Úname)r4   r   Úentry_pointr#   r#   r$   Úiter_scripts_to_remove2  s
    

z:UninstallPathSet.from_dist.<locals>.iter_scripts_to_remove)2r:   Úinfo_locationr¢   r£   Úcanonical_namer   ÚlocalÚsysÚprefixÚ	sysconfigÚget_pathr   r>   Ú"installed_with_setuptools_egg_infor   r    r¸   r@   Úsetuptools_filenamer+   r;   r!   Úis_fileÚ	read_textÚFileNotFoundErrorÚ
splitlinesÚinstalled_by_distutilsr   r<   Úinstalled_as_eggrA   rf   r½   Úinstalled_with_dist_inforH   ÚopenrZ   ÚreadlineÚstripr¤   Úin_usersiter   r   Úiterdirr×   r   ÚNotADirectoryErrorr   ri   r   )Úclsr4   Údist_locationrÚ   Únormalized_dist_locationÚpaths_to_removeÚdevelop_egg_linkÚsetuptools_flat_installationÚinstalled_filesÚinstalled_fileÚnamespace_packagesÚtop_level_pkgr    Úeasy_install_eggÚeasy_install_pthÚfhÚlink_pointerr   ÚscriptrÙ   Úsr#   rÎ   r$   Ú	from_dist¦  sÜ    þüþý
ÿ
þú



þ

ýÿ

þ
4ÿÿÿ
ÿý$ý
zUninstallPathSet.from_dist)FF)r«   r¬   r­   r®   r   rŠ   ri   r©   r¶   r+   r½   rÂ   rÁ   r¨   r¡   Úclassmethodr   r#   r#   r#   r$   r°   -  s   	r°   c                   @   sH   e Zd Zeddœdd„Zeddœdd„Zddœd	d
„Zedœdd„ZdS )r¼   N)r»   r   c                 C   s   || _ tƒ | _d | _d S r)   )Úfiler*   rB   Ú_saved_lines)r‰   r»   r#   r#   r$   rŠ   C  s    zUninstallPthEntries.__init__)rE   r   c                 C   s<   t j |¡}tr,t j |¡d s,| dd¡}| j |¡ d S )Nr   ú\ú/)r   r    rZ   r   Ú
splitdriveÚreplacerB   r+   )r‰   rE   r#   r#   r$   r+   H  s    
zUninstallPthEntries.addr…   c              	   C   s2  t  d| j¡ tj | j¡s.t  d| j¡ d S t| jdƒ�}| ¡ }|| _	W d   ƒ n1 s^0    Y  t
dd„ |D ƒƒr€d}nd}|r²|d  | d	¡¡s²|d | d	¡ |d< | jD ]<}z$t  d
|¡ | ||  d	¡¡ W q¸ tyò   Y q¸0 q¸t| jdƒ�}| |¡ W d   ƒ n1 �s$0    Y  d S )NzRemoving pth entries from %s:z.Cannot remove entries from nonexistent file %sÚrbc                 s   s   | ]}d |v V  qdS )s   
Nr#   )rP   Úliner#   r#   r$   rT   b  r^   z-UninstallPthEntries.remove.<locals>.<genexpr>z
Ú
éÿÿÿÿzutf-8zRemoving entry: %sÚwb)r¢   r¿   r  r   r    ry   Úwarningrê   Ú	readlinesr  rV   r@   ÚencoderB   rÂ   Ú
ValueErrorÚ
writelines)r‰   rü   ÚlinesÚendlinerE   r#   r#   r$   rÂ   W  s(    $
zUninstallPthEntries.removec                 C   sf   | j d u rt d| j¡ dS t d| j¡ t| jdƒ�}| | j ¡ W d   ƒ n1 sX0    Y  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¨   r  s    
*zUninstallPthEntries.rollback)	r«   r¬   r­   ri   rŠ   r+   rÂ   r©   r¨   r#   r#   r#   r$   r¼   B  s   r¼   )4r0   r   rÝ   rß   Úimportlib.utilr   Útypingr   r   r   r   r   r   r	   r
   r   Úpip._internal.exceptionsr   Úpip._internal.locationsr   r   Úpip._internal.metadatar   Úpip._internal.utils.compatr   Úpip._internal.utils.egg_linkr   Úpip._internal.utils.loggingr   r   Úpip._internal.utils.miscr   r   r   r   r   Úpip._internal.utils.temp_dirr   r   r«   r¢   ri   r©   r%   r2   rH   rY   rw   rƒ   r„   r°   r¼   r#   r#   r#   r$   Ú<module>   s4   ,(+"$2i  