o
    1c]                  	   @   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(de)de)de*dee) fddZ+dedee f dedee f fddZ,e,dedee) fddZ-de
e) dee) fddZ.de
e) dee) fddZ/de
e) deee) ee) f f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   sZ    t j| |}|V  tsdS | dV  | dV  |r%| dV  dS | dV  dS )zCreate 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   Zexe_name r"   X/var/www/html/django/env/lib/python3.10/site-packages/pip/_internal/req/req_uninstall.py_script_names   s   r$   fn.c                    s,   t  dtdtdtt f fdd}|S )Nargskwr   c                  ?   s8    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    r1   distc                 c   s    | j }|dusJ d|  }|du rAdj| d}| j}|r#|dkr6d| j| j}|d|7 }t||d|7 }t||D ]7}tj	||}|V  |
d	rztj|\}}	|	dd
 }
tj	||
d }|V  tj	||
d }|V  qCd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.)r2   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)r2   r8   entriesmsgr;   Zdepentryr    dnr%   baser"   r"   r#   uninstallation_paths1   s8   
rE   pathsc                    sJ   t jjt }t| tdD ] t fdd|D }|s"|  q|S )zCompact 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<    | ]}  |d o t|d  kV  qdS )*N)
startswithrstriplen).0Z	shortpathr    sepr"   r#   	<genexpr>f   s    
zcompact.<locals>.<genexpr>)r   r    rO   r)   sortedrL   anyr*   )rF   Zshort_pathsZshould_skipr"   rN   r#   compact]   s   
rS   c           	         s   dd | D }t |}tdd | D td}t  }dtdtfdd	|D ]Ltfd
d|D r4q&t  }t  }tD ]!\ }}| fdd|D  | fdd|D  q?|| sr|	| |
tj  q&t t|j||B S )zReturns 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       z'compress_for_rename.<locals>.<dictcomp>c                 S   s   h | ]
}t j|d  qS )r   )r   r    r?   rU   r"   r"   r#   	<setcomp>x   s    z&compress_for_rename.<locals>.<setcomp>rG   ar   c                  W   s   t jt jj|  S r(   )r   r    rT   r!   )rZ   r"   r"   r#   	norm_join{   s   z&compress_for_rename.<locals>.norm_joinc                 3   s"    | ]}t j |V  qd S r(   )r   r    rT   rJ   )rM   w)rootr"   r#   rP      s     z&compress_for_rename.<locals>.<genexpr>c                 3       | ]	} |V  qd S r(   r"   )rM   ddirnamer[   r]   r"   r#   rP          c                 3   r^   r(   r"   )rM   fr`   r"   r#   rP      rb   )r)   rQ   valuesrL   strrR   r   walkupdatedifference_updater*   rO   map__getitem__)	rF   Zcase_map	remainingZ	unchecked	wildcardsZ	all_filesZall_subdirssubdirsfilesr"   r`   r#   compress_for_renamep   s$   
ro   c                 C   s   t | }t  }t  }t  }|D ]}|drq|ds d|v r)|tj| || qt ttjj|}t|}|D ]2}t	|D ]*\}}	}
|
D ]"}|drTqLtj
||}tj|rntj||vrn|| qLqEq>|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.
    r6   z__init__.pyz
.dist-infoc                 S   s   h | ]	}t j|d qS )rI   )r   r    r!   )rM   folderr"   r"   r#   rY      rX   z.compress_for_output_listing.<locals>.<setcomp>)r)   r>   r*   r   r    ra   ri   rT   rS   rf   r!   isfile)rF   will_remove	will_skipZfoldersrn   r    Z_normcased_filesrp   dirpath_ZdirfilesfnameZfile_r"   r"   r#   compress_for_output_listing   s8   



rw   c                   @   sv   e Zd ZdZdddZdedefddZdedefd	d
ZdedefddZdddZ	dddZ
edefddZdS )StashedUninstallPathSetzWA set of file rename operations to stash files while
    tentatively uninstalling them.r   Nc                 C   s   i | _ g | _d S r(   )
