mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-18 03:13:48 +00:00
Enable first-class dependency exclusions (#16528)
## Summary This PR adds an `exclude-dependencies` setting that allows users to omit a dependency during resolution. It's effectively a formalized version of the `flask ; python_version < '0'` hack that we've suggested to users in various issues. Closes #12616.
This commit is contained in:
parent
7978122837
commit
5c71b5c124
42 changed files with 711 additions and 21 deletions
|
|
@ -1246,6 +1246,16 @@ pub struct PipCompileArgs {
|
|||
#[arg(long, alias = "override", env = EnvVars::UV_OVERRIDE, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||
pub overrides: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Exclude packages from resolution using the given requirements files.
|
||||
///
|
||||
/// Excludes files are `requirements.txt`-like files that specify packages to exclude
|
||||
/// from the resolution. When a package is excluded, it will be omitted from the
|
||||
/// dependency list entirely and its own dependencies will be ignored during the resolution
|
||||
/// phase. Excludes are unconditional in that requirement specifiers and markers are ignored;
|
||||
/// any package listed in the provided file will be omitted from all resolved environments.
|
||||
#[arg(long, alias = "exclude", env = EnvVars::UV_EXCLUDE, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||
pub excludes: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Constrain build dependencies using the given requirements files when building source
|
||||
/// distributions.
|
||||
///
|
||||
|
|
@ -1897,6 +1907,16 @@ pub struct PipInstallArgs {
|
|||
#[arg(long, alias = "override", env = EnvVars::UV_OVERRIDE, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||
pub overrides: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Exclude packages from resolution using the given requirements files.
|
||||
///
|
||||
/// Excludes files are `requirements.txt`-like files that specify packages to exclude
|
||||
/// from the resolution. When a package is excluded, it will be omitted from the
|
||||
/// dependency list entirely and its own dependencies will be ignored during the resolution
|
||||
/// phase. Excludes are unconditional in that requirement specifiers and markers are ignored;
|
||||
/// any package listed in the provided file will be omitted from all resolved environments.
|
||||
#[arg(long, alias = "exclude", env = EnvVars::UV_EXCLUDE, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||
pub excludes: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Constrain build dependencies using the given requirements files when building source
|
||||
/// distributions.
|
||||
///
|
||||
|
|
@ -4848,6 +4868,16 @@ pub struct ToolInstallArgs {
|
|||
#[arg(long, alias = "override", env = EnvVars::UV_OVERRIDE, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||
pub overrides: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Exclude packages from resolution using the given requirements files.
|
||||
///
|
||||
/// Excludes files are `requirements.txt`-like files that specify packages to exclude
|
||||
/// from the resolution. When a package is excluded, it will be omitted from the
|
||||
/// dependency list entirely and its own dependencies will be ignored during the resolution
|
||||
/// phase. Excludes are unconditional in that requirement specifiers and markers are ignored;
|
||||
/// any package listed in the provided file will be omitted from all resolved environments.
|
||||
#[arg(long, alias = "exclude", env = EnvVars::UV_EXCLUDE, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
|
||||
pub excludes: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Constrain build dependencies using the given requirements files when building source
|
||||
/// distributions.
|
||||
///
|
||||
|
|
|
|||
25
crates/uv-configuration/src/excludes.rs
Normal file
25
crates/uv-configuration/src/excludes.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use rustc_hash::FxHashSet;
|
||||
|
||||
use uv_normalize::PackageName;
|
||||
|
||||
/// A set of packages to exclude from resolution.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Excludes(FxHashSet<PackageName>);
|
||||
|
||||
impl Excludes {
|
||||
/// Return an iterator over all package names in the exclusion set.
|
||||
pub fn iter(&self) -> impl Iterator<Item = &PackageName> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
/// Check if a package is excluded.
|
||||
pub fn contains(&self, name: &PackageName) -> bool {
|
||||
self.0.contains(name)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<PackageName> for Excludes {
|
||||
fn from_iter<I: IntoIterator<Item = PackageName>>(iter: I) -> Self {
|
||||
Self(iter.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ pub use dependency_groups::*;
|
|||
pub use dry_run::*;
|
||||
pub use editable::*;
|
||||
pub use env_file::*;
|
||||
pub use excludes::*;
|
||||
pub use export_format::*;
|
||||
pub use extras::*;
|
||||
pub use hash::*;
|
||||
|
|
@ -30,6 +31,7 @@ mod dependency_groups;
|
|||
mod dry_run;
|
||||
mod editable;
|
||||
mod env_file;
|
||||
mod excludes;
|
||||
mod export_format;
|
||||
mod extras;
|
||||
mod hash;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ pub struct RequirementsSpecification {
|
|||
pub constraints: Vec<NameRequirementSpecification>,
|
||||
/// The overrides for the project.
|
||||
pub overrides: Vec<UnresolvedRequirementSpecification>,
|
||||
/// The excludes for the project.
|
||||
pub excludes: Vec<PackageName>,
|
||||
/// The `pylock.toml` file from which to extract the resolution.
|
||||
pub pylock: Option<PathBuf>,
|
||||
/// The source trees from which to extract requirements.
|
||||
|
|
@ -345,6 +347,7 @@ impl RequirementsSpecification {
|
|||
requirements: &[RequirementsSource],
|
||||
constraints: &[RequirementsSource],
|
||||
overrides: &[RequirementsSource],
|
||||
excludes: &[RequirementsSource],
|
||||
groups: Option<&GroupsSpecification>,
|
||||
client_builder: &BaseClientBuilder<'_>,
|
||||
) -> Result<Self> {
|
||||
|
|
@ -378,6 +381,20 @@ impl RequirementsSpecification {
|
|||
));
|
||||
}
|
||||
|
||||
// Disallow `pylock.toml` files as excludes.
|
||||
if let Some(pylock_toml) = excludes.iter().find_map(|source| {
|
||||
if let RequirementsSource::PylockToml(path) = source {
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Cannot use `{}` as an exclude file",
|
||||
pylock_toml.user_display()
|
||||
));
|
||||
}
|
||||
|
||||
// If we have a `pylock.toml`, don't allow additional requirements, constraints, or
|
||||
// overrides.
|
||||
if let Some(pylock_toml) = requirements.iter().find_map(|source| {
|
||||
|
|
@ -582,6 +599,24 @@ impl RequirementsSpecification {
|
|||
spec.no_build.extend(source.no_build);
|
||||
}
|
||||
|
||||
// Collect excludes.
|
||||
for source in excludes {
|
||||
let source = Self::from_source(source, client_builder).await?;
|
||||
for req_spec in source.requirements {
|
||||
match req_spec.requirement {
|
||||
UnresolvedRequirement::Named(requirement) => {
|
||||
spec.excludes.push(requirement.name);
|
||||
}
|
||||
UnresolvedRequirement::Unnamed(requirement) => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Unnamed requirements are not allowed as exclusions (found: `{requirement}`)"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
spec.excludes.extend(source.excludes.into_iter());
|
||||
}
|
||||
|
||||
Ok(spec)
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +632,7 @@ impl RequirementsSpecification {
|
|||
requirements: &[RequirementsSource],
|
||||
client_builder: &BaseClientBuilder<'_>,
|
||||
) -> Result<Self> {
|
||||
Self::from_sources(requirements, &[], &[], None, client_builder).await
|
||||
Self::from_sources(requirements, &[], &[], &[], None, client_builder).await
|
||||
}
|
||||
|
||||
/// Initialize a [`RequirementsSpecification`] from a list of [`Requirement`].
|
||||
|
|
|
|||
|
|
@ -1163,6 +1163,23 @@ impl Lock {
|
|||
manifest_table.insert("overrides", value(overrides));
|
||||
}
|
||||
|
||||
if !self.manifest.excludes.is_empty() {
|
||||
let excludes = self
|
||||
.manifest
|
||||
.excludes
|
||||
.iter()
|
||||
.map(|name| {
|
||||
serde::Serialize::serialize(&name, toml_edit::ser::ValueSerializer::new())
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let excludes = match excludes.as_slice() {
|
||||
[] => Array::new(),
|
||||
[name] => Array::from_iter([name]),
|
||||
excludes => each_element_on_its_line_array(excludes.iter()),
|
||||
};
|
||||
manifest_table.insert("excludes", value(excludes));
|
||||
}
|
||||
|
||||
if !self.manifest.build_constraints.is_empty() {
|
||||
let build_constraints = self
|
||||
.manifest
|
||||
|
|
@ -1447,6 +1464,7 @@ impl Lock {
|
|||
requirements: &[Requirement],
|
||||
constraints: &[Requirement],
|
||||
overrides: &[Requirement],
|
||||
excludes: &[PackageName],
|
||||
build_constraints: &[Requirement],
|
||||
dependency_groups: &BTreeMap<GroupName, Vec<Requirement>>,
|
||||
dependency_metadata: &DependencyMetadata,
|
||||
|
|
@ -1563,6 +1581,15 @@ impl Lock {
|
|||
}
|
||||
}
|
||||
|
||||
// Validate that the lockfile was generated with the same excludes.
|
||||
{
|
||||
let expected: BTreeSet<_> = excludes.iter().cloned().collect();
|
||||
let actual: BTreeSet<_> = self.manifest.excludes.iter().cloned().collect();
|
||||
if expected != actual {
|
||||
return Ok(SatisfiesResult::MismatchedExcludes(expected, actual));
|
||||
}
|
||||
}
|
||||
|
||||
// Validate that the lockfile was generated with the same build constraints.
|
||||
{
|
||||
let expected: BTreeSet<_> = build_constraints
|
||||
|
|
@ -2049,6 +2076,8 @@ pub enum SatisfiesResult<'lock> {
|
|||
MismatchedConstraints(BTreeSet<Requirement>, BTreeSet<Requirement>),
|
||||
/// The lockfile uses a different set of overrides.
|
||||
MismatchedOverrides(BTreeSet<Requirement>, BTreeSet<Requirement>),
|
||||
/// The lockfile uses a different set of excludes.
|
||||
MismatchedExcludes(BTreeSet<PackageName>, BTreeSet<PackageName>),
|
||||
/// The lockfile uses a different set of build constraints.
|
||||
MismatchedBuildConstraints(BTreeSet<Requirement>, BTreeSet<Requirement>),
|
||||
/// The lockfile uses a different set of dependency groups.
|
||||
|
|
@ -2148,6 +2177,9 @@ pub struct ResolverManifest {
|
|||
/// The overrides provided to the resolver.
|
||||
#[serde(default)]
|
||||
overrides: BTreeSet<Requirement>,
|
||||
/// The excludes provided to the resolver.
|
||||
#[serde(default)]
|
||||
excludes: BTreeSet<PackageName>,
|
||||
/// The build constraints provided to the resolver.
|
||||
#[serde(default)]
|
||||
build_constraints: BTreeSet<Requirement>,
|
||||
|
|
@ -2164,6 +2196,7 @@ impl ResolverManifest {
|
|||
requirements: impl IntoIterator<Item = Requirement>,
|
||||
constraints: impl IntoIterator<Item = Requirement>,
|
||||
overrides: impl IntoIterator<Item = Requirement>,
|
||||
excludes: impl IntoIterator<Item = PackageName>,
|
||||
build_constraints: impl IntoIterator<Item = Requirement>,
|
||||
dependency_groups: impl IntoIterator<Item = (GroupName, Vec<Requirement>)>,
|
||||
dependency_metadata: impl IntoIterator<Item = StaticMetadata>,
|
||||
|
|
@ -2173,6 +2206,7 @@ impl ResolverManifest {
|
|||
requirements: requirements.into_iter().collect(),
|
||||
constraints: constraints.into_iter().collect(),
|
||||
overrides: overrides.into_iter().collect(),
|
||||
excludes: excludes.into_iter().collect(),
|
||||
build_constraints: build_constraints.into_iter().collect(),
|
||||
dependency_groups: dependency_groups
|
||||
.into_iter()
|
||||
|
|
@ -2201,6 +2235,7 @@ impl ResolverManifest {
|
|||
.into_iter()
|
||||
.map(|requirement| requirement.relative_to(root))
|
||||
.collect::<Result<BTreeSet<_>, _>>()?,
|
||||
excludes: self.excludes,
|
||||
build_constraints: self
|
||||
.build_constraints
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ Ok(
|
|||
dependency_groups: {},
|
||||
constraints: {},
|
||||
overrides: {},
|
||||
excludes: {},
|
||||
build_constraints: {},
|
||||
dependency_metadata: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::collections::BTreeSet;
|
|||
|
||||
use either::Either;
|
||||
|
||||
use uv_configuration::{Constraints, Overrides};
|
||||
use uv_configuration::{Constraints, Excludes, Overrides};
|
||||
use uv_distribution_types::Requirement;
|
||||
use uv_normalize::PackageName;
|
||||
use uv_types::RequestedRequirements;
|
||||
|
|
@ -23,6 +23,9 @@ pub struct Manifest {
|
|||
/// The overrides for the project.
|
||||
pub(crate) overrides: Overrides,
|
||||
|
||||
/// The dependency excludes for the project.
|
||||
pub(crate) excludes: Excludes,
|
||||
|
||||
/// The preferences for the project.
|
||||
///
|
||||
/// These represent "preferred" versions of a given package. For example, they may be the
|
||||
|
|
@ -55,6 +58,7 @@ impl Manifest {
|
|||
requirements: Vec<Requirement>,
|
||||
constraints: Constraints,
|
||||
overrides: Overrides,
|
||||
excludes: Excludes,
|
||||
preferences: Preferences,
|
||||
project: Option<PackageName>,
|
||||
workspace_members: BTreeSet<PackageName>,
|
||||
|
|
@ -65,6 +69,7 @@ impl Manifest {
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
preferences,
|
||||
project,
|
||||
workspace_members,
|
||||
|
|
@ -78,6 +83,7 @@ impl Manifest {
|
|||
requirements,
|
||||
constraints: Constraints::default(),
|
||||
overrides: Overrides::default(),
|
||||
excludes: Excludes::default(),
|
||||
preferences: Preferences::default(),
|
||||
project: None,
|
||||
exclusions: Exclusions::default(),
|
||||
|
|
@ -122,6 +128,7 @@ impl Manifest {
|
|||
.flat_map(move |lookahead| {
|
||||
self.overrides
|
||||
.apply(lookahead.requirements())
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.filter(move |requirement| {
|
||||
requirement
|
||||
.evaluate_markers(env.marker_environment(), lookahead.extras())
|
||||
|
|
@ -130,6 +137,7 @@ impl Manifest {
|
|||
.chain(
|
||||
self.overrides
|
||||
.apply(&self.requirements)
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.filter(move |requirement| {
|
||||
requirement.evaluate_markers(env.marker_environment(), &[])
|
||||
}),
|
||||
|
|
@ -137,6 +145,7 @@ impl Manifest {
|
|||
.chain(
|
||||
self.constraints
|
||||
.requirements()
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.filter(move |requirement| {
|
||||
requirement.evaluate_markers(env.marker_environment(), &[])
|
||||
})
|
||||
|
|
@ -148,6 +157,7 @@ impl Manifest {
|
|||
self.overrides
|
||||
.apply(&self.requirements)
|
||||
.chain(self.constraints.requirements().map(Cow::Borrowed))
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.filter(move |requirement| {
|
||||
requirement.evaluate_markers(env.marker_environment(), &[])
|
||||
}),
|
||||
|
|
@ -166,6 +176,7 @@ impl Manifest {
|
|||
DependencyMode::Transitive => Either::Left(
|
||||
self.overrides
|
||||
.requirements()
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.filter(move |requirement| {
|
||||
requirement.evaluate_markers(env.marker_environment(), &[])
|
||||
})
|
||||
|
|
@ -175,6 +186,7 @@ impl Manifest {
|
|||
DependencyMode::Direct => Either::Right(
|
||||
self.overrides
|
||||
.requirements()
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.filter(move |requirement| {
|
||||
requirement.evaluate_markers(env.marker_environment(), &[])
|
||||
})
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use tokio::sync::oneshot;
|
|||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tracing::{Level, debug, info, instrument, trace, warn};
|
||||
|
||||
use uv_configuration::{Constraints, Overrides};
|
||||
use uv_configuration::{Constraints, Excludes, Overrides};
|
||||
use uv_distribution::{ArchiveMetadata, DistributionDatabase};
|
||||
use uv_distribution_types::{
|
||||
BuiltDist, CompatibleDist, DerivationChain, Dist, DistErrorKind, DistributionMetadata,
|
||||
|
|
@ -111,6 +111,7 @@ struct ResolverState<InstalledPackages: InstalledPackagesProvider> {
|
|||
requirements: Vec<Requirement>,
|
||||
constraints: Constraints,
|
||||
overrides: Overrides,
|
||||
excludes: Excludes,
|
||||
preferences: Preferences,
|
||||
git: GitResolver,
|
||||
capabilities: IndexCapabilities,
|
||||
|
|
@ -240,6 +241,7 @@ impl<Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvider>
|
|||
requirements: manifest.requirements,
|
||||
constraints: manifest.constraints,
|
||||
overrides: manifest.overrides,
|
||||
excludes: manifest.excludes,
|
||||
preferences: manifest.preferences,
|
||||
exclusions: manifest.exclusions,
|
||||
hasher: hasher.clone(),
|
||||
|
|
@ -1866,6 +1868,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
);
|
||||
|
||||
requirements
|
||||
.filter(|requirement| !self.excludes.contains(&requirement.name))
|
||||
.flat_map(|requirement| {
|
||||
PubGrubDependency::from_requirement(
|
||||
&self.conflicts,
|
||||
|
|
|
|||
|
|
@ -426,6 +426,7 @@ pub struct ToolUv {
|
|||
#[serde(flatten)]
|
||||
pub top_level: ResolverInstallerSchema,
|
||||
pub override_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
pub exclude_dependencies: Option<Vec<uv_normalize::PackageName>>,
|
||||
pub constraint_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
pub build_constraint_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
pub extra_build_dependencies: Option<BTreeMap<PackageName, Vec<ExtraBuildDependency>>>,
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ fn validate_uv_toml(path: &Path, options: &Options) -> Result<(), Error> {
|
|||
pip: _,
|
||||
cache_keys: _,
|
||||
override_dependencies: _,
|
||||
exclude_dependencies: _,
|
||||
constraint_dependencies: _,
|
||||
build_constraint_dependencies: _,
|
||||
environments,
|
||||
|
|
@ -352,6 +353,7 @@ fn warn_uv_toml_masked_fields(options: &Options) {
|
|||
pip,
|
||||
cache_keys,
|
||||
override_dependencies,
|
||||
exclude_dependencies,
|
||||
constraint_dependencies,
|
||||
build_constraint_dependencies,
|
||||
environments: _,
|
||||
|
|
@ -525,6 +527,9 @@ fn warn_uv_toml_masked_fields(options: &Options) {
|
|||
if override_dependencies.is_some() {
|
||||
masked_fields.push("override-dependencies");
|
||||
}
|
||||
if exclude_dependencies.is_some() {
|
||||
masked_fields.push("exclude-dependencies");
|
||||
}
|
||||
if constraint_dependencies.is_some() {
|
||||
masked_fields.push("constraint-dependencies");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@ pub struct Options {
|
|||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||
pub override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||
|
||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||
pub exclude_dependencies: Option<Vec<uv_normalize::PackageName>>,
|
||||
|
||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||
pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||
|
||||
|
|
@ -2110,6 +2113,7 @@ pub struct OptionsWire {
|
|||
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
||||
// They're respected in both `pyproject.toml` and `uv.toml` files.
|
||||
override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||
exclude_dependencies: Option<Vec<uv_normalize::PackageName>>,
|
||||
constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||
build_constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||
environments: Option<SupportedEnvironments>,
|
||||
|
|
@ -2180,6 +2184,7 @@ impl From<OptionsWire> for Options {
|
|||
pip,
|
||||
cache_keys,
|
||||
override_dependencies,
|
||||
exclude_dependencies,
|
||||
constraint_dependencies,
|
||||
build_constraint_dependencies,
|
||||
environments,
|
||||
|
|
@ -2254,6 +2259,7 @@ impl From<OptionsWire> for Options {
|
|||
cache_keys,
|
||||
build_backend,
|
||||
override_dependencies,
|
||||
exclude_dependencies,
|
||||
constraint_dependencies,
|
||||
build_constraint_dependencies,
|
||||
environments,
|
||||
|
|
|
|||
|
|
@ -120,21 +120,26 @@ impl EnvVars {
|
|||
#[attr_added_in("0.1.34")]
|
||||
pub const UV_REQUIRE_HASHES: &'static str = "UV_REQUIRE_HASHES";
|
||||
|
||||
/// Equivalent to the `--constraint` command-line argument. If set, uv will use this
|
||||
/// Equivalent to the `--constraints` command-line argument. If set, uv will use this
|
||||
/// file as the constraints file. Uses space-separated list of files.
|
||||
#[attr_added_in("0.1.36")]
|
||||
pub const UV_CONSTRAINT: &'static str = "UV_CONSTRAINT";
|
||||
|
||||
/// Equivalent to the `--build-constraint` command-line argument. If set, uv will use this file
|
||||
/// Equivalent to the `--build-constraints` command-line argument. If set, uv will use this file
|
||||
/// as constraints for any source distribution builds. Uses space-separated list of files.
|
||||
#[attr_added_in("0.2.34")]
|
||||
pub const UV_BUILD_CONSTRAINT: &'static str = "UV_BUILD_CONSTRAINT";
|
||||
|
||||
/// Equivalent to the `--override` command-line argument. If set, uv will use this file
|
||||
/// Equivalent to the `--overrides` command-line argument. If set, uv will use this file
|
||||
/// as the overrides file. Uses space-separated list of files.
|
||||
#[attr_added_in("0.2.22")]
|
||||
pub const UV_OVERRIDE: &'static str = "UV_OVERRIDE";
|
||||
|
||||
/// Equivalent to the `--excludes` command-line argument. If set, uv will use this
|
||||
/// as the excludes file. Uses space-separated list of files.
|
||||
#[attr_added_in("0.9.8")]
|
||||
pub const UV_EXCLUDE: &'static str = "UV_EXCLUDE";
|
||||
|
||||
/// Equivalent to the `--link-mode` command-line argument. If set, uv will use this as
|
||||
/// a link mode.
|
||||
#[attr_added_in("0.1.40")]
|
||||
|
|
|
|||
|
|
@ -489,6 +489,37 @@ pub struct ToolUv {
|
|||
)]
|
||||
pub override_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,
|
||||
|
||||
/// Dependencies to exclude when resolving the project's dependencies.
|
||||
///
|
||||
/// Excludes are used to prevent a package from being selected during resolution,
|
||||
/// regardless of whether it's requested by any other package. When a package is excluded,
|
||||
/// it will be omitted from the dependency list entirely.
|
||||
///
|
||||
/// Including a package as an exclusion will prevent it from being installed, even if
|
||||
/// it's requested by transitive dependencies. This can be useful for removing optional
|
||||
/// dependencies or working around packages with broken dependencies.
|
||||
///
|
||||
/// !!! note
|
||||
/// In `uv lock`, `uv sync`, and `uv run`, uv will only read `exclude-dependencies` from
|
||||
/// the `pyproject.toml` at the workspace root, and will ignore any declarations in other
|
||||
/// workspace members or `uv.toml` files.
|
||||
#[cfg_attr(
|
||||
feature = "schemars",
|
||||
schemars(
|
||||
with = "Option<Vec<String>>",
|
||||
description = "Package names to exclude, e.g., `werkzeug`, `numpy`."
|
||||
)
|
||||
)]
|
||||
#[option(
|
||||
default = "[]",
|
||||
value_type = "list[str]",
|
||||
example = r#"
|
||||
# Exclude Werkzeug from being installed, even if transitive dependencies request it.
|
||||
exclude-dependencies = ["werkzeug"]
|
||||
"#
|
||||
)]
|
||||
pub exclude_dependencies: Option<Vec<PackageName>>,
|
||||
|
||||
/// Constraints to apply when resolving the project's dependencies.
|
||||
///
|
||||
/// Constraints are used to restrict the versions of dependencies that are selected during
|
||||
|
|
|
|||
|
|
@ -661,6 +661,20 @@ impl Workspace {
|
|||
overrides.clone()
|
||||
}
|
||||
|
||||
/// Returns the set of dependency exclusions for the workspace.
|
||||
pub fn exclude_dependencies(&self) -> Vec<uv_normalize::PackageName> {
|
||||
let Some(excludes) = self
|
||||
.pyproject_toml
|
||||
.tool
|
||||
.as_ref()
|
||||
.and_then(|tool| tool.uv.as_ref())
|
||||
.and_then(|uv| uv.exclude_dependencies.as_ref())
|
||||
else {
|
||||
return vec![];
|
||||
};
|
||||
excludes.clone()
|
||||
}
|
||||
|
||||
/// Returns the set of constraints for the workspace.
|
||||
pub fn constraints(&self) -> Vec<uv_pep508::Requirement<VerbatimParsedUrl>> {
|
||||
let Some(constraints) = self
|
||||
|
|
@ -2059,6 +2073,7 @@ mod tests {
|
|||
"dependency-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"exclude-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"build-constraint-dependencies": null,
|
||||
"environments": null,
|
||||
|
|
@ -2159,6 +2174,7 @@ mod tests {
|
|||
"dependency-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"exclude-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"build-constraint-dependencies": null,
|
||||
"environments": null,
|
||||
|
|
@ -2372,6 +2388,7 @@ mod tests {
|
|||
"dependency-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"exclude-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"build-constraint-dependencies": null,
|
||||
"environments": null,
|
||||
|
|
@ -2481,6 +2498,7 @@ mod tests {
|
|||
"dependency-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"exclude-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"build-constraint-dependencies": null,
|
||||
"environments": null,
|
||||
|
|
@ -2603,6 +2621,7 @@ mod tests {
|
|||
"dependency-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"exclude-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"build-constraint-dependencies": null,
|
||||
"environments": null,
|
||||
|
|
@ -2699,6 +2718,7 @@ mod tests {
|
|||
"dependency-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"exclude-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"build-constraint-dependencies": null,
|
||||
"environments": null,
|
||||
|
|
|
|||
|
|
@ -62,9 +62,11 @@ pub(crate) async fn pip_compile(
|
|||
requirements: &[RequirementsSource],
|
||||
constraints: &[RequirementsSource],
|
||||
overrides: &[RequirementsSource],
|
||||
excludes: &[RequirementsSource],
|
||||
build_constraints: &[RequirementsSource],
|
||||
constraints_from_workspace: Vec<Requirement>,
|
||||
overrides_from_workspace: Vec<Requirement>,
|
||||
excludes_from_workspace: Vec<uv_normalize::PackageName>,
|
||||
build_constraints_from_workspace: Vec<Requirement>,
|
||||
environments: SupportedEnvironments,
|
||||
extras: ExtrasSpecification,
|
||||
|
|
@ -202,6 +204,7 @@ pub(crate) async fn pip_compile(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
pylock,
|
||||
source_trees,
|
||||
groups,
|
||||
|
|
@ -216,6 +219,7 @@ pub(crate) async fn pip_compile(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
Some(&groups),
|
||||
&client_builder,
|
||||
)
|
||||
|
|
@ -248,6 +252,11 @@ pub(crate) async fn pip_compile(
|
|||
)
|
||||
.collect();
|
||||
|
||||
let excludes: Vec<PackageName> = excludes
|
||||
.into_iter()
|
||||
.chain(excludes_from_workspace)
|
||||
.collect();
|
||||
|
||||
// Read build constraints.
|
||||
let build_constraints: Vec<NameRequirementSpecification> =
|
||||
operations::read_constraints(build_constraints, &client_builder)
|
||||
|
|
@ -532,6 +541,7 @@ pub(crate) async fn pip_compile(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
project,
|
||||
BTreeSet::default(),
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ use uv_distribution_types::{
|
|||
use uv_fs::Simplified;
|
||||
use uv_install_wheel::LinkMode;
|
||||
use uv_installer::{InstallationStrategy, SatisfiesResult, SitePackages};
|
||||
use uv_normalize::{DefaultExtras, DefaultGroups};
|
||||
use uv_normalize::{DefaultExtras, DefaultGroups, PackageName};
|
||||
use uv_preview::{Preview, PreviewFeatures};
|
||||
use uv_pypi_types::Conflicts;
|
||||
use uv_python::{
|
||||
|
|
@ -54,9 +54,11 @@ pub(crate) async fn pip_install(
|
|||
requirements: &[RequirementsSource],
|
||||
constraints: &[RequirementsSource],
|
||||
overrides: &[RequirementsSource],
|
||||
excludes: &[RequirementsSource],
|
||||
build_constraints: &[RequirementsSource],
|
||||
constraints_from_workspace: Vec<Requirement>,
|
||||
overrides_from_workspace: Vec<Requirement>,
|
||||
excludes_from_workspace: Vec<uv_normalize::PackageName>,
|
||||
build_constraints_from_workspace: Vec<Requirement>,
|
||||
extras: &ExtrasSpecification,
|
||||
groups: &GroupsSpecification,
|
||||
|
|
@ -118,6 +120,7 @@ pub(crate) async fn pip_install(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
pylock,
|
||||
source_trees,
|
||||
groups,
|
||||
|
|
@ -132,6 +135,7 @@ pub(crate) async fn pip_install(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
extras,
|
||||
Some(groups),
|
||||
&client_builder,
|
||||
|
|
@ -167,6 +171,11 @@ pub(crate) async fn pip_install(
|
|||
)
|
||||
.collect();
|
||||
|
||||
let excludes: Vec<PackageName> = excludes
|
||||
.into_iter()
|
||||
.chain(excludes_from_workspace)
|
||||
.collect();
|
||||
|
||||
// Read build constraints.
|
||||
let build_constraints: Vec<NameRequirementSpecification> =
|
||||
operations::read_constraints(build_constraints, &client_builder)
|
||||
|
|
@ -550,6 +559,7 @@ pub(crate) async fn pip_install(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
project,
|
||||
BTreeSet::default(),
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ use tracing::debug;
|
|||
use uv_cache::Cache;
|
||||
use uv_client::{BaseClientBuilder, RegistryClient};
|
||||
use uv_configuration::{
|
||||
BuildOptions, Concurrency, Constraints, DependencyGroups, DryRun, ExtrasSpecification,
|
||||
Overrides, Reinstall, Upgrade,
|
||||
BuildOptions, Concurrency, Constraints, DependencyGroups, DryRun, Excludes,
|
||||
ExtrasSpecification, Overrides, Reinstall, Upgrade,
|
||||
};
|
||||
use uv_dispatch::BuildDispatch;
|
||||
use uv_distribution::{DistributionDatabase, SourcedDependencyGroups};
|
||||
|
|
@ -54,6 +54,7 @@ pub(crate) async fn read_requirements(
|
|||
requirements: &[RequirementsSource],
|
||||
constraints: &[RequirementsSource],
|
||||
overrides: &[RequirementsSource],
|
||||
excludes: &[RequirementsSource],
|
||||
extras: &ExtrasSpecification,
|
||||
groups: Option<&GroupsSpecification>,
|
||||
client_builder: &BaseClientBuilder<'_>,
|
||||
|
|
@ -80,6 +81,7 @@ pub(crate) async fn read_requirements(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
groups,
|
||||
client_builder,
|
||||
)
|
||||
|
|
@ -92,7 +94,7 @@ pub(crate) async fn read_constraints(
|
|||
client_builder: &BaseClientBuilder<'_>,
|
||||
) -> Result<Vec<NameRequirementSpecification>, Error> {
|
||||
Ok(
|
||||
RequirementsSpecification::from_sources(&[], constraints, &[], None, client_builder)
|
||||
RequirementsSpecification::from_sources(&[], constraints, &[], &[], None, client_builder)
|
||||
.await?
|
||||
.constraints,
|
||||
)
|
||||
|
|
@ -103,6 +105,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
|
|||
requirements: Vec<UnresolvedRequirementSpecification>,
|
||||
constraints: Vec<NameRequirementSpecification>,
|
||||
overrides: Vec<UnresolvedRequirementSpecification>,
|
||||
excludes: Vec<PackageName>,
|
||||
source_trees: Vec<SourceTree>,
|
||||
mut project: Option<PackageName>,
|
||||
workspace_members: BTreeSet<PackageName>,
|
||||
|
|
@ -282,7 +285,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
|
|||
overrides
|
||||
};
|
||||
|
||||
// Collect constraints and overrides.
|
||||
// Collect constraints, overrides, and excludes.
|
||||
let constraints = Constraints::from_requirements(
|
||||
constraints
|
||||
.into_iter()
|
||||
|
|
@ -290,6 +293,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
|
|||
.chain(upgrade.constraints().cloned()),
|
||||
);
|
||||
let overrides = Overrides::from_requirements(overrides);
|
||||
let excludes = excludes.into_iter().collect::<Excludes>();
|
||||
let preferences = Preferences::from_iter(preferences, &resolver_env);
|
||||
|
||||
// Determine any lookahead requirements.
|
||||
|
|
@ -318,6 +322,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
preferences,
|
||||
project,
|
||||
workspace_members,
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ pub(crate) async fn pip_sync(
|
|||
|
||||
// Initialize a few defaults.
|
||||
let overrides = &[];
|
||||
let excludes = &[];
|
||||
let upgrade = Upgrade::default();
|
||||
let resolution_mode = ResolutionMode::default();
|
||||
let prerelease_mode = PrereleaseMode::default();
|
||||
|
|
@ -113,6 +114,7 @@ pub(crate) async fn pip_sync(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
pylock,
|
||||
source_trees,
|
||||
groups,
|
||||
|
|
@ -127,6 +129,7 @@ pub(crate) async fn pip_sync(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
extras,
|
||||
Some(groups),
|
||||
&client_builder,
|
||||
|
|
@ -461,6 +464,7 @@ pub(crate) async fn pip_sync(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
project,
|
||||
BTreeSet::default(),
|
||||
|
|
|
|||
|
|
@ -354,6 +354,7 @@ pub(crate) async fn add(
|
|||
&requirements,
|
||||
&constraints,
|
||||
&[],
|
||||
&[],
|
||||
None,
|
||||
&client_builder,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -485,6 +485,7 @@ async fn do_lock(
|
|||
let required_members = target.required_members();
|
||||
let requirements = target.requirements();
|
||||
let overrides = target.overrides();
|
||||
let excludes = target.exclude_dependencies();
|
||||
let constraints = target.constraints();
|
||||
let build_constraints = target.build_constraints();
|
||||
let dependency_groups = target.dependency_groups()?;
|
||||
|
|
@ -764,6 +765,7 @@ async fn do_lock(
|
|||
&dependency_groups,
|
||||
&constraints,
|
||||
&overrides,
|
||||
&excludes,
|
||||
&build_constraints,
|
||||
&conflicts,
|
||||
environments,
|
||||
|
|
@ -887,6 +889,7 @@ async fn do_lock(
|
|||
.cloned()
|
||||
.map(UnresolvedRequirementSpecification::from)
|
||||
.collect(),
|
||||
excludes.clone(),
|
||||
source_trees,
|
||||
// The root is always null in workspaces, it "depends on" the projects
|
||||
None,
|
||||
|
|
@ -925,6 +928,7 @@ async fn do_lock(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes.clone(),
|
||||
build_constraints,
|
||||
dependency_groups,
|
||||
dependency_metadata.values().cloned(),
|
||||
|
|
@ -983,6 +987,7 @@ impl ValidatedLock {
|
|||
dependency_groups: &BTreeMap<GroupName, Vec<Requirement>>,
|
||||
constraints: &[Requirement],
|
||||
overrides: &[Requirement],
|
||||
excludes: &[PackageName],
|
||||
build_constraints: &[Requirement],
|
||||
conflicts: &Conflicts,
|
||||
environments: Option<&SupportedEnvironments>,
|
||||
|
|
@ -1213,6 +1218,7 @@ impl ValidatedLock {
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
build_constraints,
|
||||
dependency_groups,
|
||||
dependency_metadata,
|
||||
|
|
@ -1305,6 +1311,13 @@ impl ValidatedLock {
|
|||
);
|
||||
Ok(Self::Preferable(lock))
|
||||
}
|
||||
SatisfiesResult::MismatchedExcludes(expected, actual) => {
|
||||
debug!(
|
||||
"Resolving despite existing lockfile due to mismatched excludes:\n Requested: {:?}\n Existing: {:?}",
|
||||
expected, actual
|
||||
);
|
||||
Ok(Self::Preferable(lock))
|
||||
}
|
||||
SatisfiesResult::MismatchedBuildConstraints(expected, actual) => {
|
||||
debug!(
|
||||
"Resolving despite existing lockfile due to mismatched build constraints:\n Requested: {:?}\n Existing: {:?}",
|
||||
|
|
|
|||
|
|
@ -62,6 +62,23 @@ impl<'lock> LockTarget<'lock> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the set of dependency exclusions for the [`LockTarget`].
|
||||
pub(crate) fn exclude_dependencies(self) -> Vec<uv_normalize::PackageName> {
|
||||
match self {
|
||||
Self::Workspace(workspace) => workspace.exclude_dependencies(),
|
||||
Self::Script(script) => script
|
||||
.metadata
|
||||
.tool
|
||||
.as_ref()
|
||||
.and_then(|tool| tool.uv.as_ref())
|
||||
.and_then(|uv| uv.exclude_dependencies.as_ref())
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the set of constraints for the [`LockTarget`].
|
||||
pub(crate) fn constraints(self) -> Vec<uv_pep508::Requirement<VerbatimParsedUrl>> {
|
||||
match self {
|
||||
|
|
|
|||
|
|
@ -1878,6 +1878,7 @@ pub(crate) async fn resolve_environment(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
..
|
||||
} = spec.requirements;
|
||||
|
|
@ -1997,6 +1998,7 @@ pub(crate) async fn resolve_environment(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
project,
|
||||
BTreeSet::default(),
|
||||
|
|
@ -2234,6 +2236,7 @@ pub(crate) async fn update_environment(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
..
|
||||
} = spec;
|
||||
|
|
@ -2366,6 +2369,7 @@ pub(crate) async fn update_environment(
|
|||
requirements,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
source_trees,
|
||||
project,
|
||||
BTreeSet::default(),
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ pub(crate) async fn install(
|
|||
with: &[RequirementsSource],
|
||||
constraints: &[RequirementsSource],
|
||||
overrides: &[RequirementsSource],
|
||||
excludes: &[RequirementsSource],
|
||||
build_constraints: &[RequirementsSource],
|
||||
entrypoints: &[PackageName],
|
||||
python: Option<String>,
|
||||
|
|
@ -251,6 +252,7 @@ pub(crate) async fn install(
|
|||
with,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
None,
|
||||
&client_builder,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -871,9 +871,15 @@ async fn get_or_create_environment(
|
|||
};
|
||||
|
||||
// Read the `--with` requirements.
|
||||
let spec =
|
||||
RequirementsSpecification::from_sources(with, constraints, overrides, None, client_builder)
|
||||
.await?;
|
||||
let spec = RequirementsSpecification::from_sources(
|
||||
with,
|
||||
constraints,
|
||||
overrides,
|
||||
&[],
|
||||
None,
|
||||
client_builder,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Resolve the `--from` and `--with` requirements.
|
||||
let requirements = {
|
||||
|
|
|
|||
|
|
@ -568,6 +568,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
.into_iter()
|
||||
.map(RequirementsSource::from_overrides_txt)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let excludes = args
|
||||
.excludes
|
||||
.into_iter()
|
||||
.map(RequirementsSource::from_requirements_txt)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let build_constraints = args
|
||||
.build_constraints
|
||||
.into_iter()
|
||||
|
|
@ -582,9 +587,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
&requirements,
|
||||
&constraints,
|
||||
&overrides,
|
||||
&excludes,
|
||||
&build_constraints,
|
||||
args.constraints_from_workspace,
|
||||
args.overrides_from_workspace,
|
||||
args.excludes_from_workspace,
|
||||
args.build_constraints_from_workspace,
|
||||
args.environments,
|
||||
args.settings.extras,
|
||||
|
|
@ -751,6 +758,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
.into_iter()
|
||||
.map(RequirementsSource::from_overrides_txt)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let excludes = args
|
||||
.excludes
|
||||
.into_iter()
|
||||
.map(RequirementsSource::from_requirements_txt)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let build_constraints = args
|
||||
.build_constraints
|
||||
.into_iter()
|
||||
|
|
@ -814,9 +826,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
&requirements,
|
||||
&constraints,
|
||||
&overrides,
|
||||
&excludes,
|
||||
&build_constraints,
|
||||
args.constraints_from_workspace,
|
||||
args.overrides_from_workspace,
|
||||
args.excludes_from_workspace,
|
||||
args.build_constraints_from_workspace,
|
||||
&args.settings.extras,
|
||||
&groups,
|
||||
|
|
@ -1376,6 +1390,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
.into_iter()
|
||||
.map(RequirementsSource::from_overrides_txt)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let excludes = args
|
||||
.excludes
|
||||
.into_iter()
|
||||
.map(RequirementsSource::from_requirements_txt)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let build_constraints = args
|
||||
.build_constraints
|
||||
.into_iter()
|
||||
|
|
@ -1389,6 +1408,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
&requirements,
|
||||
&constraints,
|
||||
&overrides,
|
||||
&excludes,
|
||||
&build_constraints,
|
||||
&entrypoints,
|
||||
args.python,
|
||||
|
|
|
|||
|
|
@ -681,6 +681,7 @@ pub(crate) struct ToolInstallSettings {
|
|||
pub(crate) with_editable: Vec<String>,
|
||||
pub(crate) constraints: Vec<PathBuf>,
|
||||
pub(crate) overrides: Vec<PathBuf>,
|
||||
pub(crate) excludes: Vec<PathBuf>,
|
||||
pub(crate) build_constraints: Vec<PathBuf>,
|
||||
pub(crate) python: Option<String>,
|
||||
pub(crate) python_platform: Option<TargetTriple>,
|
||||
|
|
@ -710,6 +711,7 @@ impl ToolInstallSettings {
|
|||
with_executables_from,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
build_constraints,
|
||||
installer,
|
||||
force,
|
||||
|
|
@ -762,6 +764,10 @@ impl ToolInstallSettings {
|
|||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.collect(),
|
||||
excludes: excludes
|
||||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.collect(),
|
||||
build_constraints: build_constraints
|
||||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
|
|
@ -2119,9 +2125,11 @@ pub(crate) struct PipCompileSettings {
|
|||
pub(crate) src_file: Vec<PathBuf>,
|
||||
pub(crate) constraints: Vec<PathBuf>,
|
||||
pub(crate) overrides: Vec<PathBuf>,
|
||||
pub(crate) excludes: Vec<PathBuf>,
|
||||
pub(crate) build_constraints: Vec<PathBuf>,
|
||||
pub(crate) constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) overrides_from_workspace: Vec<Requirement>,
|
||||
pub(crate) excludes_from_workspace: Vec<uv_normalize::PackageName>,
|
||||
pub(crate) build_constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) environments: SupportedEnvironments,
|
||||
pub(crate) refresh: Refresh,
|
||||
|
|
@ -2139,6 +2147,7 @@ impl PipCompileSettings {
|
|||
src_file,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
extra,
|
||||
all_extras,
|
||||
no_all_extras,
|
||||
|
|
@ -2216,6 +2225,15 @@ impl PipCompileSettings {
|
|||
Vec::new()
|
||||
};
|
||||
|
||||
let excludes_from_workspace = if let Some(configuration) = &filesystem {
|
||||
configuration
|
||||
.exclude_dependencies
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let build_constraints_from_workspace = if let Some(configuration) = &filesystem {
|
||||
configuration
|
||||
.build_constraint_dependencies
|
||||
|
|
@ -2251,8 +2269,13 @@ impl PipCompileSettings {
|
|||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.collect(),
|
||||
excludes: excludes
|
||||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.collect(),
|
||||
constraints_from_workspace,
|
||||
overrides_from_workspace,
|
||||
excludes_from_workspace,
|
||||
build_constraints_from_workspace,
|
||||
environments,
|
||||
refresh: Refresh::from(refresh),
|
||||
|
|
@ -2417,10 +2440,12 @@ pub(crate) struct PipInstallSettings {
|
|||
pub(crate) editables: Vec<String>,
|
||||
pub(crate) constraints: Vec<PathBuf>,
|
||||
pub(crate) overrides: Vec<PathBuf>,
|
||||
pub(crate) excludes: Vec<PathBuf>,
|
||||
pub(crate) build_constraints: Vec<PathBuf>,
|
||||
pub(crate) dry_run: DryRun,
|
||||
pub(crate) constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) overrides_from_workspace: Vec<Requirement>,
|
||||
pub(crate) excludes_from_workspace: Vec<uv_normalize::PackageName>,
|
||||
pub(crate) build_constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) modifications: Modifications,
|
||||
pub(crate) refresh: Refresh,
|
||||
|
|
@ -2440,6 +2465,7 @@ impl PipInstallSettings {
|
|||
editable,
|
||||
constraints,
|
||||
overrides,
|
||||
excludes,
|
||||
build_constraints,
|
||||
extra,
|
||||
all_extras,
|
||||
|
|
@ -2503,6 +2529,15 @@ impl PipInstallSettings {
|
|||
Vec::new()
|
||||
};
|
||||
|
||||
let excludes_from_workspace = if let Some(configuration) = &filesystem {
|
||||
configuration
|
||||
.exclude_dependencies
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let build_constraints_from_workspace = if let Some(configuration) = &filesystem {
|
||||
configuration
|
||||
.build_constraint_dependencies
|
||||
|
|
@ -2529,6 +2564,10 @@ impl PipInstallSettings {
|
|||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.collect(),
|
||||
excludes: excludes
|
||||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.collect(),
|
||||
build_constraints: build_constraints
|
||||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
|
|
@ -2536,6 +2575,7 @@ impl PipInstallSettings {
|
|||
dry_run: DryRun::from_args(dry_run),
|
||||
constraints_from_workspace,
|
||||
overrides_from_workspace,
|
||||
excludes_from_workspace,
|
||||
build_constraints_from_workspace,
|
||||
modifications: if flag(exact, inexact, "inexact").unwrap_or(false) {
|
||||
Modifications::Exact
|
||||
|
|
|
|||
|
|
@ -1774,6 +1774,203 @@ fn lock_project_with_override_sources() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Lock a project with `uv.tool.exclude-dependencies`.
|
||||
#[test]
|
||||
fn lock_project_with_excludes() -> 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 = ["flask==3.0.0"]
|
||||
|
||||
[tool.uv]
|
||||
exclude-dependencies = ["werkzeug"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock(), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 8 packages in [TIME]
|
||||
"###);
|
||||
|
||||
// Re-run with `--locked`.
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 8 packages in [TIME]
|
||||
"###);
|
||||
|
||||
// Install the base dependencies from the lockfile.
|
||||
uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 6 packages in [TIME]
|
||||
Installed 6 packages in [TIME]
|
||||
+ blinker==1.7.0
|
||||
+ click==8.1.7
|
||||
+ flask==3.0.0
|
||||
+ itsdangerous==2.1.2
|
||||
+ jinja2==3.1.3
|
||||
+ markupsafe==2.1.5
|
||||
"###);
|
||||
|
||||
// Check the lockfile contains the excludes.
|
||||
let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock"))?;
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r#"
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[options]
|
||||
exclude-newer = "2024-03-25T00:00:00Z"
|
||||
|
||||
[manifest]
|
||||
excludes = ["werkzeug"]
|
||||
|
||||
[[package]]
|
||||
name = "blinker"
|
||||
version = "1.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134, upload-time = "2023-11-01T22:06:01.588Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068, upload-time = "2023-11-01T22:06:00.162Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121, upload-time = "2023-08-17T17:29:11.868Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941, upload-time = "2023-08-17T17:29:10.08Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "3.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "blinker" },
|
||||
{ name = "click" },
|
||||
{ name = "itsdangerous" },
|
||||
{ name = "jinja2" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz", hash = "sha256:cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58", size = 674171, upload-time = "2023-09-30T14:36:12.918Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/36/42/015c23096649b908c809c69388a805a571a3bea44362fe87e33fc3afa01f/flask-3.0.0-py3-none-any.whl", hash = "sha256:21128f47e4e3b9d597a3e8521a329bf56909b690fcc3fa3e477725aa81367638", size = 99724, upload-time = "2023-09-30T14:36:10.961Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itsdangerous"
|
||||
version = "2.1.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143, upload-time = "2022-03-24T15:12:15.102Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749, upload-time = "2022-03-24T15:12:13.2Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markupsafe" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b2/5e/3a21abf3cd467d7876045335e681d276ac32492febe6d98ad89562d1a7e1/Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90", size = 268261, upload-time = "2024-01-10T23:12:21.133Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/30/6d/6de6be2d02603ab56e72997708809e8a5b0fbfee080735109b40a3564843/Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", size = 133236, upload-time = "2024-01-10T23:12:19.504Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "2.1.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384, upload-time = "2024-02-02T16:31:22.863Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215, upload-time = "2024-02-02T16:30:33.081Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069, upload-time = "2024-02-02T16:30:34.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452, upload-time = "2024-02-02T16:30:35.149Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462, upload-time = "2024-02-02T16:30:36.166Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869, upload-time = "2024-02-02T16:30:37.834Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906, upload-time = "2024-02-02T16:30:39.366Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296, upload-time = "2024-02-02T16:30:40.413Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038, upload-time = "2024-02-02T16:30:42.243Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572, upload-time = "2024-02-02T16:30:43.326Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127, upload-time = "2024-02-02T16:30:44.418Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "flask" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "flask", specifier = "==3.0.0" }]
|
||||
"#
|
||||
);
|
||||
});
|
||||
|
||||
// Modify the excludes and verify that `--locked` fails.
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["flask==3.0.0"]
|
||||
|
||||
[tool.uv]
|
||||
exclude-dependencies = ["jinja2"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 8 packages in [TIME]
|
||||
The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Lock a project with `uv.tool.constraint-dependencies`.
|
||||
#[test]
|
||||
fn lock_project_with_constraints() -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -98,9 +98,11 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -299,9 +301,11 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -501,9 +505,11 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -735,9 +741,11 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -938,9 +946,11 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -1117,9 +1127,11 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -1345,9 +1357,11 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -1581,9 +1595,11 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -1875,9 +1891,11 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -2100,9 +2118,11 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -2284,9 +2304,11 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -2518,9 +2540,11 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -2775,9 +2799,11 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -2949,9 +2975,11 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -3123,9 +3151,11 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -3299,9 +3329,11 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -3496,6 +3528,7 @@ fn resolve_tool() -> anyhow::Result<()> {
|
|||
with_editable: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
python: None,
|
||||
python_platform: None,
|
||||
|
|
@ -3681,9 +3714,11 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -3889,9 +3924,11 @@ fn resolve_both() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -4136,9 +4173,11 @@ fn resolve_both_special_fields() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -4462,9 +4501,11 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -4642,7 +4683,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
|||
|
|
||||
1 | [project]
|
||||
| ^^^^^^^
|
||||
unknown field `project`, expected one of `required-version`, `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `fork-strategy`, `dependency-metadata`, `config-settings`, `config-settings-package`, `no-build-isolation`, `no-build-isolation-package`, `extra-build-dependencies`, `extra-build-variables`, `exclude-newer`, `exclude-newer-package`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `python-downloads-json-url`, `publish-url`, `trusted-publishing`, `check-url`, `add-bounds`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `build-constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dependency-groups`, `dev-dependencies`, `build-backend`
|
||||
unknown field `project`, expected one of `required-version`, `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `fork-strategy`, `dependency-metadata`, `config-settings`, `config-settings-package`, `no-build-isolation`, `no-build-isolation-package`, `extra-build-dependencies`, `extra-build-variables`, `exclude-newer`, `exclude-newer-package`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `python-downloads-json-url`, `publish-url`, `trusted-publishing`, `check-url`, `add-bounds`, `pip`, `cache-keys`, `override-dependencies`, `exclude-dependencies`, `constraint-dependencies`, `build-constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dependency-groups`, `dev-dependencies`, `build-backend`
|
||||
"
|
||||
);
|
||||
|
||||
|
|
@ -4763,9 +4804,11 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -4940,9 +4983,11 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -5136,9 +5181,11 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -5324,9 +5371,11 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -5560,9 +5609,11 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -5802,9 +5853,11 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -6039,9 +6092,11 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -6283,9 +6338,11 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -6520,9 +6577,11 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -6771,10 +6830,12 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
editables: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
dry_run: Disabled,
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
modifications: Sufficient,
|
||||
refresh: None(
|
||||
|
|
@ -6938,10 +6999,12 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
editables: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
dry_run: Disabled,
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
modifications: Sufficient,
|
||||
refresh: None(
|
||||
|
|
@ -7103,10 +7166,12 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
editables: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
dry_run: Disabled,
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
modifications: Sufficient,
|
||||
refresh: None(
|
||||
|
|
@ -7270,10 +7335,12 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
editables: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
dry_run: Disabled,
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
modifications: Sufficient,
|
||||
refresh: None(
|
||||
|
|
@ -7435,10 +7502,12 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
editables: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
dry_run: Disabled,
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
modifications: Sufficient,
|
||||
refresh: None(
|
||||
|
|
@ -7601,10 +7670,12 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
editables: [],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
dry_run: Disabled,
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
modifications: Sufficient,
|
||||
refresh: None(
|
||||
|
|
@ -8488,9 +8559,11 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -8663,9 +8736,11 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -8861,9 +8936,11 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -9034,9 +9111,11 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -9201,9 +9280,11 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -9369,9 +9450,11 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -10367,9 +10450,11 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
@ -10537,9 +10622,11 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
|||
],
|
||||
constraints: [],
|
||||
overrides: [],
|
||||
excludes: [],
|
||||
build_constraints: [],
|
||||
constraints_from_workspace: [],
|
||||
overrides_from_workspace: [],
|
||||
excludes_from_workspace: [],
|
||||
build_constraints_from_workspace: [],
|
||||
environments: SupportedEnvironments(
|
||||
[],
|
||||
|
|
|
|||
|
|
@ -2613,7 +2613,9 @@ uv tool install [OPTIONS] <PACKAGE>
|
|||
<p>May also be set with the <code>UV_EXCLUDE_NEWER</code> environment variable.</p></dd><dt id="uv-tool-install--exclude-newer-package"><a href="#uv-tool-install--exclude-newer-package"><code>--exclude-newer-package</code></a> <i>exclude-newer-package</i></dt><dd><p>Limit candidate packages for specific packages to those that were uploaded prior to the given date.</p>
|
||||
<p>Accepts package-date pairs in the format <code>PACKAGE=DATE</code>, where <code>DATE</code> is an RFC 3339 timestamp (e.g., <code>2006-12-02T02:07:43Z</code>) or local date (e.g., <code>2006-12-02</code>) in your system's configured time zone.</p>
|
||||
<p>Can be provided multiple times for different packages.</p>
|
||||
</dd><dt id="uv-tool-install--extra-index-url"><a href="#uv-tool-install--extra-index-url"><code>--extra-index-url</code></a> <i>extra-index-url</i></dt><dd><p>(Deprecated: use <code>--index</code> instead) Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</p>
|
||||
</dd><dt id="uv-tool-install--excludes"><a href="#uv-tool-install--excludes"><code>--excludes</code></a>, <code>--exclude</code> <i>excludes</i></dt><dd><p>Exclude packages from resolution using the given requirements files.</p>
|
||||
<p>Excludes files are <code>requirements.txt</code>-like files that specify packages to exclude from the resolution. When a package is excluded, it will be omitted from the dependency list entirely and its own dependencies will be ignored during the resolution phase. Excludes are unconditional in that requirement specifiers and markers are ignored; any package listed in the provided file will be omitted from all resolved environments.</p>
|
||||
<p>May also be set with the <code>UV_EXCLUDE</code> environment variable.</p></dd><dt id="uv-tool-install--extra-index-url"><a href="#uv-tool-install--extra-index-url"><code>--extra-index-url</code></a> <i>extra-index-url</i></dt><dd><p>(Deprecated: use <code>--index</code> instead) Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</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>All indexes provided via this flag take priority over the index specified by <code>--index-url</code> (which defaults to PyPI). When multiple <code>--extra-index-url</code> flags are provided, earlier values take priority.</p>
|
||||
<p>May also be set with the <code>UV_EXTRA_INDEX_URL</code> environment variable.</p></dd><dt id="uv-tool-install--find-links"><a href="#uv-tool-install--find-links"><code>--find-links</code></a>, <code>-f</code> <i>find-links</i></dt><dd><p>Locations to search for candidate distributions, in addition to those found in the registry indexes.</p>
|
||||
|
|
@ -4054,7 +4056,9 @@ uv pip compile [OPTIONS] <SRC_FILE|--group <GROUP>>
|
|||
<p>May also be set with the <code>UV_EXCLUDE_NEWER</code> environment variable.</p></dd><dt id="uv-pip-compile--exclude-newer-package"><a href="#uv-pip-compile--exclude-newer-package"><code>--exclude-newer-package</code></a> <i>exclude-newer-package</i></dt><dd><p>Limit candidate packages for a specific package to those that were uploaded prior to the given date.</p>
|
||||
<p>Accepts package-date pairs in the format <code>PACKAGE=DATE</code>, where <code>DATE</code> is an RFC 3339 timestamp (e.g., <code>2006-12-02T02:07:43Z</code>) or local date (e.g., <code>2006-12-02</code>) in your system's configured time zone.</p>
|
||||
<p>Can be provided multiple times for different packages.</p>
|
||||
</dd><dt id="uv-pip-compile--extra"><a href="#uv-pip-compile--extra"><code>--extra</code></a> <i>extra</i></dt><dd><p>Include optional dependencies from the specified extra name; may be provided more than once.</p>
|
||||
</dd><dt id="uv-pip-compile--excludes"><a href="#uv-pip-compile--excludes"><code>--excludes</code></a>, <code>--exclude</code> <i>excludes</i></dt><dd><p>Exclude packages from resolution using the given requirements files.</p>
|
||||
<p>Excludes files are <code>requirements.txt</code>-like files that specify packages to exclude from the resolution. When a package is excluded, it will be omitted from the dependency list entirely and its own dependencies will be ignored during the resolution phase. Excludes are unconditional in that requirement specifiers and markers are ignored; any package listed in the provided file will be omitted from all resolved environments.</p>
|
||||
<p>May also be set with the <code>UV_EXCLUDE</code> environment variable.</p></dd><dt id="uv-pip-compile--extra"><a href="#uv-pip-compile--extra"><code>--extra</code></a> <i>extra</i></dt><dd><p>Include optional dependencies from the specified extra 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>
|
||||
</dd><dt id="uv-pip-compile--extra-index-url"><a href="#uv-pip-compile--extra-index-url"><code>--extra-index-url</code></a> <i>extra-index-url</i></dt><dd><p>(Deprecated: use <code>--index</code> instead) Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</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>
|
||||
|
|
@ -4647,7 +4651,9 @@ uv pip install [OPTIONS] <PACKAGE|--requirements <REQUIREMENTS>|--editable <EDIT
|
|||
<p>May also be set with the <code>UV_EXCLUDE_NEWER</code> environment variable.</p></dd><dt id="uv-pip-install--exclude-newer-package"><a href="#uv-pip-install--exclude-newer-package"><code>--exclude-newer-package</code></a> <i>exclude-newer-package</i></dt><dd><p>Limit candidate packages for specific packages to those that were uploaded prior to the given date.</p>
|
||||
<p>Accepts package-date pairs in the format <code>PACKAGE=DATE</code>, where <code>DATE</code> is an RFC 3339 timestamp (e.g., <code>2006-12-02T02:07:43Z</code>) or local date (e.g., <code>2006-12-02</code>) in your system's configured time zone.</p>
|
||||
<p>Can be provided multiple times for different packages.</p>
|
||||
</dd><dt id="uv-pip-install--extra"><a href="#uv-pip-install--extra"><code>--extra</code></a> <i>extra</i></dt><dd><p>Include optional dependencies from the specified extra name; may be provided more than once.</p>
|
||||
</dd><dt id="uv-pip-install--excludes"><a href="#uv-pip-install--excludes"><code>--excludes</code></a>, <code>--exclude</code> <i>excludes</i></dt><dd><p>Exclude packages from resolution using the given requirements files.</p>
|
||||
<p>Excludes files are <code>requirements.txt</code>-like files that specify packages to exclude from the resolution. When a package is excluded, it will be omitted from the dependency list entirely and its own dependencies will be ignored during the resolution phase. Excludes are unconditional in that requirement specifiers and markers are ignored; any package listed in the provided file will be omitted from all resolved environments.</p>
|
||||
<p>May also be set with the <code>UV_EXCLUDE</code> environment variable.</p></dd><dt id="uv-pip-install--extra"><a href="#uv-pip-install--extra"><code>--extra</code></a> <i>extra</i></dt><dd><p>Include optional dependencies from the specified extra name; may be provided more than once.</p>
|
||||
<p>Only applies to <code>pylock.toml</code>, <code>pyproject.toml</code>, <code>setup.py</code>, and <code>setup.cfg</code> sources.</p>
|
||||
</dd><dt id="uv-pip-install--extra-index-url"><a href="#uv-pip-install--extra-index-url"><code>--extra-index-url</code></a> <i>extra-index-url</i></dt><dd><p>(Deprecated: use <code>--index</code> instead) Extra URLs of package indexes to use, in addition to <code>--index-url</code>.</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>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Python can lead to unexpected behavior.
|
|||
### `UV_BUILD_CONSTRAINT`
|
||||
<small class="added-in">added in `0.2.34`</small>
|
||||
|
||||
Equivalent to the `--build-constraint` command-line argument. If set, uv will use this file
|
||||
Equivalent to the `--build-constraints` command-line argument. If set, uv will use this file
|
||||
as constraints for any source distribution builds. Uses space-separated list of files.
|
||||
|
||||
### `UV_CACHE_DIR`
|
||||
|
|
@ -62,7 +62,7 @@ local `uv.toml` file to use as the configuration file.
|
|||
### `UV_CONSTRAINT`
|
||||
<small class="added-in">added in `0.1.36`</small>
|
||||
|
||||
Equivalent to the `--constraint` command-line argument. If set, uv will use this
|
||||
Equivalent to the `--constraints` command-line argument. If set, uv will use this
|
||||
file as the constraints file. Uses space-separated list of files.
|
||||
|
||||
### `UV_CREDENTIALS_DIR`
|
||||
|
|
@ -103,6 +103,12 @@ compatibility.
|
|||
|
||||
`.env` files from which to load environment variables when executing `uv run` commands.
|
||||
|
||||
### `UV_EXCLUDE`
|
||||
<small class="added-in">added in `0.9.8`</small>
|
||||
|
||||
Equivalent to the `--excludes` command-line argument. If set, uv will use this
|
||||
as the excludes file. Uses space-separated list of files.
|
||||
|
||||
### `UV_EXCLUDE_NEWER`
|
||||
<small class="added-in">added in `0.2.12`</small>
|
||||
|
||||
|
|
@ -405,7 +411,7 @@ Equivalent to the `--offline` command-line argument. If set, uv will disable net
|
|||
### `UV_OVERRIDE`
|
||||
<small class="added-in">added in `0.2.22`</small>
|
||||
|
||||
Equivalent to the `--override` command-line argument. If set, uv will use this file
|
||||
Equivalent to the `--overrides` command-line argument. If set, uv will use this file
|
||||
as the overrides file. Uses space-separated list of files.
|
||||
|
||||
### `UV_PRERELEASE`
|
||||
|
|
|
|||
|
|
@ -202,6 +202,37 @@ environments = ["sys_platform == 'darwin'"]
|
|||
|
||||
---
|
||||
|
||||
### [`exclude-dependencies`](#exclude-dependencies) {: #exclude-dependencies }
|
||||
|
||||
Dependencies to exclude when resolving the project's dependencies.
|
||||
|
||||
Excludes are used to prevent a package from being selected during resolution,
|
||||
regardless of whether it's requested by any other package. When a package is excluded,
|
||||
it will be omitted from the dependency list entirely.
|
||||
|
||||
Including a package as an exclusion will prevent it from being installed, even if
|
||||
it's requested by transitive dependencies. This can be useful for removing optional
|
||||
dependencies or working around packages with broken dependencies.
|
||||
|
||||
!!! note
|
||||
In `uv lock`, `uv sync`, and `uv run`, uv will only read `exclude-dependencies` from
|
||||
the `pyproject.toml` at the workspace root, and will ignore any declarations in other
|
||||
workspace members or `uv.toml` files.
|
||||
|
||||
**Default value**: `[]`
|
||||
|
||||
**Type**: `list[str]`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml title="pyproject.toml"
|
||||
[tool.uv]
|
||||
# Exclude Werkzeug from being installed, even if transitive dependencies request it.
|
||||
exclude-dependencies = ["werkzeug"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### [`index`](#index) {: #index }
|
||||
|
||||
The indexes to use when resolving dependencies.
|
||||
|
|
|
|||
10
uv.schema.json
generated
10
uv.schema.json
generated
|
|
@ -203,6 +203,16 @@
|
|||
"type": "string"
|
||||
}
|
||||
},
|
||||
"exclude-dependencies": {
|
||||
"description": "Package names to exclude, e.g., `werkzeug`, `numpy`.",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"exclude-newer": {
|
||||
"description": "Limit candidate packages to those that were uploaded prior to a given point in time.\n\nAccepts a superset of [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) (e.g.,\n`2006-12-02T02:07:43Z`). A full timestamp is required to ensure that the resolver will\nbehave consistently across timezones.",
|
||||
"anyOf": [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue