From 6ed6fc108e95e742075cf1eddb09ec86c04f632e Mon Sep 17 00:00:00 2001 From: konsti Date: Wed, 4 Dec 2024 16:57:18 +0100 Subject: [PATCH] Build backend: Add direct builds to the resolver and installer (#9621) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is like #9556, but at the level of all other builds, including the resolver and installer. Going through PEP 517 to build a package is slow, so when building a package with the uv build backend, we can call into the uv build backend directly instead: No temporary virtual env, no temp venv sync, no python subprocess calls, no uv subprocess calls. This fast path is gated through preview. Since the uv wheel is not available at test time, I've manually confirmed the feature by comparing `uv venv && cargo run pip install . -v --preview --reinstall .` and `uv venv && cargo run pip install . -v --reinstall .`. When hacking the preview so that the python uv build backend works without the setting the direct build also (wheel built with `maturin build --profile profiling`), we can see the perfomance difference: ``` $ hyperfine --prepare "uv venv" --warmup 3 \ "UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview" \ "target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/" Benchmark 1: UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview Time (mean ± σ): 33.1 ms ± 2.5 ms [User: 25.7 ms, System: 13.0 ms] Range (min … max): 29.8 ms … 47.3 ms 73 runs Benchmark 2: target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/ Time (mean ± σ): 115.1 ms ± 4.3 ms [User: 54.0 ms, System: 27.0 ms] Range (min … max): 109.2 ms … 123.8 ms 25 runs Summary UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview ran 3.48 ± 0.29 times faster than target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/ ``` Do we need a global option to disable the fast path? There is one for `uv build` because `--force-pep517` moves `uv build` much closer to a `pip install` from source that a user of a library would experience (See discussion at #9610), but uv overall doesn't really make guarantees around the build env of dependencies, so I consider the direct build a valid option. Best reviewed commit-by-commit, only the last commit is the actual implementation, while the preview mode introduction is just a refactoring touching too many files. --- Cargo.lock | 6 ++ crates/uv-bench/benches/uv.rs | 3 +- crates/uv-build-backend/Cargo.toml | 1 + crates/uv-build-backend/src/lib.rs | 2 +- crates/uv-build-backend/src/metadata.rs | 36 +++++++++ crates/uv-build-frontend/src/lib.rs | 6 +- crates/uv-dispatch/Cargo.toml | 4 + crates/uv-dispatch/src/lib.rs | 81 +++++++++++++++++-- crates/uv-distribution/src/source/mod.rs | 42 +++++++--- crates/uv-types/Cargo.toml | 1 + crates/uv-types/src/traits.rs | 22 ++++- crates/uv/src/commands/build_frontend.rs | 64 +++++---------- crates/uv/src/commands/pip/compile.rs | 4 +- crates/uv/src/commands/pip/install.rs | 4 +- crates/uv/src/commands/pip/sync.rs | 4 +- crates/uv/src/commands/project/add.rs | 11 ++- crates/uv/src/commands/project/environment.rs | 5 +- crates/uv/src/commands/project/export.rs | 4 +- crates/uv/src/commands/project/lock.rs | 11 ++- crates/uv/src/commands/project/mod.rs | 10 ++- crates/uv/src/commands/project/remove.rs | 5 +- crates/uv/src/commands/project/run.rs | 7 +- crates/uv/src/commands/project/sync.rs | 7 +- crates/uv/src/commands/project/tree.rs | 4 +- crates/uv/src/commands/tool/install.rs | 10 ++- crates/uv/src/commands/tool/run.rs | 8 +- crates/uv/src/commands/tool/upgrade.rs | 8 +- crates/uv/src/commands/venv.rs | 6 +- crates/uv/src/lib.rs | 14 ++++ 29 files changed, 304 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c57eef85..0d20151ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4583,6 +4583,7 @@ dependencies = [ "uv-pep440", "uv-pep508", "uv-pypi-types", + "uv-version", "uv-warnings", "version-ranges", "walkdir", @@ -4841,12 +4842,15 @@ dependencies = [ "futures", "itertools 0.13.0", "rustc-hash", + "tokio", "tracing", + "uv-build-backend", "uv-build-frontend", "uv-cache", "uv-client", "uv-configuration", "uv-distribution", + "uv-distribution-filename", "uv-distribution-types", "uv-git", "uv-install-wheel", @@ -4855,6 +4859,7 @@ dependencies = [ "uv-python", "uv-resolver", "uv-types", + "uv-version", ] [[package]] @@ -5590,6 +5595,7 @@ dependencies = [ "url", "uv-cache", "uv-configuration", + "uv-distribution-filename", "uv-distribution-types", "uv-git", "uv-normalize", diff --git a/crates/uv-bench/benches/uv.rs b/crates/uv-bench/benches/uv.rs index c7c71ceb2..204c341e3 100644 --- a/crates/uv-bench/benches/uv.rs +++ b/crates/uv-bench/benches/uv.rs @@ -87,7 +87,7 @@ mod resolver { use uv_client::RegistryClient; use uv_configuration::{ BuildOptions, Concurrency, ConfigSettings, Constraints, IndexStrategy, LowerBound, - SourceStrategy, + PreviewMode, SourceStrategy, }; use uv_dispatch::{BuildDispatch, SharedState}; use uv_distribution::DistributionDatabase; @@ -190,6 +190,7 @@ mod resolver { LowerBound::default(), sources, concurrency, + PreviewMode::Enabled, ); let markers = if universal { diff --git a/crates/uv-build-backend/Cargo.toml b/crates/uv-build-backend/Cargo.toml index d2e605702..2c8a6c76b 100644 --- a/crates/uv-build-backend/Cargo.toml +++ b/crates/uv-build-backend/Cargo.toml @@ -20,6 +20,7 @@ uv-normalize = { workspace = true } uv-pep440 = { workspace = true } uv-pep508 = { workspace = true } uv-pypi-types = { workspace = true } +uv-version = { workspace = true } uv-warnings = { workspace = true } csv = { workspace = true } diff --git a/crates/uv-build-backend/src/lib.rs b/crates/uv-build-backend/src/lib.rs index 20d63f290..c1f08455e 100644 --- a/crates/uv-build-backend/src/lib.rs +++ b/crates/uv-build-backend/src/lib.rs @@ -2,7 +2,7 @@ mod metadata; mod source_dist; mod wheel; -pub use metadata::PyProjectToml; +pub use metadata::{check_direct_build, PyProjectToml}; pub use source_dist::{build_source_dist, list_source_dist}; pub use wheel::{build_editable, build_wheel, list_wheel, metadata}; diff --git a/crates/uv-build-backend/src/metadata.rs b/crates/uv-build-backend/src/metadata.rs index 54a9f62d3..3ee691ce3 100644 --- a/crates/uv-build-backend/src/metadata.rs +++ b/crates/uv-build-backend/src/metadata.rs @@ -3,6 +3,7 @@ use itertools::Itertools; use serde::Deserialize; use std::collections::{BTreeMap, Bound}; use std::ffi::OsStr; +use std::fmt::Display; use std::path::{Path, PathBuf}; use std::str::FromStr; use tracing::{debug, trace}; @@ -50,6 +51,41 @@ pub enum ValidationError { InvalidSpdx(String, #[source] spdx::error::ParseError), } +/// Check if the build backend is matching the currently running uv version. +pub fn check_direct_build(source_tree: &Path, name: impl Display) -> bool { + let pyproject_toml: PyProjectToml = + match fs_err::read_to_string(source_tree.join("pyproject.toml")) + .map_err(|err| err.to_string()) + .and_then(|pyproject_toml| { + toml::from_str(&pyproject_toml).map_err(|err| err.to_string()) + }) { + Ok(pyproject_toml) => pyproject_toml, + Err(err) => { + debug!( + "Not using uv build backend direct build of {name}, no pyproject.toml: {err}" + ); + return false; + } + }; + match pyproject_toml + .check_build_system(uv_version::version()) + .as_slice() + { + // No warnings -> match + [] => true, + // Any warning -> no match + [first, others @ ..] => { + debug!( + "Not using uv build backend direct build of {name}, pyproject.toml does not match: {first}" + ); + for other in others { + trace!("Further uv build backend direct build of {name} mismatch: {other}"); + } + false + } + } +} + /// A `pyproject.toml` as specified in PEP 517. #[derive(Deserialize, Debug, Clone)] #[serde( diff --git a/crates/uv-build-frontend/src/lib.rs b/crates/uv-build-frontend/src/lib.rs index 57817a9a8..05b1b2cfc 100644 --- a/crates/uv-build-frontend/src/lib.rs +++ b/crates/uv-build-frontend/src/lib.rs @@ -251,7 +251,7 @@ impl SourceBuild { interpreter: &Interpreter, build_context: &impl BuildContext, source_build_context: SourceBuildContext, - version_id: Option, + version_id: Option<&str>, locations: &IndexLocations, source_strategy: SourceStrategy, config_settings: ConfigSettings, @@ -376,7 +376,7 @@ impl SourceBuild { build_context, package_name.as_ref(), package_version.as_ref(), - version_id.as_deref(), + version_id, locations, source_strategy, build_kind, @@ -401,7 +401,7 @@ impl SourceBuild { metadata_directory: None, package_name, package_version, - version_id, + version_id: version_id.map(ToString::to_string), environment_variables, modified_path, runner, diff --git a/crates/uv-dispatch/Cargo.toml b/crates/uv-dispatch/Cargo.toml index b61a7534b..3750ab24a 100644 --- a/crates/uv-dispatch/Cargo.toml +++ b/crates/uv-dispatch/Cargo.toml @@ -17,11 +17,13 @@ doctest = false workspace = true [dependencies] +uv-build-backend = { workspace = true } uv-build-frontend = { workspace = true } uv-cache = { workspace = true } uv-client = { workspace = true } uv-configuration = { workspace = true } uv-distribution = { workspace = true } +uv-distribution-filename = { workspace = true } uv-distribution-types = { workspace = true } uv-git = { workspace = true } uv-install-wheel = { workspace = true } @@ -30,9 +32,11 @@ uv-pypi-types = { workspace = true } uv-python = { workspace = true } uv-resolver = { workspace = true } uv-types = { workspace = true } +uv-version = { workspace = true } anyhow = { workspace = true } futures = { workspace = true } itertools = { workspace = true } rustc-hash = { workspace = true } +tokio = { workspace = true } tracing = { workspace = true } diff --git a/crates/uv-dispatch/src/lib.rs b/crates/uv-dispatch/src/lib.rs index 24c9619a1..6c1981b0f 100644 --- a/crates/uv-dispatch/src/lib.rs +++ b/crates/uv-dispatch/src/lib.rs @@ -9,17 +9,18 @@ use anyhow::{anyhow, Context, Result}; use futures::FutureExt; use itertools::Itertools; use rustc_hash::FxHashMap; -use tracing::{debug, instrument}; - +use tracing::{debug, instrument, trace}; +use uv_build_backend::check_direct_build; use uv_build_frontend::{SourceBuild, SourceBuildContext}; use uv_cache::Cache; use uv_client::RegistryClient; use uv_configuration::{ - BuildKind, BuildOptions, ConfigSettings, Constraints, IndexStrategy, LowerBound, Reinstall, - SourceStrategy, + BuildKind, BuildOptions, ConfigSettings, Constraints, IndexStrategy, LowerBound, PreviewMode, + Reinstall, SourceStrategy, }; use uv_configuration::{BuildOutput, Concurrency}; use uv_distribution::DistributionDatabase; +use uv_distribution_filename::DistFilename; use uv_distribution_types::{ CachedDist, DependencyMetadata, IndexCapabilities, IndexLocations, Name, Resolution, SourceDist, VersionOrUrlRef, @@ -57,6 +58,7 @@ pub struct BuildDispatch<'a> { bounds: LowerBound, sources: SourceStrategy, concurrency: Concurrency, + preview: PreviewMode, } impl<'a> BuildDispatch<'a> { @@ -79,6 +81,7 @@ impl<'a> BuildDispatch<'a> { bounds: LowerBound, sources: SourceStrategy, concurrency: Concurrency, + preview: PreviewMode, ) -> Self { Self { client, @@ -101,6 +104,7 @@ impl<'a> BuildDispatch<'a> { bounds, sources, concurrency, + preview, } } @@ -340,7 +344,7 @@ impl<'a> BuildContext for BuildDispatch<'a> { source: &'data Path, subdirectory: Option<&'data Path>, install_path: &'data Path, - version_id: Option, + version_id: Option<&'data str>, dist: Option<&'data SourceDist>, sources: SourceStrategy, build_kind: BuildKind, @@ -394,6 +398,73 @@ impl<'a> BuildContext for BuildDispatch<'a> { .await?; Ok(builder) } + + async fn direct_build<'data>( + &'data self, + source: &'data Path, + subdirectory: Option<&'data Path>, + output_dir: &'data Path, + build_kind: BuildKind, + version_id: Option<&'data str>, + ) -> Result> { + // Direct builds are a preview feature with the uv build backend. + if self.preview.is_disabled() { + trace!("Preview is disabled, not checking for direct build"); + return Ok(None); + } + + let source_tree = if let Some(subdir) = subdirectory { + source.join(subdir) + } else { + source.to_path_buf() + }; + + // Only perform the direct build if the backend is uv in a compatible version. + let source_tree_str = source_tree.display().to_string(); + let identifier = version_id.unwrap_or_else(|| &source_tree_str); + if !check_direct_build(&source_tree, identifier) { + trace!("Requirements for direct build not matched: {identifier}"); + return Ok(None); + } + + debug!("Performing direct build for {identifier}"); + + let output_dir = output_dir.to_path_buf(); + let filename = tokio::task::spawn_blocking(move || -> Result<_> { + let filename = match build_kind { + BuildKind::Wheel => { + let wheel = uv_build_backend::build_wheel( + &source_tree, + &output_dir, + None, + uv_version::version(), + )?; + DistFilename::WheelFilename(wheel) + } + BuildKind::Sdist => { + let source_dist = uv_build_backend::build_source_dist( + &source_tree, + &output_dir, + uv_version::version(), + )?; + DistFilename::SourceDistFilename(source_dist) + } + BuildKind::Editable => { + let wheel = uv_build_backend::build_editable( + &source_tree, + &output_dir, + None, + uv_version::version(), + )?; + DistFilename::WheelFilename(wheel) + } + }; + Ok(filename) + }) + .await??; + + Ok(Some(filename)) + } } /// Shared state used during resolution and installation. diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index 54cac0b7f..8df51913f 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -1803,27 +1803,47 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { fs::create_dir_all(&cache_shard) .await .map_err(Error::CacheWrite)?; - let disk_filename = self + // Try a direct build if that isn't disabled and the uv build backend is used. + let disk_filename = if let Some(name) = self .build_context - .setup_build( + .direct_build( source_root, subdirectory, - source_root, - Some(source.to_string()), - source.as_dist(), - source_strategy, + temp_dir.path(), if source.is_editable() { BuildKind::Editable } else { BuildKind::Wheel }, - BuildOutput::Debug, + Some(&source.to_string()), ) .await .map_err(Error::Build)? - .wheel(temp_dir.path()) - .await - .map_err(Error::Build)?; + { + // In the uv build backend, the normalized filename and the disk filename are the same. + name.to_string() + } else { + self.build_context + .setup_build( + source_root, + subdirectory, + source_root, + Some(&source.to_string()), + source.as_dist(), + source_strategy, + if source.is_editable() { + BuildKind::Editable + } else { + BuildKind::Wheel + }, + BuildOutput::Debug, + ) + .await + .map_err(Error::Build)? + .wheel(temp_dir.path()) + .await + .map_err(Error::Build)? + }; // Read the metadata from the wheel. let filename = WheelFilename::from_str(&disk_filename)?; @@ -1884,7 +1904,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { source_root, subdirectory, source_root, - Some(source.to_string()), + Some(&source.to_string()), source.as_dist(), source_strategy, if source.is_editable() { diff --git a/crates/uv-types/Cargo.toml b/crates/uv-types/Cargo.toml index 57ac4571a..192e50eb6 100644 --- a/crates/uv-types/Cargo.toml +++ b/crates/uv-types/Cargo.toml @@ -18,6 +18,7 @@ workspace = true [dependencies] uv-cache = { workspace = true } uv-configuration = { workspace = true } +uv-distribution-filename = { workspace = true } uv-distribution-types = { workspace = true } uv-git = { workspace = true } uv-normalize = { workspace = true } diff --git a/crates/uv-types/src/traits.rs b/crates/uv-types/src/traits.rs index b39e26138..68c17258a 100644 --- a/crates/uv-types/src/traits.rs +++ b/crates/uv-types/src/traits.rs @@ -1,5 +1,6 @@ use std::future::Future; use std::path::{Path, PathBuf}; +use uv_distribution_filename::DistFilename; use anyhow::Result; @@ -115,12 +116,27 @@ pub trait BuildContext { source: &'a Path, subdirectory: Option<&'a Path>, install_path: &'a Path, - version_id: Option, + version_id: Option<&'a str>, dist: Option<&'a SourceDist>, sources: SourceStrategy, build_kind: BuildKind, build_output: BuildOutput, ) -> impl Future> + 'a; + + /// Build by calling directly into the uv build backend without PEP 517, if possible. + /// + /// Checks if the source tree uses uv as build backend. If not, it returns `Ok(None)`, otherwise + /// it builds and returns the name of the built file. + /// + /// `version_id` is for error reporting only. + fn direct_build<'a>( + &'a self, + source: &'a Path, + subdirectory: Option<&'a Path>, + output_dir: &'a Path, + build_kind: BuildKind, + version_id: Option<&'a str>, + ) -> impl Future>> + 'a; } /// A wrapper for `uv_build::SourceBuild` to avoid cyclical crate dependencies. @@ -140,7 +156,9 @@ pub trait SourceBuildTrait { /// /// For PEP 517 builds, this calls `build_wheel`. /// - /// Returns the filename of the built wheel inside the given `wheel_dir`. + /// Returns the filename of the built wheel inside the given `wheel_dir`. The filename is a + /// string and not a `WheelFilename` because the on disk filename might not be normalized in the + /// same way as uv would. fn wheel<'a>(&'a self, wheel_dir: &'a Path) -> impl Future> + 'a; } diff --git a/crates/uv/src/commands/build_frontend.rs b/crates/uv/src/commands/build_frontend.rs index 42c67bd9f..2fa5f1d5c 100644 --- a/crates/uv/src/commands/build_frontend.rs +++ b/crates/uv/src/commands/build_frontend.rs @@ -8,7 +8,7 @@ use std::{fmt, io}; use anyhow::{Context, Result}; use owo_colors::OwoColorize; use thiserror::Error; -use tracing::{debug, instrument, trace}; +use tracing::instrument; use crate::commands::pip::operations; use crate::commands::project::find_requires_python; @@ -17,7 +17,7 @@ use crate::commands::ExitStatus; use crate::printer::Printer; use crate::settings::{ResolverSettings, ResolverSettingsRef}; use uv_auth::store_credentials; -use uv_build_backend::PyProjectToml; +use uv_build_backend::check_direct_build; use uv_cache::{Cache, CacheBucket}; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ @@ -190,7 +190,7 @@ async fn build_impl( preview: PreviewMode, ) -> Result { if list && preview.is_disabled() { - // We need the fast path for list and that is preview only. + // We need the direct build for list and that is preview only. writeln!( printer.stderr(), "The `--list` option is only available in preview mode; add the `--preview` flag to use `--list`" @@ -576,6 +576,7 @@ async fn build_package( LowerBound::Allow, sources, concurrency, + preview, ); prepare_output_directory(&output_dir).await?; @@ -590,14 +591,17 @@ async fn build_package( return Err(Error::ListForcePep517); } - if !check_fast_path(source.path()) { + if !check_direct_build(source.path(), source.path().user_display()) { // TODO(konsti): Provide more context on what mismatched return Err(Error::ListNonUv); } BuildAction::List - } else if preview.is_enabled() && !force_pep517 && check_fast_path(source.path()) { - BuildAction::FastPath + } else if preview.is_enabled() + && !force_pep517 + && check_direct_build(source.path(), source.path().user_display()) + { + BuildAction::DirectBuild } else { BuildAction::Pep517 }; @@ -816,7 +820,7 @@ enum BuildAction { /// Only list the files that would be included, don't actually build. List, /// Build by calling directly into the build backend. - FastPath, + DirectBuild, /// Build through the PEP 517 hooks. Pep517, } @@ -826,14 +830,14 @@ impl BuildAction { fn force_build(self) -> Self { match self { // List is only available for the uv build backend - Self::List => Self::FastPath, - Self::FastPath => Self::FastPath, + Self::List => Self::DirectBuild, + Self::DirectBuild => Self::DirectBuild, Self::Pep517 => Self::Pep517, } } } -/// Build a source distribution, either through PEP 517 or through the fast path. +/// Build a source distribution, either through PEP 517 or through a direct build. #[instrument(skip_all)] async fn build_sdist( source_tree: &Path, @@ -864,7 +868,7 @@ async fn build_sdist( file_list, } } - BuildAction::FastPath => { + BuildAction::DirectBuild => { writeln!( printer.stderr(), "{}", @@ -911,7 +915,7 @@ async fn build_sdist( source_tree, subdirectory, source.path(), - version_id.map(ToString::to_string), + version_id, dist, sources, BuildKind::Sdist, @@ -932,7 +936,7 @@ async fn build_sdist( Ok(build_result) } -/// Build a wheel, either through PEP 517 or through the fast path. +/// Build a wheel, either through PEP 517 or through a direct build. #[instrument(skip_all)] async fn build_wheel( source_tree: &Path, @@ -964,7 +968,7 @@ async fn build_wheel( file_list, } } - BuildAction::FastPath => { + BuildAction::DirectBuild => { writeln!( printer.stderr(), "{}", @@ -1008,7 +1012,7 @@ async fn build_wheel( source_tree, subdirectory, source.path(), - version_id.map(ToString::to_string), + version_id, dist, sources, BuildKind::Wheel, @@ -1246,33 +1250,3 @@ impl BuildPlan { }) } } - -/// Check if the build backend is matching the currently running uv version. -fn check_fast_path(source_tree: &Path) -> bool { - let pyproject_toml: PyProjectToml = - match fs_err::read_to_string(source_tree.join("pyproject.toml")) - .map_err(anyhow::Error::from) - .and_then(|pyproject_toml| Ok(toml::from_str(&pyproject_toml)?)) - { - Ok(pyproject_toml) => pyproject_toml, - Err(err) => { - debug!("Not using uv build backend fast path, no pyproject.toml: {err}"); - return false; - } - }; - match pyproject_toml - .check_build_system(uv_version::version()) - .as_slice() - { - // No warnings -> match - [] => true, - // Any warning -> no match - [first, others @ ..] => { - debug!("Not using uv build backend fast path, pyproject.toml does not match: {first}"); - for other in others { - trace!("Further uv build backend fast path mismatch: {other}"); - } - false - } - } -} diff --git a/crates/uv/src/commands/pip/compile.rs b/crates/uv/src/commands/pip/compile.rs index 1cfb34208..65b437be0 100644 --- a/crates/uv/src/commands/pip/compile.rs +++ b/crates/uv/src/commands/pip/compile.rs @@ -11,7 +11,7 @@ use uv_cache::Cache; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ BuildOptions, Concurrency, ConfigSettings, Constraints, ExtrasSpecification, IndexStrategy, - LowerBound, NoBinary, NoBuild, Reinstall, SourceStrategy, TrustedHost, Upgrade, + LowerBound, NoBinary, NoBuild, PreviewMode, Reinstall, SourceStrategy, TrustedHost, Upgrade, }; use uv_configuration::{KeyringProviderType, TargetTriple}; use uv_dispatch::{BuildDispatch, SharedState}; @@ -96,6 +96,7 @@ pub(crate) async fn pip_compile( quiet: bool, cache: Cache, printer: Printer, + preview: PreviewMode, ) -> Result { // If the user requests `extras` but does not provide a valid source (e.g., a `pyproject.toml`), // return an error. @@ -354,6 +355,7 @@ pub(crate) async fn pip_compile( LowerBound::Warn, sources, concurrency, + preview, ); let options = OptionsBuilder::new() diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index f4ee781fd..e156bf81d 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -8,7 +8,7 @@ use uv_cache::Cache; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ BuildOptions, Concurrency, ConfigSettings, Constraints, ExtrasSpecification, HashCheckingMode, - IndexStrategy, LowerBound, Reinstall, SourceStrategy, TrustedHost, Upgrade, + IndexStrategy, LowerBound, PreviewMode, Reinstall, SourceStrategy, TrustedHost, Upgrade, }; use uv_configuration::{KeyringProviderType, TargetTriple}; use uv_dispatch::{BuildDispatch, SharedState}; @@ -85,6 +85,7 @@ pub(crate) async fn pip_install( cache: Cache, dry_run: bool, printer: Printer, + preview: PreviewMode, ) -> anyhow::Result { let start = std::time::Instant::now(); @@ -383,6 +384,7 @@ pub(crate) async fn pip_install( LowerBound::Warn, sources, concurrency, + preview, ); let options = OptionsBuilder::new() diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index 74b0389b0..21f932277 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -8,7 +8,7 @@ use uv_cache::Cache; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ BuildOptions, Concurrency, ConfigSettings, Constraints, ExtrasSpecification, HashCheckingMode, - IndexStrategy, LowerBound, Reinstall, SourceStrategy, TrustedHost, Upgrade, + IndexStrategy, LowerBound, PreviewMode, Reinstall, SourceStrategy, TrustedHost, Upgrade, }; use uv_configuration::{KeyringProviderType, TargetTriple}; use uv_dispatch::{BuildDispatch, SharedState}; @@ -74,6 +74,7 @@ pub(crate) async fn pip_sync( cache: Cache, dry_run: bool, printer: Printer, + preview: PreviewMode, ) -> Result { let client_builder = BaseClientBuilder::new() .connectivity(connectivity) @@ -326,6 +327,7 @@ pub(crate) async fn pip_sync( LowerBound::Warn, sources, concurrency, + preview, ); // Determine the set of installed packages. diff --git a/crates/uv/src/commands/project/add.rs b/crates/uv/src/commands/project/add.rs index 8143df356..c0bb80796 100644 --- a/crates/uv/src/commands/project/add.rs +++ b/crates/uv/src/commands/project/add.rs @@ -15,8 +15,8 @@ use uv_cache_key::RepositoryUrl; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ Concurrency, Constraints, DevGroupsManifest, DevGroupsSpecification, DevMode, EditableMode, - ExtrasSpecification, GroupsSpecification, InstallOptions, LowerBound, SourceStrategy, - TrustedHost, + ExtrasSpecification, GroupsSpecification, InstallOptions, LowerBound, PreviewMode, + SourceStrategy, TrustedHost, }; use uv_dispatch::{BuildDispatch, SharedState}; use uv_distribution::DistributionDatabase; @@ -85,6 +85,7 @@ pub(crate) async fn add( no_config: bool, cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { for source in &requirements { match source { @@ -340,6 +341,7 @@ pub(crate) async fn add( bounds, sources, concurrency, + preview, ); // Resolve any unnamed requirements. @@ -681,6 +683,7 @@ pub(crate) async fn add( allow_insecure_host, cache, printer, + preview, ) .await { @@ -724,6 +727,7 @@ async fn lock_and_sync( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result<(), ProjectError> { let mode = if locked { LockMode::Locked(environment.interpreter()) @@ -744,6 +748,7 @@ async fn lock_and_sync( allow_insecure_host, cache, printer, + preview, ) .await? .into_lock(); @@ -862,6 +867,7 @@ async fn lock_and_sync( allow_insecure_host, cache, printer, + preview, ) .await? .into_lock(); @@ -928,6 +934,7 @@ async fn lock_and_sync( allow_insecure_host, cache, printer, + preview, ) .await?; diff --git a/crates/uv/src/commands/project/environment.rs b/crates/uv/src/commands/project/environment.rs index 91f8f99b9..e4dd28ec2 100644 --- a/crates/uv/src/commands/project/environment.rs +++ b/crates/uv/src/commands/project/environment.rs @@ -9,7 +9,7 @@ use crate::settings::ResolverInstallerSettings; use uv_cache::{Cache, CacheBucket}; use uv_cache_key::{cache_digest, hash_digest}; use uv_client::Connectivity; -use uv_configuration::{Concurrency, TrustedHost}; +use uv_configuration::{Concurrency, PreviewMode, TrustedHost}; use uv_dispatch::SharedState; use uv_distribution_types::{Name, Resolution}; use uv_python::{Interpreter, PythonEnvironment}; @@ -41,6 +41,7 @@ impl CachedEnvironment { allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { // When caching, always use the base interpreter, rather than that of the virtual // environment. @@ -72,6 +73,7 @@ impl CachedEnvironment { allow_insecure_host, cache, printer, + preview, ) .await?, ); @@ -125,6 +127,7 @@ impl CachedEnvironment { allow_insecure_host, cache, printer, + preview, ) .await?; diff --git a/crates/uv/src/commands/project/export.rs b/crates/uv/src/commands/project/export.rs index 5f8ac0263..4368af06c 100644 --- a/crates/uv/src/commands/project/export.rs +++ b/crates/uv/src/commands/project/export.rs @@ -10,7 +10,7 @@ use uv_cache::Cache; use uv_client::Connectivity; use uv_configuration::{ Concurrency, DevGroupsSpecification, EditableMode, ExportFormat, ExtrasSpecification, - InstallOptions, LowerBound, TrustedHost, + InstallOptions, LowerBound, PreviewMode, TrustedHost, }; use uv_dispatch::SharedState; use uv_normalize::PackageName; @@ -58,6 +58,7 @@ pub(crate) async fn export( quiet: bool, cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { // Identify the project. let project = if frozen { @@ -145,6 +146,7 @@ pub(crate) async fn export( allow_insecure_host, cache, printer, + preview, ) .await { diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index a19446006..f7afd49b8 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -11,8 +11,8 @@ use tracing::debug; use uv_cache::Cache; use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ - Concurrency, Constraints, ExtrasSpecification, LowerBound, Reinstall, SourceStrategy, - TrustedHost, Upgrade, + Concurrency, Constraints, ExtrasSpecification, LowerBound, PreviewMode, Reinstall, + SourceStrategy, TrustedHost, Upgrade, }; use uv_dispatch::{BuildDispatch, SharedState}; use uv_distribution::DistributionDatabase; @@ -89,6 +89,7 @@ pub(crate) async fn lock( no_config: bool, cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> anyhow::Result { // Find the project requirements. let workspace = Workspace::discover(project_dir, &DiscoveryOptions::default()).await?; @@ -142,6 +143,7 @@ pub(crate) async fn lock( allow_insecure_host, cache, printer, + preview, ) .await { @@ -201,6 +203,7 @@ pub(super) async fn do_safe_lock( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { match mode { LockMode::Frozen => { @@ -231,6 +234,7 @@ pub(super) async fn do_safe_lock( allow_insecure_host, cache, printer, + preview, ) .await?; @@ -270,6 +274,7 @@ pub(super) async fn do_safe_lock( allow_insecure_host, cache, printer, + preview, ) .await?; @@ -300,6 +305,7 @@ async fn do_lock( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { let start = std::time::Instant::now(); @@ -502,6 +508,7 @@ async fn do_lock( bounds, sources, concurrency, + preview, ); let database = DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads); diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index dd5f2be77..99ef9e6aa 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -9,7 +9,7 @@ use uv_cache::Cache; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ Concurrency, Constraints, DevGroupsManifest, DevGroupsSpecification, ExtrasSpecification, - GroupsSpecification, LowerBound, Reinstall, TrustedHost, Upgrade, + GroupsSpecification, LowerBound, PreviewMode, Reinstall, TrustedHost, Upgrade, }; use uv_dispatch::{BuildDispatch, SharedState}; use uv_distribution::DistributionDatabase; @@ -896,6 +896,7 @@ pub(crate) async fn resolve_names( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result, uv_requirements::Error> { // Partition the requirements into named and unnamed requirements. let (mut requirements, unnamed): (Vec<_>, Vec<_>) = @@ -991,6 +992,7 @@ pub(crate) async fn resolve_names( LowerBound::Allow, *sources, concurrency, + preview, ); // Resolve the unnamed requirements. @@ -1045,6 +1047,7 @@ pub(crate) async fn resolve_environment<'a>( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { warn_on_requirements_txt_setting(&spec.requirements, settings); @@ -1172,6 +1175,7 @@ pub(crate) async fn resolve_environment<'a>( LowerBound::Allow, sources, concurrency, + preview, ); // Resolve the requirements. @@ -1218,6 +1222,7 @@ pub(crate) async fn sync_environment( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { let InstallerSettingsRef { index_locations, @@ -1305,6 +1310,7 @@ pub(crate) async fn sync_environment( LowerBound::Allow, sources, concurrency, + preview, ); // Sync the environment. @@ -1370,6 +1376,7 @@ pub(crate) async fn update_environment( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { warn_on_requirements_txt_setting(&spec, settings.as_ref().into()); @@ -1510,6 +1517,7 @@ pub(crate) async fn update_environment( LowerBound::Allow, *sources, concurrency, + preview, ); // Resolve the requirements. diff --git a/crates/uv/src/commands/project/remove.rs b/crates/uv/src/commands/project/remove.rs index ae1bf0e77..3aae268c7 100644 --- a/crates/uv/src/commands/project/remove.rs +++ b/crates/uv/src/commands/project/remove.rs @@ -8,7 +8,7 @@ use uv_cache::Cache; use uv_client::Connectivity; use uv_configuration::{ Concurrency, DevGroupsManifest, EditableMode, ExtrasSpecification, InstallOptions, LowerBound, - TrustedHost, + PreviewMode, TrustedHost, }; use uv_dispatch::SharedState; use uv_fs::Simplified; @@ -54,6 +54,7 @@ pub(crate) async fn remove( no_config: bool, cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { let target = if let Some(script) = script { // If we found a PEP 723 script and the user provided a project-only setting, warn. @@ -231,6 +232,7 @@ pub(crate) async fn remove( allow_insecure_host, cache, printer, + preview, ) .await { @@ -285,6 +287,7 @@ pub(crate) async fn remove( allow_insecure_host, cache, printer, + preview, ) .await { diff --git a/crates/uv/src/commands/project/run.rs b/crates/uv/src/commands/project/run.rs index 16028c13e..9ce55a3c7 100644 --- a/crates/uv/src/commands/project/run.rs +++ b/crates/uv/src/commands/project/run.rs @@ -18,7 +18,7 @@ use uv_cli::ExternalCommand; use uv_client::{BaseClientBuilder, Connectivity}; use uv_configuration::{ Concurrency, DevGroupsSpecification, EditableMode, ExtrasSpecification, GroupsSpecification, - InstallOptions, LowerBound, SourceStrategy, TrustedHost, + InstallOptions, LowerBound, PreviewMode, SourceStrategy, TrustedHost, }; use uv_dispatch::SharedState; use uv_distribution::LoweredRequirement; @@ -86,6 +86,7 @@ pub(crate) async fn run( printer: Printer, env_file: Vec, no_env_file: bool, + preview: PreviewMode, ) -> anyhow::Result { // These cases seem quite complex because (in theory) they should change the "current package". // Let's ban them entirely for now. @@ -341,6 +342,7 @@ pub(crate) async fn run( allow_insecure_host, cache, printer, + preview, ) .await; @@ -662,6 +664,7 @@ pub(crate) async fn run( allow_insecure_host, cache, printer, + preview, ) .await { @@ -742,6 +745,7 @@ pub(crate) async fn run( allow_insecure_host, cache, printer, + preview, ) .await { @@ -893,6 +897,7 @@ pub(crate) async fn run( allow_insecure_host, cache, printer, + preview, ) .await; diff --git a/crates/uv/src/commands/project/sync.rs b/crates/uv/src/commands/project/sync.rs index 6d9c3a71c..f1e385dc7 100644 --- a/crates/uv/src/commands/project/sync.rs +++ b/crates/uv/src/commands/project/sync.rs @@ -10,7 +10,7 @@ use uv_cache::Cache; use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ Concurrency, Constraints, DevGroupsManifest, DevGroupsSpecification, EditableMode, - ExtrasSpecification, HashCheckingMode, InstallOptions, LowerBound, TrustedHost, + ExtrasSpecification, HashCheckingMode, InstallOptions, LowerBound, PreviewMode, TrustedHost, }; use uv_dispatch::{BuildDispatch, SharedState}; use uv_distribution_types::{ @@ -67,6 +67,7 @@ pub(crate) async fn sync( no_config: bool, cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { // Identify the project. let project = if frozen { @@ -156,6 +157,7 @@ pub(crate) async fn sync( allow_insecure_host, cache, printer, + preview, ) .await { @@ -231,6 +233,7 @@ pub(crate) async fn sync( allow_insecure_host, cache, printer, + preview, ) .await { @@ -265,6 +268,7 @@ pub(super) async fn do_sync( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result<(), ProjectError> { // Use isolated state for universal resolution. When resolving, we don't enforce that the // prioritized distributions match the current platform. So if we lock here, then try to @@ -425,6 +429,7 @@ pub(super) async fn do_sync( bounds, sources, concurrency, + preview, ); let site_packages = SitePackages::from_environment(venv)?; diff --git a/crates/uv/src/commands/project/tree.rs b/crates/uv/src/commands/project/tree.rs index dfc674004..77bffa57a 100644 --- a/crates/uv/src/commands/project/tree.rs +++ b/crates/uv/src/commands/project/tree.rs @@ -8,7 +8,7 @@ use uv_cache::{Cache, Refresh}; use uv_cache_info::Timestamp; use uv_client::{Connectivity, RegistryClientBuilder}; use uv_configuration::{ - Concurrency, DevGroupsSpecification, LowerBound, TargetTriple, TrustedHost, + Concurrency, DevGroupsSpecification, LowerBound, PreviewMode, TargetTriple, TrustedHost, }; use uv_dispatch::SharedState; use uv_distribution_types::IndexCapabilities; @@ -58,6 +58,7 @@ pub(crate) async fn tree( no_config: bool, cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { // Find the project requirements. let workspace = Workspace::discover(project_dir, &DiscoveryOptions::default()).await?; @@ -121,6 +122,7 @@ pub(crate) async fn tree( allow_insecure_host, cache, printer, + preview, ) .await { diff --git a/crates/uv/src/commands/tool/install.rs b/crates/uv/src/commands/tool/install.rs index f51854fa7..f36d9a19b 100644 --- a/crates/uv/src/commands/tool/install.rs +++ b/crates/uv/src/commands/tool/install.rs @@ -8,7 +8,7 @@ use tracing::{debug, trace}; use uv_cache::{Cache, Refresh}; use uv_cache_info::Timestamp; use uv_client::{BaseClientBuilder, Connectivity}; -use uv_configuration::{Concurrency, Reinstall, TrustedHost, Upgrade}; +use uv_configuration::{Concurrency, PreviewMode, Reinstall, TrustedHost, Upgrade}; use uv_dispatch::SharedState; use uv_distribution_types::{NameRequirementSpecification, UnresolvedRequirementSpecification}; use uv_normalize::PackageName; @@ -61,6 +61,7 @@ pub(crate) async fn install( allow_insecure_host: &[TrustedHost], cache: Cache, printer: Printer, + preview: PreviewMode, ) -> Result { let client_builder = BaseClientBuilder::new() .connectivity(connectivity) @@ -128,6 +129,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await? .pop() @@ -202,6 +204,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await? .pop() @@ -266,6 +269,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await?, ); @@ -291,6 +295,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await?; @@ -422,6 +427,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await { @@ -456,6 +462,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await { @@ -490,6 +497,7 @@ pub(crate) async fn install( allow_insecure_host, &cache, printer, + preview, ) .await .inspect_err(|_| { diff --git a/crates/uv/src/commands/tool/run.rs b/crates/uv/src/commands/tool/run.rs index c3797bee9..8d97bc104 100644 --- a/crates/uv/src/commands/tool/run.rs +++ b/crates/uv/src/commands/tool/run.rs @@ -14,7 +14,7 @@ use uv_cache::{Cache, Refresh}; use uv_cache_info::Timestamp; use uv_cli::ExternalCommand; use uv_client::{BaseClientBuilder, Connectivity}; -use uv_configuration::{Concurrency, TrustedHost}; +use uv_configuration::{Concurrency, PreviewMode, TrustedHost}; use uv_dispatch::SharedState; use uv_distribution_types::{Name, UnresolvedRequirementSpecification}; use uv_installer::{SatisfiesResult, SitePackages}; @@ -84,6 +84,7 @@ pub(crate) async fn run( allow_insecure_host: &[TrustedHost], cache: Cache, printer: Printer, + preview: PreviewMode, ) -> anyhow::Result { let Some(command) = command else { // When a command isn't provided, we'll show a brief help including available tools @@ -128,6 +129,7 @@ pub(crate) async fn run( allow_insecure_host, &cache, printer, + preview, ) .await; @@ -446,6 +448,7 @@ async fn get_or_create_environment( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result<(Requirement, PythonEnvironment), ProjectError> { let client_builder = BaseClientBuilder::new() .connectivity(connectivity) @@ -529,6 +532,7 @@ async fn get_or_create_environment( allow_insecure_host, cache, printer, + preview, ) .await? .pop() @@ -560,6 +564,7 @@ async fn get_or_create_environment( allow_insecure_host, cache, printer, + preview, ) .await?, ); @@ -638,6 +643,7 @@ async fn get_or_create_environment( allow_insecure_host, cache, printer, + preview, ) .await?; diff --git a/crates/uv/src/commands/tool/upgrade.rs b/crates/uv/src/commands/tool/upgrade.rs index f35489864..088803976 100644 --- a/crates/uv/src/commands/tool/upgrade.rs +++ b/crates/uv/src/commands/tool/upgrade.rs @@ -7,7 +7,7 @@ use tracing::debug; use uv_cache::Cache; use uv_client::{BaseClientBuilder, Connectivity}; -use uv_configuration::{Concurrency, TrustedHost}; +use uv_configuration::{Concurrency, PreviewMode, TrustedHost}; use uv_dispatch::SharedState; use uv_fs::CWD; use uv_normalize::PackageName; @@ -48,6 +48,7 @@ pub(crate) async fn upgrade( allow_insecure_host: &[TrustedHost], cache: &Cache, printer: Printer, + preview: PreviewMode, ) -> Result { let installed_tools = InstalledTools::from_settings()?.init()?; let _lock = installed_tools.lock().await?; @@ -129,6 +130,7 @@ pub(crate) async fn upgrade( concurrency, native_tls, allow_insecure_host, + preview, ) .await; @@ -219,6 +221,7 @@ async fn upgrade_tool( concurrency: Concurrency, native_tls: bool, allow_insecure_host: &[TrustedHost], + preview: PreviewMode, ) -> Result { // Ensure the tool is installed. let existing_tool_receipt = match installed_tools.get_tool_receipt(name) { @@ -301,6 +304,7 @@ async fn upgrade_tool( allow_insecure_host, cache, printer, + preview, ) .await?; @@ -319,6 +323,7 @@ async fn upgrade_tool( allow_insecure_host, cache, printer, + preview, ) .await?; @@ -344,6 +349,7 @@ async fn upgrade_tool( allow_insecure_host, cache, printer, + preview, ) .await?; diff --git a/crates/uv/src/commands/venv.rs b/crates/uv/src/commands/venv.rs index c38de43ea..f9f6b1698 100644 --- a/crates/uv/src/commands/venv.rs +++ b/crates/uv/src/commands/venv.rs @@ -13,7 +13,7 @@ use uv_cache::Cache; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{ BuildOptions, Concurrency, ConfigSettings, Constraints, IndexStrategy, KeyringProviderType, - LowerBound, NoBinary, NoBuild, SourceStrategy, TrustedHost, + LowerBound, NoBinary, NoBuild, PreviewMode, SourceStrategy, TrustedHost, }; use uv_dispatch::{BuildDispatch, SharedState}; use uv_distribution_types::{DependencyMetadata, Index, IndexLocations}; @@ -65,6 +65,7 @@ pub(crate) async fn venv( cache: &Cache, printer: Printer, relocatable: bool, + preview: PreviewMode, ) -> Result { match venv_impl( project_dir, @@ -92,6 +93,7 @@ pub(crate) async fn venv( cache, printer, relocatable, + preview, ) .await { @@ -150,6 +152,7 @@ async fn venv_impl( cache: &Cache, printer: Printer, relocatable: bool, + preview: PreviewMode, ) -> miette::Result { let project = if no_project { None @@ -333,6 +336,7 @@ async fn venv_impl( LowerBound::Allow, sources, concurrency, + preview, ); // Resolve the seed packages. diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 20216bc18..ff7f60465 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -374,6 +374,7 @@ async fn run(mut cli: Cli) -> Result { globals.quiet, cache, printer, + globals.preview, ) .await } @@ -445,6 +446,7 @@ async fn run(mut cli: Cli) -> Result { cache, args.dry_run, printer, + globals.preview, ) .await } @@ -535,6 +537,7 @@ async fn run(mut cli: Cli) -> Result { cache, args.dry_run, printer, + globals.preview, ) .await } @@ -807,6 +810,7 @@ async fn run(mut cli: Cli) -> Result { &cache, printer, args.relocatable, + globals.preview, ) .await } @@ -927,6 +931,7 @@ async fn run(mut cli: Cli) -> Result { &globals.allow_insecure_host, cache, printer, + globals.preview, ) .await } @@ -991,6 +996,7 @@ async fn run(mut cli: Cli) -> Result { &globals.allow_insecure_host, cache, printer, + globals.preview, )) .await } @@ -1037,6 +1043,7 @@ async fn run(mut cli: Cli) -> Result { &globals.allow_insecure_host, &cache, printer, + globals.preview, )) .await } @@ -1375,6 +1382,7 @@ async fn run_project( printer, args.env_file, args.no_env_file, + globals.preview, )) .await } @@ -1414,6 +1422,7 @@ async fn run_project( no_config, &cache, printer, + globals.preview, ) .await } @@ -1445,6 +1454,7 @@ async fn run_project( no_config, &cache, printer, + globals.preview, ) .await } @@ -1500,6 +1510,7 @@ async fn run_project( no_config, &cache, printer, + globals.preview, )) .await } @@ -1544,6 +1555,7 @@ async fn run_project( no_config, &cache, printer, + globals.preview, )) .await } @@ -1581,6 +1593,7 @@ async fn run_project( no_config, &cache, printer, + globals.preview, ) .await } @@ -1620,6 +1633,7 @@ async fn run_project( globals.quiet, &cache, printer, + globals.preview, ) .await }