13
13
from pip ._internal .utils .logging import getLogger , indent_log
14
14
from pip ._internal .utils .misc import ask , is_local , normalize_path , normalize_path_cached , renames , rmtree
15
15
from pip ._internal .utils .temp_dir import AdjacentTempDirectory , TempDirectory
16
+ from pip ._internal .utils .virtualenv import running_under_virtualenv
16
17
17
18
logger = getLogger (__name__ )
18
19
@@ -312,22 +313,25 @@ def __init__(self, dist: BaseDistribution) -> None:
312
313
self ._pth : Dict [str , UninstallPthEntries ] = {}
313
314
self ._dist = dist
314
315
self ._moved_paths = StashedUninstallPathSet ()
315
- normalize_path_cached . cache_clear ( )
316
+ self . _normalize_path_cached = functools . lru_cache ( maxsize = 256 )( normalize_path )
316
317
317
318
def _permitted (self , path : str ) -> bool :
318
319
"""
319
320
Return True if the given path is one we are permitted to
320
321
remove/modify, False otherwise.
321
322
322
323
"""
323
- return is_local (path )
324
+ # aka is_local, but caching normalized sys.prefix
325
+ if not running_under_virtualenv ():
326
+ return True
327
+ return path .startswith (self ._normalize_path_cached (sys .prefix ))
324
328
325
329
def add (self , path : str ) -> None :
326
330
head , tail = os .path .split (path )
327
331
328
332
# we normalize the head to resolve parent directory symlinks, but not
329
333
# the tail, since we only want to uninstall symlinks, not their targets
330
- path = os .path .join (normalize_path_cached (head ), os .path .normcase (tail ))
334
+ path = os .path .join (self . _normalize_path_cached (head ), os .path .normcase (tail ))
331
335
332
336
if not os .path .exists (path ):
333
337
return
@@ -342,7 +346,7 @@ def add(self, path: str) -> None:
342
346
self .add (cache_from_source (path ))
343
347
344
348
def add_pth (self , pth_file : str , entry : str ) -> None :
345
- pth_file = normalize_path_cached (pth_file )
349
+ pth_file = self . _normalize_path_cached (pth_file )
346
350
if self ._permitted (pth_file ):
347
351
if pth_file not in self ._pth :
348
352
self ._pth [pth_file ] = UninstallPthEntries (pth_file )
@@ -435,7 +439,7 @@ def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet":
435
439
)
436
440
return cls (dist )
437
441
438
- normalized_dist_location = normalize_path_cached (dist_location )
442
+ normalized_dist_location = normalize_path (dist_location )
439
443
if not dist .local :
440
444
logger .info (
441
445
"Not uninstalling %s at %s, outside environment %s" ,
@@ -532,7 +536,7 @@ def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet":
532
536
# above, so this only covers the setuptools-style editable.
533
537
with open (develop_egg_link ) as fh :
534
538
link_pointer = os .path .normcase (fh .readline ().strip ())
535
- normalized_link_pointer = normalize_path_cached (link_pointer )
539
+ normalized_link_pointer = paths_to_remove . _normalize_path_cached (link_pointer )
536
540
assert os .path .samefile (
537
541
normalized_link_pointer , normalized_dist_location
538
542
), (
0 commit comments