Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion kernels/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ license = { text = "Apache-2.0" }
readme = "README.md"
requires-python = ">= 3.10"
dependencies = [
"huggingface-hub>=1.10.0",
"huggingface-hub>=1.31.0",
"packaging>=20.0",
"pyyaml>=6",
"sigstore>=4,<5",
Expand Down
7 changes: 6 additions & 1 deletion kernels/src/kernels/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from pathlib import Path
from typing import Protocol, runtime_checkable

from huggingface_hub.errors import LocalEntryNotFoundError
from huggingface_hub.errors import IncompleteSnapshotError, LocalEntryNotFoundError
from huggingface_hub.hf_api import HfApi

from kernels._rust import KernelDependency, KernelLocks, KernelPaths, Metadata, Oid
Expand Down Expand Up @@ -207,6 +207,11 @@ def resolve_hub_cache_kernel(
)
)
)
except IncompleteSnapshotError as e:
# This exception is raised when the snapshot is incomplete. However,
# for us that's nearly always the case, since we ownly download the
# build variant required for the system. Variants are reported below.
repo_path = Path(e.snapshot_path)
except LocalEntryNotFoundError as e:
raise FileNotFoundError(
f"Cannot find a local snapshot for {repo_id} (revision: {revision}). "
Expand Down
29 changes: 29 additions & 0 deletions kernels/tests/test_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pathlib import Path

import pytest
from huggingface_hub.errors import IncompleteSnapshotError
from huggingface_hub.hf_api import GitRefInfo

import kernels.resolver as resolver_module
Expand Down Expand Up @@ -33,6 +34,7 @@
Resolver,
SequentialResolver,
_locked_revision,
resolve_hub_cache_kernel,
resolve_hub_kernel,
)
from kernels.variants import parse_variant
Expand Down Expand Up @@ -419,6 +421,33 @@ def test_hub_cache_resolver_uncached_repo(api):
)


class _IncompleteSnapshotApi:
"""API stub whose offline `snapshot_download` reports an incomplete snapshot."""

def __init__(self, snapshot_path: Path):
self.snapshot_path = snapshot_path

def snapshot_download(self, *args, **kwargs):
raise IncompleteSnapshotError("incomplete snapshot", snapshot_path=str(self.snapshot_path))


def test_resolve_hub_cache_kernel_uses_incomplete_snapshot(tmp_path):
# huggingface-hub now raises `IncompleteSnapshotError` when the cached
# snapshot was incomplete. However, this is nearly always the case for
# us, because we only download the variant that we need. Check that
# the resolver accepts the incomplete snapshot and fails on the missing
# variant.
(tmp_path / "build").mkdir()

with pytest.raises(FileNotFoundError, match="Cannot find a build variant"):
resolve_hub_cache_kernel(
_IncompleteSnapshotApi(tmp_path), # type: ignore[arg-type]
"test/kernel",
revision=Oid.from_str("0" * 40),
backend="cpu",
)


def test_locked_hub_resolver_resolves_locked_revision(api, relu_locks):
dep, locks, commit = relu_locks

Expand Down
Loading
Loading