Skip to content

Commit 3086fb0

Browse files
committed
Pin named indexes
1 parent 110fec4 commit 3086fb0

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

crates/uv-workspace/src/pyproject.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@ impl Source {
701701
source: RequirementSource,
702702
workspace: bool,
703703
editable: Option<bool>,
704+
index: Option<String>,
704705
rev: Option<String>,
705706
tag: Option<String>,
706707
branch: Option<String>,
@@ -741,7 +742,19 @@ impl Source {
741742
}
742743

743744
let source = match source {
744-
RequirementSource::Registry { .. } => return Ok(None),
745+
RequirementSource::Registry { index: Some(_), .. } => {
746+
return Ok(None);
747+
}
748+
RequirementSource::Registry { index: None, .. } => {
749+
if let Some(index) = index {
750+
Source::Registry {
751+
index,
752+
marker: MarkerTree::TRUE,
753+
}
754+
} else {
755+
return Ok(None);
756+
}
757+
}
745758
RequirementSource::Path { install_path, .. }
746759
| RequirementSource::Directory { install_path, .. } => Source::Path {
747760
editable,

crates/uv/src/commands/project/add.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,13 @@ pub(crate) async fn add(
381381
}
382382
}
383383

384+
// If the user provides a single, named index, pin all requirements to that index.
385+
let index = indexes
386+
.first()
387+
.as_ref()
388+
.and_then(|index| index.name.as_ref())
389+
.filter(|_| indexes.len() == 1);
390+
384391
// Add the requirements to the `pyproject.toml` or script.
385392
let mut toml = match &target {
386393
Target::Script(script, _) => {
@@ -426,6 +433,7 @@ pub(crate) async fn add(
426433
requirement,
427434
false,
428435
editable,
436+
index.cloned(),
429437
rev.clone(),
430438
tag.clone(),
431439
branch.clone(),
@@ -441,6 +449,7 @@ pub(crate) async fn add(
441449
requirement,
442450
workspace,
443451
editable,
452+
index.cloned(),
444453
rev.clone(),
445454
tag.clone(),
446455
branch.clone(),
@@ -709,7 +718,11 @@ async fn lock_and_sync(
709718
};
710719

711720
// Only set a minimum version for registry requirements.
712-
if edit.source.is_some() {
721+
if edit
722+
.source
723+
.as_ref()
724+
.is_some_and(|source| !matches!(source, Source::Registry { .. }))
725+
{
713726
continue;
714727
}
715728

@@ -900,6 +913,7 @@ fn resolve_requirement(
900913
requirement: pypi_types::Requirement,
901914
workspace: bool,
902915
editable: Option<bool>,
916+
index: Option<String>,
903917
rev: Option<String>,
904918
tag: Option<String>,
905919
branch: Option<String>,
@@ -910,6 +924,7 @@ fn resolve_requirement(
910924
requirement.source.clone(),
911925
workspace,
912926
editable,
927+
index,
913928
rev,
914929
tag,
915930
branch,

crates/uv/tests/edit.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5064,7 +5064,7 @@ fn add_no_warn_index_url() -> Result<()> {
50645064

50655065
/// Add an index provided via `--index`.
50665066
#[test]
5067-
fn add_index_url() -> Result<()> {
5067+
fn add_index() -> Result<()> {
50685068
let context = TestContext::new("3.12");
50695069

50705070
let pyproject_toml = context.temp_dir.child("pyproject.toml");
@@ -5149,6 +5149,7 @@ fn add_index_url() -> Result<()> {
51495149
----- stdout -----
51505150
51515151
----- stderr -----
5152+
warning: Missing version constraint (e.g., a lower bound) for `jinja2`
51525153
Resolved 4 packages in [TIME]
51535154
Prepared 2 packages in [TIME]
51545155
Installed 2 packages in [TIME]
@@ -5178,6 +5179,9 @@ fn add_index_url() -> Result<()> {
51785179
51795180
[[tool.uv.index]]
51805181
url = "https://pypi.org/simple"
5182+
5183+
[tool.uv.sources]
5184+
jinja2 = { index = "pytorch" }
51815185
"###
51825186
);
51835187
});
@@ -5237,7 +5241,7 @@ fn add_index_url() -> Result<()> {
52375241
[package.metadata]
52385242
requires-dist = [
52395243
{ name = "iniconfig", specifier = "==2.0.0" },
5240-
{ name = "jinja2", specifier = ">=3.1.3" },
5244+
{ name = "jinja2", specifier = ">=3.1.3", index = "https://download.pytorch.org/whl/cu121" },
52415245
]
52425246
"###
52435247
);
@@ -5276,6 +5280,9 @@ fn add_index_url() -> Result<()> {
52765280
52775281
[[tool.uv.index]]
52785282
url = "https://pypi.org/simple"
5283+
5284+
[tool.uv.sources]
5285+
jinja2 = { index = "pytorch" }
52795286
"###
52805287
);
52815288
});
@@ -5341,7 +5348,7 @@ fn add_index_url() -> Result<()> {
53415348
[package.metadata]
53425349
requires-dist = [
53435350
{ name = "iniconfig", specifier = "==2.0.0" },
5344-
{ name = "jinja2", specifier = ">=3.1.3" },
5351+
{ name = "jinja2", specifier = ">=3.1.3", index = "https://test.pypi.org/simple" },
53455352
]
53465353
"###
53475354
);

0 commit comments

Comments
 (0)