diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index cd8355a10..428b2aa9a 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -26,7 +26,7 @@ use uv_normalize::PackageName; use uv_requirements::{RequirementsSource, RequirementsSpecification}; use uv_resolver::{ DependencyMode, ExcludeNewer, FlatIndex, InMemoryIndex, Lock, OptionsBuilder, PreReleaseMode, - ResolutionMode, + Preference, ResolutionMode, }; use uv_types::{BuildIsolation, HashStrategy, InFlight}; @@ -255,6 +255,12 @@ pub(crate) async fn pip_install( HashStrategy::None }; + // When resolving, prefer current site packages. + let preferences = site_packages + .iter() + .map(Preference::from_installed) + .collect::>(); + // Incorporate any index locations from the provided sources. let index_locations = index_locations.combine(index_url, extra_index_urls, find_links, no_index); @@ -340,6 +346,7 @@ pub(crate) async fn pip_install( source_trees, project, extras, + preferences, site_packages.clone(), &hasher, &reinstall, diff --git a/crates/uv/src/commands/pip/operations.rs b/crates/uv/src/commands/pip/operations.rs index a655dcb40..743d46b8a 100644 --- a/crates/uv/src/commands/pip/operations.rs +++ b/crates/uv/src/commands/pip/operations.rs @@ -110,6 +110,7 @@ pub(crate) async fn resolve( source_trees: Vec, project: Option, extras: &ExtrasSpecification, + preferences: Vec, installed_packages: InstalledPackages, hasher: &HashStrategy, reinstall: &Reinstall, @@ -196,11 +197,10 @@ pub(crate) async fn resolve( // TODO(zanieb): Consider consuming these instead of cloning let exclusions = Exclusions::new(reinstall.clone(), upgrade.clone()); - // Prefer current site packages; filter out packages that are marked for reinstall or upgrade. - let preferences = installed_packages - .iter() + // Filter out any excluded distributions from the preferences. + let preferences = preferences + .into_iter() .filter(|dist| !exclusions.contains(dist.name())) - .map(Preference::from_installed) .collect::>(); // Create a manifest of the requirements. diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index 88584e9f2..711351a9f 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -24,7 +24,7 @@ use uv_interpreter::{PythonEnvironment, PythonVersion, SystemPython, Target}; use uv_requirements::{RequirementsSource, RequirementsSpecification}; use uv_resolver::{ DependencyMode, ExcludeNewer, FlatIndex, InMemoryIndex, OptionsBuilder, PreReleaseMode, - ResolutionMode, + Preference, ResolutionMode, }; use uv_types::{BuildIsolation, HashStrategy, InFlight}; @@ -275,6 +275,12 @@ pub(crate) async fn pip_sync( // Determine the set of installed packages. let site_packages = SitePackages::from_executable(&venv)?; + // When resolving, prefer current site packages. + let preferences = site_packages + .iter() + .map(Preference::from_installed) + .collect::>(); + let options = OptionsBuilder::new() .resolution_mode(resolution_mode) .prerelease_mode(prerelease_mode) @@ -290,6 +296,7 @@ pub(crate) async fn pip_sync( source_trees, project, &extras, + preferences, site_packages.clone(), &hasher, reinstall, diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index 8c5f36fe8..b536db4e2 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -96,6 +96,7 @@ pub(super) async fn do_lock( let link_mode = LinkMode::default(); let no_binary = NoBinary::default(); let no_build = NoBuild::default(); + let preferences = Vec::default(); let reinstall = Reinstall::default(); let setup_py = SetupPyStrategy::default(); let upgrade = Upgrade::default(); @@ -129,6 +130,7 @@ pub(super) async fn do_lock( source_trees, Some(project_name), &extras, + preferences, EmptyInstalledPackages, &hasher, &reinstall, diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index 08c68ae58..3e3b71847 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -169,7 +169,11 @@ pub(crate) async fn update_environment( // TODO(charlie): Respect project configuration. let build_isolation = BuildIsolation::default(); + let compile = false; + let concurrency = Concurrency::default(); let config_settings = ConfigSettings::default(); + let dry_run = false; + let extras = ExtrasSpecification::default(); let flat_index = FlatIndex::default(); let hasher = HashStrategy::default(); let in_flight = InFlight::default(); @@ -178,14 +182,11 @@ pub(crate) async fn update_environment( let link_mode = LinkMode::default(); let no_binary = NoBinary::default(); let no_build = NoBuild::default(); - let setup_py = SetupPyStrategy::default(); - let concurrency = Concurrency::default(); - let reinstall = Reinstall::default(); - let compile = false; - let dry_run = false; - let extras = ExtrasSpecification::default(); - let upgrade = Upgrade::default(); let options = Options::default(); + let preferences = Vec::default(); + let reinstall = Reinstall::default(); + let setup_py = SetupPyStrategy::default(); + let upgrade = Upgrade::default(); // Create a build dispatch. let resolve_dispatch = BuildDispatch::new( @@ -213,6 +214,7 @@ pub(crate) async fn update_environment( spec.source_trees, spec.project, &extras, + preferences, site_packages.clone(), &hasher, &reinstall,