mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-11-03 21:23:54 +00:00 
			
		
		
		
	Support build constraints (#5639)
## Summary Partially resolves #5561. Haven't added overrides support yet but I can add it tomorrow if the current approach for constraints is ok. ## Test Plan `cargo test` Manually checked trace logs after changing the constraints.
This commit is contained in:
		
							parent
							
								
									c558d70690
								
							
						
					
					
						commit
						ff9f3dede1
					
				
					 25 changed files with 360 additions and 4 deletions
				
			
		| 
						 | 
					@ -384,6 +384,19 @@ Specifically, uv does not support installing new `.egg-info`- or `.egg-link`-sty
 | 
				
			||||||
but will respect any such existing distributions during resolution, list them with `uv pip list` and
 | 
					but will respect any such existing distributions during resolution, list them with `uv pip list` and
 | 
				
			||||||
`uv pip freeze`, and uninstall them with `uv pip uninstall`.
 | 
					`uv pip freeze`, and uninstall them with `uv pip uninstall`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Build constraints
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When constraints are provided via `--constraint` (or `UV_CONSTRAINT`), uv will _not_ apply the
 | 
				
			||||||
 | 
					constraints when resolving build dependencies (i.e., to build a source distribution). Instead,
 | 
				
			||||||
 | 
					build constraints should be provided via the dedicated `--build-constraint` (or `UV_BUILD_CONSTRAINT`)
 | 
				
			||||||
 | 
					setting.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pip, meanwhile, applies constraints to build dependencies when specified via `PIP_CONSTRAINT`, but
 | 
				
			||||||
 | 
					not when provided via `--constraint` on the command line.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, to ensure that `setuptools 60.0.0` is used to build any packages with a build
 | 
				
			||||||
 | 
					dependency on `setuptools`, use `--build-constraint`, rather than `--constraint`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## `pip compile` defaults
 | 
					## `pip compile` defaults
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are a few small but notable differences in the default behaviors of `pip compile` and
 | 
					There are a few small but notable differences in the default behaviors of `pip compile` and
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -574,6 +574,8 @@ uv accepts the following command-line arguments as environment variables:
 | 
				
			||||||
  uv will require that all dependencies have a hash specified in the requirements file.
 | 
					  uv will require that all dependencies have a hash specified in the requirements file.
 | 
				
			||||||
- `UV_CONSTRAINT`: Equivalent to the `--constraint` command-line argument. If set, uv will use this
 | 
					- `UV_CONSTRAINT`: Equivalent to the `--constraint` command-line argument. If set, uv will use this
 | 
				
			||||||
  file as the constraints file. Uses space-separated list of files.
 | 
					  file as the constraints file. Uses space-separated list of files.
 | 
				
			||||||
 | 
					- `UV_BUILD_CONSTRAINT`: Equivalent to the `--build-constraint` command-line argument. If set, uv
 | 
				
			||||||
 | 
					  will use this file as constraints for any source distribution builds. Uses space-separated list of files.
 | 
				
			||||||
- `UV_OVERRIDE`: Equivalent to the `--override` command-line argument. If set, uv will use this
 | 
					- `UV_OVERRIDE`: Equivalent to the `--override` command-line argument. If set, uv will use this
 | 
				
			||||||
  file as the overrides file. Uses space-separated list of files.
 | 
					  file as the overrides file. Uses space-separated list of files.
 | 
				
			||||||
- `UV_LINK_MODE`: Equivalent to the `--link-mode` command-line argument. If set, uv will use this
 | 
					- `UV_LINK_MODE`: Equivalent to the `--link-mode` command-line argument. If set, uv will use this
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,10 +151,12 @@ mod resolver {
 | 
				
			||||||
        let python_requirement = PythonRequirement::from_interpreter(interpreter);
 | 
					        let python_requirement = PythonRequirement::from_interpreter(interpreter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
 | 
					        let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
 | 
				
			||||||
 | 
					        let build_constraints = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let build_context = BuildDispatch::new(
 | 
					        let build_context = BuildDispatch::new(
 | 
				
			||||||
            client,
 | 
					            client,
 | 
				
			||||||
            &cache,
 | 
					            &cache,
 | 
				
			||||||
 | 
					            &build_constraints,
 | 
				
			||||||
            interpreter,
 | 
					            interpreter,
 | 
				
			||||||
            &index_locations,
 | 
					            &index_locations,
 | 
				
			||||||
            &flat_index,
 | 
					            &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -541,6 +541,15 @@ pub struct PipCompileArgs {
 | 
				
			||||||
    #[arg(long, env = "UV_OVERRIDE", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
 | 
					    #[arg(long, env = "UV_OVERRIDE", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
 | 
				
			||||||
    pub r#override: Vec<Maybe<PathBuf>>,
 | 
					    pub r#override: Vec<Maybe<PathBuf>>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Constrain build dependencies using the given requirements files when building source
 | 
				
			||||||
 | 
					    /// distributions.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// 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.
 | 
					    /// 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.
 | 
					    /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
 | 
				
			||||||
| 
						 | 
					@ -838,6 +847,15 @@ pub struct PipSyncArgs {
 | 
				
			||||||
    #[arg(long, short, env = "UV_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
 | 
					    #[arg(long, short, env = "UV_CONSTRAINT", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
 | 
				
			||||||
    pub constraint: Vec<Maybe<PathBuf>>,
 | 
					    pub constraint: Vec<Maybe<PathBuf>>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Constrain build dependencies using the given requirements files when building source
 | 
				
			||||||
 | 
					    /// distributions.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// 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)]
 | 
					    #[command(flatten)]
 | 
				
			||||||
    pub installer: InstallerArgs,
 | 
					    pub installer: InstallerArgs,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1111,6 +1129,15 @@ pub struct PipInstallArgs {
 | 
				
			||||||
    #[arg(long, env = "UV_OVERRIDE", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
 | 
					    #[arg(long, env = "UV_OVERRIDE", value_delimiter = ' ', value_parser = parse_maybe_file_path)]
 | 
				
			||||||
    pub r#override: Vec<Maybe<PathBuf>>,
 | 
					    pub r#override: Vec<Maybe<PathBuf>>,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Constrain build dependencies using the given requirements files when building source
 | 
				
			||||||
 | 
					    /// distributions.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// 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.
 | 
					    /// 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.
 | 
					    /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,10 +74,12 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
 | 
				
			||||||
        &cache,
 | 
					        &cache,
 | 
				
			||||||
    )?;
 | 
					    )?;
 | 
				
			||||||
    let build_options = BuildOptions::default();
 | 
					    let build_options = BuildOptions::default();
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        &cache,
 | 
					        &cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        python.interpreter(),
 | 
					        python.interpreter(),
 | 
				
			||||||
        &index_urls,
 | 
					        &index_urls,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ use uv_build::{SourceBuild, SourceBuildContext};
 | 
				
			||||||
use uv_cache::Cache;
 | 
					use uv_cache::Cache;
 | 
				
			||||||
use uv_client::RegistryClient;
 | 
					use uv_client::RegistryClient;
 | 
				
			||||||
use uv_configuration::{
 | 
					use uv_configuration::{
 | 
				
			||||||
    BuildKind, BuildOptions, ConfigSettings, IndexStrategy, Reinstall, SetupPyStrategy,
 | 
					    BuildKind, BuildOptions, ConfigSettings, Constraints, IndexStrategy, Reinstall, SetupPyStrategy,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use uv_configuration::{Concurrency, PreviewMode};
 | 
					use uv_configuration::{Concurrency, PreviewMode};
 | 
				
			||||||
use uv_distribution::DistributionDatabase;
 | 
					use uv_distribution::DistributionDatabase;
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@ use uv_types::{BuildContext, BuildIsolation, EmptyInstalledPackages, HashStrateg
 | 
				
			||||||
pub struct BuildDispatch<'a> {
 | 
					pub struct BuildDispatch<'a> {
 | 
				
			||||||
    client: &'a RegistryClient,
 | 
					    client: &'a RegistryClient,
 | 
				
			||||||
    cache: &'a Cache,
 | 
					    cache: &'a Cache,
 | 
				
			||||||
 | 
					    constraints: Constraints,
 | 
				
			||||||
    interpreter: &'a Interpreter,
 | 
					    interpreter: &'a Interpreter,
 | 
				
			||||||
    index_locations: &'a IndexLocations,
 | 
					    index_locations: &'a IndexLocations,
 | 
				
			||||||
    index_strategy: IndexStrategy,
 | 
					    index_strategy: IndexStrategy,
 | 
				
			||||||
| 
						 | 
					@ -58,6 +59,7 @@ impl<'a> BuildDispatch<'a> {
 | 
				
			||||||
    pub fn new(
 | 
					    pub fn new(
 | 
				
			||||||
        client: &'a RegistryClient,
 | 
					        client: &'a RegistryClient,
 | 
				
			||||||
        cache: &'a Cache,
 | 
					        cache: &'a Cache,
 | 
				
			||||||
 | 
					        constraints: &'a [Requirement],
 | 
				
			||||||
        interpreter: &'a Interpreter,
 | 
					        interpreter: &'a Interpreter,
 | 
				
			||||||
        index_locations: &'a IndexLocations,
 | 
					        index_locations: &'a IndexLocations,
 | 
				
			||||||
        flat_index: &'a FlatIndex,
 | 
					        flat_index: &'a FlatIndex,
 | 
				
			||||||
| 
						 | 
					@ -77,6 +79,7 @@ impl<'a> BuildDispatch<'a> {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            client,
 | 
					            client,
 | 
				
			||||||
            cache,
 | 
					            cache,
 | 
				
			||||||
 | 
					            constraints: Constraints::from_requirements(constraints.iter().cloned()),
 | 
				
			||||||
            interpreter,
 | 
					            interpreter,
 | 
				
			||||||
            index_locations,
 | 
					            index_locations,
 | 
				
			||||||
            flat_index,
 | 
					            flat_index,
 | 
				
			||||||
| 
						 | 
					@ -140,8 +143,9 @@ impl<'a> BuildContext for BuildDispatch<'a> {
 | 
				
			||||||
        let python_requirement = PythonRequirement::from_interpreter(self.interpreter);
 | 
					        let python_requirement = PythonRequirement::from_interpreter(self.interpreter);
 | 
				
			||||||
        let markers = self.interpreter.markers();
 | 
					        let markers = self.interpreter.markers();
 | 
				
			||||||
        let tags = self.interpreter.tags()?;
 | 
					        let tags = self.interpreter.tags()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let resolver = Resolver::new(
 | 
					        let resolver = Resolver::new(
 | 
				
			||||||
            Manifest::simple(requirements.to_vec()),
 | 
					            Manifest::simple(requirements.to_vec()).with_constraints(self.constraints.clone()),
 | 
				
			||||||
            OptionsBuilder::new()
 | 
					            OptionsBuilder::new()
 | 
				
			||||||
                .exclude_newer(self.exclude_newer)
 | 
					                .exclude_newer(self.exclude_newer)
 | 
				
			||||||
                .index_strategy(self.index_strategy)
 | 
					                .index_strategy(self.index_strategy)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,6 +86,12 @@ impl Manifest {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[must_use]
 | 
				
			||||||
 | 
					    pub fn with_constraints(mut self, constraints: Constraints) -> Self {
 | 
				
			||||||
 | 
					        self.constraints = constraints;
 | 
				
			||||||
 | 
					        self
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Return an iterator over all requirements, constraints, and overrides, in priority order,
 | 
					    /// Return an iterator over all requirements, constraints, and overrides, in priority order,
 | 
				
			||||||
    /// such that requirements come first, followed by constraints, followed by overrides.
 | 
					    /// such that requirements come first, followed by constraints, followed by overrides.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,6 +48,7 @@ pub(crate) async fn pip_compile(
 | 
				
			||||||
    requirements: &[RequirementsSource],
 | 
					    requirements: &[RequirementsSource],
 | 
				
			||||||
    constraints: &[RequirementsSource],
 | 
					    constraints: &[RequirementsSource],
 | 
				
			||||||
    overrides: &[RequirementsSource],
 | 
					    overrides: &[RequirementsSource],
 | 
				
			||||||
 | 
					    build_constraints: &[RequirementsSource],
 | 
				
			||||||
    constraints_from_workspace: Vec<Requirement>,
 | 
					    constraints_from_workspace: Vec<Requirement>,
 | 
				
			||||||
    overrides_from_workspace: Vec<Requirement>,
 | 
					    overrides_from_workspace: Vec<Requirement>,
 | 
				
			||||||
    extras: ExtrasSpecification,
 | 
					    extras: ExtrasSpecification,
 | 
				
			||||||
| 
						 | 
					@ -143,6 +144,10 @@ pub(crate) async fn pip_compile(
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        .collect();
 | 
					        .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read build constraints.
 | 
				
			||||||
 | 
					    let build_constraints =
 | 
				
			||||||
 | 
					        operations::read_constraints(build_constraints, &client_builder).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // If all the metadata could be statically resolved, validate that every extra was used. If we
 | 
					    // 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.
 | 
					    // need to resolve metadata via PEP 517, we don't know which extras are used until much later.
 | 
				
			||||||
    if source_trees.is_empty() {
 | 
					    if source_trees.is_empty() {
 | 
				
			||||||
| 
						 | 
					@ -304,6 +309,7 @@ pub(crate) async fn pip_compile(
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        &cache,
 | 
					        &cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        &interpreter,
 | 
					        &interpreter,
 | 
				
			||||||
        &index_locations,
 | 
					        &index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,7 @@ pub(crate) async fn pip_install(
 | 
				
			||||||
    requirements: &[RequirementsSource],
 | 
					    requirements: &[RequirementsSource],
 | 
				
			||||||
    constraints: &[RequirementsSource],
 | 
					    constraints: &[RequirementsSource],
 | 
				
			||||||
    overrides: &[RequirementsSource],
 | 
					    overrides: &[RequirementsSource],
 | 
				
			||||||
 | 
					    build_constraints: &[RequirementsSource],
 | 
				
			||||||
    constraints_from_workspace: Vec<Requirement>,
 | 
					    constraints_from_workspace: Vec<Requirement>,
 | 
				
			||||||
    overrides_from_workspace: Vec<Requirement>,
 | 
					    overrides_from_workspace: Vec<Requirement>,
 | 
				
			||||||
    extras: &ExtrasSpecification,
 | 
					    extras: &ExtrasSpecification,
 | 
				
			||||||
| 
						 | 
					@ -105,6 +106,10 @@ pub(crate) async fn pip_install(
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    .await?;
 | 
					    .await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read build constraints.
 | 
				
			||||||
 | 
					    let build_constraints =
 | 
				
			||||||
 | 
					        operations::read_constraints(build_constraints, &client_builder).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let constraints: Vec<Requirement> = constraints
 | 
					    let constraints: Vec<Requirement> = constraints
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .cloned()
 | 
					        .cloned()
 | 
				
			||||||
| 
						 | 
					@ -294,6 +299,7 @@ pub(crate) async fn pip_install(
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        &cache,
 | 
					        &cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        interpreter,
 | 
					        interpreter,
 | 
				
			||||||
        &index_locations,
 | 
					        &index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,18 @@ pub(crate) async fn read_requirements(
 | 
				
			||||||
    .await?)
 | 
					    .await?)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Resolve a set of constraints.
 | 
				
			||||||
 | 
					pub(crate) async fn read_constraints(
 | 
				
			||||||
 | 
					    constraints: &[RequirementsSource],
 | 
				
			||||||
 | 
					    client_builder: &BaseClientBuilder<'_>,
 | 
				
			||||||
 | 
					) -> Result<Vec<Requirement>, Error> {
 | 
				
			||||||
 | 
					    Ok(
 | 
				
			||||||
 | 
					        RequirementsSpecification::from_sources(&[], constraints, &[], client_builder)
 | 
				
			||||||
 | 
					            .await?
 | 
				
			||||||
 | 
					            .constraints,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Resolve a set of requirements, similar to running `pip compile`.
 | 
					/// Resolve a set of requirements, similar to running `pip compile`.
 | 
				
			||||||
pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
 | 
					pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
 | 
				
			||||||
    requirements: Vec<UnresolvedRequirementSpecification>,
 | 
					    requirements: Vec<UnresolvedRequirementSpecification>,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,7 @@ use crate::printer::Printer;
 | 
				
			||||||
pub(crate) async fn pip_sync(
 | 
					pub(crate) async fn pip_sync(
 | 
				
			||||||
    requirements: &[RequirementsSource],
 | 
					    requirements: &[RequirementsSource],
 | 
				
			||||||
    constraints: &[RequirementsSource],
 | 
					    constraints: &[RequirementsSource],
 | 
				
			||||||
 | 
					    build_constraints: &[RequirementsSource],
 | 
				
			||||||
    reinstall: Reinstall,
 | 
					    reinstall: Reinstall,
 | 
				
			||||||
    link_mode: LinkMode,
 | 
					    link_mode: LinkMode,
 | 
				
			||||||
    compile: bool,
 | 
					    compile: bool,
 | 
				
			||||||
| 
						 | 
					@ -103,6 +104,10 @@ pub(crate) async fn pip_sync(
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    .await?;
 | 
					    .await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Read build constraints.
 | 
				
			||||||
 | 
					    let build_constraints =
 | 
				
			||||||
 | 
					        operations::read_constraints(build_constraints, &client_builder).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Validate that the requirements are non-empty.
 | 
					    // Validate that the requirements are non-empty.
 | 
				
			||||||
    if !allow_empty_requirements {
 | 
					    if !allow_empty_requirements {
 | 
				
			||||||
        let num_requirements = requirements.len() + source_trees.len();
 | 
					        let num_requirements = requirements.len() + source_trees.len();
 | 
				
			||||||
| 
						 | 
					@ -240,6 +245,7 @@ pub(crate) async fn pip_sync(
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        &cache,
 | 
					        &cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        interpreter,
 | 
					        interpreter,
 | 
				
			||||||
        &index_locations,
 | 
					        &index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,10 +123,14 @@ pub(crate) async fn add(
 | 
				
			||||||
        FlatIndex::from_entries(entries, Some(&tags), &hasher, &settings.build_options)
 | 
					        FlatIndex::from_entries(entries, Some(&tags), &hasher, &settings.build_options)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: read locked build constraints
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create a build dispatch.
 | 
					    // Create a build dispatch.
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        cache,
 | 
					        cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        venv.interpreter(),
 | 
					        venv.interpreter(),
 | 
				
			||||||
        &settings.index_locations,
 | 
					        &settings.index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -403,10 +403,13 @@ async fn do_lock(
 | 
				
			||||||
            // Prefill the index with the lockfile metadata.
 | 
					            // Prefill the index with the lockfile metadata.
 | 
				
			||||||
            let index = lock.to_index(workspace.install_path(), upgrade)?;
 | 
					            let index = lock.to_index(workspace.install_path(), upgrade)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // TODO: read locked build constraints
 | 
				
			||||||
 | 
					            let build_constraints = [];
 | 
				
			||||||
            // Create a build dispatch.
 | 
					            // Create a build dispatch.
 | 
				
			||||||
            let build_dispatch = BuildDispatch::new(
 | 
					            let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
                &client,
 | 
					                &client,
 | 
				
			||||||
                cache,
 | 
					                cache,
 | 
				
			||||||
 | 
					                &build_constraints,
 | 
				
			||||||
                interpreter,
 | 
					                interpreter,
 | 
				
			||||||
                index_locations,
 | 
					                index_locations,
 | 
				
			||||||
                &flat_index,
 | 
					                &flat_index,
 | 
				
			||||||
| 
						 | 
					@ -479,10 +482,13 @@ async fn do_lock(
 | 
				
			||||||
        None => {
 | 
					        None => {
 | 
				
			||||||
            debug!("Starting clean resolution");
 | 
					            debug!("Starting clean resolution");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // TODO: read locked build constraints
 | 
				
			||||||
 | 
					            let build_constraints = [];
 | 
				
			||||||
            // Create a build dispatch.
 | 
					            // Create a build dispatch.
 | 
				
			||||||
            let build_dispatch = BuildDispatch::new(
 | 
					            let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
                &client,
 | 
					                &client,
 | 
				
			||||||
                cache,
 | 
					                cache,
 | 
				
			||||||
 | 
					                &build_constraints,
 | 
				
			||||||
                interpreter,
 | 
					                interpreter,
 | 
				
			||||||
                index_locations,
 | 
					                index_locations,
 | 
				
			||||||
                &flat_index,
 | 
					                &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -405,10 +405,13 @@ pub(crate) async fn resolve_names(
 | 
				
			||||||
    let setup_py = SetupPyStrategy::default();
 | 
					    let setup_py = SetupPyStrategy::default();
 | 
				
			||||||
    let flat_index = FlatIndex::default();
 | 
					    let flat_index = FlatIndex::default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: read locked build constraints
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
    // Create a build dispatch.
 | 
					    // Create a build dispatch.
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        cache,
 | 
					        cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        interpreter,
 | 
					        interpreter,
 | 
				
			||||||
        index_locations,
 | 
					        index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					@ -525,10 +528,13 @@ pub(crate) async fn resolve_environment<'a>(
 | 
				
			||||||
        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
					        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: read locked build constraints
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
    // Create a build dispatch.
 | 
					    // Create a build dispatch.
 | 
				
			||||||
    let resolve_dispatch = BuildDispatch::new(
 | 
					    let resolve_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        cache,
 | 
					        cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        interpreter,
 | 
					        interpreter,
 | 
				
			||||||
        index_locations,
 | 
					        index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					@ -638,10 +644,13 @@ pub(crate) async fn sync_environment(
 | 
				
			||||||
        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
					        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: read locked build constraints
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
    // Create a build dispatch.
 | 
					    // Create a build dispatch.
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        cache,
 | 
					        cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        interpreter,
 | 
					        interpreter,
 | 
				
			||||||
        index_locations,
 | 
					        index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					@ -799,10 +808,14 @@ pub(crate) async fn update_environment(
 | 
				
			||||||
        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
					        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: read locked build constraints
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create a build dispatch.
 | 
					    // Create a build dispatch.
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        cache,
 | 
					        cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        interpreter,
 | 
					        interpreter,
 | 
				
			||||||
        index_locations,
 | 
					        index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,10 +209,13 @@ pub(super) async fn do_sync(
 | 
				
			||||||
        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
					        FlatIndex::from_entries(entries, Some(tags), &hasher, build_options)
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: read locked build constraints
 | 
				
			||||||
 | 
					    let build_constraints = [];
 | 
				
			||||||
    // Create a build dispatch.
 | 
					    // Create a build dispatch.
 | 
				
			||||||
    let build_dispatch = BuildDispatch::new(
 | 
					    let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
        &client,
 | 
					        &client,
 | 
				
			||||||
        cache,
 | 
					        cache,
 | 
				
			||||||
 | 
					        &build_constraints,
 | 
				
			||||||
        venv.interpreter(),
 | 
					        venv.interpreter(),
 | 
				
			||||||
        index_locations,
 | 
					        index_locations,
 | 
				
			||||||
        &flat_index,
 | 
					        &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,10 +276,13 @@ async fn venv_impl(
 | 
				
			||||||
        // Do not allow builds
 | 
					        // Do not allow builds
 | 
				
			||||||
        let build_options = BuildOptions::new(NoBinary::None, NoBuild::All);
 | 
					        let build_options = BuildOptions::new(NoBinary::None, NoBuild::All);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let build_constraints = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Prep the build context.
 | 
					        // Prep the build context.
 | 
				
			||||||
        let build_dispatch = BuildDispatch::new(
 | 
					        let build_dispatch = BuildDispatch::new(
 | 
				
			||||||
            &client,
 | 
					            &client,
 | 
				
			||||||
            cache,
 | 
					            cache,
 | 
				
			||||||
 | 
					            &build_constraints,
 | 
				
			||||||
            interpreter,
 | 
					            interpreter,
 | 
				
			||||||
            index_locations,
 | 
					            index_locations,
 | 
				
			||||||
            &flat_index,
 | 
					            &flat_index,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -236,11 +236,17 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .map(RequirementsSource::from_overrides_txt)
 | 
					                .map(RequirementsSource::from_overrides_txt)
 | 
				
			||||||
                .collect::<Vec<_>>();
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            let build_constraints = args
 | 
				
			||||||
 | 
					                .build_constraint
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(RequirementsSource::from_constraints_txt)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            commands::pip_compile(
 | 
					            commands::pip_compile(
 | 
				
			||||||
                &requirements,
 | 
					                &requirements,
 | 
				
			||||||
                &constraints,
 | 
					                &constraints,
 | 
				
			||||||
                &overrides,
 | 
					                &overrides,
 | 
				
			||||||
 | 
					                &build_constraints,
 | 
				
			||||||
                args.constraints_from_workspace,
 | 
					                args.constraints_from_workspace,
 | 
				
			||||||
                args.overrides_from_workspace,
 | 
					                args.overrides_from_workspace,
 | 
				
			||||||
                args.settings.extras,
 | 
					                args.settings.extras,
 | 
				
			||||||
| 
						 | 
					@ -316,10 +322,16 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .map(RequirementsSource::from_constraints_txt)
 | 
					                .map(RequirementsSource::from_constraints_txt)
 | 
				
			||||||
                .collect::<Vec<_>>();
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					            let build_constraints = args
 | 
				
			||||||
 | 
					                .build_constraint
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(RequirementsSource::from_constraints_txt)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            commands::pip_sync(
 | 
					            commands::pip_sync(
 | 
				
			||||||
                &requirements,
 | 
					                &requirements,
 | 
				
			||||||
                &constraints,
 | 
					                &constraints,
 | 
				
			||||||
 | 
					                &build_constraints,
 | 
				
			||||||
                args.settings.reinstall,
 | 
					                args.settings.reinstall,
 | 
				
			||||||
                args.settings.link_mode,
 | 
					                args.settings.link_mode,
 | 
				
			||||||
                args.settings.compile_bytecode,
 | 
					                args.settings.compile_bytecode,
 | 
				
			||||||
| 
						 | 
					@ -392,10 +404,17 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
 | 
				
			||||||
                .map(RequirementsSource::from_overrides_txt)
 | 
					                .map(RequirementsSource::from_overrides_txt)
 | 
				
			||||||
                .collect::<Vec<_>>();
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let build_constraints = args
 | 
				
			||||||
 | 
					                .build_constraint
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .map(RequirementsSource::from_overrides_txt)
 | 
				
			||||||
 | 
					                .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            commands::pip_install(
 | 
					            commands::pip_install(
 | 
				
			||||||
                &requirements,
 | 
					                &requirements,
 | 
				
			||||||
                &constraints,
 | 
					                &constraints,
 | 
				
			||||||
                &overrides,
 | 
					                &overrides,
 | 
				
			||||||
 | 
					                &build_constraints,
 | 
				
			||||||
                args.constraints_from_workspace,
 | 
					                args.constraints_from_workspace,
 | 
				
			||||||
                args.overrides_from_workspace,
 | 
					                args.overrides_from_workspace,
 | 
				
			||||||
                &args.settings.extras,
 | 
					                &args.settings.extras,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -814,6 +814,7 @@ pub(crate) struct PipCompileSettings {
 | 
				
			||||||
    pub(crate) r#override: Vec<PathBuf>,
 | 
					    pub(crate) r#override: Vec<PathBuf>,
 | 
				
			||||||
    pub(crate) constraints_from_workspace: Vec<Requirement>,
 | 
					    pub(crate) constraints_from_workspace: Vec<Requirement>,
 | 
				
			||||||
    pub(crate) overrides_from_workspace: Vec<Requirement>,
 | 
					    pub(crate) overrides_from_workspace: Vec<Requirement>,
 | 
				
			||||||
 | 
					    pub(crate) build_constraint: Vec<PathBuf>,
 | 
				
			||||||
    pub(crate) refresh: Refresh,
 | 
					    pub(crate) refresh: Refresh,
 | 
				
			||||||
    pub(crate) settings: PipSettings,
 | 
					    pub(crate) settings: PipSettings,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -828,6 +829,7 @@ impl PipCompileSettings {
 | 
				
			||||||
            extra,
 | 
					            extra,
 | 
				
			||||||
            all_extras,
 | 
					            all_extras,
 | 
				
			||||||
            no_all_extras,
 | 
					            no_all_extras,
 | 
				
			||||||
 | 
					            build_constraint,
 | 
				
			||||||
            refresh,
 | 
					            refresh,
 | 
				
			||||||
            no_deps,
 | 
					            no_deps,
 | 
				
			||||||
            deps,
 | 
					            deps,
 | 
				
			||||||
| 
						 | 
					@ -908,6 +910,10 @@ impl PipCompileSettings {
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .filter_map(Maybe::into_option)
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
                .collect(),
 | 
					                .collect(),
 | 
				
			||||||
 | 
					            build_constraint: build_constraint
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
 | 
					                .collect(),
 | 
				
			||||||
            r#override: r#override
 | 
					            r#override: r#override
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .filter_map(Maybe::into_option)
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
| 
						 | 
					@ -961,6 +967,7 @@ impl PipCompileSettings {
 | 
				
			||||||
pub(crate) struct PipSyncSettings {
 | 
					pub(crate) struct PipSyncSettings {
 | 
				
			||||||
    pub(crate) src_file: Vec<PathBuf>,
 | 
					    pub(crate) src_file: Vec<PathBuf>,
 | 
				
			||||||
    pub(crate) constraint: Vec<PathBuf>,
 | 
					    pub(crate) constraint: Vec<PathBuf>,
 | 
				
			||||||
 | 
					    pub(crate) build_constraint: Vec<PathBuf>,
 | 
				
			||||||
    pub(crate) dry_run: bool,
 | 
					    pub(crate) dry_run: bool,
 | 
				
			||||||
    pub(crate) refresh: Refresh,
 | 
					    pub(crate) refresh: Refresh,
 | 
				
			||||||
    pub(crate) settings: PipSettings,
 | 
					    pub(crate) settings: PipSettings,
 | 
				
			||||||
| 
						 | 
					@ -972,6 +979,7 @@ impl PipSyncSettings {
 | 
				
			||||||
        let PipSyncArgs {
 | 
					        let PipSyncArgs {
 | 
				
			||||||
            src_file,
 | 
					            src_file,
 | 
				
			||||||
            constraint,
 | 
					            constraint,
 | 
				
			||||||
 | 
					            build_constraint,
 | 
				
			||||||
            installer,
 | 
					            installer,
 | 
				
			||||||
            refresh,
 | 
					            refresh,
 | 
				
			||||||
            require_hashes,
 | 
					            require_hashes,
 | 
				
			||||||
| 
						 | 
					@ -1009,6 +1017,10 @@ impl PipSyncSettings {
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .filter_map(Maybe::into_option)
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
                .collect(),
 | 
					                .collect(),
 | 
				
			||||||
 | 
					            build_constraint: build_constraint
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
 | 
					                .collect(),
 | 
				
			||||||
            dry_run,
 | 
					            dry_run,
 | 
				
			||||||
            refresh: Refresh::from(refresh),
 | 
					            refresh: Refresh::from(refresh),
 | 
				
			||||||
            settings: PipSettings::combine(
 | 
					            settings: PipSettings::combine(
 | 
				
			||||||
| 
						 | 
					@ -1052,6 +1064,7 @@ pub(crate) struct PipInstallSettings {
 | 
				
			||||||
    pub(crate) editable: Vec<String>,
 | 
					    pub(crate) editable: Vec<String>,
 | 
				
			||||||
    pub(crate) constraint: Vec<PathBuf>,
 | 
					    pub(crate) constraint: Vec<PathBuf>,
 | 
				
			||||||
    pub(crate) r#override: Vec<PathBuf>,
 | 
					    pub(crate) r#override: Vec<PathBuf>,
 | 
				
			||||||
 | 
					    pub(crate) build_constraint: Vec<PathBuf>,
 | 
				
			||||||
    pub(crate) dry_run: bool,
 | 
					    pub(crate) dry_run: bool,
 | 
				
			||||||
    pub(crate) constraints_from_workspace: Vec<Requirement>,
 | 
					    pub(crate) constraints_from_workspace: Vec<Requirement>,
 | 
				
			||||||
    pub(crate) overrides_from_workspace: Vec<Requirement>,
 | 
					    pub(crate) overrides_from_workspace: Vec<Requirement>,
 | 
				
			||||||
| 
						 | 
					@ -1071,6 +1084,7 @@ impl PipInstallSettings {
 | 
				
			||||||
            extra,
 | 
					            extra,
 | 
				
			||||||
            all_extras,
 | 
					            all_extras,
 | 
				
			||||||
            no_all_extras,
 | 
					            no_all_extras,
 | 
				
			||||||
 | 
					            build_constraint,
 | 
				
			||||||
            refresh,
 | 
					            refresh,
 | 
				
			||||||
            no_deps,
 | 
					            no_deps,
 | 
				
			||||||
            deps,
 | 
					            deps,
 | 
				
			||||||
| 
						 | 
					@ -1142,6 +1156,10 @@ impl PipInstallSettings {
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .filter_map(Maybe::into_option)
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
                .collect(),
 | 
					                .collect(),
 | 
				
			||||||
 | 
					            build_constraint: build_constraint
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .filter_map(Maybe::into_option)
 | 
				
			||||||
 | 
					                .collect(),
 | 
				
			||||||
            dry_run,
 | 
					            dry_run,
 | 
				
			||||||
            constraints_from_workspace,
 | 
					            constraints_from_workspace,
 | 
				
			||||||
            overrides_from_workspace,
 | 
					            overrides_from_workspace,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -413,10 +413,10 @@ impl TestContext {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Create a `uv help` command with options shared across scenarios.
 | 
					    /// Create a `uv help` command with options shared across scenarios.
 | 
				
			||||||
    #[allow(clippy::unused_self)]
 | 
					 | 
				
			||||||
    pub fn help(&self) -> Command {
 | 
					    pub fn help(&self) -> Command {
 | 
				
			||||||
        let mut command = Command::new(get_bin());
 | 
					        let mut command = Command::new(get_bin());
 | 
				
			||||||
        command.arg("help");
 | 
					        command.arg("help");
 | 
				
			||||||
 | 
					        self.add_shared_args(&mut command);
 | 
				
			||||||
        command
 | 
					        command
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -627,7 +627,7 @@ fn help_unknown_subsubcommand() {
 | 
				
			||||||
fn help_with_global_option() {
 | 
					fn help_with_global_option() {
 | 
				
			||||||
    let context = TestContext::new_with_versions(&[]);
 | 
					    let context = TestContext::new_with_versions(&[]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uv_snapshot!(context.filters(), context.help().arg("--cache-dir").arg("/dev/null"), @r###"
 | 
					    uv_snapshot!(context.filters(), context.help().arg("--no-cache"), @r###"
 | 
				
			||||||
    success: true
 | 
					    success: true
 | 
				
			||||||
    exit_code: 0
 | 
					    exit_code: 0
 | 
				
			||||||
    ----- stdout -----
 | 
					    ----- stdout -----
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11508,3 +11508,63 @@ fn ignore_invalid_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Include a `build_constraints.txt` file with an incompatible constraint.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn incompatible_build_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					    let context = TestContext::new("3.8");
 | 
				
			||||||
 | 
					    let requirements_txt = context.temp_dir.child("requirements.txt");
 | 
				
			||||||
 | 
					    requirements_txt.write_str("requests==1.2")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let constraints_txt = context.temp_dir.child("build_constraints.txt");
 | 
				
			||||||
 | 
					    constraints_txt.write_str("setuptools==1")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uv_snapshot!(context.pip_compile()
 | 
				
			||||||
 | 
					        .arg("requirements.txt")
 | 
				
			||||||
 | 
					        .arg("--build-constraint")
 | 
				
			||||||
 | 
					        .arg("build_constraints.txt"), @r###"
 | 
				
			||||||
 | 
					    success: false
 | 
				
			||||||
 | 
					    exit_code: 2
 | 
				
			||||||
 | 
					    ----- stdout -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ----- stderr -----
 | 
				
			||||||
 | 
					    error: Failed to download and build `requests==1.2.0`
 | 
				
			||||||
 | 
					      Caused by: Failed to build: `requests==1.2.0`
 | 
				
			||||||
 | 
					      Caused by: Failed to install requirements from setup.py build (resolve)
 | 
				
			||||||
 | 
					      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 the requirements are unsatisfiable.
 | 
				
			||||||
 | 
					    "###
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Include a `build_constraints.txt` file with a compatible constraint.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn compatible_build_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					    let context = TestContext::new("3.8");
 | 
				
			||||||
 | 
					    let requirements_txt = context.temp_dir.child("requirements.txt");
 | 
				
			||||||
 | 
					    requirements_txt.write_str("requests==1.2")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let constraints_txt = context.temp_dir.child("build_constraints.txt");
 | 
				
			||||||
 | 
					    constraints_txt.write_str("setuptools>=40")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uv_snapshot!(context.pip_compile()
 | 
				
			||||||
 | 
					        .arg("requirements.txt")
 | 
				
			||||||
 | 
					        .arg("--build-constraint")
 | 
				
			||||||
 | 
					        .arg("build_constraints.txt"), @r###"
 | 
				
			||||||
 | 
					    success: true
 | 
				
			||||||
 | 
					    exit_code: 0
 | 
				
			||||||
 | 
					    ----- stdout -----
 | 
				
			||||||
 | 
					    # This file was autogenerated by uv via the following command:
 | 
				
			||||||
 | 
					    #    uv pip compile --cache-dir [CACHE_DIR] requirements.txt --build-constraint build_constraints.txt
 | 
				
			||||||
 | 
					    requests==1.2.0
 | 
				
			||||||
 | 
					        # via -r requirements.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ----- stderr -----
 | 
				
			||||||
 | 
					    Resolved 1 package in [TIME]
 | 
				
			||||||
 | 
					    "###
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6244,3 +6244,58 @@ fn install_relocatable() -> Result<()> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Include a `build_constraints.txt` file with an incompatible constraint.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn incompatible_build_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					    let context = TestContext::new("3.8");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let constraints_txt = context.temp_dir.child("build_constraints.txt");
 | 
				
			||||||
 | 
					    constraints_txt.write_str("setuptools==1")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uv_snapshot!(context.pip_install()
 | 
				
			||||||
 | 
					        .arg("requests==1.2")
 | 
				
			||||||
 | 
					        .arg("--build-constraint")
 | 
				
			||||||
 | 
					        .arg("build_constraints.txt"), @r###"
 | 
				
			||||||
 | 
					    success: false
 | 
				
			||||||
 | 
					    exit_code: 2
 | 
				
			||||||
 | 
					    ----- stdout -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ----- stderr -----
 | 
				
			||||||
 | 
					    error: Failed to download and build `requests==1.2.0`
 | 
				
			||||||
 | 
					      Caused by: Failed to build: `requests==1.2.0`
 | 
				
			||||||
 | 
					      Caused by: Failed to install requirements from setup.py build (resolve)
 | 
				
			||||||
 | 
					      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 the requirements are unsatisfiable.
 | 
				
			||||||
 | 
					    "###
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Include a `build_constraints.txt` file with a compatible constraint.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn compatible_build_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					    let context = TestContext::new("3.8");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let constraints_txt = context.temp_dir.child("build_constraints.txt");
 | 
				
			||||||
 | 
					    constraints_txt.write_str("setuptools>=40")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uv_snapshot!(context.pip_install()
 | 
				
			||||||
 | 
					        .arg("requests==1.2")
 | 
				
			||||||
 | 
					        .arg("--build-constraint")
 | 
				
			||||||
 | 
					        .arg("build_constraints.txt"), @r###"
 | 
				
			||||||
 | 
					    success: true
 | 
				
			||||||
 | 
					    exit_code: 0
 | 
				
			||||||
 | 
					    ----- stdout -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ----- stderr -----
 | 
				
			||||||
 | 
					    Resolved 1 package in [TIME]
 | 
				
			||||||
 | 
					    Prepared 1 package in [TIME]
 | 
				
			||||||
 | 
					    Installed 1 package in [TIME]
 | 
				
			||||||
 | 
					     + requests==1.2.0
 | 
				
			||||||
 | 
					    "###
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5349,3 +5349,62 @@ fn preserve_markers() -> Result<()> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Include a `build_constraints.txt` file with an incompatible constraint.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn incompatible_build_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					    let context = TestContext::new("3.8");
 | 
				
			||||||
 | 
					    let requirements_txt = context.temp_dir.child("requirements.txt");
 | 
				
			||||||
 | 
					    requirements_txt.write_str("requests==1.2")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let constraints_txt = context.temp_dir.child("build_constraints.txt");
 | 
				
			||||||
 | 
					    constraints_txt.write_str("setuptools==1")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uv_snapshot!(context.pip_sync()
 | 
				
			||||||
 | 
					        .arg("requirements.txt")
 | 
				
			||||||
 | 
					        .arg("--build-constraint")
 | 
				
			||||||
 | 
					        .arg("build_constraints.txt"), @r###"
 | 
				
			||||||
 | 
					    success: false
 | 
				
			||||||
 | 
					    exit_code: 2
 | 
				
			||||||
 | 
					    ----- stdout -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ----- stderr -----
 | 
				
			||||||
 | 
					    error: Failed to download and build `requests==1.2.0`
 | 
				
			||||||
 | 
					      Caused by: Failed to build: `requests==1.2.0`
 | 
				
			||||||
 | 
					      Caused by: Failed to install requirements from setup.py build (resolve)
 | 
				
			||||||
 | 
					      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 the requirements are unsatisfiable.
 | 
				
			||||||
 | 
					    "###
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Include a `build_constraints.txt` file with a compatible constraint.
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn compatible_build_constraint() -> Result<()> {
 | 
				
			||||||
 | 
					    let context = TestContext::new("3.8");
 | 
				
			||||||
 | 
					    let requirements_txt = context.temp_dir.child("requirements.txt");
 | 
				
			||||||
 | 
					    requirements_txt.write_str("requests==1.2")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let constraints_txt = context.temp_dir.child("build_constraints.txt");
 | 
				
			||||||
 | 
					    constraints_txt.write_str("setuptools>=40")?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uv_snapshot!(context.pip_sync()
 | 
				
			||||||
 | 
					        .arg("requirements.txt")
 | 
				
			||||||
 | 
					        .arg("--build-constraint")
 | 
				
			||||||
 | 
					        .arg("build_constraints.txt"), @r###"
 | 
				
			||||||
 | 
					    success: true
 | 
				
			||||||
 | 
					    exit_code: 0
 | 
				
			||||||
 | 
					    ----- stdout -----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ----- stderr -----
 | 
				
			||||||
 | 
					    Resolved 1 package in [TIME]
 | 
				
			||||||
 | 
					    Prepared 1 package in [TIME]
 | 
				
			||||||
 | 
					    Installed 1 package in [TIME]
 | 
				
			||||||
 | 
					     + requests==1.2.0
 | 
				
			||||||
 | 
					    "###
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -207,6 +208,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -341,6 +343,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -507,6 +510,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -642,6 +646,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -763,6 +768,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -921,6 +927,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -1079,6 +1086,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -1282,6 +1290,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -1439,6 +1448,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -1566,6 +1576,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -1721,6 +1732,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -1900,6 +1912,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -2017,6 +2030,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -2134,6 +2148,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -2253,6 +2268,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -2397,6 +2413,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					@ -2542,6 +2559,7 @@ fn resolve_both() -> anyhow::Result<()> {
 | 
				
			||||||
        override: [],
 | 
					        override: [],
 | 
				
			||||||
        constraints_from_workspace: [],
 | 
					        constraints_from_workspace: [],
 | 
				
			||||||
        overrides_from_workspace: [],
 | 
					        overrides_from_workspace: [],
 | 
				
			||||||
 | 
					        build_constraint: [],
 | 
				
			||||||
        refresh: None(
 | 
					        refresh: None(
 | 
				
			||||||
            Timestamp(
 | 
					            Timestamp(
 | 
				
			||||||
                SystemTime {
 | 
					                SystemTime {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,6 +108,10 @@ uv pip compile [OPTIONS] <SRC_FILE>...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>While constraints are <em>additive</em>, in that they’re combined with the requirements of the constituent packages, overrides are <em>absolute</em>, in that they completely replace the requirements of the constituent packages.</p>
 | 
					<p>While constraints are <em>additive</em>, in that they’re combined with the requirements of the constituent packages, overrides are <em>absolute</em>, in that they completely replace the requirements of the constituent packages.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</dd><dt><code>--build-constraint</code>, <code>-b</code> <i>build-constraint</i></dt><dd><p>Constrain build dependencies using the given requirements files when building source distributions.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>Constraints files are <code>requirements.txt</code>-like files that only control the <em>version</em> of a requirement that’s installed. However, including a package in a constraints file will <em>not</em> trigger the installation of that package.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name; may be provided more than once.</p>
 | 
					</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name; may be provided more than once.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>Only applies to <code>pyproject.toml</code>, <code>setup.py</code>, and <code>setup.cfg</code> sources.</p>
 | 
					<p>Only applies to <code>pyproject.toml</code>, <code>setup.py</code>, and <code>setup.cfg</code> sources.</p>
 | 
				
			||||||
| 
						 | 
					@ -254,6 +258,10 @@ uv pip sync [OPTIONS] <SRC_FILE>...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>This is equivalent to pip’s <code>--constraint</code> option.</p>
 | 
					<p>This is equivalent to pip’s <code>--constraint</code> option.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</dd><dt><code>--build-constraint</code>, <code>-b</code> <i>build-constraint</i></dt><dd><p>Constrain build dependencies using the given requirements files when building source distributions.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>Constraints files are <code>requirements.txt</code>-like files that only control the <em>version</em> of a requirement that’s installed. However, including a package in a constraints file will <em>not</em> trigger the installation of that package.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</dd><dt><code>--index-url</code>, <code>-i</code> <i>index-url</i></dt><dd><p>The URL of the Python package index (by default: <https://pypi.org/simple>).</p>
 | 
					</dd><dt><code>--index-url</code>, <code>-i</code> <i>index-url</i></dt><dd><p>The URL of the Python package index (by default: <https://pypi.org/simple>).</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
 | 
					<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
 | 
				
			||||||
| 
						 | 
					@ -390,6 +398,10 @@ uv pip install [OPTIONS] <PACKAGE|--requirement <REQUIREMENT>|--editable <EDITAB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>While constraints are <em>additive</em>, in that they’re combined with the requirements of the constituent packages, overrides are <em>absolute</em>, in that they completely replace the requirements of the constituent packages.</p>
 | 
					<p>While constraints are <em>additive</em>, in that they’re combined with the requirements of the constituent packages, overrides are <em>absolute</em>, in that they completely replace the requirements of the constituent packages.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</dd><dt><code>--build-constraint</code>, <code>-b</code> <i>build-constraint</i></dt><dd><p>Constrain build dependencies using the given requirements files when building source distributions.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>Constraints files are <code>requirements.txt</code>-like files that only control the <em>version</em> of a requirement that’s installed. However, including a package in a constraints file will <em>not</em> trigger the installation of that package.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name; may be provided more than once.</p>
 | 
					</dd><dt><code>--extra</code> <i>extra</i></dt><dd><p>Include optional dependencies from the extra group name; may be provided more than once.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>Only applies to <code>pyproject.toml</code>, <code>setup.py</code>, and <code>setup.cfg</code> sources.</p>
 | 
					<p>Only applies to <code>pyproject.toml</code>, <code>setup.py</code>, and <code>setup.cfg</code> sources.</p>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue