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
10 changes: 7 additions & 3 deletions src/fromager/bootstrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,13 +1100,17 @@ def _download_wheel_from_cache(
f"checking if wheel was already uploaded to {self.cache_wheel_server_url}"
)
try:
wheel_url, _ = resolver.resolve(
ctx=self.ctx,
req=Requirement(f"{req.name}=={resolved_version}"),
# Use PyPIProvider directly for cache lookups, bypassing resolver
# hooks. Cache servers are always simple PyPI index servers.
pinned_req = Requirement(f"{req.name}=={resolved_version}")
provider = resolver.PyPIProvider(
sdist_server_url=self.cache_wheel_server_url,
include_sdists=False,
include_wheels=True,
constraints=self.ctx.constraints,
)
results = resolver.find_all_matching_from_provider(provider, pinned_req)
wheel_url, _ = results[0]
wheelfile_name = pathlib.Path(urlparse(wheel_url).path)
pbi = self.ctx.package_build_info(req)
expected_build_tag = pbi.build_tag(resolved_version)
Expand Down
38 changes: 38 additions & 0 deletions tests/test_bootstrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,41 @@ def mock_bootstrap_impl(
success_key_10 = f"{canonicalize_name('testpkg')}==1.0"
assert success_key_20 in tmp_context.dependency_graph.nodes
assert success_key_10 in tmp_context.dependency_graph.nodes


@patch("fromager.resolver.find_all_matching_from_provider")
@patch("fromager.resolver.PyPIProvider")
def test_download_wheel_from_cache_bypasses_hooks(
mock_pypi_provider: Mock,
mock_find_all: Mock,
tmp_context: WorkContext,
) -> None:
"""Verify _download_wheel_from_cache uses PyPIProvider directly, not hooks."""
bt = bootstrapper.Bootstrapper(tmp_context)
bt.cache_wheel_server_url = "https://cache.example.com/simple/"

mock_provider = Mock()
mock_pypi_provider.return_value = mock_provider
# Raise so the except clause returns (None, None) before hitting
# network calls later in the function.
mock_find_all.side_effect = RuntimeError("no match")

with patch("fromager.overrides.find_and_invoke") as mock_override:
result = bt._download_wheel_from_cache(
req=Requirement("test-pkg"),
resolved_version=Version("1.0.0"),
)

assert result == (None, None)

# Hook system must NOT be called for cache lookups
mock_override.assert_not_called()

# PyPIProvider must be instantiated directly
mock_pypi_provider.assert_called_once_with(
sdist_server_url="https://cache.example.com/simple/",
include_sdists=False,
include_wheels=True,
constraints=tmp_context.constraints,
)
mock_find_all.assert_called_once_with(mock_provider, Requirement("test-pkg==1.0.0"))
Loading