Skip to content

Commit

Permalink
Record origin url in wheel cache
Browse files Browse the repository at this point in the history
  • Loading branch information
sbidoul committed May 22, 2022
1 parent 79a7f88 commit 3342b3b
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/pip/_internal/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import json
import logging
import os
from pathlib import Path
from typing import Any, Dict, List, Optional, Set

from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version
from pip._vendor.packaging.utils import canonicalize_name

from pip._internal.exceptions import InvalidWheelFilename
from pip._internal.models.direct_url import DirectUrl
from pip._internal.models.format_control import FormatControl
from pip._internal.models.link import Link
from pip._internal.models.wheel import Wheel
Expand All @@ -19,6 +21,8 @@

logger = logging.getLogger(__name__)

ORIGIN_JSON_NAME = "origin.json"


def _hash_dict(d: Dict[str, str]) -> str:
"""Return a stable sha224 of a dictionary."""
Expand Down Expand Up @@ -204,6 +208,10 @@ def __init__(
):
self.link = link
self.persistent = persistent
self.origin: Optional[DirectUrl] = None
origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
if origin_direct_url_path.exists():
self.origin = DirectUrl.from_json(origin_direct_url_path.read_text())


class WheelCache(Cache):
Expand Down Expand Up @@ -262,3 +270,20 @@ def get_cache_entry(
return CacheEntry(retval, persistent=False)

return None

@staticmethod
def record_download_origin(cache_dir: str, download_info: DirectUrl) -> None:
origin_path = Path(cache_dir) / ORIGIN_JSON_NAME
if origin_path.is_file():
origin = DirectUrl.from_json(origin_path.read_text())
# TODO: use DirectUrl.equivalent when https://github.com/pypa/pip/pull/10564
# is merged.
if origin.url != download_info.url:
logger.warning(
"Origin URL %s in cache entry %s does not match download URL %s. "
"This is likely a pip bug or a cache corruption issue.",
origin.url,
cache_dir,
download_info.url,
)
origin_path.write_text(download_info.to_json())
2 changes: 2 additions & 0 deletions src/pip/_internal/resolution/legacy/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ def _populate_link(self, req: InstallRequirement) -> None:
logger.debug("Using cached wheel link: %s", cache_entry.link)
if req.link is req.original_link and cache_entry.persistent:
req.original_link_is_in_wheel_cache = True
if cache_entry.origin is not None:
req.download_info = cache_entry.origin
req.link = cache_entry.link

def _get_dist_for(self, req: InstallRequirement) -> BaseDistribution:
Expand Down
2 changes: 2 additions & 0 deletions src/pip/_internal/resolution/resolvelib/candidates.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ def __init__(
and template.link is template.original_link
):
ireq.original_link_is_in_wheel_cache = True
if cache_entry.origin is not None:
ireq.download_info = cache_entry.origin

super().__init__(
link=link,
Expand Down
6 changes: 6 additions & 0 deletions src/pip/_internal/wheel_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ def build(
req.editable and req.permit_editable_wheels,
)
if wheel_file:
# Record the download origin in the cache
if req.download_info is not None:
# download_info is guaranteed to be set because when we build an
# InstallRequirement it has been through the preparer before, but
# let's be cautious.
wheel_cache.record_download_origin(cache_dir, req.download_info)
# Update the link for this.
req.link = Link(path_to_url(wheel_file))
req.local_file_path = req.link.file_path
Expand Down

0 comments on commit 3342b3b

Please sign in to comment.