Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support build constraints #5639

Merged
merged 7 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/bench/benches/uv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,12 @@ mod resolver {
let python_requirement = PythonRequirement::from_interpreter(interpreter);

let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
let build_constraints = [];

let build_context = BuildDispatch::new(
client,
&cache,
&build_constraints,
interpreter,
&index_locations,
&flat_index,
Expand Down
24 changes: 24 additions & 0 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,14 @@ pub struct PipCompileArgs {
#[arg(long, env = "UV_OVERRIDE", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub r#override: Vec<Maybe<PathBuf>>,

/// Constrain build requirement versions using the given requirements files.
///
/// Constraints files are `requirements.txt`-like files that only control the _version_ of a
/// requirement that's installed. However, including a package in a constraints file will _not_
/// trigger the installation of that package.
#[arg(long, short, env = "UV_BUILD_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub build_constraint: Vec<Maybe<PathBuf>>,

/// Include optional dependencies from the extra group name; may be provided more than once.
///
/// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
Expand Down Expand Up @@ -817,6 +825,14 @@ pub struct PipSyncArgs {
#[arg(long, short, env = "UV_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub constraint: Vec<Maybe<PathBuf>>,

/// Constrain build requirement versions using the given requirements files.
///
/// Constraints files are `requirements.txt`-like files that only control the _version_ of a
/// requirement that's installed. However, including a package in a constraints file will _not_
/// trigger the installation of that package.
#[arg(long, short, env = "UV_BUILD_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub build_constraint: Vec<Maybe<PathBuf>>,

#[command(flatten)]
pub installer: InstallerArgs,

Expand Down Expand Up @@ -1084,6 +1100,14 @@ pub struct PipInstallArgs {
#[arg(long, env = "UV_OVERRIDE", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub r#override: Vec<Maybe<PathBuf>>,

/// Constrain build requirement versions using the given requirements files.
///
/// Constraints files are `requirements.txt`-like files that only control the _version_ of a
/// requirement that's installed. However, including a package in a constraints file will _not_
/// trigger the installation of that package.
#[arg(long, short, env = "UV_BUILD_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub build_constraint: Vec<Maybe<PathBuf>>,

/// Include optional dependencies from the extra group name; may be provided more than once.
///
/// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
Expand Down
4 changes: 4 additions & 0 deletions crates/uv-dev/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,13 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
)?;
let build_options = BuildOptions::default();

// TODO: support build constraints
let build_constraints = [];

let build_dispatch = BuildDispatch::new(
&client,
&cache,
&build_constraints,
python.interpreter(),
&index_urls,
&flat_index,
Expand Down
23 changes: 19 additions & 4 deletions crates/uv-dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ use uv_build::{SourceBuild, SourceBuildContext};
use uv_cache::Cache;
use uv_client::RegistryClient;
use uv_configuration::{
BuildKind, BuildOptions, ConfigSettings, IndexStrategy, Reinstall, SetupPyStrategy,
BuildKind, BuildOptions, ConfigSettings, Constraints, IndexStrategy, Overrides, 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_python::{Interpreter, PythonEnvironment};
use uv_resolver::{
ExcludeNewer, FlatIndex, InMemoryIndex, Manifest, OptionsBuilder, PythonRequirement, Resolver,
ResolverMarkers,
ExcludeNewer, Exclusions, FlatIndex, InMemoryIndex, Manifest, OptionsBuilder, Preferences,
PythonRequirement, Resolver, ResolverMarkers,
};
use uv_types::{BuildContext, BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};

Expand All @@ -35,6 +36,7 @@ use uv_types::{BuildContext, BuildIsolation, EmptyInstalledPackages, HashStrateg
pub struct BuildDispatch<'a> {
client: &'a RegistryClient,
cache: &'a Cache,
constraints: Constraints,
interpreter: &'a Interpreter,
index_locations: &'a IndexLocations,
index_strategy: IndexStrategy,
Expand All @@ -58,6 +60,7 @@ impl<'a> BuildDispatch<'a> {
pub fn new(
client: &'a RegistryClient,
cache: &'a Cache,
constraints: &'a [Requirement],
interpreter: &'a Interpreter,
index_locations: &'a IndexLocations,
flat_index: &'a FlatIndex,
Expand All @@ -77,6 +80,7 @@ impl<'a> BuildDispatch<'a> {
Self {
client,
cache,
constraints: Constraints::from_requirements(constraints.iter().cloned()),
interpreter,
index_locations,
flat_index,
Expand Down Expand Up @@ -140,8 +144,19 @@ impl<'a> BuildContext for BuildDispatch<'a> {
let python_requirement = PythonRequirement::from_interpreter(self.interpreter);
let markers = self.interpreter.markers();
let tags = self.interpreter.tags()?;
let manifest = Manifest::new(
requirements.to_vec(),
self.constraints.clone(),
Overrides::default(),
Vec::new(),
Preferences::default(),
None,
Exclusions::default(),
Vec::new(),
);

let resolver = Resolver::new(
Manifest::simple(requirements.to_vec()),
manifest,
OptionsBuilder::new()
.exclude_newer(self.exclude_newer)
.index_strategy(self.index_strategy)
Expand Down
16 changes: 16 additions & 0 deletions crates/uv/src/commands/pip/compile.rs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does uv pip compile now include build dependencies in its output? Or do --build-constraints files have to be generated separately (how?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe this PR adds any way to lock the build resolution, only to constrain it, but we want to add that to uv.lock eventually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related issue #5190

Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub(crate) async fn pip_compile(
requirements: &[RequirementsSource],
constraints: &[RequirementsSource],
overrides: &[RequirementsSource],
build_constraints: &[RequirementsSource],
constraints_from_workspace: Vec<Requirement>,
overrides_from_workspace: Vec<Requirement>,
extras: ExtrasSpecification,
Expand Down Expand Up @@ -143,6 +144,20 @@ pub(crate) async fn pip_compile(
)
.collect();

// Read build constraints and overrides
let RequirementsSpecification {
constraints: build_constraints,
overrides: _build_overrides,
..
} = operations::read_requirements(
&[],
build_constraints,
&[],
&ExtrasSpecification::None,
&client_builder,
)
.await?;

// If all the metadata could be statically resolved, validate that every extra was used. If we
// need to resolve metadata via PEP 517, we don't know which extras are used until much later.
if source_trees.is_empty() {
Expand Down Expand Up @@ -304,6 +319,7 @@ pub(crate) async fn pip_compile(
let build_dispatch = BuildDispatch::new(
&client,
&cache,
&build_constraints,
&interpreter,
&index_locations,
&flat_index,
Expand Down
16 changes: 16 additions & 0 deletions crates/uv/src/commands/pip/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub(crate) async fn pip_install(
requirements: &[RequirementsSource],
constraints: &[RequirementsSource],
overrides: &[RequirementsSource],
build_constraints: &[RequirementsSource],
constraints_from_workspace: Vec<Requirement>,
overrides_from_workspace: Vec<Requirement>,
extras: &ExtrasSpecification,
Expand Down Expand Up @@ -105,6 +106,20 @@ pub(crate) async fn pip_install(
)
.await?;

// Read build constraints and overrides
let RequirementsSpecification {
constraints: build_constraints,
overrides: _build_overrides,
..
} = operations::read_requirements(
&[],
build_constraints,
&[],
&ExtrasSpecification::None,
&client_builder,
)
.await?;

let constraints: Vec<Requirement> = constraints
.iter()
.cloned()
Expand Down Expand Up @@ -294,6 +309,7 @@ pub(crate) async fn pip_install(
let build_dispatch = BuildDispatch::new(
&client,
&cache,
&build_constraints,
interpreter,
&index_locations,
&flat_index,
Expand Down
16 changes: 16 additions & 0 deletions crates/uv/src/commands/pip/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::printer::Printer;
pub(crate) async fn pip_sync(
requirements: &[RequirementsSource],
constraints: &[RequirementsSource],
build_constraints: &[RequirementsSource],
reinstall: Reinstall,
link_mode: LinkMode,
compile: bool,
Expand Down Expand Up @@ -103,6 +104,20 @@ pub(crate) async fn pip_sync(
)
.await?;

// Read build constraints and overrides
let RequirementsSpecification {
constraints: build_constraints,
overrides: _build_overrides,
..
} = operations::read_requirements(
&[],
build_constraints,
&[],
&ExtrasSpecification::None,
&client_builder,
)
.await?;

// Validate that the requirements are non-empty.
if !allow_empty_requirements {
let num_requirements = requirements.len() + source_trees.len();
Expand Down Expand Up @@ -240,6 +255,7 @@ pub(crate) async fn pip_sync(
let build_dispatch = BuildDispatch::new(
&client,
&cache,
&build_constraints,
interpreter,
&index_locations,
&flat_index,
Expand Down
4 changes: 4 additions & 0 deletions crates/uv/src/commands/project/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,14 @@ pub(crate) async fn add(
FlatIndex::from_entries(entries, Some(&tags), &hasher, &settings.build_options)
};

// TODO: read locked build constraints
let build_constraints = [];

// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
venv.interpreter(),
&settings.index_locations,
&flat_index,
Expand Down
6 changes: 6 additions & 0 deletions crates/uv/src/commands/project/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,10 +396,13 @@ async fn do_lock(
// Prefill the index with the lockfile metadata.
let index = lock.to_index(workspace.install_path(), upgrade)?;

// TODO: read locked build constraints
let build_constraints = [];
// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down Expand Up @@ -472,10 +475,13 @@ async fn do_lock(
None => {
debug!("Starting clean resolution");

// TODO: read locked build constraints
let build_constraints = [];
// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down
13 changes: 13 additions & 0 deletions crates/uv/src/commands/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,13 @@ pub(crate) async fn resolve_names(
let setup_py = SetupPyStrategy::default();
let flat_index = FlatIndex::default();

// TODO: read locked build constraints
let build_constraints = [];
// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down Expand Up @@ -491,10 +494,13 @@ pub(crate) async fn resolve_environment<'a>(
FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
};

// TODO: read locked build constraints
let build_constraints = [];
// Create a build dispatch.
let resolve_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down Expand Up @@ -604,10 +610,13 @@ pub(crate) async fn sync_environment(
FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
};

// TODO: read locked build constraints
let build_constraints = [];
// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down Expand Up @@ -765,10 +774,14 @@ pub(crate) async fn update_environment(
FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
};

// TODO: read locked build constraints
let build_constraints = [];

// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down
3 changes: 3 additions & 0 deletions crates/uv/src/commands/project/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,13 @@ pub(super) async fn do_sync(
FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
};

// TODO: read locked build constraints
let build_constraints = [];
// Create a build dispatch.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
venv.interpreter(),
index_locations,
&flat_index,
Expand Down
3 changes: 3 additions & 0 deletions crates/uv/src/commands/venv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,13 @@ async fn venv_impl(
// Do not allow builds
let build_options = BuildOptions::new(NoBinary::None, NoBuild::All);

let build_constraints = [];

// Prep the build context.
let build_dispatch = BuildDispatch::new(
&client,
cache,
&build_constraints,
interpreter,
index_locations,
&flat_index,
Expand Down
Loading
Loading