Skip to content

Commit

Permalink
handle deprecation of link.hash_name and link.hash in favor of link.h…
Browse files Browse the repository at this point in the history
  • Loading branch information
radoering authored Feb 4, 2024
1 parent d00ad15 commit 7243b94
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 28 deletions.
42 changes: 24 additions & 18 deletions src/poetry/installation/chooser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from poetry.config.config import Config
from poetry.config.config import PackageFilterPolicy
from poetry.repositories.http_repository import HTTPRepository
from poetry.utils.helpers import get_highest_priority_hash_type
from poetry.utils.wheel import Wheel


Expand Down Expand Up @@ -88,38 +89,43 @@ def _get_links(self, package: Package) -> list[Link]:
repository = self._pool.repository("pypi")
links = repository.find_links_for_package(package)

hashes = {f["hash"] for f in package.files}
if not hashes:
locked_hashes = {f["hash"] for f in package.files}
if not locked_hashes:
return links

selected_links = []
skipped = []
locked_hash_names = {h.split(":")[0] for h in locked_hashes}
for link in links:
if not link.hash:
if not link.hashes:
selected_links.append(link)
continue

assert link.hash_name is not None
h = link.hash_name + ":" + link.hash
if (
h not in hashes
and link.hash_name not in ("sha256", "sha384", "sha512")
and isinstance(repository, HTTPRepository)
link_hash: str | None = None
if (candidates := locked_hash_names.intersection(link.hashes.keys())) and (
hash_name := get_highest_priority_hash_type(candidates, link.filename)
):
h = repository.calculate_sha256(link) or h
if h not in hashes:
link_hash = f"{hash_name}:{link.hashes[hash_name]}"

elif isinstance(repository, HTTPRepository):
link_hash = repository.calculate_sha256(link)

if link_hash not in locked_hashes:
skipped.append((link.filename, link_hash))
logger.debug(
"Skipping %s as %s checksum does not match expected value",
link.filename,
link.hash_name,
link_hash,
)
continue

selected_links.append(link)

if links and not selected_links:
links_str = ", ".join(f"{link}({h})" for link, h in skipped)
raise RuntimeError(
f"Retrieved digest for link {link.filename}({h}) not in poetry.lock"
f" metadata {hashes}"
f"Retrieved digests for links {links_str} not in poetry.lock"
f" metadata {locked_hashes}"
)

return selected_links
Expand Down Expand Up @@ -186,10 +192,10 @@ def _sort_key(
)

def _is_link_hash_allowed_for_package(self, link: Link, package: Package) -> bool:
if not link.hash:
if not link.hashes:
return True

assert link.hash_name is not None
h = link.hash_name + ":" + link.hash
link_hashes = {f"{name}:{h}" for name, h in link.hashes.items()}
locked_hashes = {f["hash"] for f in package.files}

return h in {f["hash"] for f in package.files}
return bool(link_hashes & locked_hashes)
30 changes: 22 additions & 8 deletions src/poetry/repositories/http_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from poetry.utils.constants import REQUESTS_TIMEOUT
from poetry.utils.helpers import HTTPRangeRequestSupported
from poetry.utils.helpers import download_file
from poetry.utils.helpers import get_highest_priority_hash_type
from poetry.utils.patterns import wheel_file_re


Expand Down Expand Up @@ -280,14 +281,20 @@ def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]
):
urls["sdist"].append(link.url)

file_hash = f"{link.hash_name}:{link.hash}" if link.hash else None
file_hash: str | None
for hash_name in ("sha512", "sha384", "sha256"):
if hash_name in link.hashes:
file_hash = f"{hash_name}:{link.hashes[hash_name]}"
break
else:
file_hash = self.calculate_sha256(link)

if not link.hash or (
link.hash_name is not None
and link.hash_name not in ("sha256", "sha384", "sha512")
and hasattr(hashlib, link.hash_name)
if file_hash is None and (
hash_type := get_highest_priority_hash_type(
set(link.hashes.keys()), link.filename
)
):
file_hash = self.calculate_sha256(link) or file_hash
file_hash = f"{hash_type}:{link.hashes[hash_type]}"

files.append({"file": link.filename, "hash": file_hash})

Expand All @@ -303,7 +310,10 @@ def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]

def calculate_sha256(self, link: Link) -> str | None:
with self._cached_or_downloaded_file(link) as filepath:
known_hash = getattr(hashlib, link.hash_name)() if link.hash_name else None
hash_name = get_highest_priority_hash_type(
set(link.hashes.keys()), link.filename
)
known_hash = getattr(hashlib, hash_name)() if hash_name else None
required_hash = hashlib.sha256()

chunksize = 4096
Expand All @@ -316,7 +326,11 @@ def calculate_sha256(self, link: Link) -> str | None:
known_hash.update(chunk)
required_hash.update(chunk)

if not known_hash or known_hash.hexdigest() == link.hash:
if (
not hash_name
or not known_hash
or known_hash.hexdigest() == link.hashes[hash_name]
):
return f"{required_hash.name}:{required_hash.hexdigest()}"
return None

Expand Down
7 changes: 5 additions & 2 deletions src/poetry/utils/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

from poetry.utils._compat import decode
from poetry.utils._compat import encode
from poetry.utils.helpers import get_highest_priority_hash_type
from poetry.utils.wheel import InvalidWheelName
from poetry.utils.wheel import Wheel

Expand Down Expand Up @@ -197,8 +198,10 @@ def __init__(self, *, cache_dir: Path) -> None:
def get_cache_directory_for_link(self, link: Link) -> Path:
key_parts = {"url": link.url_without_fragment}

if link.hash_name is not None and link.hash is not None:
key_parts[link.hash_name] = link.hash
if hash_name := get_highest_priority_hash_type(
set(link.hashes.keys()), link.filename
):
key_parts[hash_name] = link.hashes[hash_name]

if link.subdirectory_fragment:
key_parts["subdirectory"] = link.subdirectory_fragment
Expand Down

0 comments on commit 7243b94

Please sign in to comment.