Skip to content

Commit

Permalink
Merge pull request #7335 from sbidoul/subdirectory-cache-key-sbi
Browse files Browse the repository at this point in the history
Include subdirectory URL fragments in cache keys
  • Loading branch information
xavfernandez committed Nov 15, 2019
2 parents ccd2ced + 47ae034 commit 9e1b1c7
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
1 change: 1 addition & 0 deletions news/7333.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Include ``subdirectory`` URL fragments in cache keys.
25 changes: 20 additions & 5 deletions src/pip/_internal/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ def _get_cache_path_parts(self, link):
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]))
if link.subdirectory_fragment:
key_parts.append(
"=".join(["subdirectory", link.subdirectory_fragment])
)
key_url = "#".join(key_parts)

# Encode our key url with sha224, we'll use this because it has similar
Expand All @@ -73,19 +77,18 @@ def _get_cache_path_parts(self, link):

return parts

def _get_candidates(self, link, package_name):
def _get_candidates(self, link, canonical_package_name):
# type: (Link, Optional[str]) -> List[Any]
can_not_cache = (
not self.cache_dir or
not package_name or
not canonical_package_name or
not link
)
if can_not_cache:
return []

canonical_name = canonicalize_name(package_name)
formats = self.format_control.get_allowed_formats(
canonical_name
canonical_package_name
)
if not self.allowed_formats.intersection(formats):
return []
Expand Down Expand Up @@ -168,11 +171,23 @@ def get(
# type: (...) -> Link
candidates = []

for wheel_name in self._get_candidates(link, package_name):
if not package_name:
return link

canonical_package_name = canonicalize_name(package_name)
for wheel_name in self._get_candidates(link, canonical_package_name):
try:
wheel = Wheel(wheel_name)
except InvalidWheelFilename:
continue
if canonicalize_name(wheel.name) != canonical_package_name:
logger.debug(
"Ignoring cached wheel {} for {} as it "
"does not match the expected distribution name {}.".format(
wheel_name, link, package_name
)
)
continue
if not wheel.supported(supported_tags):
# Built for a different python/arch/etc
continue
Expand Down
45 changes: 38 additions & 7 deletions tests/unit/test_cache.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
import os

from pip._internal.cache import WheelCache
from pip._internal.models.format_control import FormatControl
from pip._internal.models.link import Link
from pip._internal.utils.compat import expanduser
from pip._internal.utils.misc import ensure_dir


def test_expands_path():
wc = WheelCache("~/.foo/", None)
assert wc.cache_dir == expanduser("~/.foo/")


def test_falsey_path_none():
wc = WheelCache(False, None)
assert wc.cache_dir is None


class TestWheelCache:
def test_subdirectory_fragment():
"""
Test the subdirectory URL fragment is part of the cache key.
"""
wc = WheelCache("~/.foo/", None)
link1 = Link("git+https://g.c/o/r#subdirectory=d1")
link2 = Link("git+https://g.c/o/r#subdirectory=d2")
assert wc.get_path_for_link(link1) != wc.get_path_for_link(link2)

def test_expands_path(self):
wc = WheelCache("~/.foo/", None)
assert wc.cache_dir == expanduser("~/.foo/")

def test_falsey_path_none(self):
wc = WheelCache(False, None)
assert wc.cache_dir is None
def test_wheel_name_filter(tmpdir):
"""
Test the wheel cache filters on wheel name when several wheels
for different package are stored under the same cache directory.
"""
wc = WheelCache(tmpdir, FormatControl())
link = Link("https://g.c/package.tar.gz")
cache_path = wc.get_path_for_link(link)
ensure_dir(cache_path)
with open(os.path.join(cache_path, "package-1.0-py3-none-any.whl"), "w"):
pass
# package matches wheel name
assert wc.get(link, "package", [("py3", "none", "any")]) is not link
# package2 does not match wheel name
assert wc.get(link, "package2", [("py3", "none", "any")]) is link

0 comments on commit 9e1b1c7

Please sign in to comment.