mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Use parsed URLs for conflicting URL error message (#14380)
## Summary There's a good example of the downside of using verbatim URLs here: https://github.com/astral-sh/uv/pull/14197#discussion_r2163599625 (we show two relative paths that point to the same directory, but it's not clear from the error message). The diff: ``` 2 2 │ ----- stdout ----- 3 3 │ 4 4 │ ----- stderr ----- 5 5 │ error: Requirements contain conflicting URLs for package `library` in all marker environments: 6 │-- ../../library 7 │-- ./library 6 │+- file://[TEMP_DIR]/library 7 │+- file://[TEMP_DIR]/library (editable) ```
This commit is contained in:
parent
b1812d111a
commit
3774a656d7
6 changed files with 23 additions and 19 deletions
|
@ -17,6 +17,8 @@ use uv_normalize::{ExtraName, InvalidNameError, PackageName};
|
|||
use uv_pep440::{LocalVersionSlice, LowerBound, Version, VersionSpecifier};
|
||||
use uv_pep508::{MarkerEnvironment, MarkerExpression, MarkerTree, MarkerValueVersion};
|
||||
use uv_platform_tags::Tags;
|
||||
use uv_pypi_types::ParsedUrl;
|
||||
use uv_redacted::DisplaySafeUrl;
|
||||
use uv_static::EnvVars;
|
||||
|
||||
use crate::candidate_selector::CandidateSelector;
|
||||
|
@ -56,11 +58,14 @@ pub enum ResolveError {
|
|||
} else {
|
||||
format!(" in {env}")
|
||||
},
|
||||
urls.join("\n- "),
|
||||
urls.iter()
|
||||
.map(|url| format!("{}{}", DisplaySafeUrl::from(url.clone()), if url.is_editable() { " (editable)" } else { "" }))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n- ")
|
||||
)]
|
||||
ConflictingUrls {
|
||||
package_name: PackageName,
|
||||
urls: Vec<String>,
|
||||
urls: Vec<ParsedUrl>,
|
||||
env: ResolverEnvironment,
|
||||
},
|
||||
|
||||
|
@ -71,11 +76,14 @@ pub enum ResolveError {
|
|||
} else {
|
||||
format!(" in {env}")
|
||||
},
|
||||
indexes.join("\n- "),
|
||||
indexes.iter()
|
||||
.map(std::string::ToString::to_string)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n- ")
|
||||
)]
|
||||
ConflictingIndexesForEnvironment {
|
||||
package_name: PackageName,
|
||||
indexes: Vec<String>,
|
||||
indexes: Vec<IndexUrl>,
|
||||
env: ResolverEnvironment,
|
||||
},
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ impl ForkIndexes {
|
|||
) -> Result<(), ResolveError> {
|
||||
if let Some(previous) = self.0.insert(package_name.clone(), index.clone()) {
|
||||
if &previous != index {
|
||||
let mut conflicts = vec![previous.url.to_string(), index.url.to_string()];
|
||||
let mut conflicts = vec![previous.url, index.url.clone()];
|
||||
conflicts.sort();
|
||||
return Err(ResolveError::ConflictingIndexesForEnvironment {
|
||||
package_name: package_name.clone(),
|
||||
|
|
|
@ -2,7 +2,6 @@ use std::collections::hash_map::Entry;
|
|||
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use uv_distribution_types::Verbatim;
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pypi_types::VerbatimParsedUrl;
|
||||
|
||||
|
@ -34,10 +33,8 @@ impl ForkUrls {
|
|||
match self.0.entry(package_name.clone()) {
|
||||
Entry::Occupied(previous) => {
|
||||
if previous.get() != url {
|
||||
let mut conflicting_url = vec![
|
||||
previous.get().verbatim.verbatim().to_string(),
|
||||
url.verbatim.verbatim().to_string(),
|
||||
];
|
||||
let mut conflicting_url =
|
||||
vec![previous.get().parsed_url.clone(), url.parsed_url.clone()];
|
||||
conflicting_url.sort();
|
||||
return Err(ResolveError::ConflictingUrls {
|
||||
package_name: package_name.clone(),
|
||||
|
|
|
@ -4,7 +4,6 @@ use same_file::is_same_file;
|
|||
use tracing::debug;
|
||||
|
||||
use uv_cache_key::CanonicalUrl;
|
||||
use uv_distribution_types::Verbatim;
|
||||
use uv_git::GitResolver;
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pep508::{MarkerTree, VerbatimUrl};
|
||||
|
@ -170,8 +169,8 @@ impl Urls {
|
|||
let [allowed_url] = matching_urls.as_slice() else {
|
||||
let mut conflicting_urls: Vec<_> = matching_urls
|
||||
.into_iter()
|
||||
.map(|parsed_url| parsed_url.verbatim.verbatim().to_string())
|
||||
.chain(std::iter::once(verbatim_url.verbatim().to_string()))
|
||||
.map(|parsed_url| parsed_url.parsed_url.clone())
|
||||
.chain(std::iter::once(parsed_url.clone()))
|
||||
.collect();
|
||||
conflicting_urls.sort();
|
||||
return Err(ResolveError::ConflictingUrls {
|
||||
|
|
|
@ -2909,16 +2909,16 @@ fn incompatible_narrowed_url_dependency() -> Result<()> {
|
|||
"})?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_compile()
|
||||
.arg("requirements.in"), @r###"
|
||||
.arg("requirements.in"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Requirements contain conflicting URLs for package `uv-public-pypackage`:
|
||||
- git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389
|
||||
- git+https://github.com/astral-test/uv-public-pypackage@test-branch
|
||||
"###
|
||||
- git+https://github.com/astral-test/uv-public-pypackage@b270df1a2fb5d012294e9aaf05e7e0bab1e6a389
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -1515,16 +1515,16 @@ fn install_editable_incompatible_constraint_url() -> Result<()> {
|
|||
.arg("-e")
|
||||
.arg(context.workspace_root.join("scripts/packages/black_editable"))
|
||||
.arg("--constraint")
|
||||
.arg("constraints.txt"), @r###"
|
||||
.arg("constraints.txt"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Requirements contain conflicting URLs for package `black`:
|
||||
- [WORKSPACE]/scripts/packages/black_editable
|
||||
- file://[WORKSPACE]/scripts/packages/black_editable (editable)
|
||||
- https://files.pythonhosted.org/packages/0f/89/294c9a6b6c75a08da55e9d05321d0707e9418735e3062b12ef0f54c33474/black-24.4.2-py3-none-any.whl
|
||||
"###
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue