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
7 changes: 6 additions & 1 deletion crates/uv-resolver/src/lock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1969,7 +1969,12 @@ impl Lock {
// not be available as top-level configuration (i.e., if they're defined within a
// workspace member), but we already validated that the dependencies are up-to-date, so
// we can consider them "available".
for requirement in &package.metadata.requires_dist {
for requirement in package
.metadata
.requires_dist
.iter()
.chain(package.metadata.dependency_groups.values().flatten())
{
if let RequirementSource::Registry {
index: Some(index), ..
} = &requirement.source
Expand Down
97 changes: 97 additions & 0 deletions crates/uv/tests/it/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32281,3 +32281,100 @@ fn lock_unsupported_wheel_url_required_platform() -> Result<()> {

Ok(())
}

/// If an index is filtered out (e.g., it's the second `default = true` index defined in the file),
/// we should still consider the lockfile valid if it's referenced by name, regardless of whether
/// it's defined in a dependency group or the top-level `project.dependencies` field.
///
/// See: <https://github.com/astral-sh/uv/issues/16843>
#[test]
fn lock_check_multiple_default_indexes_explicit_assignment_dependency_group() -> Result<()> {
let context = TestContext::new("3.12").with_exclude_newer("2025-01-30T00:00:00Z");

let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"

[dependency-groups]
dev = ["iniconfig"]

[tool.uv.sources]
iniconfig = { index = "second" }

[[tool.uv.index]]
name = "first"
url = "https://test.pypi.org/simple"
default = true

[[tool.uv.index]]
name = "second"
url = "https://public:[email protected]/basic-auth/simple"
default = true
"#,
)?;

uv_snapshot!(context.filters(), context.lock(), @r"
success: true
exit_code: 0
----- stdout -----

----- stderr -----
Resolved 2 packages in [TIME]
");

let lock = context.read("uv.lock");

insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
lock, @r#"
version = 1
revision = 3
requires-python = ">=3.12"

[options]
exclude-newer = "2025-01-30T00:00:00Z"

[[package]]
name = "iniconfig"
version = "2.0.0"
source = { registry = "https://pypi-proxy.fly.dev/basic-auth/simple" }
sdist = { url = "https://pypi-proxy.fly.dev/basic-auth/files/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" }
wheels = [
{ url = "https://pypi-proxy.fly.dev/basic-auth/files/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" },
]

[[package]]
name = "project"
version = "0.1.0"
source = { virtual = "." }

[package.dev-dependencies]
dev = [
{ name = "iniconfig" },
]

[package.metadata]

[package.metadata.requires-dev]
dev = [{ name = "iniconfig", index = "https://pypi-proxy.fly.dev/basic-auth/simple" }]
"#
);
});

uv_snapshot!(context.filters(), context.lock().arg("--check"), @r"
success: true
exit_code: 0
----- stdout -----

----- stderr -----
Resolved 2 packages in [TIME]
");

Ok(())
}
Loading