Respect index strategy in source distribution builds (#4468)

## Summary

The `--index-strategy` is linked to the index locations, which we
propagate to source distribution builds; so it makes sense to pass the
`--index-strategy` too.

While I was here, I made `exclude_newer` a required argument so that we
don't forget to set it via the `with_options` builder.

Closes https://github.com/astral-sh/uv/issues/4465.
This commit is contained in:
Charlie Marsh 2024-06-24 15:03:38 +03:00 committed by GitHub
parent 1eee427c94
commit cba270f750
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 130 additions and 123 deletions

View file

@ -82,7 +82,7 @@ mod resolver {
use uv_cache::Cache;
use uv_client::RegistryClient;
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, PreviewMode, SetupPyStrategy,
BuildOptions, Concurrency, ConfigSettings, IndexStrategy, PreviewMode, SetupPyStrategy,
};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
@ -128,8 +128,17 @@ mod resolver {
venv: &PythonEnvironment,
) -> Result<ResolutionGraph> {
let build_isolation = BuildIsolation::Isolated;
let build_options = BuildOptions::default();
let concurrency = Concurrency::default();
let config_settings = ConfigSettings::default();
let exclude_newer = Some(
NaiveDate::from_ymd_opt(2024, 6, 20)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap()
.and_utc()
.into(),
);
let flat_index = FlatIndex::default();
let git = GitResolver::default();
let hashes = HashStrategy::None;
@ -139,7 +148,8 @@ mod resolver {
let installed_packages = EmptyInstalledPackages;
let interpreter = venv.interpreter();
let python_requirement = PythonRequirement::from_interpreter(interpreter);
let build_options = BuildOptions::default();
let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
let build_context = BuildDispatch::new(
client,
@ -150,26 +160,17 @@ mod resolver {
&index,
&git,
&in_flight,
IndexStrategy::default(),
SetupPyStrategy::default(),
&config_settings,
build_isolation,
LinkMode::default(),
&build_options,
exclude_newer,
concurrency,
PreviewMode::Disabled,
);
let options = OptionsBuilder::new()
.exclude_newer(Some(
NaiveDate::from_ymd_opt(2024, 6, 20)
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap()
.and_utc()
.into(),
))
.build();
let resolver = Resolver::new(
manifest,
options,

View file

@ -11,7 +11,8 @@ use uv_build::{SourceBuild, SourceBuildContext};
use uv_cache::{Cache, CacheArgs};
use uv_client::RegistryClientBuilder;
use uv_configuration::{
BuildKind, BuildOptions, Concurrency, ConfigSettings, PreviewMode, SetupPyStrategy,
BuildKind, BuildOptions, Concurrency, ConfigSettings, IndexStrategy, PreviewMode,
SetupPyStrategy,
};
use uv_dispatch::BuildDispatch;
use uv_git::GitResolver;
@ -59,11 +60,13 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
let client = RegistryClientBuilder::new(cache.clone()).build();
let concurrency = Concurrency::default();
let config_settings = ConfigSettings::default();
let exclude_newer = None;
let flat_index = FlatIndex::default();
let git = GitResolver::default();
let in_flight = InFlight::default();
let index = InMemoryIndex::default();
let index_urls = IndexLocations::default();
let index_strategy = IndexStrategy::default();
let setup_py = SetupPyStrategy::default();
let toolchain = PythonEnvironment::find(
&ToolchainRequest::default(),
@ -81,11 +84,13 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
&index,
&git,
&in_flight,
index_strategy,
setup_py,
&config_settings,
BuildIsolation::Isolated,
install_wheel_rs::linker::LinkMode::default(),
&build_options,
exclude_newer,
concurrency,
PreviewMode::Enabled,
);

View file

@ -16,12 +16,16 @@ use pypi_types::Requirement;
use uv_build::{SourceBuild, SourceBuildContext};
use uv_cache::Cache;
use uv_client::RegistryClient;
use uv_configuration::{BuildKind, BuildOptions, ConfigSettings, Reinstall, SetupPyStrategy};
use uv_configuration::{
BuildKind, BuildOptions, ConfigSettings, IndexStrategy, Reinstall, SetupPyStrategy,
};
use uv_configuration::{Concurrency, PreviewMode};
use uv_distribution::DistributionDatabase;
use uv_git::GitResolver;
use uv_installer::{Installer, Plan, Planner, Preparer, SitePackages};
use uv_resolver::{FlatIndex, InMemoryIndex, Manifest, Options, PythonRequirement, Resolver};
use uv_resolver::{
ExcludeNewer, FlatIndex, InMemoryIndex, Manifest, OptionsBuilder, PythonRequirement, Resolver,
};
use uv_toolchain::{Interpreter, PythonEnvironment};
use uv_types::{BuildContext, BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
@ -32,6 +36,7 @@ pub struct BuildDispatch<'a> {
cache: &'a Cache,
interpreter: &'a Interpreter,
index_locations: &'a IndexLocations,
index_strategy: IndexStrategy,
flat_index: &'a FlatIndex,
index: &'a InMemoryIndex,
git: &'a GitResolver,
@ -41,8 +46,8 @@ pub struct BuildDispatch<'a> {
link_mode: install_wheel_rs::linker::LinkMode,
build_options: &'a BuildOptions,
config_settings: &'a ConfigSettings,
exclude_newer: Option<ExcludeNewer>,
source_build_context: SourceBuildContext,
options: Options,
build_extra_env_vars: FxHashMap<OsString, OsString>,
concurrency: Concurrency,
preview_mode: PreviewMode,
@ -59,11 +64,13 @@ impl<'a> BuildDispatch<'a> {
index: &'a InMemoryIndex,
git: &'a GitResolver,
in_flight: &'a InFlight,
index_strategy: IndexStrategy,
setup_py: SetupPyStrategy,
config_settings: &'a ConfigSettings,
build_isolation: BuildIsolation<'a>,
link_mode: install_wheel_rs::linker::LinkMode,
build_options: &'a BuildOptions,
exclude_newer: Option<ExcludeNewer>,
concurrency: Concurrency,
preview_mode: PreviewMode,
) -> Self {
@ -76,25 +83,20 @@ impl<'a> BuildDispatch<'a> {
index,
git,
in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,
build_options,
exclude_newer,
concurrency,
source_build_context: SourceBuildContext::default(),
options: Options::default(),
build_extra_env_vars: FxHashMap::default(),
preview_mode,
}
}
#[must_use]
pub fn with_options(mut self, options: Options) -> Self {
self.options = options;
self
}
/// Set the environment variables to be used when building a source distribution.
#[must_use]
pub fn with_build_extra_env_vars<I, K, V>(mut self, sdist_build_env_variables: I) -> Self
@ -126,10 +128,6 @@ impl<'a> BuildContext for BuildDispatch<'a> {
self.interpreter
}
fn build_isolation(&self) -> BuildIsolation {
self.build_isolation
}
fn build_options(&self) -> &BuildOptions {
self.build_options
}
@ -138,17 +136,16 @@ impl<'a> BuildContext for BuildDispatch<'a> {
self.index_locations
}
fn setup_py_strategy(&self) -> SetupPyStrategy {
self.setup_py
}
async fn resolve<'data>(&'data self, requirements: &'data [Requirement]) -> Result<Resolution> {
let python_requirement = PythonRequirement::from_interpreter(self.interpreter);
let markers = self.interpreter.markers();
let tags = self.interpreter.tags()?;
let resolver = Resolver::new(
Manifest::simple(requirements.to_vec()),
self.options,
OptionsBuilder::new()
.exclude_newer(self.exclude_newer)
.index_strategy(self.index_strategy)
.build(),
&python_requirement,
Some(markers),
Some(tags),

View file

@ -7,12 +7,10 @@ use distribution_types::{CachedDist, IndexLocations, InstalledDist, Resolution,
use pep508_rs::PackageName;
use pypi_types::Requirement;
use uv_cache::Cache;
use uv_configuration::{BuildKind, BuildOptions, SetupPyStrategy};
use uv_configuration::{BuildKind, BuildOptions};
use uv_git::GitResolver;
use uv_toolchain::{Interpreter, PythonEnvironment};
use crate::BuildIsolation;
/// Avoids cyclic crate dependencies between resolver, installer and builder.
///
/// To resolve the dependencies of a packages, we may need to build one or more source
@ -63,9 +61,6 @@ pub trait BuildContext {
/// it's metadata (e.g. wheel compatibility tags).
fn interpreter(&self) -> &Interpreter;
/// Whether to enforce build isolation when building source distributions.
fn build_isolation(&self) -> BuildIsolation;
/// Whether source distribution building or pre-built wheels is disabled.
///
/// This [`BuildContext::setup_build`] calls will fail if builds are disabled.
@ -75,9 +70,6 @@ pub trait BuildContext {
/// The index locations being searched.
fn index_locations(&self) -> &IndexLocations;
/// The strategy to use when building source distributions that lack a `pyproject.toml`.
fn setup_py_strategy(&self) -> SetupPyStrategy;
/// Resolve the given requirements into a ready-to-install set of package versions.
fn resolve<'a>(
&'a self,
@ -92,7 +84,7 @@ pub trait BuildContext {
venv: &'a PythonEnvironment,
) -> impl Future<Output = Result<Vec<CachedDist>>> + 'a;
/// Setup a source distribution build by installing the required dependencies. A wrapper for
/// Set up a source distribution build by installing the required dependencies. A wrapper for
/// `uv_build::SourceBuild::setup`.
///
/// For PEP 517 builds, this calls `get_requires_for_build_wheel`.
@ -141,7 +133,7 @@ pub trait InstalledPackagesProvider: Clone + Send + Sync + 'static {
pub struct EmptyInstalledPackages;
impl InstalledPackagesProvider for EmptyInstalledPackages {
fn get_packages(&self, _name: &pep508_rs::PackageName) -> Vec<&InstalledDist> {
fn get_packages(&self, _name: &PackageName) -> Vec<&InstalledDist> {
Vec::new()
}

View file

@ -281,15 +281,16 @@ pub(crate) async fn pip_compile(
&source_index,
&git,
&in_flight,
index_strategy,
setup_py,
&config_settings,
build_isolation,
link_mode,
&build_options,
exclude_newer,
concurrency,
preview,
)
.with_options(OptionsBuilder::new().exclude_newer(exclude_newer).build());
);
// Resolve the requirements from the provided sources.
let requirements = {

View file

@ -294,15 +294,16 @@ pub(crate) async fn pip_install(
&index,
&git,
&in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,
&build_options,
exclude_newer,
concurrency,
preview,
)
.with_options(OptionsBuilder::new().exclude_newer(exclude_newer).build());
);
let options = OptionsBuilder::new()
.resolution_mode(resolution_mode)
@ -368,15 +369,16 @@ pub(crate) async fn pip_install(
&index,
&git,
&in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,
&build_options,
exclude_newer,
concurrency,
preview,
)
.with_options(OptionsBuilder::new().exclude_newer(exclude_newer).build())
};
// Sync the environment.

View file

@ -244,15 +244,16 @@ pub(crate) async fn pip_sync(
&index,
&git,
&in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,
&build_options,
exclude_newer,
concurrency,
preview,
)
.with_options(OptionsBuilder::new().exclude_newer(exclude_newer).build());
);
// Determine the set of installed packages.
let site_packages = SitePackages::from_executable(&environment)?;
@ -320,15 +321,16 @@ pub(crate) async fn pip_sync(
&index,
&git,
&in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,
&build_options,
exclude_newer,
concurrency,
preview,
)
.with_options(OptionsBuilder::new().exclude_newer(exclude_newer).build())
};
// Sync the environment.

View file

@ -5,7 +5,7 @@ use uv_distribution::pyproject::{Source, SourceError};
use uv_distribution::pyproject_mut::PyProjectTomlMut;
use uv_git::GitResolver;
use uv_requirements::{NamedRequirementsResolver, RequirementsSource, RequirementsSpecification};
use uv_resolver::{FlatIndex, InMemoryIndex, OptionsBuilder};
use uv_resolver::{FlatIndex, InMemoryIndex};
use uv_toolchain::{ToolchainPreference, ToolchainRequest};
use uv_types::{BuildIsolation, HashStrategy, InFlight};
@ -115,18 +115,15 @@ pub(crate) async fn add(
&index,
&git,
&in_flight,
settings.index_strategy,
setup_py,
&settings.config_setting,
build_isolation,
settings.link_mode,
&settings.build_options,
settings.exclude_newer,
concurrency,
preview,
)
.with_options(
OptionsBuilder::new()
.exclude_newer(settings.exclude_newer)
.build(),
);
// Resolve any unnamed requirements.
@ -191,13 +188,13 @@ pub(crate) async fn add(
venv.interpreter(),
&settings.upgrade,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
&settings.resolution,
&settings.prerelease,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer.as_ref(),
&settings.link_mode,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview,
connectivity,
@ -223,11 +220,11 @@ pub(crate) async fn add(
Modifications::Sufficient,
&settings.reinstall,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
&settings.link_mode,
&settings.compile_bytecode,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview,
connectivity,

View file

@ -65,13 +65,13 @@ pub(crate) async fn lock(
&interpreter,
&settings.upgrade,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
&settings.resolution,
&settings.prerelease,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer.as_ref(),
&settings.link_mode,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview,
connectivity,
@ -102,13 +102,13 @@ pub(super) async fn do_lock(
interpreter: &Interpreter,
upgrade: &Upgrade,
index_locations: &IndexLocations,
index_strategy: &IndexStrategy,
keyring_provider: &KeyringProviderType,
resolution: &ResolutionMode,
prerelease: &PreReleaseMode,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
resolution: ResolutionMode,
prerelease: PreReleaseMode,
config_setting: &ConfigSettings,
exclude_newer: Option<&ExcludeNewer>,
link_mode: &LinkMode,
exclude_newer: Option<ExcludeNewer>,
link_mode: LinkMode,
build_options: &BuildOptions,
preview: PreviewMode,
connectivity: Connectivity,
@ -152,17 +152,17 @@ pub(super) async fn do_lock(
.native_tls(native_tls)
.connectivity(connectivity)
.index_urls(index_locations.index_urls())
.index_strategy(*index_strategy)
.keyring(*keyring_provider)
.index_strategy(index_strategy)
.keyring(keyring_provider)
.markers(interpreter.markers())
.platform(interpreter.platform())
.build();
let options = OptionsBuilder::new()
.resolution_mode(*resolution)
.prerelease_mode(*prerelease)
.exclude_newer(exclude_newer.copied())
.index_strategy(*index_strategy)
.resolution_mode(resolution)
.prerelease_mode(prerelease)
.exclude_newer(exclude_newer)
.index_strategy(index_strategy)
.build();
let hasher = HashStrategy::Generate;
@ -199,11 +199,13 @@ pub(super) async fn do_lock(
&index,
&git,
&in_flight,
index_strategy,
setup_py,
config_setting,
build_isolation,
*link_mode,
link_mode,
build_options,
exclude_newer,
concurrency,
preview,
);

View file

@ -396,11 +396,13 @@ pub(crate) async fn update_environment(
&index,
&git,
&in_flight,
*index_strategy,
setup_py,
config_setting,
build_isolation,
*link_mode,
build_options,
*exclude_newer,
concurrency,
preview,
);
@ -455,11 +457,13 @@ pub(crate) async fn update_environment(
&index,
&git,
&in_flight,
*index_strategy,
setup_py,
config_setting,
build_isolation,
*link_mode,
build_options,
*exclude_newer,
concurrency,
preview,
)

View file

@ -103,13 +103,13 @@ pub(crate) async fn remove(
venv.interpreter(),
&settings.upgrade,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
&settings.resolution,
&settings.prerelease,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer.as_ref(),
&settings.link_mode,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview,
connectivity,
@ -136,11 +136,11 @@ pub(crate) async fn remove(
Modifications::Exact,
&settings.reinstall,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
&settings.link_mode,
&settings.compile_bytecode,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview,
connectivity,

View file

@ -80,13 +80,13 @@ pub(crate) async fn run(
venv.interpreter(),
&settings.upgrade,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
&settings.resolution,
&settings.prerelease,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer.as_ref(),
&settings.link_mode,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview,
connectivity,
@ -106,11 +106,11 @@ pub(crate) async fn run(
Modifications::Sufficient,
&settings.reinstall,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
&settings.link_mode,
&settings.compile_bytecode,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview,
connectivity,

View file

@ -79,11 +79,11 @@ pub(crate) async fn sync(
modifications,
&settings.reinstall,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
&settings.link_mode,
&settings.compile_bytecode,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview,
connectivity,
@ -109,11 +109,11 @@ pub(super) async fn do_sync(
modifications: Modifications,
reinstall: &Reinstall,
index_locations: &IndexLocations,
index_strategy: &IndexStrategy,
keyring_provider: &KeyringProviderType,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
config_setting: &ConfigSettings,
link_mode: &LinkMode,
compile_bytecode: &bool,
link_mode: LinkMode,
compile_bytecode: bool,
build_options: &BuildOptions,
preview: PreviewMode,
connectivity: Connectivity,
@ -151,8 +151,8 @@ pub(super) async fn do_sync(
.native_tls(native_tls)
.connectivity(connectivity)
.index_urls(index_locations.index_urls())
.index_strategy(*index_strategy)
.keyring(*keyring_provider)
.index_strategy(index_strategy)
.keyring(keyring_provider)
.markers(markers)
.platform(venv.interpreter().platform())
.build();
@ -166,6 +166,7 @@ pub(super) async fn do_sync(
// optional on the downstream APIs.
let build_isolation = BuildIsolation::default();
let dry_run = false;
let exclude_newer = None;
let hasher = HashStrategy::default();
let setup_py = SetupPyStrategy::default();
@ -186,11 +187,13 @@ pub(super) async fn do_sync(
&index,
&git,
&in_flight,
index_strategy,
setup_py,
config_setting,
build_isolation,
*link_mode,
link_mode,
build_options,
exclude_newer,
concurrency,
preview,
);
@ -204,8 +207,8 @@ pub(super) async fn do_sync(
modifications,
reinstall,
build_options,
*link_mode,
*compile_bytecode,
link_mode,
compile_bytecode,
index_locations,
&hasher,
tags,

View file

@ -22,7 +22,7 @@ use uv_configuration::{
use uv_dispatch::BuildDispatch;
use uv_fs::Simplified;
use uv_git::GitResolver;
use uv_resolver::{ExcludeNewer, FlatIndex, InMemoryIndex, OptionsBuilder};
use uv_resolver::{ExcludeNewer, FlatIndex, InMemoryIndex};
use uv_toolchain::{
request_from_version_file, EnvironmentPreference, Toolchain, ToolchainPreference,
ToolchainRequest,
@ -234,15 +234,16 @@ async fn venv_impl(
&index,
&git,
&in_flight,
index_strategy,
SetupPyStrategy::default(),
&config_settings,
BuildIsolation::Isolated,
link_mode,
&build_options,
exclude_newer,
concurrency,
preview,
)
.with_options(OptionsBuilder::new().exclude_newer(exclude_newer).build());
);
// Resolve the seed packages.
let requirements = if interpreter.python_tuple() < (3, 12) {