diff --git a/pip/cache.py b/pip/cache.py index 87fd0e1b595..8da8f3b4152 100644 --- a/pip/cache.py +++ b/pip/cache.py @@ -2,6 +2,7 @@ """ import errno +import hashlib import logging import os @@ -10,7 +11,6 @@ import pip.index from pip.compat import expanduser from pip.download import path_to_url -from pip.utils.cache import get_cache_path_for_link from pip.wheel import InvalidWheelFilename, Wheel logger = logging.getLogger(__name__) @@ -29,6 +29,46 @@ def __init__(self, cache_dir, format_control): self._cache_dir = expanduser(cache_dir) if cache_dir else None self._format_control = format_control + def get_cache_path_for_link(self, link): + """ + Return a directory to store cached wheels in for link. + + Because there are M wheels for any one sdist, we provide a directory + to cache them in, and then consult that directory when looking up + cache hits. + + We only insert things into the cache if they have plausible version + numbers, so that we don't contaminate the cache with things that were + not unique. E.g. ./package might have dozens of installs done for it + and build a version of 0.0...and if we built and cached a wheel, we'd + end up using the same wheel even if the source has been edited. + + :param link: The link of the sdist for which this will cache wheels. + """ + + # We want to generate an url to use as our cache key, we don't want to + # just re-use the URL because it might have other items in the fragment + # and we don't care about those. + key_parts = [link.url_without_fragment] + if link.hash_name is not None and link.hash is not None: + key_parts.append("=".join([link.hash_name, link.hash])) + key_url = "#".join(key_parts) + + # Encode our key url with sha224, we'll use this because it has similar + # security properties to sha256, but with a shorter total output (and + # thus less secure). However the differences don't make a lot of + # difference for our use case here. + hashed = hashlib.sha224(key_url.encode()).hexdigest() + + # We want to nest the directories some to prevent having a ton of top + # level directories where we might run out of sub directories on some + # FS. + parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] + + # Inside of the base location for cached wheels, expand our parts and + # join them all together. + return os.path.join(self._cache_dir, "wheels", *parts) + def cached_wheel(self, link, package_name): not_cached = ( not self._cache_dir or @@ -47,7 +87,7 @@ def cached_wheel(self, link, package_name): ) if "binary" not in formats: return link - root = get_cache_path_for_link(self._cache_dir, link) + root = self.get_cache_path_for_link(link) try: wheel_names = os.listdir(root) except OSError as err: diff --git a/pip/utils/cache.py b/pip/utils/cache.py deleted file mode 100644 index 6e34088fcb8..00000000000 --- a/pip/utils/cache.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Helpers for caches -""" - -import hashlib -import os.path - - -def get_cache_path_for_link(cache_dir, link): - """ - Return a directory to store cached wheels in for link. - - Because there are M wheels for any one sdist, we provide a directory - to cache them in, and then consult that directory when looking up - cache hits. - - We only insert things into the cache if they have plausible version - numbers, so that we don't contaminate the cache with things that were not - unique. E.g. ./package might have dozens of installs done for it and build - a version of 0.0...and if we built and cached a wheel, we'd end up using - the same wheel even if the source has been edited. - - :param cache_dir: The cache_dir being used by pip. - :param link: The link of the sdist for which this will cache wheels. - """ - - # We want to generate an url to use as our cache key, we don't want to just - # re-use the URL because it might have other items in the fragment and we - # don't care about those. - key_parts = [link.url_without_fragment] - if link.hash_name is not None and link.hash is not None: - key_parts.append("=".join([link.hash_name, link.hash])) - key_url = "#".join(key_parts) - - # Encode our key url with sha224, we'll use this because it has similar - # security properties to sha256, but with a shorter total output (and thus - # less secure). However the differences don't make a lot of difference for - # our use case here. - hashed = hashlib.sha224(key_url.encode()).hexdigest() - - # We want to nest the directories some to prevent having a ton of top level - # directories where we might run out of sub directories on some FS. - parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] - - # Inside of the base location for cached wheels, expand our parts and join - # them all together. - return os.path.join(cache_dir, "wheels", *parts) diff --git a/pip/wheel.py b/pip/wheel.py index ca080e24381..339ab6de950 100644 --- a/pip/wheel.py +++ b/pip/wheel.py @@ -31,7 +31,6 @@ ) from pip.locations import PIP_DELETE_MARKER_FILENAME, distutils_scheme from pip.utils import call_subprocess, captured_stdout, ensure_dir, read_chunks -from pip.utils.cache import get_cache_path_for_link from pip.utils.logging import indent_log from pip.utils.setuptools_build import SETUPTOOLS_SHIM from pip.utils.temp_dir import TempDirectory @@ -779,9 +778,8 @@ def build(self, session, autobuilding=False): python_tag = None if autobuilding: python_tag = pep425tags.implementation_tag - # NOTE: Should move out a method on the cache directly. - output_dir = get_cache_path_for_link( - self.wheel_cache._cache_dir, req.link + output_dir = self.wheel_cache.get_cache_path_for_link( + req.link ) try: ensure_dir(output_dir)