Skip to content

Commit 58882a1

Browse files
DefaultRyansbidoul
authored andcommitted
Move normalize_path caching to an instance on UninstallPathSet
1 parent 1bb8496 commit 58882a1

File tree

2 files changed

+11
-20
lines changed

2 files changed

+11
-20
lines changed

src/pip/_internal/req/req_uninstall.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pip._internal.utils.logging import getLogger, indent_log
1414
from pip._internal.utils.misc import ask, is_local, normalize_path, normalize_path_cached, renames, rmtree
1515
from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory
16+
from pip._internal.utils.virtualenv import running_under_virtualenv
1617

1718
logger = getLogger(__name__)
1819

@@ -312,22 +313,25 @@ def __init__(self, dist: BaseDistribution) -> None:
312313
self._pth: Dict[str, UninstallPthEntries] = {}
313314
self._dist = dist
314315
self._moved_paths = StashedUninstallPathSet()
315-
normalize_path_cached.cache_clear()
316+
self._normalize_path_cached = functools.lru_cache(maxsize=256)(normalize_path)
316317

317318
def _permitted(self, path: str) -> bool:
318319
"""
319320
Return True if the given path is one we are permitted to
320321
remove/modify, False otherwise.
321322
322323
"""
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))
324328

325329
def add(self, path: str) -> None:
326330
head, tail = os.path.split(path)
327331

328332
# we normalize the head to resolve parent directory symlinks, but not
329333
# 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))
331335

332336
if not os.path.exists(path):
333337
return
@@ -342,7 +346,7 @@ def add(self, path: str) -> None:
342346
self.add(cache_from_source(path))
343347

344348
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)
346350
if self._permitted(pth_file):
347351
if pth_file not in self._pth:
348352
self._pth[pth_file] = UninstallPthEntries(pth_file)
@@ -435,7 +439,7 @@ def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet":
435439
)
436440
return cls(dist)
437441

438-
normalized_dist_location = normalize_path_cached(dist_location)
442+
normalized_dist_location = normalize_path(dist_location)
439443
if not dist.local:
440444
logger.info(
441445
"Not uninstalling %s at %s, outside environment %s",
@@ -532,7 +536,7 @@ def from_dist(cls, dist: BaseDistribution) -> "UninstallPathSet":
532536
# above, so this only covers the setuptools-style editable.
533537
with open(develop_egg_link) as fh:
534538
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)
536540
assert os.path.samefile(
537541
normalized_link_pointer, normalized_dist_location
538542
), (

src/pip/_internal/utils/misc.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
import contextlib
55
import errno
6-
import functools
76
import getpass
87
import hashlib
98
import io
@@ -295,17 +294,6 @@ def normalize_path(path: str, resolve_symlinks: bool = True) -> str:
295294
return os.path.normcase(path)
296295

297296

298-
@functools.lru_cache(maxsize=128)
299-
def normalize_path_cached(path: str, resolve_symlinks: bool = True) -> str:
300-
"""
301-
Cache the results of normalize_path when called frequently during certain
302-
operations. Separate function because it is probably unsafe to
303-
cache normalize_path in the general case, e.g. symlinks can be changed
304-
while the process is running.
305-
"""
306-
return normalize_path(path, resolve_symlinks)
307-
308-
309297
def splitext(path: str) -> Tuple[str, str]:
310298
"""Like os.path.splitext, but take off .tar too"""
311299
base, ext = posixpath.splitext(path)
@@ -343,8 +331,7 @@ def is_local(path: str) -> bool:
343331
"""
344332
if not running_under_virtualenv():
345333
return True
346-
# Safe to call cached because sys.prefix shouldn't change
347-
return path.startswith(normalize_path_cached(sys.prefix))
334+
return path.startswith(normalize_path(sys.prefix))
348335

349336

350337
def write_output(msg: Any, *args: Any) -> None:

0 commit comments

Comments
 (0)