From e1a36d7260bb7fdbe4d5dbd0a6fbc5ad0e3f9399 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 11 Nov 2024 21:59:10 -0500 Subject: [PATCH] Use rich diagnostic formatting for install failures --- crates/uv-dispatch/src/lib.rs | 5 +- crates/uv-installer/src/lib.rs | 2 +- crates/uv-installer/src/preparer.rs | 18 +- crates/uv/src/commands/diagnostics.rs | 30 ++- crates/uv/src/commands/pip/install.rs | 23 +- crates/uv/src/commands/pip/operations.rs | 8 +- crates/uv/src/commands/pip/sync.rs | 23 +- crates/uv/src/commands/project/add.rs | 18 ++ crates/uv/src/commands/project/remove.rs | 70 +++++- crates/uv/src/commands/project/run.rs | 26 +- crates/uv/src/commands/project/sync.rs | 26 +- crates/uv/tests/it/pip_install.rs | 45 ++-- crates/uv/tests/it/pip_sync.rs | 300 +++++++++++------------ crates/uv/tests/it/sync.rs | 48 ++-- 14 files changed, 397 insertions(+), 245 deletions(-) diff --git a/crates/uv-dispatch/src/lib.rs b/crates/uv-dispatch/src/lib.rs index 6003e45b1d93e..c07f48f5ee2c8 100644 --- a/crates/uv-dispatch/src/lib.rs +++ b/crates/uv-dispatch/src/lib.rs @@ -275,10 +275,7 @@ impl<'a> BuildContext for BuildDispatch<'a> { remote.iter().map(ToString::to_string).join(", ") ); - preparer - .prepare(remote, self.in_flight) - .await - .context("Failed to prepare distributions")? + preparer.prepare(remote, self.in_flight).await? }; // Remove any unnecessary packages. diff --git a/crates/uv-installer/src/lib.rs b/crates/uv-installer/src/lib.rs index a13419723e49b..1f5b333bd48b2 100644 --- a/crates/uv-installer/src/lib.rs +++ b/crates/uv-installer/src/lib.rs @@ -1,7 +1,7 @@ pub use compile::{compile_tree, CompileError}; pub use installer::{Installer, Reporter as InstallReporter}; pub use plan::{Plan, Planner}; -pub use preparer::{Preparer, Reporter as PrepareReporter}; +pub use preparer::{Error as PrepareError, Preparer, Reporter as PrepareReporter}; pub use site_packages::{SatisfiesResult, SitePackages, SitePackagesDiagnostic}; pub use uninstall::{uninstall, UninstallError}; diff --git a/crates/uv-installer/src/preparer.rs b/crates/uv-installer/src/preparer.rs index f75f085def5e0..3d05ecda49964 100644 --- a/crates/uv-installer/src/preparer.rs +++ b/crates/uv-installer/src/preparer.rs @@ -23,11 +23,11 @@ pub enum Error { #[error("Using pre-built wheels is disabled, but attempted to use `{0}`")] NoBinary(PackageName), #[error("Failed to download `{0}`")] - Download(Box, #[source] Box), + Download(Box, #[source] uv_distribution::Error), #[error("Failed to download and build `{0}`")] - DownloadAndBuild(Box, #[source] Box), + DownloadAndBuild(Box, #[source] uv_distribution::Error), #[error("Failed to build `{0}`")] - Build(Box, #[source] Box), + Build(Box, #[source] uv_distribution::Error), #[error("Unzip failed in another thread: {0}")] Thread(String), } @@ -146,12 +146,12 @@ impl<'a, Context: BuildContext> Preparer<'a, Context> { .get_or_build_wheel(&dist, self.tags, policy) .boxed_local() .map_err(|err| match dist.clone() { - Dist::Built(dist) => Error::Download(Box::new(dist), Box::new(err)), + Dist::Built(dist) => Error::Download(Box::new(dist), err), Dist::Source(dist) => { if dist.is_local() { - Error::Build(Box::new(dist), Box::new(err)) + Error::Build(Box::new(dist), err) } else { - Error::DownloadAndBuild(Box::new(dist), Box::new(err)) + Error::DownloadAndBuild(Box::new(dist), err) } } }) @@ -166,12 +166,12 @@ impl<'a, Context: BuildContext> Preparer<'a, Context> { wheel.hashes(), ); Err(match dist { - Dist::Built(dist) => Error::Download(Box::new(dist), Box::new(err)), + Dist::Built(dist) => Error::Download(Box::new(dist), err), Dist::Source(dist) => { if dist.is_local() { - Error::Build(Box::new(dist), Box::new(err)) + Error::Build(Box::new(dist), err) } else { - Error::DownloadAndBuild(Box::new(dist), Box::new(err)) + Error::DownloadAndBuild(Box::new(dist), err) } } }) diff --git a/crates/uv/src/commands/diagnostics.rs b/crates/uv/src/commands/diagnostics.rs index 9a63542845cc0..391948d66d759 100644 --- a/crates/uv/src/commands/diagnostics.rs +++ b/crates/uv/src/commands/diagnostics.rs @@ -2,7 +2,7 @@ use owo_colors::OwoColorize; use rustc_hash::FxHashMap; use std::str::FromStr; use std::sync::LazyLock; -use uv_distribution_types::{Name, SourceDist}; +use uv_distribution_types::{BuiltDist, Name, SourceDist}; use uv_normalize::PackageName; /// Static map of common package name typos or misconfigurations to their correct package names. @@ -48,6 +48,34 @@ pub(crate) fn download_and_build(sdist: Box, cause: uv_distribution: anstream::eprint!("{report:?}"); } +/// Render a remote binary distribution download failure with a help message. +pub(crate) fn download(sdist: Box, cause: uv_distribution::Error) { + #[derive(Debug, miette::Diagnostic, thiserror::Error)] + #[error("Failed to download `{sdist}`")] + #[diagnostic()] + struct Error { + sdist: Box, + #[source] + cause: uv_distribution::Error, + #[help] + help: Option, + } + + let report = miette::Report::new(Error { + help: SUGGESTIONS.get(sdist.name()).map(|suggestion| { + format!( + "`{}` is often confused for `{}` Did you mean to install `{}` instead?", + sdist.name().cyan(), + suggestion.cyan(), + suggestion.cyan(), + ) + }), + sdist, + cause, + }); + anstream::eprint!("{report:?}"); +} + /// Render a local source distribution build failure with a help message. pub(crate) fn build(sdist: Box, cause: uv_distribution::Error) { #[derive(Debug, miette::Diagnostic, thiserror::Error)] diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index 1e146e9f3c5c6..8dfb6490e7560 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -439,7 +439,7 @@ pub(crate) async fn pip_install( }; // Sync the environment. - operations::install( + match operations::install( &resolution, site_packages, modifications, @@ -461,7 +461,26 @@ pub(crate) async fn pip_install( dry_run, printer, ) - .await?; + .await + { + Ok(_) => {} + Err(operations::Error::Prepare(uv_installer::PrepareError::Build(dist, err))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(operations::Error::Prepare(uv_installer::PrepareError::DownloadAndBuild( + dist, + err, + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(operations::Error::Prepare(uv_installer::PrepareError::Download(dist, err))) => { + diagnostics::download(dist, err); + return Ok(ExitStatus::Failure); + } + Err(err) => return Err(err.into()), + } // Notify the user of any resolution diagnostics. operations::diagnose_resolution(resolution.diagnostics(), printer)?; diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index 88d06a2be6f30..d954c73ee4d15 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -457,10 +457,7 @@ pub(crate) async fn install( ) .with_reporter(PrepareReporter::from(printer).with_length(remote.len() as u64)); - let wheels = preparer - .prepare(remote.clone(), in_flight) - .await - .context("Failed to prepare distributions")?; + let wheels = preparer.prepare(remote.clone(), in_flight).await?; logger.on_prepare(wheels.len(), start, printer)?; @@ -751,6 +748,9 @@ pub(crate) fn diagnose_environment( #[derive(thiserror::Error, Debug)] pub(crate) enum Error { + #[error("Failed to prepare distributions")] + Prepare(#[from] uv_installer::PrepareError), + #[error(transparent)] Resolve(#[from] uv_resolver::ResolveError), diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index 10118692b876c..551ad6798664d 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -383,7 +383,7 @@ pub(crate) async fn pip_sync( }; // Sync the environment. - operations::install( + match operations::install( &resolution, site_packages, Modifications::Exact, @@ -405,7 +405,26 @@ pub(crate) async fn pip_sync( dry_run, printer, ) - .await?; + .await + { + Ok(_) => {} + Err(operations::Error::Prepare(uv_installer::PrepareError::Build(dist, err))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(operations::Error::Prepare(uv_installer::PrepareError::DownloadAndBuild( + dist, + err, + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(operations::Error::Prepare(uv_installer::PrepareError::Download(dist, err))) => { + diagnostics::download(dist, err); + return Ok(ExitStatus::Failure); + } + Err(err) => return Err(err.into()), + } // Notify the user of any resolution diagnostics. operations::diagnose_resolution(resolution.diagnostics(), printer)?; diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index 05b57ff1509ce..30b0b7db74244 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -703,6 +703,24 @@ pub(crate) async fn add( diagnostics::build(dist, err); Ok(ExitStatus::Failure) } + ProjectError::Operation(pip::operations::Error::Prepare( + uv_installer::PrepareError::Build(dist, err), + )) => { + diagnostics::build(dist, err); + Ok(ExitStatus::Failure) + } + ProjectError::Operation(pip::operations::Error::Prepare( + uv_installer::PrepareError::DownloadAndBuild(dist, err), + )) => { + diagnostics::download_and_build(dist, err); + Ok(ExitStatus::Failure) + } + ProjectError::Operation(pip::operations::Error::Prepare( + uv_installer::PrepareError::Download(dist, err), + )) => { + diagnostics::download(dist, err); + Ok(ExitStatus::Failure) + } err => { // Revert the changes to the `pyproject.toml`, if necessary. if modified { diff --git a/crates/uv/src/commands/project/remove.rs b/crates/uv/src/commands/project/remove.rs index 736827447ee50..e68e94b35fa0b 100644 --- a/crates/uv/src/commands/project/remove.rs +++ b/crates/uv/src/commands/project/remove.rs @@ -21,10 +21,11 @@ use uv_workspace::pyproject_mut::{DependencyTarget, PyProjectTomlMut}; use uv_workspace::{DiscoveryOptions, VirtualProject, Workspace}; use crate::commands::pip::loggers::{DefaultInstallLogger, DefaultResolveLogger}; +use crate::commands::pip::operations; use crate::commands::pip::operations::Modifications; -use crate::commands::project::default_dependency_groups; use crate::commands::project::lock::LockMode; -use crate::commands::{project, ExitStatus, SharedState}; +use crate::commands::project::{default_dependency_groups, ProjectError}; +use crate::commands::{diagnostics, project, ExitStatus, SharedState}; use crate::printer::Printer; use crate::settings::ResolverInstallerSettings; @@ -213,7 +214,7 @@ pub(crate) async fn remove( let state = SharedState::default(); // Lock and sync the environment, if necessary. - let lock = project::lock::do_safe_lock( + let lock = match project::lock::do_safe_lock( mode, project.workspace(), settings.as_ref().into(), @@ -227,8 +228,41 @@ pub(crate) async fn remove( cache, printer, ) - .await? - .into_lock(); + .await + { + Ok(result) => result.into_lock(), + Err(ProjectError::Operation(operations::Error::Resolve( + uv_resolver::ResolveError::NoSolution(err), + ))) => { + diagnostics::no_solution(&err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Resolve( + uv_resolver::ResolveError::DownloadAndBuild(dist, err), + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Resolve( + uv_resolver::ResolveError::Build(dist, err), + ))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Requirements( + uv_requirements::Error::DownloadAndBuild(dist, err), + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Requirements( + uv_requirements::Error::Build(dist, err), + ))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(err) => return Err(err.into()), + }; if no_sync { return Ok(ExitStatus::Success); @@ -255,7 +289,7 @@ pub(crate) async fn remove( }, }; - project::sync::do_sync( + match project::sync::do_sync( target, &venv, &extras, @@ -272,7 +306,29 @@ pub(crate) async fn remove( cache, printer, ) - .await?; + .await + { + Ok(()) => {} + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::Build(dist, err), + ))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::DownloadAndBuild(dist, err), + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::Download(dist, err), + ))) => { + diagnostics::download(dist, err); + return Ok(ExitStatus::Failure); + } + Err(err) => return Err(err.into()), + } Ok(ExitStatus::Success) } diff --git a/crates/uv/src/commands/project/run.rs b/crates/uv/src/commands/project/run.rs index 95ab47f077b12..91988de94de35 100644 --- a/crates/uv/src/commands/project/run.rs +++ b/crates/uv/src/commands/project/run.rs @@ -697,7 +697,7 @@ pub(crate) async fn run( let install_options = InstallOptions::default(); - project::sync::do_sync( + match project::sync::do_sync( target, &venv, &extras, @@ -718,7 +718,29 @@ pub(crate) async fn run( cache, printer, ) - .await?; + .await + { + Ok(()) => {} + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::Build(dist, err), + ))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::DownloadAndBuild(dist, err), + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::Download(dist, err), + ))) => { + diagnostics::download(dist, err); + return Ok(ExitStatus::Failure); + } + Err(err) => return Err(err.into()), + } lock = Some(result.into_lock()); } diff --git a/crates/uv/src/commands/project/sync.rs b/crates/uv/src/commands/project/sync.rs index 339763252054c..76f363a8ab26f 100644 --- a/crates/uv/src/commands/project/sync.rs +++ b/crates/uv/src/commands/project/sync.rs @@ -213,7 +213,7 @@ pub(crate) async fn sync( }; // Perform the sync operation. - do_sync( + match do_sync( target, &venv, &extras, @@ -230,7 +230,29 @@ pub(crate) async fn sync( cache, printer, ) - .await?; + .await + { + Ok(()) => {} + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::Build(dist, err), + ))) => { + diagnostics::build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::DownloadAndBuild(dist, err), + ))) => { + diagnostics::download_and_build(dist, err); + return Ok(ExitStatus::Failure); + } + Err(ProjectError::Operation(operations::Error::Prepare( + uv_installer::PrepareError::Download(dist, err), + ))) => { + diagnostics::download(dist, err); + return Ok(ExitStatus::Failure); + } + Err(err) => return Err(err.into()), + } Ok(ExitStatus::Success) } diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index a1f41379cf2fc..92cd4135665f3 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -2347,16 +2347,15 @@ fn no_prerelease_hint_source_builds() -> Result<()> { uv_snapshot!(context.filters(), context.pip_install().arg(".").env(EnvVars::UV_EXCLUDE_NEWER, "2018-10-08"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to build `project @ file://[TEMP_DIR]/` - Caused by: Failed to resolve requirements from `setup.py` build - Caused by: No solution found when resolving: `setuptools>=40.8.0` - Caused by: Because only setuptools<40.8.0 is available and you require setuptools>=40.8.0, we can conclude that your requirements are unsatisfiable. + × Failed to build `project @ file://[TEMP_DIR]/` + ├─▶ Failed to resolve requirements from `setup.py` build + ├─▶ No solution found when resolving: `setuptools>=40.8.0` + ╰─▶ Because only setuptools<40.8.0 is available and you require setuptools>=40.8.0, we can conclude that your requirements are unsatisfiable. "### ); @@ -5741,21 +5740,20 @@ fn require_hashes_mismatch() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 3 packages in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - sha256:a7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a + Expected: + sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + sha256:a7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); @@ -6226,21 +6224,20 @@ fn verify_hashes_mismatch() -> Result<()> { .arg("requirements.txt") .arg("--verify-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 3 packages in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - sha256:a7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a + Expected: + sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + sha256:a7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); diff --git a/crates/uv/tests/it/pip_sync.rs b/crates/uv/tests/it/pip_sync.rs index bdfab930f3da6..26e740ed33d64 100644 --- a/crates/uv/tests/it/pip_sync.rs +++ b/crates/uv/tests/it/pip_sync.rs @@ -3565,20 +3565,19 @@ fn require_hashes_wheel_no_binary() -> Result<()> { .arg(":all:") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download and build `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a + Computed: + sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a "### ); @@ -3659,20 +3658,19 @@ fn require_hashes_source_only_binary() -> Result<()> { .arg(":all:") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a + Expected: + sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); @@ -3692,20 +3690,19 @@ fn require_hashes_wrong_digest() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); @@ -3725,20 +3722,19 @@ fn require_hashes_wrong_algorithm() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha512:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha512:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha512:f30761c1e8725b49c498273b90dba4b05c0fd157811994c806183062cb6647e773364ce45f0e1ff0b10e32fe6d0232ea5ad39476ccf37109d6b49603a09c11c2 + Computed: + sha512:f30761c1e8725b49c498273b90dba4b05c0fd157811994c806183062cb6647e773364ce45f0e1ff0b10e32fe6d0232ea5ad39476ccf37109d6b49603a09c11c2 "### ); @@ -3898,20 +3894,19 @@ fn require_hashes_wheel_url() -> Result<()> { .arg("--reinstall") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` - Caused by: Hash mismatch for `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` + × Failed to download `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` + ╰─▶ Hash mismatch for `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` - Expected: - sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); @@ -3953,20 +3948,19 @@ fn require_hashes_wheel_url_mismatch() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` - Caused by: Hash mismatch for `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` + × Failed to download `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` + ╰─▶ Hash mismatch for `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` - Expected: - sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); @@ -4062,20 +4056,19 @@ fn require_hashes_re_download() -> Result<()> { .arg("--reinstall") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio==4.0.0` - Caused by: Hash mismatch for `anyio==4.0.0` + × Failed to download `anyio==4.0.0` + ╰─▶ Hash mismatch for `anyio==4.0.0` - Expected: - sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Computed: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f "### ); @@ -4154,20 +4147,19 @@ fn require_hashes_wheel_path_mismatch() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `tqdm @ file://[WORKSPACE]/scripts/links/tqdm-1000.0.0-py3-none-any.whl` - Caused by: Hash mismatch for `tqdm @ file://[WORKSPACE]/scripts/links/tqdm-1000.0.0-py3-none-any.whl` + × Failed to download `tqdm @ file://[WORKSPACE]/scripts/links/tqdm-1000.0.0-py3-none-any.whl` + ╰─▶ Hash mismatch for `tqdm @ file://[WORKSPACE]/scripts/links/tqdm-1000.0.0-py3-none-any.whl` - Expected: - sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f + Expected: + sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f - Computed: - sha256:a34996d4bd5abb2336e14ff0a2d22b92cfd0f0ed344e6883041ce01953276a13 + Computed: + sha256:a34996d4bd5abb2336e14ff0a2d22b92cfd0f0ed344e6883041ce01953276a13 "### ); @@ -4431,20 +4423,19 @@ fn require_hashes_repeated_hash() -> Result<()> { .arg("--require-hashes") .arg("--reinstall"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` - Caused by: Hash mismatch for `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` + × Failed to download `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` + ╰─▶ Hash mismatch for `anyio @ https://files.pythonhosted.org/packages/36/55/ad4de788d84a630656ece71059665e01ca793c04294c463fd84132f40fe6/anyio-4.0.0-py3-none-any.whl` - Expected: - md5:520d85e19168705cdf0223621b18831a + Expected: + md5:520d85e19168705cdf0223621b18831a - Computed: - md5:420d85e19168705cdf0223621b18831a + Computed: + md5:420d85e19168705cdf0223621b18831a "### ); @@ -4563,20 +4554,19 @@ fn require_hashes_find_links_no_hash() -> Result<()> { .arg("--find-links") .arg("https://raw.githubusercontent.com/astral-test/astral-test-hash/main/no-hash/simple-html/example-a-961b4c22/index.html"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:123 + Expected: + sha256:123 - Computed: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + Computed: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e "### ); @@ -4593,20 +4583,19 @@ fn require_hashes_find_links_no_hash() -> Result<()> { .arg("--find-links") .arg("https://raw.githubusercontent.com/astral-test/astral-test-hash/main/no-hash/simple-html/example-a-961b4c22/index.html"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:294e788dbe500fdc39e8b88e82652ab67409a1dc9dd06543d0fe0ae31b713eb3 + Expected: + sha256:294e788dbe500fdc39e8b88e82652ab67409a1dc9dd06543d0fe0ae31b713eb3 - Computed: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + Computed: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e "### ); @@ -4684,20 +4673,19 @@ fn require_hashes_find_links_invalid_hash() -> Result<()> { .arg("--find-links") .arg("https://raw.githubusercontent.com/astral-test/astral-test-hash/main/invalid-hash/simple-html/example-a-961b4c22/index.html"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:123 + Expected: + sha256:123 - Computed: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + Computed: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e "### ); @@ -4713,20 +4701,19 @@ fn require_hashes_find_links_invalid_hash() -> Result<()> { .arg("--find-links") .arg("https://raw.githubusercontent.com/astral-test/astral-test-hash/main/invalid-hash/simple-html/example-a-961b4c22/index.html"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:8838f9d005ff0432b258ba648d9cabb1cbdf06ac29d14f788b02edae544032ea + Expected: + sha256:8838f9d005ff0432b258ba648d9cabb1cbdf06ac29d14f788b02edae544032ea - Computed: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + Computed: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e "### ); @@ -4794,21 +4781,20 @@ fn require_hashes_find_links_invalid_hash() -> Result<()> { .arg("--find-links") .arg("https://raw.githubusercontent.com/astral-test/astral-test-hash/main/invalid-hash/simple-html/example-a-961b4c22/index.html"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download and build `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e - sha256:a3cf07a05aac526131a2e8b6e4375ee6c6eaac8add05b88035e960ac6cd999ee + Expected: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + sha256:a3cf07a05aac526131a2e8b6e4375ee6c6eaac8add05b88035e960ac6cd999ee - Computed: - sha256:294e788dbe500fdc39e8b88e82652ab67409a1dc9dd06543d0fe0ae31b713eb3 + Computed: + sha256:294e788dbe500fdc39e8b88e82652ab67409a1dc9dd06543d0fe0ae31b713eb3 "### ); @@ -4890,20 +4876,19 @@ fn require_hashes_registry_invalid_hash() -> Result<()> { .arg("--index-url") .arg("https://astral-test.github.io/astral-test-hash/invalid-hash/simple-html/"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:123 + Expected: + sha256:123 - Computed: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + Computed: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e "### ); @@ -4920,20 +4905,19 @@ fn require_hashes_registry_invalid_hash() -> Result<()> { .arg("--index-url") .arg("https://astral-test.github.io/astral-test-hash/invalid-hash/simple-html/"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:8838f9d005ff0432b258ba648d9cabb1cbdf06ac29d14f788b02edae544032ea + Expected: + sha256:8838f9d005ff0432b258ba648d9cabb1cbdf06ac29d14f788b02edae544032ea - Computed: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + Computed: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e "### ); @@ -5004,21 +4988,20 @@ fn require_hashes_registry_invalid_hash() -> Result<()> { .arg("--index-url") .arg("https://astral-test.github.io/astral-test-hash/invalid-hash/simple-html/"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `example-a-961b4c22==1.0.0` - Caused by: Hash mismatch for `example-a-961b4c22==1.0.0` + × Failed to download and build `example-a-961b4c22==1.0.0` + ╰─▶ Hash mismatch for `example-a-961b4c22==1.0.0` - Expected: - sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e - sha256:a3cf07a05aac526131a2e8b6e4375ee6c6eaac8add05b88035e960ac6cd999ee + Expected: + sha256:5d69f0b590514103234f0c3526563856f04d044d8d0ea1073a843ae429b3187e + sha256:a3cf07a05aac526131a2e8b6e4375ee6c6eaac8add05b88035e960ac6cd999ee - Computed: - sha256:294e788dbe500fdc39e8b88e82652ab67409a1dc9dd06543d0fe0ae31b713eb3 + Computed: + sha256:294e788dbe500fdc39e8b88e82652ab67409a1dc9dd06543d0fe0ae31b713eb3 "### ); @@ -5092,20 +5075,19 @@ fn require_hashes_url_invalid() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` - Caused by: Hash mismatch for `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` + × Failed to download `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` + ╰─▶ Hash mismatch for `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` - Expected: - sha256:c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 + Expected: + sha256:c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 - Computed: - sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 + Computed: + sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 "### ); @@ -5126,20 +5108,19 @@ fn require_hashes_url_ignore() -> Result<()> { .arg("requirements.txt") .arg("--require-hashes"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` - Caused by: Hash mismatch for `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` + × Failed to download `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` + ╰─▶ Hash mismatch for `iniconfig @ https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl#sha256=b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374` - Expected: - sha256:c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 + Expected: + sha256:c6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 - Computed: - sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 + Computed: + sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 "### ); @@ -5487,16 +5468,15 @@ fn incompatible_build_constraint() -> Result<()> { .arg("--build-constraint") .arg("build_constraints.txt"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 1 package in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `requests==1.2.0` - Caused by: Failed to resolve requirements from `setup.py` build - Caused by: No solution found when resolving: `setuptools>=40.8.0` - Caused by: Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable. + × Failed to download and build `requests==1.2.0` + ├─▶ Failed to resolve requirements from `setup.py` build + ├─▶ No solution found when resolving: `setuptools>=40.8.0` + ╰─▶ Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable. "### ); diff --git a/crates/uv/tests/it/sync.rs b/crates/uv/tests/it/sync.rs index f95f9d4d14556..1e0b9a21a1a4e 100644 --- a/crates/uv/tests/it/sync.rs +++ b/crates/uv/tests/it/sync.rs @@ -688,20 +688,18 @@ fn sync_build_isolation_package() -> Result<()> { .collect::>(); uv_snapshot!(filters, context.sync().arg("--no-build-isolation-package").arg("source-distribution"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved 2 packages in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz` - Caused by: Build backend failed to build wheel through `build_wheel` (exit status: 1) - - [stderr] - Traceback (most recent call last): - File "", line 8, in - ModuleNotFoundError: No module named 'hatchling' + × Failed to download and build `source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz` + ╰─▶ Build backend failed to build wheel through `build_wheel` (exit status: 1) + [stderr] + Traceback (most recent call last): + File "", line 8, in + ModuleNotFoundError: No module named 'hatchling' "###); // Install `hatchling` for `source-distribution`. @@ -779,39 +777,35 @@ fn sync_build_isolation_extra() -> Result<()> { .collect::>(); uv_snapshot!(&filters, context.sync().arg("--extra").arg("compile"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved [N] packages in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz` - Caused by: Build backend failed to build wheel through `build_wheel` (exit status: 1) - - [stderr] - Traceback (most recent call last): - File "", line 8, in - ModuleNotFoundError: No module named 'hatchling' + × Failed to download and build `source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz` + ╰─▶ Build backend failed to build wheel through `build_wheel` (exit status: 1) + [stderr] + Traceback (most recent call last): + File "", line 8, in + ModuleNotFoundError: No module named 'hatchling' "###); // Running `uv sync` with `--all-extras` should also fail. uv_snapshot!(&filters, context.sync().arg("--all-extras"), @r###" success: false - exit_code: 2 + exit_code: 1 ----- stdout ----- ----- stderr ----- Resolved [N] packages in [TIME] - error: Failed to prepare distributions - Caused by: Failed to download and build `source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz` - Caused by: Build backend failed to build wheel through `build_wheel` (exit status: 1) - - [stderr] - Traceback (most recent call last): - File "", line 8, in - ModuleNotFoundError: No module named 'hatchling' + × Failed to download and build `source-distribution @ https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz` + ╰─▶ Build backend failed to build wheel through `build_wheel` (exit status: 1) + [stderr] + Traceback (most recent call last): + File "", line 8, in + ModuleNotFoundError: No module named 'hatchling' "###); // Install the build dependencies.