diff --git a/crates/uv-distribution/src/metadata/lowering.rs b/crates/uv-distribution/src/metadata/lowering.rs index 0e7cb1a5bbb3f..51fffa0c908a0 100644 --- a/crates/uv-distribution/src/metadata/lowering.rs +++ b/crates/uv-distribution/src/metadata/lowering.rs @@ -185,9 +185,6 @@ impl LoweredRequirement { marker, .. } => { - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let source = git_source( &git, subdirectory.map(PathBuf::from), @@ -203,9 +200,6 @@ impl LoweredRequirement { marker, .. } => { - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let source = url_source(url, subdirectory.map(PathBuf::from))?; (source, marker) } @@ -215,9 +209,6 @@ impl LoweredRequirement { marker, .. } => { - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let source = path_source( PathBuf::from(path), git_member, @@ -276,9 +267,6 @@ impl LoweredRequirement { if !is_workspace { return Err(LoweringError::WorkspaceFalse); } - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let member = workspace .packages() .get(&requirement.name) @@ -433,9 +421,6 @@ impl LoweredRequirement { marker, .. } => { - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let source = git_source( &git, subdirectory.map(PathBuf::from), @@ -451,9 +436,6 @@ impl LoweredRequirement { marker, .. } => { - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let source = url_source(url, subdirectory.map(PathBuf::from))?; (source, marker) } @@ -463,9 +445,6 @@ impl LoweredRequirement { marker, .. } => { - if matches!(requirement.version_or_url, Some(VersionOrUrl::Url(_))) { - return Err(LoweringError::ConflictingUrls); - } let source = path_source( PathBuf::from(path), None, @@ -550,8 +529,6 @@ pub enum LoweringError { InvalidUrl(#[from] url::ParseError), #[error(transparent)] InvalidVerbatimUrl(#[from] uv_pep508::VerbatimUrlError), - #[error("Can't combine URLs from both `project.dependencies` and `tool.uv.sources`")] - ConflictingUrls, #[error("Fragments are not allowed in URLs: `{0}`")] ForbiddenFragment(Url), #[error("`workspace = false` is not yet supported")] @@ -678,7 +655,19 @@ fn registry_source( index: Some(index), conflict, }), - Some(VersionOrUrl::Url(_)) => Err(LoweringError::ConflictingUrls), + Some(VersionOrUrl::Url(_)) => { + if matches!(bounds, LowerBound::Warn) { + warn_user_once!( + "Missing version constraint (e.g., a lower bound) for `{}`", + requirement.name + ); + } + Ok(RequirementSource::Registry { + specifier: VersionSpecifiers::empty(), + index: Some(index), + conflict, + }) + } } } diff --git a/crates/uv-distribution/src/metadata/requires_dist.rs b/crates/uv-distribution/src/metadata/requires_dist.rs index 0c33dfd12e6b3..6a71201f61f8e 100644 --- a/crates/uv-distribution/src/metadata/requires_dist.rs +++ b/crates/uv-distribution/src/metadata/requires_dist.rs @@ -568,7 +568,7 @@ mod test { assert_snapshot!(format_err(input).await, @r###" error: Failed to parse entry: `tqdm` - Caused by: Can't combine URLs from both `project.dependencies` and `tool.uv.sources` + Caused by: `tqdm` references a workspace in `tool.uv.sources` (e.g., `tqdm = { workspace = true }`), but is not a workspace member "###); } diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 38c5e89007801..f0956f851ed4e 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -9738,7 +9738,7 @@ fn lock_transitive_extra() -> Result<()> { } /// If a source is provided via `tool.uv.sources` _and_ a URL is provided in `project.dependencies`, -/// we raise an error. +/// we accept the source in `tool.uv.sources`, unless `--no-sources` is provided. #[test] fn lock_mismatched_sources() -> Result<()> { let context = TestContext::new("3.12"); @@ -9760,16 +9760,88 @@ fn lock_mismatched_sources() -> Result<()> { )?; uv_snapshot!(context.filters(), context.lock(), @r###" - success: false - exit_code: 1 + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- - × Failed to build `project @ file://[TEMP_DIR]/` - ├─▶ Failed to parse entry: `uv-public-pypackage` - ╰─▶ Can't combine URLs from both `project.dependencies` and `tool.uv.sources` + Resolved 2 packages in [TIME] "###); + let lock = context.read("uv.lock"); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [[package]] + name = "project" + version = "0.1.0" + source = { virtual = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] + + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } + "### + ); + }); + + // If we run with `--no-sources`, we should use the URL provided in `project.dependencies`. + uv_snapshot!(context.filters(), context.lock().arg("--no-sources"), @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 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [[package]] + name = "project" + version = "0.1.0" + source = { virtual = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] + + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=0.0.2" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=0.0.2#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); + Ok(()) }