_save_dirs_movesselfr"   r"   r#   __init__   s   
z StashedUninstallPathSet.__init__r    c                 C   sB   zt |}W n ty   tdd}Y nw || jtj|< |jS )zStashes 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   ry   r   r    rT   )r|   r    save_dirr"   r"   r#   _get_directory_stash   s   z,StashedUninstallPathSet._get_directory_stashc                 C   s   t j|}t j|d}}d}||kr3z| j| }W n& ty%   Y nw t j||}}||kst j|}tdd}|| j|< t j||}|rZ|t jjkrZt j	|j|S |jS )zStashes 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    rT   ra   ry   KeyErrorr   relpathcurdirr!   )r|   r    headZ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 )zStashes the directory or file and returns its new location.
        Handle symlinks as files to avoid modifying the symlink targets.
        )
r   r    isdirislinkr   r   rz   appendrmdirr   )r|   r    Z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)ry   itemscleanuprz   )r|   ru   r   r"   r"   r#   commit  s   

zStashedUninstallPathSet.commitc                 C   s   | j D ]}tjdg|R   q| j D ]L\}}z*td|| tj|s*tj|r0t| n
tj	|r:t
| t|| W q ty^ } ztd| td| W Y d}~qd}~ww |   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)rz   loggerinfodebugr   r    rq   r   unlinkr   r   r   r   errorr   )r|   rV   r   r    exr"   r"   r#   rollback  s    
z StashedUninstallPathSet.rollbackc                 C   s
   t | jS r(   )boolrz   r{   r"   r"   r#   can_rollback(  s   
z$StashedUninstallPathSet.can_rollbackr   N)__name__
__module____qualname____doc__r}   re   r   r   r   r   r   propertyr   r   r"   r"   r"   r#   rx      s    


rx   c                   @   s   e Zd ZdZdeddfddZdedefdd	Zdeddfd
dZ	dededdfddZ
ddededdfddZdedefddZdddZdddZededd fddZdS )UninstallPathSetzMA set of file paths to be removed in the uninstallation of a
    requirement.r2   r   Nc                 C   s(   t  | _t  | _i | _|| _t | _d S r(   )r)   _paths_refuse_pth_distrx   _moved_paths)r|   r2   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 | |r)| j	| n| j
	| t j|d dkrB| 	t| d S d S )N   r4   )r   r    r?   r!   r   rT   existsr   r   r*   r   splitextr   )r|   r    r   tailr"   r"   r#   r*   @  s   
zUninstallPathSet.addpth_filerB   c                 C   sN   t |}| |r|| jvrt|| j|< | j| | d S | j| d S r(   )r   r   r   UninstallPthEntriesr*   r   )r|   r   rB   r"   r"   r#   add_pthS  s   

zUninstallPathSet.add_pthFauto_confirmverbosec                 C   s   | j std| jj dS | jj d| jj }td| t F |s)| |r_| j}t	| j }t
t|D ]}|| td| q7| j D ]}|  qJtd| W d   dS W d   dS 1 sjw   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   ro   rQ   rS   r   r   r   rd   remove)r|   r   r   Zdist_name_versionmovedZ
for_renamer    pthr"   r"   r#   r   \  s*   


