3 ]@sddlmZddlZddlZddlZddlmZmZmZddl m Z ddl m Z m Z mZmZmZddlmZejeZGdddeZGd d d eZdS) )absolute_importN) uses_pycacheWINDOWScache_from_source)UninstallationError)rmtreeaskis_localrenamesnormalize_path) indent_logc@sZeZdZdZddZddZddZdd Zd d Zd d Z dddZ ddZ ddZ dS)UninstallPathSetzMA set of file paths to be removed in the uninstallation of a requirement.cCs,t|_t|_i|_||_d|_g|_dS)N)setpaths_refusepthdistsave_dir _moved_paths)selfrr4/tmp/pip-build-8jg9gmni/pip/pip/req/req_uninstall.py__init__s zUninstallPathSet.__init__cCst|S)zs Return True if the given path is one we are permitted to remove/modify, False otherwise. )r )rpathrrr _permittedszUninstallPathSet._permittedcCstjj|\}}tjjt|tjj|}tjj|s:dS|j|rR|jj |n |j j |tjj |ddkrt r|j t |dS)Nz.py)osrsplitjoinr normcaseexistsrraddrsplitextrr)rrheadtailrrrr!#s   zUninstallPathSet.addcCsLt|}|j|r<||jkr*t||j|<|j|j|n |jj|dS)N)r rrUninstallPthEntriesr!r)rpth_fileentryrrradd_pth6s   zUninstallPathSet.add_pthcs@t}x4t|tdD]$tfdd|Ds|jqW|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.)keycs4g|],}j|o.t|jtjjtjjkqSr) startswithlenrstriprrsep).0 shortpath)rrr Gsz,UninstallPathSet.compact..)rsortedr+anyr!)rr short_pathsr)rrcompact?s  zUninstallPathSet.compactcCs&tjj|jtjj|djtjjS)Nr)rrrr splitdrivelstripr-)rrrrr_stashMszUninstallPathSet._stashFc Cs:|jstjd|jjdStjd|jj|jjtt|j|j}|rRd}n"x|D]}tj|qXWt dd }|j rtjdx|j|j D]}tj|qW|dkr,t j dd d |_ x8|D]0}|j|}tjd ||jj|t||qWx|jjD]}|jqWtjd |jj|jjWdQRXdS)z[Remove paths in ``self.paths`` with confirmation (unless ``auto_confirm`` is True).z7Can't uninstall '%s'. No files were found to uninstall.NzUninstalling %s-%s:yzProceed (y/n)? nz.Not removing or modifying (outside of prefix):z -uninstallzpip-)suffixprefixzRemoving file or directory %szSuccessfully uninstalled %s-%s)r8r9)rloggerinfor project_nameversionr r1r4rrtempfilemkdtemprr7debugrappendr rvaluesremove)r auto_confirmrresponsernew_pathrrrrrEQs@          zUninstallPathSet.removecCs~|jdkrtjd|jjdStjd|jjx.|jD]$}|j|}tjd|t ||q6Wx|j j D] }|j qjWdS)z1Rollback the changes previously made by remove().Nz'Can't roll back %s; was not uninstalledFzRolling back uninstall of %sz Replacing %s) rr<errorrr>r=rr7rBr rrDrollback)rrtmp_pathrrrrrJ{s     zUninstallPathSet.rollbackcCs$|jdk r t|jd|_g|_dS)z?Remove temporary save dir: rollback will no longer be possible.N)rrr)rrrrcommits  zUninstallPathSet.commitN)F) __name__ __module__ __qualname____doc__rrr!r(r4r7rErJrLrrrrr s  *r c@s,eZdZddZddZddZddZd S) r%cCs0tjj|std|||_t|_d|_dS)Nz.Cannot remove entries from nonexistent file %s)rrisfilerfilerentries _saved_lines)rr&rrrrs   zUninstallPthEntries.__init__cCs>tjj|}tr.tjj|d r.|jdd}|jj|dS)Nr\/)rrrrr5replacerSr!)rr'rrrr!s  zUninstallPthEntries.addcCstjd|jt|jd}|j}||_WdQRXtdd|DrLd}nd}xH|jD]>}y$tjd||j||j dWqXt k rYqXXqXWt|jd }|j |WdQRXdS) NzRemoving pth entries from %s:rbcss|]}d|kVqdS)s Nr)r.linerrr sz-UninstallPthEntries.remove..z  zRemoving entry: %szutf-8wb) r<rBrRopen readlinesrTr2rSrEencode ValueError writelines)rfhlinesendliner'rrrrEs   zUninstallPthEntries.removec CsR|jdkrtjd|jdStjd|jt|jd}|j|jWdQRXdS)Nz.Cannot roll back changes to %s, none were madeFz!Rolling %s back to previous stater\T)rTr<rIrRrBr]ra)rrbrrrrJs  zUninstallPthEntries.rollbackN)rMrNrOrr!rErJrrrrr%s  r%) __future__rloggingrr@ pip.compatrrrpip.exceptionsr pip.utilsrrr r r pip.utils.loggingr getLoggerrMr<objectr r%rrrrs