Y@sddlmZddlZddlZddlZddlmZmZmZddl m Z ddl m Z m Z mZmZmZddlmZejeZGdddeZGd d d eZdS) )absolute_importN) uses_pycacheWINDOWScache_from_source)UninstallationError)rmtreeaskis_localrenamesnormalize_path) indent_logc@seZdZdZddZddZddZdd 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-3puug3g5/pip/pip/req/req_uninstall.py__init__s      zUninstallPathSet.__init__cCs t|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|sUdS|j|rw|jj |n|j j |tjj |ddkrt r|j t |dS)Nz.py)osrsplitjoinr normcaseexistsrraddrsplitextrr)rrheadtailrrrr!#s'"zUninstallPathSet.addcCsht|}|j|rT||jkr=t||j|<|j|j|n|jj|dS)N)r rrUninstallPthEntriesr!r)rpth_fileentryrrradd_pth6s  zUninstallPathSet.add_pthcsVt}xFt|dtD]2tfdd|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.keycsJg|]@}j|oCt|jtjjtjjkqSr) startswithlenrstriprrsep).0 shortpath)rrr Gs z,UninstallPathSet.compact..)rsortedr+anyr!)rr short_pathsr)rrcompact?s  zUninstallPathSet.compactcCs5tjj|jtjj|djtjjS)Nr)rrrr splitdrivelstripr-)rrrrr_stashMs zUninstallPathSet._stashFc Cs|js#tjd|jjdStjd|jj|jjtPt|j|j}|rsd}n-x|D]}tj|qzWt dd}|j rtjdx'|j|j D]}tj|qW|dkrt j dd d d |_ xJ|D]B}|j|}tjd ||jj|t||qWx!|jjD]}|jqdWtjd |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):suffixz -uninstallprefixzpip-zRemoving file or directory %szSuccessfully uninstalled %s-%s)r8r9)rloggerinfor project_nameversionr r1r4rrtempfilemkdtemprr7debugrappendr rvaluesremove)r auto_confirmrresponsernew_pathrrrrrEQs@          zUninstallPathSet.removecCs|jdkr)tjd|jjdStjd|jjx=|jD]2}|j|}tjd|t ||qIWx!|j j D]}|j qWdS)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.rollbackcCs2|jdk r.t|jd|_g|_dS)z?Remove temporary save dir: rollback will no longer be possible.N)rrr)rrrrcommits  zUninstallPathSet.commitN) __name__ __module__ __qualname____doc__rrr!r(r4r7rErJrLrrrrr s      * r c@s@eZdZddZddZddZddZd S) r%cCsDtjj|s"td|||_t|_d|_dS)Nz.Cannot remove entries from nonexistent file %s)rrisfilerfilerentries _saved_lines)rr&rrrrs    zUninstallPthEntries.__init__cCsUtjj|}trAtjj|d rA|jdd}|jj|dS)Nr\/)rrrrr5replacerSr!)rr'rrrr!szUninstallPthEntries.addcCstjd|jt|jd}|j}||_WdQRXtdd|Drfd}nd}xT|jD]I}y.tjd||j||j dWqvt k rYqvXqvWt|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 Csi|jdkr&tjd|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   (