"zUninstallPathSet.removec                 C   s   dt dtt  ddfdd}|st| j\}}nt| j}t }|d| |d| |d	| j |r9|d
t| j tdddkS )z@Display which files would be deleted and prompt for confirmationrA   rF   r   Nc                 S   sZ   |sd S t |  t  tt|D ]}t | qW d    d S 1 s&w   Y  d S r(   )r   r   r   rQ   rS   )rA   rF   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   )re   r   rw   r   r)   r   ro   r   )r|   r   r   rr   rs   r"   r"   r#   r   y  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   rd   )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s*td|j|tj | |S |dd t	
dt	
dhD v rGtd|j| | |S | |}t|j}|jof|d uoftj|of||j d }|r|d urr|| | }|d ur|D ]}	|tj||	 q|n|d	rz|d
}
W n ty   g  Y nw |
jdd  fdd|d	 D D ]&}tj||}|| || d || d || d qn|jrtd|j|jr|| tj|d }tjtj|d}| |d|  nf|j!r t"|D ]}|| qnT|rmt#|}tj$|% & }W d    n	1 s=w   Y  ||ksVJ d| d|j d| d|| tjtj|d}| || nt'd|| |j(r|t) }nt* }z'|+dD ]}|tj||j, t-r|tj||j, d qW n tt.fy   Y nw dt/dt0dt1t0 f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"   rU   r"   r"   r#   rY     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"   rU   
namespacesr"   r#   
<listcomp>  s    z.UninstallPathSet.from_dist.<locals>.<listcomp>r4   r6   r7   zCannot 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.batr2   r   r   c                 s   sR    |   D ]!}|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)r2   r   entry_pointr"   r"   r#   iter_scripts_to_remove2  s   

z:UninstallPathSet.from_dist.<locals>.iter_scripts_to_remove)2r8   info_locationr   r   canonical_namer   localsysprefix	sysconfigget_pathr   r<   "installed_with_setuptools_egg_infor   r    r   r>   setuptools_filenamer*   r9   r!   is_file	read_textFileNotFoundError
splitlinesinstalled_by_distutilsr   r:   installed_as_eggr?   ra   r   installed_with_dist_inforE   openrT   readlinestripr   in_usersiter   r   iterdirr   r   NotADirectoryErrorr   re   r   )clsr2   Zdist_locationr   Znormalized_dist_locationZpaths_to_removeZdevelop_egg_linkZsetuptools_flat_installationZinstalled_filesZinstalled_fileZnamespace_packagesZtop_level_pkgr    Zeasy_install_eggZeasy_install_pthfhZlink_pointerr   scriptr   sr"   r   r#   	from_dist  s   












zUninstallPathSet.from_dist)FFr   )r   r   r   r   r   r}   re   r   r   r*   r   r   r   r   r   classmethodr   r"   r"   r"   r#   r   -  s    	

r   c                   @   sH   e Zd ZdeddfddZdeddfddZdd	d
ZdefddZdS )r   r   r   Nc                 C   s   || _ t | _d | _d S r(   )filer)   r@   _saved_lines)r|   r   r"   r"   r#   r}   C  s   
zUninstallPthEntries.__init__rB   c                 C   s<   t j|}trt j|d s|dd}| j| d S )Nr   \/)r   r    rT   r   
splitdrivereplacer@   r*   )r|   rB   r"   r"   r#   r*   H  s   
zUninstallPthEntries.addc              	   C   s0  t d| j tj| jst d| j d S t| jd}| }|| _	W d    n1 s/w   Y  t
dd |D r@d}nd}|rY|d |d	sY|d |d	 |d< | jD ]}zt d
| ||| d	 W q\ tyy   Y q\w t| jd}|| W d    d S 1 sw   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"   )rM   liner"   r"   r#   rP   b  s    z-UninstallPthEntries.remove.<locals>.<genexpr>z

zutf-8zRemoving entry: %swb)r   r   r   r   r    rq   warningr   	readlinesr   rR   r>   encoder@   r   
ValueError
writelines)r|   r   linesZendlinerB   r"   r"   r#   r   W  s.   
"zUninstallPthEntries.removec                 C   sh   | j d u rtd| j dS td| j t| jd}|| j  W d    dS 1 s-w   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.rollbackr   )	r   r   r   re   r}   r*   r   r   r   r"   r"   r"   r#   r   B  s
    
r   )4r/   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   re   r   r$   r1   rE   rS   ro   rw   rx   r   r   r"   r"   r"   r#   <module>   s6    ,*+&"2i  