Use distinct `Constraints` and `Overrides` types more widely (#2741)

## Summary

No functional changes.
This commit is contained in:
Charlie Marsh 2024-03-31 13:46:37 -04:00 committed by GitHub
parent 472d302ef0
commit 6d5b5ae9a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 71 additions and 45 deletions

1
Cargo.lock generated
View File

@ -4786,6 +4786,7 @@ version = "0.0.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"distribution-types", "distribution-types",
"itertools 0.12.1",
"once-map", "once-map",
"pep508_rs", "pep508_rs",
"rustc-hash", "rustc-hash",

View File

@ -18,7 +18,7 @@ pub use yanks::AllowedYanks;
mod bare; mod bare;
mod candidate_selector; mod candidate_selector;
mod constraints;
mod dependency_mode; mod dependency_mode;
mod dependency_provider; mod dependency_provider;
mod editables; mod editables;
@ -26,7 +26,6 @@ mod error;
mod exclusions; mod exclusions;
mod manifest; mod manifest;
mod options; mod options;
mod overrides;
mod pins; mod pins;
mod preferences; mod preferences;
mod prerelease_mode; mod prerelease_mode;

View File

@ -2,7 +2,7 @@ use distribution_types::LocalEditable;
use pep508_rs::{MarkerEnvironment, Requirement}; use pep508_rs::{MarkerEnvironment, Requirement};
use pypi_types::Metadata23; use pypi_types::Metadata23;
use uv_normalize::PackageName; use uv_normalize::PackageName;
use uv_types::RequestedRequirements; use uv_types::{Constraints, Overrides, RequestedRequirements};
use crate::{preferences::Preference, Exclusions}; use crate::{preferences::Preference, Exclusions};
@ -13,10 +13,10 @@ pub struct Manifest {
pub(crate) requirements: Vec<Requirement>, pub(crate) requirements: Vec<Requirement>,
/// The constraints for the project. /// The constraints for the project.
pub(crate) constraints: Vec<Requirement>, pub(crate) constraints: Constraints,
/// The overrides for the project. /// The overrides for the project.
pub(crate) overrides: Vec<Requirement>, pub(crate) overrides: Overrides,
/// The preferences for the project. /// The preferences for the project.
/// ///
@ -52,8 +52,8 @@ impl Manifest {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
requirements: Vec<Requirement>, requirements: Vec<Requirement>,
constraints: Vec<Requirement>, constraints: Constraints,
overrides: Vec<Requirement>, overrides: Overrides,
preferences: Vec<Preference>, preferences: Vec<Preference>,
project: Option<PackageName>, project: Option<PackageName>,
editables: Vec<(LocalEditable, Metadata23)>, editables: Vec<(LocalEditable, Metadata23)>,
@ -75,8 +75,8 @@ impl Manifest {
pub fn simple(requirements: Vec<Requirement>) -> Self { pub fn simple(requirements: Vec<Requirement>) -> Self {
Self { Self {
requirements, requirements,
constraints: Vec::new(), constraints: Constraints::default(),
overrides: Vec::new(), overrides: Overrides::default(),
preferences: Vec::new(), preferences: Vec::new(),
project: None, project: None,
editables: Vec::new(), editables: Vec::new(),
@ -118,12 +118,12 @@ impl Manifest {
) )
.chain( .chain(
self.constraints self.constraints
.iter() .requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])), .filter(|requirement| requirement.evaluate_markers(markers, &[])),
) )
.chain( .chain(
self.overrides self.overrides
.iter() .requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])), .filter(|requirement| requirement.evaluate_markers(markers, &[])),
) )
} }

View File

@ -6,9 +6,8 @@ use distribution_types::Verbatim;
use pep440_rs::Version; use pep440_rs::Version;
use pep508_rs::{MarkerEnvironment, Requirement, VersionOrUrl}; use pep508_rs::{MarkerEnvironment, Requirement, VersionOrUrl};
use uv_normalize::{ExtraName, PackageName}; use uv_normalize::{ExtraName, PackageName};
use uv_types::{Constraints, Overrides};
use crate::constraints::Constraints;
use crate::overrides::Overrides;
use crate::pubgrub::specifier::PubGrubSpecifier; use crate::pubgrub::specifier::PubGrubSpecifier;
use crate::pubgrub::PubGrubPackage; use crate::pubgrub::PubGrubPackage;
use crate::resolver::{Locals, Urls}; use crate::resolver::{Locals, Urls};

