U ʗRe]@sddlZddlZddlZddlZddlmZddlmZmZm Z m Z m Z m Z m Z mZmZddlmZddlmZmZddlmZddlmZddlmZdd lmZmZdd lmZm Z m!Z!m"Z"m#Z#dd l$m%Z%m&Z&ee'Z(e)e)e*e e)ddfd d dZ+ede eddffede eddffdddZ,e,ee e)ddfdddZ-e e)ee)dddZ.e e)ee)dddZ/e e)eee)ee)fdddZ0GdddZ1Gdd d Z2Gd!d"d"Z3dS)#N)cache_from_source) AnyCallableDict GeneratorIterableListOptionalSetTuple)UninstallationError)get_bin_prefix get_bin_user)BaseDistribution)WINDOWS)egg_link_path_from_location) getLogger indent_log)askis_localnormalize_pathrenamesrmtree)AdjacentTempDirectory TempDirectory)bin_dir script_nameis_guireturnccsVtj||}|VtsdS|dV|dV|rF|dVn |dVdS)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)ospathjoinr)rrrexe_namer#/builddir/build/BUILDROOT/alt-python38-pip-22.2.1-2.el8.x86_64/opt/alt/python38/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py _script_namess  r%.)fnrcs.tttttddfdfdd }|S)N)argskwrc?s2t}||D]}||kr|||VqdSN)setadd)r'r(seenitemr&r#r$unique*s  z_unique..unique) functoolswrapsrr)r&r/r#r.r$_unique's"r2distrc cs|j}|dk std|}|dkrzdj|d}|j}|rD|dkrdd|j|j}|d|7}n|d|7}t||D]n}tj ||}|V| d r~tj |\}} | dd } tj || d }|Vtj || d }|Vq~dS) 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.)r4pipz{}=={}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) locationAssertionErroriter_declared_entriesformat installerraw_nameversionr rr r!endswithsplit) r4r:entriesmsgr>depentryr dnr&baser#r#r$uninstallation_paths5s2    rI)pathsrcsJtjjt}t|tdD]*tfdd|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.keyc3s:|]2}|do0t|dkVqdS)*N) startswithrstriplen).0 shortpathr sepr#r$ jszcompact..)rr rTr*sortedrPanyr+)rJ short_paths should_skipr#rSr$compactas rZc sdd|D}t|}tdd|Dtd}t}ttddd|D]tfd d |DrfqJt}t}tD]B\}}|fd d |D|fd d |Dq|||sJ| || tj qJtt |j ||BS) 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. cSsi|]}tj||qSr#)rr normcaserQpr#r#r$ zs z'compress_for_rename..cSsh|]}tj|dqS)r)rr rBr\r#r#r$ |sz&compress_for_rename..rK)arcWstjtjj|Sr))rr r[r!)r`r#r#r$ norm_joinsz&compress_for_rename..norm_joinc3s |]}tj|VqdSr))rr r[rN)rQw)rootr#r$rUsz&compress_for_rename..c3s|]}|VqdSr)r#)rQddirnamerarcr#r$rUsc3s|]}|VqdSr)r#)rQfrer#r$rUs)r*rVvaluesrPstrrWrwalkupdatedifference_updater+rTmap __getitem__) rJcase_map remaining unchecked wildcards all_files all_subdirssubdirsfilesr#rer$compress_for_renamets" rwc Cst|}t}t}t}|D]>}|dr.q|ds@d|krR|tj|||qtttjj|}t|}|D]d}t |D]T\}} } | D]D} | drqtj || } tj | rtj| |kr|| qqq||dd|DB}||fS)asReturns 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. r8z __init__.pyz .dist-infocSsh|]}tj|dqS)rM)rr r!)rQfolderr#r#r$r_sz.compress_for_output_listing..) r*rAr+rr rfrmr[rZrjr!isfile) rJ will_remove will_skipfoldersrvr _normcased_filesrxdirpath_dirfilesfnamefile_r#r#r$compress_for_output_listings2     rc@s|eZdZdZddddZeedddZeedd d Zeedd d Zddd dZ ddddZ e e dddZ dS)StashedUninstallPathSetzWA set of file rename operations to stash files while tentatively uninstalling them.NrcCsi|_g|_dSr)) _save_dirs_movesselfr#r#r$__init__sz StashedUninstallPathSet.__init__r rcCsDz t|}Wntk r*tdd}YnX||jtj|<|jS)zStashes a directory. Directories are stashed adjacent to their original location if possible, or else moved/copied into the user's temp dir. uninstallkind)rOSErrorrrrr r[)rr save_dirr#r#r$_get_directory_stashs  z,StashedUninstallPathSet._get_directory_stashcCstj|}tj|d}}d}||krfz|j|}WqWntk rPYnXtj||}}q"tj|}tdd}||j|<tj||}|r|tjjkrtj |j|S|jS)zStashes a file. If no root has been provided, one will be created for the directory in the user's temp directory.Nrr) rr r[rfrKeyErrorrrelpathcurdirr!)rr headold_headrrr#r#r$_get_file_stashs"     z'StashedUninstallPathSet._get_file_stashcCsltj|otj| }|r*||}n ||}|j||f|r^tj|r^t|t |||S)zStashes the directory or file and returns its new location. Handle symlinks as files to avoid modifying the symlink targets. ) rr isdirislinkrrrappendrmdirr)rr path_is_dirnew_pathr#r#r$stashs    zStashedUninstallPathSet.stashcCs,|jD]\}}|q g|_i|_dS)z0Commits the uninstall by removing stashed files.N)ritemscleanupr)rrrr#r#r$commits zStashedUninstallPathSet.commitc Cs|jD]}tjd|q|jD]\}}zTtd||tj|sPtj|r\t|ntj |rpt |t ||Wq t k r}zt d|td|W5d}~XYq Xq |dS)z2Undoes the uninstall by moving stashed files back.Moving to %s from %szReplacing %s from %szFailed to restore %sz Exception: %sN)r)rloggerinfodebugrr ryrunlinkrrrrerrorr)rr]rr exr#r#r$rollbacks     z StashedUninstallPathSet.rollbackcCs t|jSr))boolrrr#r#r$ can_rollback,sz$StashedUninstallPathSet.can_rollback)__name__ __module__ __qualname____doc__rrirrrrrpropertyrrr#r#r#r$rsrc@seZdZdZeddddZeedddZeddd d Z eedd d d Z deeddddZ eedddZ ddddZ ddddZeeddddZdS)UninstallPathSetzMA set of file paths to be removed in the uninstallation of a requirement.Nr3cCs(t|_t|_i|_||_t|_dSr))r*_paths_refuse_pth_distr _moved_paths)rr4r#r#r$r5s zUninstallPathSet.__init__rcCst|S)zs Return True if the given path is one we are permitted to remove/modify, False otherwise. )r)rr r#r#r$ _permitted<szUninstallPathSet._permittedcCstj|\}}tjt|tj|}tj|s:dS||rR|j |n |j |tj |ddkr| t |dS)Nr6) rr rBr!rr[existsrrr+rsplitextr)rr rtailr#r#r$r+Ds   zUninstallPathSet.add)pth_filerFrcCsLt|}||r<||jkr*t||j|<|j||n |j|dSr))rrrUninstallPthEntriesr+r)rrrFr#r#r$add_pthWs   zUninstallPathSet.add_pthF) auto_confirmverboserc Cs|jstd|jjdS|jjd|jj}td|tp|sR||r|j}t |j}t t |D]}| |t d|qn|jD] }|qtd|W5QRXdS)z\Remove paths in ``self._paths`` with confirmation (unless ``auto_confirm`` is True).z7Can't uninstall '%s'. No files were found to uninstall.N-zUninstalling %s:zRemoving file or directory %szSuccessfully uninstalled %s)rrrrr?r@r_allowed_to_proceedrrwrVrZrrrrhremove)rrrdist_name_versionmoved for_renamer pthr#r#r$r`s$    zUninstallPathSet.remove)rrcCs|tttdddd}|s*t|j\}}nt|j}t}|d||d||d|j|rn|dt|jtd d d kS) z@Display which files would be deleted and prompt for confirmationN)rDrJrc SsD|sdSt|t"tt|D]}t|q&W5QRXdSr))rrrrVrZ)rDrJr r#r#r$_displays  z6UninstallPathSet._allowed_to_proceed.._displayz Would remove:z+Would not remove (might be manually added):z%Would not remove (outside of prefix):zWill actually move:zProceed (Y/n)? )ynr)rirrrr*rrwr)rrrrzr{r#r#r$r}s     z$UninstallPathSet._allowed_to_proceedrcCsR|jjstd|jjdStd|jj|j|j D] }|q@dS)z1Rollback the changes previously made by remove().z'Can't roll back %s; was not uninstalledNzRolling back uninstall of %s) rrrrrr?rrrrh)rrr#r#r$rs zUninstallPathSet.rollbackcCs|jdS)z?Remove temporary save dir: rollback will no longer be possible.N)rrrr#r#r$rszUninstallPathSet.commitc s|j}|j}|dkr*td|j||St|}|jsTtd|j|tj||S|ddt dt dhDkrtd|j|||S||}t |j }|j o|dk otj|o||jd }|r|dk r|||}|dk r|D]} |tj|| qn|d rz|d } Wntk rLgYnX| jd d fd d|d DD]N} tj|| } || || d|| d|| dqvn*|jrtd|j n|jr0||tj|d} tjtj|d}| |d| n|j!rTt"|D]} || q@n|rt#|"}tj$|%&}t|}W5QRXtj'||st(d|d|j d|d||tjtj|d}| ||nt)d|||j*rt+}nt,}zH|-D]:}|tj||t.r|tj||dqWntt/fk rlYnXt0t1t2t1ddfddd}|||D]}||q|S)Nz-Not uninstalling %s since it is not installedz1Not uninstalling %s at %s, outside environment %scSsh|] }|r|qSr#r#r\r#r#r$r_sz-UninstallPathSet.from_dist..stdlib platstdlibzsz.UninstallPathSet.from_dist..r6r8r9zCannot 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.rzeasy-install.pthz./z Egg-link z& does not match installed location of z (at )z)Not sure how to uninstall: %s - Check: %sz.bat)r4rrcssP|D]B}|jdkr,t||jdEdHq|jdkrt||jdEdHqdS)Nconsole_scriptsF gui_scriptsT)iter_entry_pointsgroupr%name)r4r entry_pointr#r#r$iter_scripts_to_remove9s    z:UninstallPathSet.from_dist..iter_scripts_to_remove)3r: info_locationrrcanonical_namerlocalsysprefix sysconfigget_pathrr?"installed_with_setuptools_egg_inforr rrAsetuptools_filenamer+r<r!is_file read_textFileNotFoundError splitlinesinstalled_by_distutilsr r=installed_as_eggrBrfrinstalled_with_dist_inforIopenr[readlinestripsamefiler;r in_usersiterr iter_distutils_script_namesrNotADirectoryErrorrrir)clsr4 dist_locationrnormalized_dist_locationpaths_to_removedevelop_egg_linksetuptools_flat_installationinstalled_filesinstalled_filenamespace_packages top_level_pkgr easy_install_eggeasy_install_pthfh link_pointernormalized_link_pointerrscriptrsr#rr$ from_dists                  " zUninstallPathSet.from_dist)FF)rrrrrrrirrr+rrrrr classmethodrr#r#r#r$r1s  rc@sHeZdZeddddZeddddZddd d Zedd d ZdS) rN)rrcCs||_t|_d|_dSr))filer*rC _saved_lines)rrr#r#r$rJszUninstallPthEntries.__init__)rFrcCs<tj|}tr,tj|ds,|dd}|j|dS)Nr\/)rr r[r splitdrivereplacerCr+)rrFr#r#r$r+Os  zUninstallPthEntries.addrc Cs td|jtj|js.td|jdSt|jd}|}||_ W5QRXt dd|Drld}nd}|r|d | d s|d| d |d<|j D]>}z$td |||| d Wqtk rYqXqt|jd }||W5QRXdS) NzRemoving pth entries from %s:z.Cannot remove entries from nonexistent file %srbcss|]}d|kVqdS)s Nr#)rQliner#r#r$rUisz-UninstallPthEntries.remove..z  zutf-8zRemoving entry: %swb)rrrrr rywarningr readlinesrrWrAencoderCr ValueError writelines)rrlinesendlinerFr#r#r$r^s(  zUninstallPthEntries.removec CsR|jdkrtd|jdStd|jt|jd}||jW5QRXdS)Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous staterT)rrrrrrr)rrr#r#r$rys zUninstallPthEntries.rollback) rrrrirr+rrrr#r#r#r$rIsr)4r0rrrimportlib.utilrtypingrrrrrrr r r pip._internal.exceptionsr pip._internal.locationsr rpip._internal.metadatarpip._internal.utils.compatrpip._internal.utils.egg_linkrpip._internal.utils.loggingrrpip._internal.utils.miscrrrrrpip._internal.utils.temp_dirrrrrrirr%r2rIrZrwrrrrr#r#r#r$s@ ,      +"$2i