Respect tool.uv.environments in pip compile --universal (#6663)

## Summary

We now respect the `environments` field in `uv pip compile --universal`,
e.g.:

```toml
[tool.uv]
environments = ["platform_system == 'Emscripten'"]
```

Closes https://github.com/astral-sh/uv/issues/6641.
This commit is contained in:
Charlie Marsh 2024-08-26 19:58:17 -04:00 committed by GitHub
parent 154ea243d0
commit 1ae2c3f142
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 179 additions and 45 deletions

View file

@ -7,6 +7,7 @@ pub use parsed_url::*;
pub use requirement::*; pub use requirement::*;
pub use scheme::*; pub use scheme::*;
pub use simple_json::*; pub use simple_json::*;
pub use supported_environments::*;
mod base_url; mod base_url;
mod direct_url; mod direct_url;
@ -17,3 +18,4 @@ mod parsed_url;
mod requirement; mod requirement;
mod scheme; mod scheme;
mod simple_json; mod simple_json;
mod supported_environments;

View file

@ -4,6 +4,7 @@ use serde::ser::SerializeSeq;
use pep508_rs::MarkerTree; use pep508_rs::MarkerTree;
/// A list of supported marker environments.
#[derive(Debug, Default, Clone, Eq, PartialEq)] #[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct SupportedEnvironments(Vec<MarkerTree>); pub struct SupportedEnvironments(Vec<MarkerTree>);

View file

@ -3,6 +3,7 @@ use std::path::PathBuf;
use distribution_types::IndexUrl; use distribution_types::IndexUrl;
use install_wheel_rs::linker::LinkMode; use install_wheel_rs::linker::LinkMode;
use pypi_types::SupportedEnvironments;
use uv_configuration::{ConfigSettings, IndexStrategy, KeyringProviderType, TargetTriple}; use uv_configuration::{ConfigSettings, IndexStrategy, KeyringProviderType, TargetTriple};
use uv_python::{PythonDownloads, PythonPreference, PythonVersion}; use uv_python::{PythonDownloads, PythonPreference, PythonVersion};
use uv_resolver::{AnnotationStyle, ExcludeNewer, PrereleaseMode, ResolutionMode}; use uv_resolver::{AnnotationStyle, ExcludeNewer, PrereleaseMode, ResolutionMode};
@ -75,12 +76,13 @@ impl_combine_or!(LinkMode);
impl_combine_or!(NonZeroUsize); impl_combine_or!(NonZeroUsize);
impl_combine_or!(PathBuf); impl_combine_or!(PathBuf);
impl_combine_or!(PrereleaseMode); impl_combine_or!(PrereleaseMode);
impl_combine_or!(PythonDownloads);
impl_combine_or!(PythonPreference);
impl_combine_or!(PythonVersion); impl_combine_or!(PythonVersion);
impl_combine_or!(ResolutionMode); impl_combine_or!(ResolutionMode);
impl_combine_or!(String); impl_combine_or!(String);
impl_combine_or!(SupportedEnvironments);
impl_combine_or!(TargetTriple); impl_combine_or!(TargetTriple);
impl_combine_or!(PythonPreference);
impl_combine_or!(PythonDownloads);
impl_combine_or!(bool); impl_combine_or!(bool);
impl<T> Combine for Option<Vec<T>> { impl<T> Combine for Option<Vec<T>> {

View file

@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use distribution_types::{FlatIndexLocation, IndexUrl}; use distribution_types::{FlatIndexLocation, IndexUrl};
use install_wheel_rs::linker::LinkMode; use install_wheel_rs::linker::LinkMode;
use pep508_rs::Requirement; use pep508_rs::Requirement;
use pypi_types::VerbatimParsedUrl; use pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
use uv_configuration::{ use uv_configuration::{
ConfigSettings, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple, ConfigSettings, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple,
}; };
@ -43,9 +43,15 @@ pub struct Options {
// NOTE(charlie): These fields are shared with `ToolUv` in // NOTE(charlie): These fields are shared with `ToolUv` in
// `crates/uv-workspace/src/pyproject.rs`, and the documentation lives on that struct. // `crates/uv-workspace/src/pyproject.rs`, and the documentation lives on that struct.
#[cfg_attr(feature = "schemars", schemars(skip))]
pub override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>, pub override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
#[cfg_attr(feature = "schemars", schemars(skip))]
pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>, pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
#[cfg_attr(feature = "schemars", schemars(skip))]
pub environments: Option<SupportedEnvironments>,
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in // NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
// `crates/uv-workspace/src/pyproject.rs`. // `crates/uv-workspace/src/pyproject.rs`.
#[serde(default, skip_serializing)] #[serde(default, skip_serializing)]
@ -60,10 +66,6 @@ pub struct Options {
#[cfg_attr(feature = "schemars", schemars(skip))] #[cfg_attr(feature = "schemars", schemars(skip))]
dev_dependencies: serde::de::IgnoredAny, dev_dependencies: serde::de::IgnoredAny,
#[serde(default, skip_serializing)]
#[cfg_attr(feature = "schemars", schemars(skip))]
environments: serde::de::IgnoredAny,
#[serde(default, skip_serializing)] #[serde(default, skip_serializing)]
#[cfg_attr(feature = "schemars", schemars(skip))] #[cfg_attr(feature = "schemars", schemars(skip))]
managed: serde::de::IgnoredAny, managed: serde::de::IgnoredAny,

View file

@ -1,10 +1,8 @@
pub use environments::SupportedEnvironments;
pub use workspace::{ pub use workspace::{
check_nested_workspaces, DiscoveryOptions, ProjectWorkspace, VirtualProject, Workspace, check_nested_workspaces, DiscoveryOptions, ProjectWorkspace, VirtualProject, Workspace,
WorkspaceError, WorkspaceMember, WorkspaceError, WorkspaceMember,
}; };
mod environments;
pub mod pyproject; pub mod pyproject;
pub mod pyproject_mut; pub mod pyproject_mut;
mod workspace; mod workspace;

View file

@ -14,9 +14,8 @@ use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
use url::Url; use url::Url;
use crate::environments::SupportedEnvironments;
use pep440_rs::VersionSpecifiers; use pep440_rs::VersionSpecifiers;
use pypi_types::{RequirementSource, VerbatimParsedUrl}; use pypi_types::{RequirementSource, SupportedEnvironments, VerbatimParsedUrl};
use uv_git::GitReference; use uv_git::GitReference;
use uv_macros::OptionsMetadata; use uv_macros::OptionsMetadata;
use uv_normalize::{ExtraName, PackageName}; use uv_normalize::{ExtraName, PackageName};
@ -121,11 +120,14 @@ pub struct ToolUv {
/// By default, uv will resolve for all possible environments during a `uv lock` operation. /// By default, uv will resolve for all possible environments during a `uv lock` operation.
/// However, you can restrict the set of supported environments to improve performance and avoid /// However, you can restrict the set of supported environments to improve performance and avoid
/// unsatisfiable branches in the solution space. /// unsatisfiable branches in the solution space.
///
/// These environments will also respected when `uv pip compile` is invoked with the
/// `--universal` flag.
#[cfg_attr( #[cfg_attr(
feature = "schemars", feature = "schemars",
schemars( schemars(
with = "Option<Vec<String>>", with = "Option<Vec<String>>",
description = "A list of environment markers, e.g. `python_version >= '3.6'`." description = "A list of environment markers, e.g., `python_version >= '3.6'`."
) )
)] )]
#[option( #[option(

View file

@ -9,12 +9,11 @@ use rustc_hash::FxHashSet;
use tracing::{debug, trace, warn}; use tracing::{debug, trace, warn};
use pep508_rs::{MarkerTree, RequirementOrigin, VerbatimUrl}; use pep508_rs::{MarkerTree, RequirementOrigin, VerbatimUrl};
use pypi_types::{Requirement, RequirementSource, VerbatimParsedUrl}; use pypi_types::{Requirement, RequirementSource, SupportedEnvironments, VerbatimParsedUrl};
use uv_fs::Simplified; use uv_fs::Simplified;
use uv_normalize::{GroupName, PackageName, DEV_DEPENDENCIES}; use uv_normalize::{GroupName, PackageName, DEV_DEPENDENCIES};
use uv_warnings::warn_user; use uv_warnings::warn_user;
use crate::environments::SupportedEnvironments;
use crate::pyproject::{Project, PyProjectToml, Source, ToolUvWorkspace}; use crate::pyproject::{Project, PyProjectToml, Source, ToolUvWorkspace};
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]

View file

@ -11,7 +11,7 @@ use tracing::debug;
use distribution_types::{IndexLocations, UnresolvedRequirementSpecification, Verbatim}; use distribution_types::{IndexLocations, UnresolvedRequirementSpecification, Verbatim};
use install_wheel_rs::linker::LinkMode; use install_wheel_rs::linker::LinkMode;
use pypi_types::Requirement; use pypi_types::{Requirement, SupportedEnvironments};
use uv_auth::store_credentials_from_url; use uv_auth::store_credentials_from_url;
use uv_cache::Cache; use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
@ -53,6 +53,7 @@ pub(crate) async fn pip_compile(
build_constraints: &[RequirementsSource], build_constraints: &[RequirementsSource],
constraints_from_workspace: Vec<Requirement>, constraints_from_workspace: Vec<Requirement>,
overrides_from_workspace: Vec<Requirement>, overrides_from_workspace: Vec<Requirement>,
environments: SupportedEnvironments,
extras: ExtrasSpecification, extras: ExtrasSpecification,
output_file: Option<&Path>, output_file: Option<&Path>,
resolution_mode: ResolutionMode, resolution_mode: ResolutionMode,
@ -171,10 +172,10 @@ pub(crate) async fn pip_compile(
} }
// Find an interpreter to use for building distributions // Find an interpreter to use for building distributions
let environments = EnvironmentPreference::from_system_flag(system, false); let environment_preference = EnvironmentPreference::from_system_flag(system, false);
let interpreter = if let Some(python) = python.as_ref() { let interpreter = if let Some(python) = python.as_ref() {
let request = PythonRequest::parse(python); let request = PythonRequest::parse(python);
PythonInstallation::find(&request, environments, python_preference, &cache) PythonInstallation::find(&request, environment_preference, python_preference, &cache)
} else { } else {
// TODO(zanieb): The split here hints at a problem with the abstraction; we should be able to use // TODO(zanieb): The split here hints at a problem with the abstraction; we should be able to use
// `PythonInstallation::find(...)` here. // `PythonInstallation::find(...)` here.
@ -184,7 +185,7 @@ pub(crate) async fn pip_compile(
} else { } else {
PythonRequest::default() PythonRequest::default()
}; };
PythonInstallation::find_best(&request, environments, python_preference, &cache) PythonInstallation::find_best(&request, environment_preference, python_preference, &cache)
}? }?
.into_interpreter(); .into_interpreter();
@ -244,7 +245,10 @@ pub(crate) async fn pip_compile(
// Determine the environment for the resolution. // Determine the environment for the resolution.
let (tags, markers) = if universal { let (tags, markers) = if universal {
(None, ResolverMarkers::universal(vec![])) (
None,
ResolverMarkers::universal(environments.into_markers()),
)
} else { } else {
let (tags, markers) = let (tags, markers) =
resolution_environment(python_version, python_platform, &interpreter)?; resolution_environment(python_version, python_platform, &interpreter)?;

View file

@ -10,7 +10,7 @@ use tracing::debug;
use distribution_types::{IndexLocations, UnresolvedRequirementSpecification}; use distribution_types::{IndexLocations, UnresolvedRequirementSpecification};
use pep440_rs::Version; use pep440_rs::Version;
use pypi_types::Requirement; use pypi_types::{Requirement, SupportedEnvironments};
use uv_auth::store_credentials_from_url; use uv_auth::store_credentials_from_url;
use uv_cache::Cache; use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
@ -28,7 +28,7 @@ use uv_resolver::{
}; };
use uv_types::{BuildContext, BuildIsolation, EmptyInstalledPackages, HashStrategy}; use uv_types::{BuildContext, BuildIsolation, EmptyInstalledPackages, HashStrategy};
use uv_warnings::warn_user; use uv_warnings::warn_user;
use uv_workspace::{DiscoveryOptions, SupportedEnvironments, Workspace}; use uv_workspace::{DiscoveryOptions, Workspace};
use crate::commands::pip::loggers::{DefaultResolveLogger, ResolveLogger, SummaryResolveLogger}; use crate::commands::pip::loggers::{DefaultResolveLogger, ResolveLogger, SummaryResolveLogger};
use crate::commands::project::{find_requires_python, FoundInterpreter, ProjectError, SharedState}; use crate::commands::project::{find_requires_python, FoundInterpreter, ProjectError, SharedState};

View file

@ -303,6 +303,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
&build_constraints, &build_constraints,
args.constraints_from_workspace, args.constraints_from_workspace,
args.overrides_from_workspace, args.overrides_from_workspace,
args.environments,
args.settings.extras, args.settings.extras,
args.settings.output_file.as_deref(), args.settings.output_file.as_deref(),
args.settings.resolution, args.settings.resolution,

View file

@ -7,7 +7,7 @@ use std::str::FromStr;
use distribution_types::IndexLocations; use distribution_types::IndexLocations;
use install_wheel_rs::linker::LinkMode; use install_wheel_rs::linker::LinkMode;
use pep508_rs::{ExtraName, RequirementOrigin}; use pep508_rs::{ExtraName, RequirementOrigin};
use pypi_types::Requirement; use pypi_types::{Requirement, SupportedEnvironments};
use uv_cache::{CacheArgs, Refresh}; use uv_cache::{CacheArgs, Refresh};
use uv_cli::{ use uv_cli::{
options::{flag, resolver_installer_options, resolver_options}, options::{flag, resolver_installer_options, resolver_options},
@ -927,9 +927,10 @@ pub(crate) struct PipCompileSettings {
pub(crate) src_file: Vec<PathBuf>, pub(crate) src_file: Vec<PathBuf>,
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) 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) environments: SupportedEnvironments,
pub(crate) refresh: Refresh, pub(crate) refresh: Refresh,
pub(crate) settings: PipSettings, pub(crate) settings: PipSettings,
} }
@ -1015,6 +1016,12 @@ impl PipCompileSettings {
Vec::new() Vec::new()
}; };
let environments = if let Some(configuration) = &filesystem {
configuration.environments.clone().unwrap_or_default()
} else {
SupportedEnvironments::default()
};
Self { Self {
src_file, src_file,
constraint: constraint constraint: constraint
@ -1031,6 +1038,7 @@ impl PipCompileSettings {
.collect(), .collect(),
constraints_from_workspace, constraints_from_workspace,
overrides_from_workspace, overrides_from_workspace,
environments,
refresh: Refresh::from(refresh), refresh: Refresh::from(refresh),
settings: PipSettings::combine( settings: PipSettings::combine(
PipOptions { PipOptions {

View file

@ -11946,3 +11946,52 @@ fn symlink() -> Result<()> {
Ok(()) Ok(())
} }
/// Resolve with `--universal`, applying user-provided constraints to the space of supported
/// environments.
#[test]
fn universal_constrained_environment() -> Result<()> {
let context = TestContext::new("3.12");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["black"]
[tool.uv]
environments = "platform_system != 'Windows'"
"#,
)?;
uv_snapshot!(context.filters(), context.pip_compile()
.arg("pyproject.toml")
.arg("--universal"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] pyproject.toml --universal
black==24.3.0 ; platform_system != 'Windows'
# via project (pyproject.toml)
click==8.1.7 ; platform_system != 'Windows'
# via black
mypy-extensions==1.0.0 ; platform_system != 'Windows'
# via black
packaging==24.0 ; platform_system != 'Windows'
# via black
pathspec==0.12.1 ; platform_system != 'Windows'
# via black
platformdirs==4.2.0 ; platform_system != 'Windows'
# via black
----- stderr -----
Resolved 6 packages in [TIME]
"###
);
Ok(())
}

View file

@ -76,9 +76,12 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -211,9 +214,12 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -347,9 +353,12 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -515,9 +524,12 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -652,9 +664,12 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -775,9 +790,12 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -935,9 +953,12 @@ fn resolve_index_url() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -1095,9 +1116,12 @@ fn resolve_index_url() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -1300,9 +1324,12 @@ fn resolve_find_links() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -1459,9 +1486,12 @@ fn resolve_top_level() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -1588,9 +1618,12 @@ fn resolve_top_level() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -1745,9 +1778,12 @@ fn resolve_top_level() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -1926,9 +1962,12 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -2045,9 +2084,12 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -2164,9 +2206,12 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -2285,9 +2330,12 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -2576,9 +2624,12 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -2723,9 +2774,12 @@ fn resolve_both() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -2885,9 +2939,12 @@ fn resolve_config_file() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -3122,9 +3179,12 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {
@ -3244,9 +3304,12 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
], ],
constraint: [], constraint: [],
override: [], override: [],
build_constraint: [],
constraints_from_workspace: [], constraints_from_workspace: [],
overrides_from_workspace: [], overrides_from_workspace: [],
build_constraint: [], environments: SupportedEnvironments(
[],
),
refresh: None( refresh: None(
Timestamp( Timestamp(
SystemTime { SystemTime {

View file

@ -243,6 +243,9 @@ By default, uv will resolve for all possible environments during a `uv lock` ope
However, you can restrict the set of supported environments to improve performance and avoid However, you can restrict the set of supported environments to improve performance and avoid
unsatisfiable branches in the solution space. unsatisfiable branches in the solution space.
These environments will also respected when `uv pip compile` is invoked with the
`--universal` flag.
**Default value**: `[]` **Default value**: `[]`
**Type**: `str | list[str]` **Type**: `str | list[str]`

2
uv.schema.json generated
View file

@ -77,7 +77,7 @@
} }
}, },
"environments": { "environments": {
"description": "A list of environment markers, e.g. `python_version >= '3.6'`.", "description": "A list of environment markers, e.g., `python_version >= '3.6'`.",
"type": [ "type": [
"array", "array",
"null" "null"