Ignore --find-links entries for pinned indexes (#12396)

## Summary

In general, we merge `--find-links` entries into each index. If a
package is pinned to an index, though, it seems surprising (and wrong)
that we'd ever select a distribution from `--find-links`. This PR
modifies the provider to ignore `--find-links` for any explicitly pinned
packages.
This commit is contained in:
Charlie Marsh 2025-03-23 05:46:36 -07:00 committed by GitHub
parent 869457890a
commit 2250ddedbf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 139 additions and 5 deletions

View file

@ -160,6 +160,9 @@ impl<Context: BuildContext> ResolverProvider for DefaultResolverProvider<'_, Con
})
.await;
// If a package is pinned to an explicit index, ignore any `--find-links` entries.
let flat_index = index.is_none().then_some(&self.flat_index);
match result {
Ok(results) => Ok(VersionsResponse::Found(
results
@ -174,7 +177,9 @@ impl<Context: BuildContext> ResolverProvider for DefaultResolverProvider<'_, Con
&self.allowed_yanks,
&self.hasher,
self.exclude_newer.as_ref(),
self.flat_index.get(package_name).cloned(),
flat_index
.and_then(|flat_index| flat_index.get(package_name))
.cloned(),
self.build_options,
)
})
@ -182,23 +187,32 @@ impl<Context: BuildContext> ResolverProvider for DefaultResolverProvider<'_, Con
)),
Err(err) => match err.into_kind() {
uv_client::ErrorKind::PackageNotFound(_) => {
if let Some(flat_index) = self.flat_index.get(package_name).cloned() {
if let Some(flat_index) = flat_index
.and_then(|flat_index| flat_index.get(package_name))
.cloned()
{
Ok(VersionsResponse::Found(vec![VersionMap::from(flat_index)]))
} else {
Ok(VersionsResponse::NotFound)
}
}
uv_client::ErrorKind::NoIndex(_) => {
if let Some(flat_index) = self.flat_index.get(package_name).cloned() {
if let Some(flat_index) = flat_index
.and_then(|flat_index| flat_index.get(package_name))
.cloned()
{
Ok(VersionsResponse::Found(vec![VersionMap::from(flat_index)]))
} else if self.flat_index.offline() {
} else if flat_index.is_some_and(FlatIndex::offline) {
Ok(VersionsResponse::Offline)
} else {
Ok(VersionsResponse::NoIndex)
}
}
uv_client::ErrorKind::Offline(_) => {
if let Some(flat_index) = self.flat_index.get(package_name).cloned() {
if let Some(flat_index) = flat_index
.and_then(|flat_index| flat_index.get(package_name))
.cloned()
{
Ok(VersionsResponse::Found(vec![VersionMap::from(flat_index)]))
} else {
Ok(VersionsResponse::Offline)

View file

@ -9549,6 +9549,126 @@ fn lock_find_links_local_wheel() -> Result<()> {
Ok(())
}
/// Prefer an explicit index over any `--find-links` entries.
#[test]
fn lock_find_links_explicit_index() -> Result<()> {
let context = TestContext::new("3.12");
// Populate the `--find-links` entries.
fs_err::create_dir_all(context.temp_dir.join("links"))?;
for entry in fs_err::read_dir(context.workspace_root.join("scripts/links"))? {
let entry = entry?;
let path = entry.path();
if path
.file_name()
.and_then(|file_name| file_name.to_str())
.is_some_and(|file_name| file_name.starts_with("tqdm-"))
{
let dest = context
.temp_dir
.join("links")
.join(path.file_name().unwrap());
fs_err::copy(&path, &dest)?;
}
}
let workspace = context.temp_dir.child("workspace");
let pyproject_toml = workspace.child("pyproject.toml");
pyproject_toml.write_str(&formatdoc! { r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["tqdm"]
[[tool.uv.index]]
name = "pypi"
url = "https://pypi.org/simple"
[tool.uv.sources]
tqdm = {{ index = "pypi" }}
[tool.uv]
find-links = ["{}"]
"#,
context.temp_dir.join("links/").portable_display(),
})?;
uv_snapshot!(context.filters(), context.lock().current_dir(&workspace), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using CPython 3.12.[X] interpreter at: [PYTHON-3.12]
Resolved 3 packages in [TIME]
");
let lock = fs_err::read_to_string(workspace.join("uv.lock")).unwrap();
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
lock, @r#"
version = 1
revision = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
]
[[package]]
name = "project"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "tqdm" },
]
[package.metadata]
requires-dist = [{ name = "tqdm", index = "https://pypi.org/simple" }]
[[package]]
name = "tqdm"
version = "4.66.2"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/ea/85/3ce0f9f7d3f596e7ea57f4e5ce8c18cb44e4a9daa58ddb46ee0d13d6bff8/tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531", size = 169462 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2a/14/e75e52d521442e2fcc9f1df3c5e456aead034203d4797867980de558ab34/tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", size = 78296 },
]
"#
);
});
// Re-run with `--locked`.
uv_snapshot!(context.filters(), context.lock().arg("--locked").current_dir(&workspace), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using CPython 3.12.[X] interpreter at: [PYTHON-3.12]
Resolved 3 packages in [TIME]
");
Ok(())
}
/// Lock a local source distribution via `--find-links`.
#[test]
fn lock_find_links_local_sdist() -> Result<()> {