View File

@ -431,8 +431,8 @@ impl ResolutionGraph {
let direct_reqs = manifest let direct_reqs = manifest
.requirements .requirements
.iter() .iter()
.chain(&manifest.constraints) .chain(manifest.constraints.requirements())
.chain(&manifest.overrides); .chain(manifest.overrides.requirements());
for direct_req in direct_reqs { for direct_req in direct_reqs {
let Some(ref marker_tree) = direct_req.marker else { let Some(ref marker_tree) = direct_req.marker else {
continue; continue;

View File

@ -31,14 +31,13 @@ use uv_client::{FlatIndex, RegistryClient};
use uv_distribution::DistributionDatabase; use uv_distribution::DistributionDatabase;
use uv_interpreter::Interpreter; use uv_interpreter::Interpreter;
use uv_normalize::PackageName; use uv_normalize::PackageName;
use uv_types::{BuildContext, InstalledPackagesProvider}; use uv_types::{BuildContext, Constraints, InstalledPackagesProvider, Overrides};
use crate::candidate_selector::{CandidateDist, CandidateSelector}; use crate::candidate_selector::{CandidateDist, CandidateSelector};
use crate::constraints::Constraints;
use crate::editables::Editables; use crate::editables::Editables;
use crate::error::ResolveError; use crate::error::ResolveError;
use crate::manifest::Manifest; use crate::manifest::Manifest;
use crate::overrides::Overrides;
use crate::pins::FilePins; use crate::pins::FilePins;
use crate::preferences::Preferences; use crate::preferences::Preferences;
use crate::pubgrub::{ use crate::pubgrub::{
@ -188,8 +187,8 @@ impl<
locals: Locals::from_manifest(&manifest, markers), locals: Locals::from_manifest(&manifest, markers),
project: manifest.project, project: manifest.project,
requirements: manifest.requirements, requirements: manifest.requirements,
constraints: Constraints::from_requirements(manifest.constraints), constraints: manifest.constraints,
overrides: Overrides::from_requirements(manifest.overrides), overrides: manifest.overrides,
preferences: Preferences::from_iter(manifest.preferences, markers), preferences: Preferences::from_iter(manifest.preferences, markers),
exclusions: manifest.exclusions, exclusions: manifest.exclusions,
editables: Editables::from_requirements(manifest.editables), editables: Editables::from_requirements(manifest.editables),

View File

@ -53,7 +53,7 @@ impl Urls {
for requirement in manifest for requirement in manifest
.requirements .requirements
.iter() .iter()
.chain(manifest.constraints.iter()) .chain(manifest.constraints.requirements())
.filter(|requirement| requirement.evaluate_markers(markers, &[])) .filter(|requirement| requirement.evaluate_markers(markers, &[]))
{ {
if let Some(pep508_rs::VersionOrUrl::Url(url)) = &requirement.version_or_url { if let Some(pep508_rs::VersionOrUrl::Url(url)) = &requirement.version_or_url {
@ -125,7 +125,7 @@ impl Urls {
// authoritative. // authoritative.
for requirement in manifest for requirement in manifest
.overrides .overrides
.iter() .requirements()
.filter(|requirement| requirement.evaluate_markers(markers, &[])) .filter(|requirement| requirement.evaluate_markers(markers, &[]))
{ {
if let Some(pep508_rs::VersionOrUrl::Url(url)) = &requirement.version_or_url { if let Some(pep508_rs::VersionOrUrl::Url(url)) = &requirement.version_or_url {

View File

@ -14,6 +14,7 @@ pub struct AllowedYanks(FxHashMap<PackageName, FxHashSet<Version>>);
impl AllowedYanks { impl AllowedYanks {
pub fn from_manifest(manifest: &Manifest, markers: &MarkerEnvironment) -> Self { pub fn from_manifest(manifest: &Manifest, markers: &MarkerEnvironment) -> Self {
let mut allowed_yanks = FxHashMap::<PackageName, FxHashSet<Version>>::default(); let mut allowed_yanks = FxHashMap::<PackageName, FxHashSet<Version>>::default();
for requirement in manifest for requirement in manifest
.requirements(markers) .requirements(markers)
.chain(manifest.preferences.iter().map(Preference::requirement)) .chain(manifest.preferences.iter().map(Preference::requirement))

View File

@ -21,8 +21,8 @@ use uv_resolver::{
PreReleaseMode, Preference, ResolutionGraph, ResolutionMode, Resolver, PreReleaseMode, Preference, ResolutionGraph, ResolutionMode, Resolver,
}; };
use uv_types::{ use uv_types::{
BuildContext, BuildIsolation, BuildKind, EmptyInstalledPackages, NoBinary, NoBuild, BuildContext, BuildIsolation, BuildKind, Constraints, EmptyInstalledPackages, NoBinary,
SetupPyStrategy, SourceBuildTrait, NoBuild, Overrides, SetupPyStrategy, SourceBuildTrait,
}; };
// Exclude any packages uploaded after this date. // Exclude any packages uploaded after this date.
@ -269,8 +269,10 @@ async fn black_python_310() -> Result<()> {
async fn black_mypy_extensions() -> Result<()> { async fn black_mypy_extensions() -> Result<()> {
let manifest = Manifest::new( let manifest = Manifest::new(
vec![Requirement::from_str("black<=23.9.1").unwrap()], vec![Requirement::from_str("black<=23.9.1").unwrap()],
vec![Requirement::from_str("mypy-extensions<0.4.4").unwrap()], Constraints::from_requirements(vec![
vec![], Requirement::from_str("mypy-extensions<0.4.4").unwrap()
]),
Overrides::default(),
vec![], vec![],
None, None,
vec![], vec![],
@ -306,8 +308,10 @@ async fn black_mypy_extensions() -> Result<()> {
async fn black_mypy_extensions_extra() -> Result<()> { async fn black_mypy_extensions_extra() -> Result<()> {
let manifest = Manifest::new( let manifest = Manifest::new(
vec![Requirement::from_str("black<=23.9.1").unwrap()], vec![Requirement::from_str("black<=23.9.1").unwrap()],
vec![Requirement::from_str("mypy-extensions[extra]<0.4.4").unwrap()], Constraints::from_requirements(vec![
vec![], Requirement::from_str("mypy-extensions[extra]<0.4.4").unwrap()
]),
Overrides::default(),
vec![], vec![],
None, None,
vec![], vec![],
@ -343,8 +347,8 @@ async fn black_mypy_extensions_extra() -> Result<()> {
async fn black_flake8() -> Result<()> { async fn black_flake8() -> Result<()> {
let manifest = Manifest::new( let manifest = Manifest::new(
vec![Requirement::from_str("black<=23.9.1").unwrap()], vec![Requirement::from_str("black<=23.9.1").unwrap()],
vec![Requirement::from_str("flake8<1").unwrap()], Constraints::from_requirements(vec![Requirement::from_str("flake8<1").unwrap()]),
vec![], Overrides::default(),
vec![], vec![],
None, None,
vec![], vec![],
@ -432,8 +436,8 @@ async fn black_lowest_direct() -> Result<()> {
async fn black_respect_preference() -> Result<()> { async fn black_respect_preference() -> Result<()> {
let manifest = Manifest::new( let manifest = Manifest::new(
vec![Requirement::from_str("black<=23.9.1")?], vec![Requirement::from_str("black<=23.9.1")?],
vec![], Constraints::default(),
vec![], Overrides::default(),
vec![Preference::from_requirement(Requirement::from_str( vec![Preference::from_requirement(Requirement::from_str(
"black==23.9.0", "black==23.9.0",
)?)], )?)],
@ -470,8 +474,8 @@ async fn black_respect_preference() -> Result<()> {
async fn black_ignore_preference() -> Result<()> { async fn black_ignore_preference() -> Result<()> {
let manifest = Manifest::new( let manifest = Manifest::new(
vec![Requirement::from_str("black<=23.9.1")?], vec![Requirement::from_str("black<=23.9.1")?],
vec![], Constraints::default(),
vec![], Overrides::default(),
vec![Preference::from_requirement(Requirement::from_str( vec![Preference::from_requirement(Requirement::from_str(
"black==23.9.2", "black==23.9.2",
)?)], )?)],

View File

@ -21,6 +21,7 @@ uv-interpreter = { workspace = true }
uv-normalize = { workspace = true } uv-normalize = { workspace = true }
anyhow = { workspace = true } anyhow = { workspace = true }
itertools = { workspace = true }
rustc-hash = { workspace = true } rustc-hash = { workspace = true }
serde = { workspace = true, optional = true } serde = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true } serde_json = { workspace = true, optional = true }

View File

@ -7,11 +7,11 @@ use uv_normalize::PackageName;
/// A set of constraints for a set of requirements. /// A set of constraints for a set of requirements.
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub(crate) struct Constraints(FxHashMap<PackageName, Vec<Requirement>>); pub struct Constraints(FxHashMap<PackageName, Vec<Requirement>>);
impl Constraints { impl Constraints {
/// Create a new set of constraints from a set of requirements. /// Create a new set of constraints from a set of requirements.
pub(crate) fn from_requirements(requirements: Vec<Requirement>) -> Self { pub fn from_requirements(requirements: Vec<Requirement>) -> Self {
let mut constraints: FxHashMap<PackageName, Vec<Requirement>> = let mut constraints: FxHashMap<PackageName, Vec<Requirement>> =
FxHashMap::with_capacity_and_hasher(requirements.len(), BuildHasherDefault::default()); FxHashMap::with_capacity_and_hasher(requirements.len(), BuildHasherDefault::default());
for requirement in requirements { for requirement in requirements {
@ -23,8 +23,13 @@ impl Constraints {
Self(constraints) Self(constraints)
} }
/// Return an iterator over all [`Requirement`]s in the constraint set.
pub fn requirements(&self) -> impl Iterator<Item = &Requirement> {
self.0.values().flat_map(|requirements| requirements.iter())
}
/// Get the constraints for a package. /// Get the constraints for a package.
pub(crate) fn get(&self, name: &PackageName) -> Option<&Vec<Requirement>> { pub fn get(&self, name: &PackageName) -> Option<&Vec<Requirement>> {
self.0.get(name) self.0.get(name)
} }
} }

View File

@ -1,16 +1,20 @@
//! Fundamental types shared across `uv` crates. //! Fundamental types shared across `uv` crates.
pub use build_options::*; pub use build_options::*;
pub use config_settings::*; pub use config_settings::*;
pub use constraints::*;
pub use downloads::*; pub use downloads::*;
pub use name_specifiers::*; pub use name_specifiers::*;
pub use overrides::*;
pub use package_options::*; pub use package_options::*;
pub use requirements::*; pub use requirements::*;
pub use traits::*; pub use traits::*;
mod build_options; mod build_options;
mod config_settings; mod config_settings;
mod constraints;
mod downloads; mod downloads;
mod name_specifiers; mod name_specifiers;
mod overrides;
mod package_options; mod package_options;
mod requirements; mod requirements;
mod traits; mod traits;

View File

@ -8,11 +8,11 @@ use uv_normalize::PackageName;
/// A set of overrides for a set of requirements. /// A set of overrides for a set of requirements.
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub(crate) struct Overrides(FxHashMap<PackageName, Vec<Requirement>>); pub struct Overrides(FxHashMap<PackageName, Vec<Requirement>>);
impl Overrides { impl Overrides {
/// Create a new set of overrides from a set of requirements. /// Create a new set of overrides from a set of requirements.
pub(crate) fn from_requirements(requirements: Vec<Requirement>) -> Self { pub fn from_requirements(requirements: Vec<Requirement>) -> Self {
let mut overrides: FxHashMap<PackageName, Vec<Requirement>> = let mut overrides: FxHashMap<PackageName, Vec<Requirement>> =
FxHashMap::with_capacity_and_hasher(requirements.len(), BuildHasherDefault::default()); FxHashMap::with_capacity_and_hasher(requirements.len(), BuildHasherDefault::default());
for requirement in requirements { for requirement in requirements {
@ -24,13 +24,18 @@ impl Overrides {
Self(overrides) Self(overrides)
} }
/// Return an iterator over all [`Requirement`]s in the override set.
pub fn requirements(&self) -> impl Iterator<Item = &Requirement> {
self.0.values().flat_map(|requirements| requirements.iter())
}
/// Get the overrides for a package. /// Get the overrides for a package.
pub(crate) fn get(&self, name: &PackageName) -> Option<&Vec<Requirement>> { pub fn get(&self, name: &PackageName) -> Option<&Vec<Requirement>> {
self.0.get(name) self.0.get(name)
} }
/// Apply the overrides to a set of requirements. /// Apply the overrides to a set of requirements.
pub(crate) fn apply<'a>( pub fn apply<'a>(
&'a self, &'a self,
requirements: &'a [Requirement], requirements: &'a [Requirement],
) -> impl Iterator<Item = &Requirement> { ) -> impl Iterator<Item = &Requirement> {

View File

@ -36,8 +36,8 @@ use uv_resolver::{
OptionsBuilder, PreReleaseMode, PythonRequirement, ResolutionMode, Resolver, OptionsBuilder, PreReleaseMode, PythonRequirement, ResolutionMode, Resolver,
}; };
use uv_types::{ use uv_types::{
BuildIsolation, ConfigSettings, EmptyInstalledPackages, InFlight, NoBinary, NoBuild, BuildIsolation, ConfigSettings, Constraints, EmptyInstalledPackages, InFlight, NoBinary,
SetupPyStrategy, Upgrade, NoBuild, Overrides, SetupPyStrategy, Upgrade,
}; };
use uv_warnings::warn_user; use uv_warnings::warn_user;
@ -218,6 +218,10 @@ pub(crate) async fn pip_compile(
// Read the lockfile, if present. // Read the lockfile, if present.
let preferences = read_lockfile(output_file, upgrade).await?; let preferences = read_lockfile(output_file, upgrade).await?;
// Collect constraints and overrides.
let constraints = Constraints::from_requirements(constraints);
let overrides = Overrides::from_requirements(overrides);
// Resolve the flat indexes from `--find-links`. // Resolve the flat indexes from `--find-links`.
let flat_index = { let flat_index = {
let client = FlatIndexClient::new(&client, &cache); let client = FlatIndexClient::new(&client, &cache);

View File

@ -38,8 +38,8 @@ use uv_resolver::{
Preference, ResolutionGraph, ResolutionMode, Resolver, Preference, ResolutionGraph, ResolutionMode, Resolver,
}; };
use uv_types::{ use uv_types::{
BuildIsolation, ConfigSettings, InFlight, NoBinary, NoBuild, Reinstall, SetupPyStrategy, BuildIsolation, ConfigSettings, Constraints, InFlight, NoBinary, NoBuild, Overrides, Reinstall,
Upgrade, SetupPyStrategy, Upgrade,
}; };
use uv_warnings::warn_user; use uv_warnings::warn_user;
@ -523,6 +523,10 @@ async fn resolve(
.map(Preference::from_requirement) .map(Preference::from_requirement)
.collect(); .collect();
// Collect constraints and overrides.
let constraints = Constraints::from_requirements(constraints);
let overrides = Overrides::from_requirements(overrides);
// Map the editables to their metadata. // Map the editables to their metadata.
let editables: Vec<(LocalEditable, Metadata23)> = editables let editables: Vec<(LocalEditable, Metadata23)> = editables
.iter() .iter()