mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-23 12:56:47 +00:00
Allow users to mark platforms as "required" for wheel coverage (#10067)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
## Summary This PR revives https://github.com/astral-sh/uv/pull/10017, which might be viable now that we _don't_ enforce any platforms by default. The basic idea here is that users can mark certain platforms as required (empty, by default). When resolving, we ensure that the specified platforms have wheel coverage, backtracking if not. For example, to require that we include a version of PyTorch that supports Intel macOS: ```toml [project] name = "project" version = "0.1.0" requires-python = ">=3.11" dependencies = ["torch>1.13"] [tool.uv] required-platforms = [ "sys_platform == 'darwin' and platform_machine == 'x86_64'" ] ``` Other than that, the forking is identical to past iterations of this PR. This would give users a way to resolve the tail of issues in #9711, but with manual opt-in to supporting specific platforms.
This commit is contained in:
parent
9cdfad191c
commit
172305abb6
29 changed files with 1236 additions and 381 deletions
58
crates/uv-distribution-types/src/known_platform.rs
Normal file
58
crates/uv-distribution-types/src/known_platform.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
|
use uv_pep508::{MarkerExpression, MarkerOperator, MarkerTree, MarkerValueString};
|
||||||
|
|
||||||
|
/// A platform for which the resolver is solving.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum KnownPlatform {
|
||||||
|
Linux,
|
||||||
|
Windows,
|
||||||
|
MacOS,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KnownPlatform {
|
||||||
|
/// Return the platform's `sys.platform` value.
|
||||||
|
pub fn sys_platform(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
KnownPlatform::Linux => "linux",
|
||||||
|
KnownPlatform::Windows => "win32",
|
||||||
|
KnownPlatform::MacOS => "darwin",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a [`MarkerTree`] for the platform.
|
||||||
|
pub fn marker(self) -> MarkerTree {
|
||||||
|
MarkerTree::expression(MarkerExpression::String {
|
||||||
|
key: MarkerValueString::SysPlatform,
|
||||||
|
operator: MarkerOperator::Equal,
|
||||||
|
value: match self {
|
||||||
|
KnownPlatform::Linux => arcstr::literal!("linux"),
|
||||||
|
KnownPlatform::Windows => arcstr::literal!("win32"),
|
||||||
|
KnownPlatform::MacOS => arcstr::literal!("darwin"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine the [`KnownPlatform`] from a marker tree.
|
||||||
|
pub fn from_marker(marker: MarkerTree) -> Option<KnownPlatform> {
|
||||||
|
if marker == KnownPlatform::Linux.marker() {
|
||||||
|
Some(KnownPlatform::Linux)
|
||||||
|
} else if marker == KnownPlatform::Windows.marker() {
|
||||||
|
Some(KnownPlatform::Windows)
|
||||||
|
} else if marker == KnownPlatform::MacOS.marker() {
|
||||||
|
Some(KnownPlatform::MacOS)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for KnownPlatform {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
KnownPlatform::Linux => write!(f, "Linux"),
|
||||||
|
KnownPlatform::Windows => write!(f, "Windows"),
|
||||||
|
KnownPlatform::MacOS => write!(f, "macOS"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -66,6 +66,7 @@ pub use crate::index::*;
|
||||||
pub use crate::index_name::*;
|
pub use crate::index_name::*;
|
||||||
pub use crate::index_url::*;
|
pub use crate::index_url::*;
|
||||||
pub use crate::installed::*;
|
pub use crate::installed::*;
|
||||||
|
pub use crate::known_platform::*;
|
||||||
pub use crate::origin::*;
|
pub use crate::origin::*;
|
||||||
pub use crate::pip_index::*;
|
pub use crate::pip_index::*;
|
||||||
pub use crate::prioritized_distribution::*;
|
pub use crate::prioritized_distribution::*;
|
||||||
|
|
@ -90,6 +91,7 @@ mod index;
|
||||||
mod index_name;
|
mod index_name;
|
||||||
mod index_url;
|
mod index_url;
|
||||||
mod installed;
|
mod installed;
|
||||||
|
mod known_platform;
|
||||||
mod origin;
|
mod origin;
|
||||||
mod pip_index;
|
mod pip_index;
|
||||||
mod prioritized_distribution;
|
mod prioritized_distribution;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ use uv_platform_tags::{AbiTag, IncompatibleTag, LanguageTag, PlatformTag, TagPri
|
||||||
use uv_pypi_types::{HashDigest, Yanked};
|
use uv_pypi_types::{HashDigest, Yanked};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
InstalledDist, RegistryBuiltDist, RegistryBuiltWheel, RegistrySourceDist, ResolvedDistRef,
|
InstalledDist, KnownPlatform, RegistryBuiltDist, RegistryBuiltWheel, RegistrySourceDist,
|
||||||
|
ResolvedDistRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A collection of distributions that have been filtered by relevance.
|
/// A collection of distributions that have been filtered by relevance.
|
||||||
|
|
@ -123,6 +124,7 @@ impl IncompatibleDist {
|
||||||
None => format!("has {self}"),
|
None => format!("has {self}"),
|
||||||
},
|
},
|
||||||
IncompatibleWheel::RequiresPython(..) => format!("requires {self}"),
|
IncompatibleWheel::RequiresPython(..) => format!("requires {self}"),
|
||||||
|
IncompatibleWheel::MissingPlatform(_) => format!("has {self}"),
|
||||||
},
|
},
|
||||||
Self::Source(incompatibility) => match incompatibility {
|
Self::Source(incompatibility) => match incompatibility {
|
||||||
IncompatibleSource::NoBuild => format!("has {self}"),
|
IncompatibleSource::NoBuild => format!("has {self}"),
|
||||||
|
|
@ -150,6 +152,7 @@ impl IncompatibleDist {
|
||||||
None => format!("have {self}"),
|
None => format!("have {self}"),
|
||||||
},
|
},
|
||||||
IncompatibleWheel::RequiresPython(..) => format!("require {self}"),
|
IncompatibleWheel::RequiresPython(..) => format!("require {self}"),
|
||||||
|
IncompatibleWheel::MissingPlatform(_) => format!("have {self}"),
|
||||||
},
|
},
|
||||||
Self::Source(incompatibility) => match incompatibility {
|
Self::Source(incompatibility) => match incompatibility {
|
||||||
IncompatibleSource::NoBuild => format!("have {self}"),
|
IncompatibleSource::NoBuild => format!("have {self}"),
|
||||||
|
|
@ -194,6 +197,7 @@ impl IncompatibleDist {
|
||||||
IncompatibleWheel::Yanked(..) => None,
|
IncompatibleWheel::Yanked(..) => None,
|
||||||
IncompatibleWheel::ExcludeNewer(..) => None,
|
IncompatibleWheel::ExcludeNewer(..) => None,
|
||||||
IncompatibleWheel::RequiresPython(..) => None,
|
IncompatibleWheel::RequiresPython(..) => None,
|
||||||
|
IncompatibleWheel::MissingPlatform(..) => None,
|
||||||
},
|
},
|
||||||
Self::Source(..) => None,
|
Self::Source(..) => None,
|
||||||
Self::Unavailable => None,
|
Self::Unavailable => None,
|
||||||
|
|
@ -234,6 +238,15 @@ impl Display for IncompatibleDist {
|
||||||
IncompatibleWheel::RequiresPython(python, _) => {
|
IncompatibleWheel::RequiresPython(python, _) => {
|
||||||
write!(f, "Python {python}")
|
write!(f, "Python {python}")
|
||||||
}
|
}
|
||||||
|
IncompatibleWheel::MissingPlatform(marker) => {
|
||||||
|
if let Some(platform) = KnownPlatform::from_marker(*marker) {
|
||||||
|
write!(f, "no {platform}-compatible wheels")
|
||||||
|
} else if let Some(marker) = marker.try_to_string() {
|
||||||
|
write!(f, "no `{marker}`-compatible wheels")
|
||||||
|
} else {
|
||||||
|
write!(f, "no compatible wheels")
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Self::Source(incompatibility) => match incompatibility {
|
Self::Source(incompatibility) => match incompatibility {
|
||||||
IncompatibleSource::NoBuild => f.write_str("no usable wheels"),
|
IncompatibleSource::NoBuild => f.write_str("no usable wheels"),
|
||||||
|
|
@ -288,6 +301,8 @@ pub enum IncompatibleWheel {
|
||||||
Yanked(Yanked),
|
Yanked(Yanked),
|
||||||
/// The use of binary wheels is disabled.
|
/// The use of binary wheels is disabled.
|
||||||
NoBinary,
|
NoBinary,
|
||||||
|
/// Wheels are not available for the current platform.
|
||||||
|
MissingPlatform(MarkerTree),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
@ -694,28 +709,41 @@ impl IncompatibleWheel {
|
||||||
timestamp_other < timestamp_self
|
timestamp_other < timestamp_self
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::NoBinary | Self::RequiresPython(_, _) | Self::Tag(_) | Self::Yanked(_) => {
|
Self::MissingPlatform(_)
|
||||||
true
|
| Self::NoBinary
|
||||||
}
|
| Self::RequiresPython(_, _)
|
||||||
|
| Self::Tag(_)
|
||||||
|
| Self::Yanked(_) => true,
|
||||||
},
|
},
|
||||||
Self::Tag(tag_self) => match other {
|
Self::Tag(tag_self) => match other {
|
||||||
Self::ExcludeNewer(_) => false,
|
Self::ExcludeNewer(_) => false,
|
||||||
Self::Tag(tag_other) => tag_self > tag_other,
|
Self::Tag(tag_other) => tag_self > tag_other,
|
||||||
Self::NoBinary | Self::RequiresPython(_, _) | Self::Yanked(_) => true,
|
Self::MissingPlatform(_)
|
||||||
|
| Self::NoBinary
|
||||||
|
| Self::RequiresPython(_, _)
|
||||||
|
| Self::Yanked(_) => true,
|
||||||
},
|
},
|
||||||
Self::RequiresPython(_, _) => match other {
|
Self::RequiresPython(_, _) => match other {
|
||||||
Self::ExcludeNewer(_) | Self::Tag(_) => false,
|
Self::ExcludeNewer(_) | Self::Tag(_) => false,
|
||||||
// Version specifiers cannot be reasonably compared
|
// Version specifiers cannot be reasonably compared
|
||||||
Self::RequiresPython(_, _) => false,
|
Self::RequiresPython(_, _) => false,
|
||||||
Self::NoBinary | Self::Yanked(_) => true,
|
Self::MissingPlatform(_) | Self::NoBinary | Self::Yanked(_) => true,
|
||||||
},
|
},
|
||||||
Self::Yanked(_) => match other {
|
Self::Yanked(_) => match other {
|
||||||
Self::ExcludeNewer(_) | Self::Tag(_) | Self::RequiresPython(_, _) => false,
|
Self::ExcludeNewer(_) | Self::Tag(_) | Self::RequiresPython(_, _) => false,
|
||||||
// Yanks with a reason are more helpful for errors
|
// Yanks with a reason are more helpful for errors
|
||||||
Self::Yanked(yanked_other) => matches!(yanked_other, Yanked::Reason(_)),
|
Self::Yanked(yanked_other) => matches!(yanked_other, Yanked::Reason(_)),
|
||||||
Self::NoBinary => true,
|
Self::MissingPlatform(_) | Self::NoBinary => true,
|
||||||
},
|
},
|
||||||
Self::NoBinary => false,
|
Self::NoBinary => match other {
|
||||||
|
Self::ExcludeNewer(_)
|
||||||
|
| Self::Tag(_)
|
||||||
|
| Self::RequiresPython(_, _)
|
||||||
|
| Self::Yanked(_) => false,
|
||||||
|
Self::NoBinary => false,
|
||||||
|
Self::MissingPlatform(_) => true,
|
||||||
|
},
|
||||||
|
Self::MissingPlatform(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@ use uv_pep508::MarkerTree;
|
||||||
pub struct SupportedEnvironments(Vec<MarkerTree>);
|
pub struct SupportedEnvironments(Vec<MarkerTree>);
|
||||||
|
|
||||||
impl SupportedEnvironments {
|
impl SupportedEnvironments {
|
||||||
|
/// Create a new [`SupportedEnvironments`] struct from a list of marker trees.
|
||||||
|
pub fn from_markers(markers: Vec<MarkerTree>) -> Self {
|
||||||
|
SupportedEnvironments(markers)
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the list of marker trees.
|
/// Return the list of marker trees.
|
||||||
pub fn as_markers(&self) -> &[MarkerTree] {
|
pub fn as_markers(&self) -> &[MarkerTree] {
|
||||||
&self.0
|
&self.0
|
||||||
|
|
@ -18,6 +23,19 @@ impl SupportedEnvironments {
|
||||||
pub fn into_markers(self) -> Vec<MarkerTree> {
|
pub fn into_markers(self) -> Vec<MarkerTree> {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over the marker trees.
|
||||||
|
pub fn iter(&self) -> std::slice::Iter<MarkerTree> {
|
||||||
|
self.0.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoIterator for &'a SupportedEnvironments {
|
||||||
|
type IntoIter = std::slice::Iter<'a, MarkerTree>;
|
||||||
|
type Item = &'a MarkerTree;
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
self.iter()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize a [`SupportedEnvironments`] struct into a list of marker strings.
|
/// Serialize a [`SupportedEnvironments`] struct into a list of marker strings.
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,8 @@ pub struct Lock {
|
||||||
conflicts: Conflicts,
|
conflicts: Conflicts,
|
||||||
/// The list of supported environments specified by the user.
|
/// The list of supported environments specified by the user.
|
||||||
supported_environments: Vec<MarkerTree>,
|
supported_environments: Vec<MarkerTree>,
|
||||||
|
/// The list of required platforms specified by the user.
|
||||||
|
required_environments: Vec<MarkerTree>,
|
||||||
/// The range of supported Python versions.
|
/// The range of supported Python versions.
|
||||||
requires_python: RequiresPython,
|
requires_python: RequiresPython,
|
||||||
/// We discard the lockfile if these options don't match.
|
/// We discard the lockfile if these options don't match.
|
||||||
|
|
@ -286,6 +288,7 @@ impl Lock {
|
||||||
ResolverManifest::default(),
|
ResolverManifest::default(),
|
||||||
Conflicts::empty(),
|
Conflicts::empty(),
|
||||||
vec![],
|
vec![],
|
||||||
|
vec![],
|
||||||
resolution.fork_markers.clone(),
|
resolution.fork_markers.clone(),
|
||||||
)?;
|
)?;
|
||||||
Ok(lock)
|
Ok(lock)
|
||||||
|
|
@ -372,6 +375,7 @@ impl Lock {
|
||||||
manifest: ResolverManifest,
|
manifest: ResolverManifest,
|
||||||
conflicts: Conflicts,
|
conflicts: Conflicts,
|
||||||
supported_environments: Vec<MarkerTree>,
|
supported_environments: Vec<MarkerTree>,
|
||||||
|
required_environments: Vec<MarkerTree>,
|
||||||
fork_markers: Vec<UniversalMarker>,
|
fork_markers: Vec<UniversalMarker>,
|
||||||
) -> Result<Self, LockError> {
|
) -> Result<Self, LockError> {
|
||||||
// Put all dependencies for each package in a canonical order and
|
// Put all dependencies for each package in a canonical order and
|
||||||
|
|
@ -523,6 +527,7 @@ impl Lock {
|
||||||
fork_markers,
|
fork_markers,
|
||||||
conflicts,
|
conflicts,
|
||||||
supported_environments,
|
supported_environments,
|
||||||
|
required_environments,
|
||||||
requires_python,
|
requires_python,
|
||||||
options,
|
options,
|
||||||
packages,
|
packages,
|
||||||
|
|
@ -565,6 +570,16 @@ impl Lock {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Record the required platforms that were used to generate this lock.
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_required_environments(mut self, required_environments: Vec<MarkerTree>) -> Self {
|
||||||
|
self.required_environments = required_environments
|
||||||
|
.into_iter()
|
||||||
|
.map(|marker| self.requires_python.complexify_markers(marker))
|
||||||
|
.collect();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the lockfile version.
|
/// Returns the lockfile version.
|
||||||
pub fn version(&self) -> u32 {
|
pub fn version(&self) -> u32 {
|
||||||
self.version
|
self.version
|
||||||
|
|
@ -625,6 +640,11 @@ impl Lock {
|
||||||
&self.supported_environments
|
&self.supported_environments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the required platforms that were used to generate this lock.
|
||||||
|
pub fn required_environments(&self) -> &[MarkerTree] {
|
||||||
|
&self.required_environments
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the workspace members that were used to generate this lock.
|
/// Returns the workspace members that were used to generate this lock.
|
||||||
pub fn members(&self) -> &BTreeSet<PackageName> {
|
pub fn members(&self) -> &BTreeSet<PackageName> {
|
||||||
&self.manifest.members
|
&self.manifest.members
|
||||||
|
|
@ -667,6 +687,16 @@ impl Lock {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the required platforms that were used to generate this
|
||||||
|
/// lock.
|
||||||
|
pub fn simplified_required_environments(&self) -> Vec<MarkerTree> {
|
||||||
|
self.required_environments()
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|marker| self.simplify_environment(marker))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
/// Simplify the given marker environment with respect to the lockfile's
|
/// Simplify the given marker environment with respect to the lockfile's
|
||||||
/// `requires-python` setting.
|
/// `requires-python` setting.
|
||||||
pub fn simplify_environment(&self, marker: MarkerTree) -> MarkerTree {
|
pub fn simplify_environment(&self, marker: MarkerTree) -> MarkerTree {
|
||||||
|
|
@ -712,6 +742,17 @@ impl Lock {
|
||||||
doc.insert("supported-markers", value(supported_environments));
|
doc.insert("supported-markers", value(supported_environments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.required_environments.is_empty() {
|
||||||
|
let required_environments = each_element_on_its_line_array(
|
||||||
|
self.required_environments
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|marker| SimplifiedMarkerTree::new(&self.requires_python, marker))
|
||||||
|
.filter_map(SimplifiedMarkerTree::try_to_string),
|
||||||
|
);
|
||||||
|
doc.insert("required-markers", value(required_environments));
|
||||||
|
}
|
||||||
|
|
||||||
if !self.conflicts.is_empty() {
|
if !self.conflicts.is_empty() {
|
||||||
let mut list = Array::new();
|
let mut list = Array::new();
|
||||||
for set in self.conflicts.iter() {
|
for set in self.conflicts.iter() {
|
||||||
|
|
@ -1698,6 +1739,8 @@ struct LockWire {
|
||||||
fork_markers: Vec<SimplifiedMarkerTree>,
|
fork_markers: Vec<SimplifiedMarkerTree>,
|
||||||
#[serde(rename = "supported-markers", default)]
|
#[serde(rename = "supported-markers", default)]
|
||||||
supported_environments: Vec<SimplifiedMarkerTree>,
|
supported_environments: Vec<SimplifiedMarkerTree>,
|
||||||
|
#[serde(rename = "required-markers", default)]
|
||||||
|
required_environments: Vec<SimplifiedMarkerTree>,
|
||||||
#[serde(rename = "conflicts", default)]
|
#[serde(rename = "conflicts", default)]
|
||||||
conflicts: Option<Conflicts>,
|
conflicts: Option<Conflicts>,
|
||||||
/// We discard the lockfile if these options match.
|
/// We discard the lockfile if these options match.
|
||||||
|
|
@ -1740,6 +1783,11 @@ impl TryFrom<LockWire> for Lock {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|simplified_marker| simplified_marker.into_marker(&wire.requires_python))
|
.map(|simplified_marker| simplified_marker.into_marker(&wire.requires_python))
|
||||||
.collect();
|
.collect();
|
||||||
|
let required_environments = wire
|
||||||
|
.required_environments
|
||||||
|
.into_iter()
|
||||||
|
.map(|simplified_marker| simplified_marker.into_marker(&wire.requires_python))
|
||||||
|
.collect();
|
||||||
let fork_markers = wire
|
let fork_markers = wire
|
||||||
.fork_markers
|
.fork_markers
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -1755,6 +1803,7 @@ impl TryFrom<LockWire> for Lock {
|
||||||
wire.manifest,
|
wire.manifest,
|
||||||
wire.conflicts.unwrap_or_else(Conflicts::empty),
|
wire.conflicts.unwrap_or_else(Conflicts::empty),
|
||||||
supported_environments,
|
supported_environments,
|
||||||
|
required_environments,
|
||||||
fork_markers,
|
fork_markers,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ Ok(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
required_environments: [],
|
||||||
requires_python: RequiresPython {
|
requires_python: RequiresPython {
|
||||||
specifiers: VersionSpecifiers(
|
specifiers: VersionSpecifiers(
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use uv_configuration::{BuildOptions, IndexStrategy};
|
|
||||||
|
|
||||||
use crate::fork_strategy::ForkStrategy;
|
use crate::fork_strategy::ForkStrategy;
|
||||||
use crate::{DependencyMode, ExcludeNewer, PrereleaseMode, ResolutionMode};
|
use crate::{DependencyMode, ExcludeNewer, PrereleaseMode, ResolutionMode};
|
||||||
|
use uv_configuration::{BuildOptions, IndexStrategy};
|
||||||
|
use uv_pypi_types::SupportedEnvironments;
|
||||||
|
|
||||||
/// Options for resolving a manifest.
|
/// Options for resolving a manifest.
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||||
|
|
@ -12,6 +12,7 @@ pub struct Options {
|
||||||
pub fork_strategy: ForkStrategy,
|
pub fork_strategy: ForkStrategy,
|
||||||
pub exclude_newer: Option<ExcludeNewer>,
|
pub exclude_newer: Option<ExcludeNewer>,
|
||||||
pub index_strategy: IndexStrategy,
|
pub index_strategy: IndexStrategy,
|
||||||
|
pub required_environments: SupportedEnvironments,
|
||||||
pub flexibility: Flexibility,
|
pub flexibility: Flexibility,
|
||||||
pub build_options: BuildOptions,
|
pub build_options: BuildOptions,
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +26,7 @@ pub struct OptionsBuilder {
|
||||||
fork_strategy: ForkStrategy,
|
fork_strategy: ForkStrategy,
|
||||||
exclude_newer: Option<ExcludeNewer>,
|
exclude_newer: Option<ExcludeNewer>,
|
||||||
index_strategy: IndexStrategy,
|
index_strategy: IndexStrategy,
|
||||||
|
required_environments: SupportedEnvironments,
|
||||||
flexibility: Flexibility,
|
flexibility: Flexibility,
|
||||||
build_options: BuildOptions,
|
build_options: BuildOptions,
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +79,13 @@ impl OptionsBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the required platforms.
|
||||||
|
#[must_use]
|
||||||
|
pub fn required_environments(mut self, required_environments: SupportedEnvironments) -> Self {
|
||||||
|
self.required_environments = required_environments;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the [`Flexibility`].
|
/// Sets the [`Flexibility`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn flexibility(mut self, flexibility: Flexibility) -> Self {
|
pub fn flexibility(mut self, flexibility: Flexibility) -> Self {
|
||||||
|
|
@ -100,6 +109,7 @@ impl OptionsBuilder {
|
||||||
fork_strategy: self.fork_strategy,
|
fork_strategy: self.fork_strategy,
|
||||||
exclude_newer: self.exclude_newer,
|
exclude_newer: self.exclude_newer,
|
||||||
index_strategy: self.index_strategy,
|
index_strategy: self.index_strategy,
|
||||||
|
required_environments: self.required_environments,
|
||||||
flexibility: self.flexibility,
|
flexibility: self.flexibility,
|
||||||
build_options: self.build_options,
|
build_options: self.build_options,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,11 @@ impl PubGrubPackage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if this PubGrub package is the root package.
|
||||||
|
pub(crate) fn is_root(&self) -> bool {
|
||||||
|
matches!(&**self, PubGrubPackageInner::Root(_))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if this PubGrub package is a proxy package.
|
/// Returns `true` if this PubGrub package is a proxy package.
|
||||||
pub(crate) fn is_proxy(&self) -> bool {
|
pub(crate) fn is_proxy(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use dashmap::DashMap;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use futures::{FutureExt, StreamExt};
|
use futures::{FutureExt, StreamExt};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use pubgrub::{Id, IncompId, Incompatibility, Range, Ranges, State};
|
use pubgrub::{Id, IncompId, Incompatibility, Kind, Range, Ranges, State};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use tokio::sync::mpsc::{self, Receiver, Sender};
|
use tokio::sync::mpsc::{self, Receiver, Sender};
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
@ -501,6 +501,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
&state.fork_urls,
|
&state.fork_urls,
|
||||||
&state.env,
|
&state.env,
|
||||||
&state.python_requirement,
|
&state.python_requirement,
|
||||||
|
&state.pubgrub,
|
||||||
&mut visited,
|
&mut visited,
|
||||||
&request_sink,
|
&request_sink,
|
||||||
)?;
|
)?;
|
||||||
|
|
@ -1032,6 +1033,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
fork_urls: &ForkUrls,
|
fork_urls: &ForkUrls,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
python_requirement: &PythonRequirement,
|
python_requirement: &PythonRequirement,
|
||||||
|
pubgrub: &State<UvDependencyProvider>,
|
||||||
visited: &mut FxHashSet<PackageName>,
|
visited: &mut FxHashSet<PackageName>,
|
||||||
request_sink: &Sender<Request>,
|
request_sink: &Sender<Request>,
|
||||||
) -> Result<Option<ResolverVersion>, ResolveError> {
|
) -> Result<Option<ResolverVersion>, ResolveError> {
|
||||||
|
|
@ -1062,6 +1064,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
preferences,
|
preferences,
|
||||||
env,
|
env,
|
||||||
python_requirement,
|
python_requirement,
|
||||||
|
pubgrub,
|
||||||
pins,
|
pins,
|
||||||
visited,
|
visited,
|
||||||
request_sink,
|
request_sink,
|
||||||
|
|
@ -1163,6 +1166,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
preferences: &Preferences,
|
preferences: &Preferences,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
python_requirement: &PythonRequirement,
|
python_requirement: &PythonRequirement,
|
||||||
|
pubgrub: &State<UvDependencyProvider>,
|
||||||
pins: &mut FilePins,
|
pins: &mut FilePins,
|
||||||
visited: &mut FxHashSet<PackageName>,
|
visited: &mut FxHashSet<PackageName>,
|
||||||
request_sink: &Sender<Request>,
|
request_sink: &Sender<Request>,
|
||||||
|
|
@ -1285,6 +1289,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
range,
|
range,
|
||||||
preferences,
|
preferences,
|
||||||
env,
|
env,
|
||||||
|
pubgrub,
|
||||||
pins,
|
pins,
|
||||||
request_sink,
|
request_sink,
|
||||||
)? {
|
)? {
|
||||||
|
|
@ -1316,10 +1321,16 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
|
|
||||||
/// Determine whether a candidate covers all supported platforms; and, if not, generate a fork.
|
/// Determine whether a candidate covers all supported platforms; and, if not, generate a fork.
|
||||||
///
|
///
|
||||||
/// This only applies to versions that lack source distributions and, for now, we only apply
|
/// This only ever applies to versions that lack source distributions And, for now, we only
|
||||||
/// this to local versions. The intent is such that, if we're resolving `PyTorch`, and we choose
|
/// apply it in two cases:
|
||||||
/// `torch==2.5.2+cpu`, we want to fork so that we can select `torch==2.5.2` on macOS (since the
|
///
|
||||||
/// `+cpu` variant doesn't include any macOS wheels).
|
/// 1. Local versions, where the non-local version has greater platform coverage. The intent is
|
||||||
|
/// such that, if we're resolving `PyTorch`, and we choose `torch==2.5.2+cpu`, we want to
|
||||||
|
/// fork so that we can select `torch==2.5.2` on macOS (since the `+cpu` variant doesn't
|
||||||
|
/// include any macOS wheels).
|
||||||
|
/// 2. Platforms that the user explicitly marks as "required" (opt-in). For example, the user
|
||||||
|
/// might require that the generated resolution always includes wheels for x86 macOS, and
|
||||||
|
/// fails entirely if the platform is unsupported.
|
||||||
fn fork_version_registry(
|
fn fork_version_registry(
|
||||||
&self,
|
&self,
|
||||||
candidate: &Candidate,
|
candidate: &Candidate,
|
||||||
|
|
@ -1332,6 +1343,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
range: &Range<Version>,
|
range: &Range<Version>,
|
||||||
preferences: &Preferences,
|
preferences: &Preferences,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
|
pubgrub: &State<UvDependencyProvider>,
|
||||||
pins: &mut FilePins,
|
pins: &mut FilePins,
|
||||||
request_sink: &Sender<Request>,
|
request_sink: &Sender<Request>,
|
||||||
) -> Result<Option<ResolverVersion>, ResolveError> {
|
) -> Result<Option<ResolverVersion>, ResolveError> {
|
||||||
|
|
@ -1340,17 +1352,63 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, we only apply this to local versions.
|
|
||||||
if !candidate.version().is_local() {
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the package is already compatible with all environments (as is the case for
|
// If the package is already compatible with all environments (as is the case for
|
||||||
// packages that include a source distribution), we don't need to fork.
|
// packages that include a source distribution), we don't need to fork.
|
||||||
if dist.implied_markers().is_true() {
|
if dist.implied_markers().is_true() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If the user explicitly marked a platform as required, ensure it has coverage.
|
||||||
|
for marker in self.options.required_environments.iter().copied() {
|
||||||
|
// If the platform is part of the current environment...
|
||||||
|
if env.included_by_marker(marker) {
|
||||||
|
// But isn't supported by the distribution...
|
||||||
|
if dist.implied_markers().is_disjoint(marker)
|
||||||
|
&& !find_environments(id, pubgrub).is_disjoint(marker)
|
||||||
|
{
|
||||||
|
// Then we need to fork.
|
||||||
|
let Some((left, right)) = fork_version_by_marker(env, marker) else {
|
||||||
|
return Ok(Some(ResolverVersion::Unavailable(
|
||||||
|
candidate.version().clone(),
|
||||||
|
UnavailableVersion::IncompatibleDist(IncompatibleDist::Wheel(
|
||||||
|
IncompatibleWheel::MissingPlatform(marker),
|
||||||
|
)),
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Forking on required platform `{}` for {}=={} ({})",
|
||||||
|
marker.try_to_string().unwrap_or_else(|| "true".to_string()),
|
||||||
|
name,
|
||||||
|
candidate.version(),
|
||||||
|
[&left, &right]
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
);
|
||||||
|
let forks = vec![
|
||||||
|
VersionFork {
|
||||||
|
env: left,
|
||||||
|
id,
|
||||||
|
version: None,
|
||||||
|
},
|
||||||
|
VersionFork {
|
||||||
|
env: right,
|
||||||
|
id,
|
||||||
|
version: None,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return Ok(Some(ResolverVersion::Forked(forks)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, we only apply this to local versions.
|
||||||
|
if !candidate.version().is_local() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"Looking at local version: {}=={}",
|
"Looking at local version: {}=={}",
|
||||||
name,
|
name,
|
||||||
|
|
@ -3602,6 +3660,35 @@ pub(crate) struct VersionFork {
|
||||||
version: Option<Version>,
|
version: Option<Version>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compute the set of markers for which a package is known to be relevant.
|
||||||
|
fn find_environments(id: Id<PubGrubPackage>, state: &State<UvDependencyProvider>) -> MarkerTree {
|
||||||
|
let package = &state.package_store[id];
|
||||||
|
if package.is_root() {
|
||||||
|
return MarkerTree::TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the incompatibilities for the current package.
|
||||||
|
let Some(incompatibilities) = state.incompatibilities.get(&id) else {
|
||||||
|
return MarkerTree::FALSE;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find all dependencies on the current package.
|
||||||
|
let mut marker = MarkerTree::FALSE;
|
||||||
|
for index in incompatibilities {
|
||||||
|
let incompat = &state.incompatibility_store[*index];
|
||||||
|
if let Kind::FromDependencyOf(id1, _, id2, _) = &incompat.kind {
|
||||||
|
if id == *id2 {
|
||||||
|
marker.or({
|
||||||
|
let mut marker = package.marker();
|
||||||
|
marker.and(find_environments(*id1, state));
|
||||||
|
marker
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
marker
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
struct ConflictTracker {
|
struct ConflictTracker {
|
||||||
/// How often a decision on the package was discarded due to another package decided earlier.
|
/// How often a decision on the package was discarded due to another package decided earlier.
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ pub struct Options {
|
||||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
pub environments: Option<SupportedEnvironments>,
|
pub environments: Option<SupportedEnvironments>,
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
|
pub required_environments: Option<SupportedEnvironments>,
|
||||||
|
|
||||||
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
||||||
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
||||||
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
||||||
|
|
@ -1790,6 +1793,7 @@ pub struct OptionsWire {
|
||||||
override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||||
constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
|
||||||
environments: Option<SupportedEnvironments>,
|
environments: Option<SupportedEnvironments>,
|
||||||
|
required_environments: Option<SupportedEnvironments>,
|
||||||
|
|
||||||
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
||||||
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
||||||
|
|
@ -1855,6 +1859,7 @@ impl From<OptionsWire> for Options {
|
||||||
override_dependencies,
|
override_dependencies,
|
||||||
constraint_dependencies,
|
constraint_dependencies,
|
||||||
environments,
|
environments,
|
||||||
|
required_environments,
|
||||||
conflicts,
|
conflicts,
|
||||||
publish_url,
|
publish_url,
|
||||||
trusted_publishing,
|
trusted_publishing,
|
||||||
|
|
@ -1918,6 +1923,7 @@ impl From<OptionsWire> for Options {
|
||||||
override_dependencies,
|
override_dependencies,
|
||||||
constraint_dependencies,
|
constraint_dependencies,
|
||||||
environments,
|
environments,
|
||||||
|
required_environments,
|
||||||
install_mirrors: PythonInstallMirrors::resolve(
|
install_mirrors: PythonInstallMirrors::resolve(
|
||||||
python_install_mirror,
|
python_install_mirror,
|
||||||
pypy_install_mirror,
|
pypy_install_mirror,
|
||||||
|
|
|
||||||
|
|
@ -504,6 +504,45 @@ pub struct ToolUv {
|
||||||
)]
|
)]
|
||||||
pub environments: Option<SupportedEnvironments>,
|
pub environments: Option<SupportedEnvironments>,
|
||||||
|
|
||||||
|
/// A list of required platforms, for packages that lack source distributions.
|
||||||
|
///
|
||||||
|
/// When a package does not have a source distribution, it's availability will be limited to
|
||||||
|
/// the platforms supported by its built distributions (wheels). For example, if a package only
|
||||||
|
/// publishes wheels for Linux, then it won't be installable on macOS or Windows.
|
||||||
|
///
|
||||||
|
/// By default, uv requires each package to include at least one wheel that is compatible with
|
||||||
|
/// the designated Python version. The `required-environments` setting can be used to ensure that
|
||||||
|
/// the resulting resolution contains wheels for specific platforms, or fails if no such wheels
|
||||||
|
/// are available.
|
||||||
|
///
|
||||||
|
/// While the `environments` setting _limits_ the set of environments that uv will consider when
|
||||||
|
/// resolving dependencies, `required-environments` _expands_ the set of platforms that uv _must_
|
||||||
|
/// support when resolving dependencies.
|
||||||
|
///
|
||||||
|
/// For example, `environments = ["sys_platform == 'darwin'"]` would limit uv to solving for
|
||||||
|
/// macOS (and ignoring Linux and Windows). On the other hand, `required-environments = ["sys_platform == 'darwin'"]`
|
||||||
|
/// would _require_ that any package without a source distribution include a wheel for macOS in
|
||||||
|
/// order to be installable.
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "schemars",
|
||||||
|
schemars(
|
||||||
|
with = "Option<Vec<String>>",
|
||||||
|
description = "A list of environment markers, e.g., `sys_platform == 'darwin'."
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
#[option(
|
||||||
|
default = "[]",
|
||||||
|
value_type = "str | list[str]",
|
||||||
|
example = r#"
|
||||||
|
# Require that the package is available for macOS ARM and x86 (Intel).
|
||||||
|
required-environments = [
|
||||||
|
"sys_platform == 'darwin' and platform_machine == 'arm64'",
|
||||||
|
"sys_platform == 'darwin' and platform_machine == 'x86_64'",
|
||||||
|
]
|
||||||
|
"#
|
||||||
|
)]
|
||||||
|
pub required_environments: Option<SupportedEnvironments>,
|
||||||
|
|
||||||
/// Declare collections of extras or dependency groups that are conflicting
|
/// Declare collections of extras or dependency groups that are conflicting
|
||||||
/// (i.e., mutually exclusive).
|
/// (i.e., mutually exclusive).
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -374,6 +374,15 @@ impl Workspace {
|
||||||
.and_then(|uv| uv.environments.as_ref())
|
.and_then(|uv| uv.environments.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the set of required platforms for the workspace.
|
||||||
|
pub fn required_environments(&self) -> Option<&SupportedEnvironments> {
|
||||||
|
self.pyproject_toml
|
||||||
|
.tool
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|tool| tool.uv.as_ref())
|
||||||
|
.and_then(|uv| uv.required_environments.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the set of conflicts for the workspace.
|
/// Returns the set of conflicts for the workspace.
|
||||||
pub fn conflicts(&self) -> Conflicts {
|
pub fn conflicts(&self) -> Conflicts {
|
||||||
let mut conflicting = Conflicts::empty();
|
let mut conflicting = Conflicts::empty();
|
||||||
|
|
@ -1717,6 +1726,7 @@ mod tests {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
|
"required-environments": null,
|
||||||
"conflicts": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1740,83 +1750,84 @@ mod tests {
|
||||||
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
||||||
},
|
},
|
||||||
@r###"
|
@r###"
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
"project_root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"install_path": "[ROOT]/albatross-virtual-workspace",
|
"install_path": "[ROOT]/albatross-virtual-workspace",
|
||||||
"packages": {
|
"packages": {
|
||||||
"albatross": {
|
"albatross": {
|
||||||
"root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
"root": "[ROOT]/albatross-virtual-workspace/packages/albatross",
|
||||||
"project": {
|
"project": {
|
||||||
"name": "albatross",
|
"name": "albatross",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"requires-python": ">=3.12",
|
"requires-python": ">=3.12",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"bird-feeder",
|
"bird-feeder",
|
||||||
"tqdm>=4,<5"
|
"tqdm>=4,<5"
|
||||||
],
|
],
|
||||||
"optional-dependencies": null
|
"optional-dependencies": null
|
||||||
},
|
},
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
},
|
|
||||||
"bird-feeder": {
|
|
||||||
"root": "[ROOT]/albatross-virtual-workspace/packages/bird-feeder",
|
|
||||||
"project": {
|
|
||||||
"name": "bird-feeder",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"anyio>=4.3.0,<5",
|
|
||||||
"seeds"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
|
||||||
},
|
|
||||||
"seeds": {
|
|
||||||
"root": "[ROOT]/albatross-virtual-workspace/packages/seeds",
|
|
||||||
"project": {
|
|
||||||
"name": "seeds",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"idna==3.6"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sources": {},
|
|
||||||
"indexes": [],
|
|
||||||
"pyproject_toml": {
|
|
||||||
"project": null,
|
|
||||||
"tool": {
|
|
||||||
"uv": {
|
|
||||||
"sources": null,
|
|
||||||
"index": null,
|
|
||||||
"workspace": {
|
|
||||||
"members": [
|
|
||||||
"packages/*"
|
|
||||||
],
|
|
||||||
"exclude": null
|
|
||||||
},
|
},
|
||||||
"managed": null,
|
"bird-feeder": {
|
||||||
"package": null,
|
"root": "[ROOT]/albatross-virtual-workspace/packages/bird-feeder",
|
||||||
"default-groups": null,
|
"project": {
|
||||||
"dev-dependencies": null,
|
"name": "bird-feeder",
|
||||||
"override-dependencies": null,
|
"version": "1.0.0",
|
||||||
"constraint-dependencies": null,
|
"requires-python": ">=3.12",
|
||||||
"environments": null,
|
"dependencies": [
|
||||||
"conflicts": null
|
"anyio>=4.3.0,<5",
|
||||||
|
"seeds"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
},
|
||||||
|
"seeds": {
|
||||||
|
"root": "[ROOT]/albatross-virtual-workspace/packages/seeds",
|
||||||
|
"project": {
|
||||||
|
"name": "seeds",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"requires-python": ">=3.12",
|
||||||
|
"dependencies": [
|
||||||
|
"idna==3.6"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sources": {},
|
||||||
|
"indexes": [],
|
||||||
|
"pyproject_toml": {
|
||||||
|
"project": null,
|
||||||
|
"tool": {
|
||||||
|
"uv": {
|
||||||
|
"sources": null,
|
||||||
|
"index": null,
|
||||||
|
"workspace": {
|
||||||
|
"members": [
|
||||||
|
"packages/*"
|
||||||
|
],
|
||||||
|
"exclude": null
|
||||||
|
},
|
||||||
|
"managed": null,
|
||||||
|
"package": null,
|
||||||
|
"default-groups": null,
|
||||||
|
"dev-dependencies": null,
|
||||||
|
"override-dependencies": null,
|
||||||
|
"constraint-dependencies": null,
|
||||||
|
"environments": null,
|
||||||
|
"required-environments": null,
|
||||||
|
"conflicts": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependency-groups": null
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"dependency-groups": null
|
|
||||||
}
|
}
|
||||||
}
|
"###);
|
||||||
}
|
|
||||||
"###);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1951,78 +1962,79 @@ mod tests {
|
||||||
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
||||||
},
|
},
|
||||||
@r###"
|
@r###"
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]",
|
"project_root": "[ROOT]",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"install_path": "[ROOT]",
|
"install_path": "[ROOT]",
|
||||||
"packages": {
|
"packages": {
|
||||||
"albatross": {
|
"albatross": {
|
||||||
"root": "[ROOT]",
|
"root": "[ROOT]",
|
||||||
"project": {
|
"project": {
|
||||||
"name": "albatross",
|
"name": "albatross",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"requires-python": ">=3.12",
|
"requires-python": ">=3.12",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"tqdm>=4,<5"
|
"tqdm>=4,<5"
|
||||||
],
|
],
|
||||||
"optional-dependencies": null
|
"optional-dependencies": null
|
||||||
},
|
},
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
},
|
|
||||||
"seeds": {
|
|
||||||
"root": "[ROOT]/packages/seeds",
|
|
||||||
"project": {
|
|
||||||
"name": "seeds",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"idna==3.6"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sources": {},
|
|
||||||
"indexes": [],
|
|
||||||
"pyproject_toml": {
|
|
||||||
"project": {
|
|
||||||
"name": "albatross",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"tqdm>=4,<5"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"tool": {
|
|
||||||
"uv": {
|
|
||||||
"sources": null,
|
|
||||||
"index": null,
|
|
||||||
"workspace": {
|
|
||||||
"members": [
|
|
||||||
"packages/*"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"packages/bird-feeder"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"managed": null,
|
"seeds": {
|
||||||
"package": null,
|
"root": "[ROOT]/packages/seeds",
|
||||||
"default-groups": null,
|
"project": {
|
||||||
"dev-dependencies": null,
|
"name": "seeds",
|
||||||
"override-dependencies": null,
|
"version": "1.0.0",
|
||||||
"constraint-dependencies": null,
|
"requires-python": ">=3.12",
|
||||||
"environments": null,
|
"dependencies": [
|
||||||
"conflicts": null
|
"idna==3.6"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sources": {},
|
||||||
|
"indexes": [],
|
||||||
|
"pyproject_toml": {
|
||||||
|
"project": {
|
||||||
|
"name": "albatross",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"requires-python": ">=3.12",
|
||||||
|
"dependencies": [
|
||||||
|
"tqdm>=4,<5"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"tool": {
|
||||||
|
"uv": {
|
||||||
|
"sources": null,
|
||||||
|
"index": null,
|
||||||
|
"workspace": {
|
||||||
|
"members": [
|
||||||
|
"packages/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"packages/bird-feeder"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"managed": null,
|
||||||
|
"package": null,
|
||||||
|
"default-groups": null,
|
||||||
|
"dev-dependencies": null,
|
||||||
|
"override-dependencies": null,
|
||||||
|
"constraint-dependencies": null,
|
||||||
|
"environments": null,
|
||||||
|
"required-environments": null,
|
||||||
|
"conflicts": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependency-groups": null
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"dependency-groups": null
|
|
||||||
}
|
}
|
||||||
}
|
"###);
|
||||||
}
|
|
||||||
"###);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Rewrite the members to both include and exclude `bird-feeder` by name.
|
// Rewrite the members to both include and exclude `bird-feeder` by name.
|
||||||
|
|
@ -2054,79 +2066,80 @@ mod tests {
|
||||||
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
||||||
},
|
},
|
||||||
@r###"
|
@r###"
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]",
|
"project_root": "[ROOT]",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"install_path": "[ROOT]",
|
"install_path": "[ROOT]",
|
||||||
"packages": {
|
"packages": {
|
||||||
"albatross": {
|
"albatross": {
|
||||||
"root": "[ROOT]",
|
"root": "[ROOT]",
|
||||||
"project": {
|
"project": {
|
||||||
"name": "albatross",
|
"name": "albatross",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"requires-python": ">=3.12",
|
"requires-python": ">=3.12",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"tqdm>=4,<5"
|
"tqdm>=4,<5"
|
||||||
],
|
],
|
||||||
"optional-dependencies": null
|
"optional-dependencies": null
|
||||||
},
|
},
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
},
|
|
||||||
"seeds": {
|
|
||||||
"root": "[ROOT]/packages/seeds",
|
|
||||||
"project": {
|
|
||||||
"name": "seeds",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"idna==3.6"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sources": {},
|
|
||||||
"indexes": [],
|
|
||||||
"pyproject_toml": {
|
|
||||||
"project": {
|
|
||||||
"name": "albatross",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"tqdm>=4,<5"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"tool": {
|
|
||||||
"uv": {
|
|
||||||
"sources": null,
|
|
||||||
"index": null,
|
|
||||||
"workspace": {
|
|
||||||
"members": [
|
|
||||||
"packages/seeds",
|
|
||||||
"packages/bird-feeder"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"packages/bird-feeder"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"managed": null,
|
"seeds": {
|
||||||
"package": null,
|
"root": "[ROOT]/packages/seeds",
|
||||||
"default-groups": null,
|
"project": {
|
||||||
"dev-dependencies": null,
|
"name": "seeds",
|
||||||
"override-dependencies": null,
|
"version": "1.0.0",
|
||||||
"constraint-dependencies": null,
|
"requires-python": ">=3.12",
|
||||||
"environments": null,
|
"dependencies": [
|
||||||
"conflicts": null
|
"idna==3.6"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sources": {},
|
||||||
|
"indexes": [],
|
||||||
|
"pyproject_toml": {
|
||||||
|
"project": {
|
||||||
|
"name": "albatross",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"requires-python": ">=3.12",
|
||||||
|
"dependencies": [
|
||||||
|
"tqdm>=4,<5"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"tool": {
|
||||||
|
"uv": {
|
||||||
|
"sources": null,
|
||||||
|
"index": null,
|
||||||
|
"workspace": {
|
||||||
|
"members": [
|
||||||
|
"packages/seeds",
|
||||||
|
"packages/bird-feeder"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"packages/bird-feeder"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"managed": null,
|
||||||
|
"package": null,
|
||||||
|
"default-groups": null,
|
||||||
|
"dev-dependencies": null,
|
||||||
|
"override-dependencies": null,
|
||||||
|
"constraint-dependencies": null,
|
||||||
|
"environments": null,
|
||||||
|
"required-environments": null,
|
||||||
|
"conflicts": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependency-groups": null
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"dependency-groups": null
|
|
||||||
}
|
}
|
||||||
}
|
"###);
|
||||||
}
|
|
||||||
"###);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Rewrite the exclusion to use the top-level directory (`packages`).
|
// Rewrite the exclusion to use the top-level directory (`packages`).
|
||||||
|
|
@ -2158,92 +2171,93 @@ mod tests {
|
||||||
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
||||||
},
|
},
|
||||||
@r###"
|
@r###"
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]",
|
"project_root": "[ROOT]",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"install_path": "[ROOT]",
|
"install_path": "[ROOT]",
|
||||||
"packages": {
|
"packages": {
|
||||||
"albatross": {
|
"albatross": {
|
||||||
"root": "[ROOT]",
|
"root": "[ROOT]",
|
||||||
"project": {
|
"project": {
|
||||||
"name": "albatross",
|
"name": "albatross",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"requires-python": ">=3.12",
|
"requires-python": ">=3.12",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"tqdm>=4,<5"
|
"tqdm>=4,<5"
|
||||||
],
|
],
|
||||||
"optional-dependencies": null
|
"optional-dependencies": null
|
||||||
},
|
},
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
},
|
|
||||||
"bird-feeder": {
|
|
||||||
"root": "[ROOT]/packages/bird-feeder",
|
|
||||||
"project": {
|
|
||||||
"name": "bird-feeder",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"anyio>=4.3.0,<5"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
|
||||||
},
|
|
||||||
"seeds": {
|
|
||||||
"root": "[ROOT]/packages/seeds",
|
|
||||||
"project": {
|
|
||||||
"name": "seeds",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"idna==3.6"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sources": {},
|
|
||||||
"indexes": [],
|
|
||||||
"pyproject_toml": {
|
|
||||||
"project": {
|
|
||||||
"name": "albatross",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"tqdm>=4,<5"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"tool": {
|
|
||||||
"uv": {
|
|
||||||
"sources": null,
|
|
||||||
"index": null,
|
|
||||||
"workspace": {
|
|
||||||
"members": [
|
|
||||||
"packages/seeds",
|
|
||||||
"packages/bird-feeder"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"packages"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"managed": null,
|
"bird-feeder": {
|
||||||
"package": null,
|
"root": "[ROOT]/packages/bird-feeder",
|
||||||
"default-groups": null,
|
"project": {
|
||||||
"dev-dependencies": null,
|
"name": "bird-feeder",
|
||||||
"override-dependencies": null,
|
"version": "1.0.0",
|
||||||
"constraint-dependencies": null,
|
"requires-python": ">=3.12",
|
||||||
"environments": null,
|
"dependencies": [
|
||||||
"conflicts": null
|
"anyio>=4.3.0,<5"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
},
|
||||||
|
"seeds": {
|
||||||
|
"root": "[ROOT]/packages/seeds",
|
||||||
|
"project": {
|
||||||
|
"name": "seeds",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"requires-python": ">=3.12",
|
||||||
|
"dependencies": [
|
||||||
|
"idna==3.6"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sources": {},
|
||||||
|
"indexes": [],
|
||||||
|
"pyproject_toml": {
|
||||||
|
"project": {
|
||||||
|
"name": "albatross",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"requires-python": ">=3.12",
|
||||||
|
"dependencies": [
|
||||||
|
"tqdm>=4,<5"
|
||||||
|
],
|
||||||
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"tool": {
|
||||||
|
"uv": {
|
||||||
|
"sources": null,
|
||||||
|
"index": null,
|
||||||
|
"workspace": {
|
||||||
|
"members": [
|
||||||
|
"packages/seeds",
|
||||||
|
"packages/bird-feeder"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"packages"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"managed": null,
|
||||||
|
"package": null,
|
||||||
|
"default-groups": null,
|
||||||
|
"dev-dependencies": null,
|
||||||
|
"override-dependencies": null,
|
||||||
|
"constraint-dependencies": null,
|
||||||
|
"environments": null,
|
||||||
|
"required-environments": null,
|
||||||
|
"conflicts": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependency-groups": null
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"dependency-groups": null
|
|
||||||
}
|
}
|
||||||
}
|
"###);
|
||||||
}
|
|
||||||
"###);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Rewrite the exclusion to use the top-level directory with a glob (`packages/*`).
|
// Rewrite the exclusion to use the top-level directory with a glob (`packages/*`).
|
||||||
|
|
@ -2275,66 +2289,67 @@ mod tests {
|
||||||
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
||||||
},
|
},
|
||||||
@r###"
|
@r###"
|
||||||
{
|
{
|
||||||
"project_root": "[ROOT]",
|
"project_root": "[ROOT]",
|
||||||
"project_name": "albatross",
|
"project_name": "albatross",
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"install_path": "[ROOT]",
|
"install_path": "[ROOT]",
|
||||||
"packages": {
|
"packages": {
|
||||||
"albatross": {
|
"albatross": {
|
||||||
"root": "[ROOT]",
|
"root": "[ROOT]",
|
||||||
"project": {
|
"project": {
|
||||||
"name": "albatross",
|
"name": "albatross",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"requires-python": ">=3.12",
|
"requires-python": ">=3.12",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"tqdm>=4,<5"
|
"tqdm>=4,<5"
|
||||||
],
|
],
|
||||||
"optional-dependencies": null
|
"optional-dependencies": null
|
||||||
|
},
|
||||||
|
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
"sources": {},
|
||||||
}
|
"indexes": [],
|
||||||
},
|
"pyproject_toml": {
|
||||||
"sources": {},
|
"project": {
|
||||||
"indexes": [],
|
"name": "albatross",
|
||||||
"pyproject_toml": {
|
"version": "0.1.0",
|
||||||
"project": {
|
"requires-python": ">=3.12",
|
||||||
"name": "albatross",
|
"dependencies": [
|
||||||
"version": "0.1.0",
|
"tqdm>=4,<5"
|
||||||
"requires-python": ">=3.12",
|
|
||||||
"dependencies": [
|
|
||||||
"tqdm>=4,<5"
|
|
||||||
],
|
|
||||||
"optional-dependencies": null
|
|
||||||
},
|
|
||||||
"tool": {
|
|
||||||
"uv": {
|
|
||||||
"sources": null,
|
|
||||||
"index": null,
|
|
||||||
"workspace": {
|
|
||||||
"members": [
|
|
||||||
"packages/seeds",
|
|
||||||
"packages/bird-feeder"
|
|
||||||
],
|
],
|
||||||
"exclude": [
|
"optional-dependencies": null
|
||||||
"packages/*"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"managed": null,
|
"tool": {
|
||||||
"package": null,
|
"uv": {
|
||||||
"default-groups": null,
|
"sources": null,
|
||||||
"dev-dependencies": null,
|
"index": null,
|
||||||
"override-dependencies": null,
|
"workspace": {
|
||||||
"constraint-dependencies": null,
|
"members": [
|
||||||
"environments": null,
|
"packages/seeds",
|
||||||
"conflicts": null
|
"packages/bird-feeder"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"packages/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"managed": null,
|
||||||
|
"package": null,
|
||||||
|
"default-groups": null,
|
||||||
|
"dev-dependencies": null,
|
||||||
|
"override-dependencies": null,
|
||||||
|
"constraint-dependencies": null,
|
||||||
|
"environments": null,
|
||||||
|
"required-environments": null,
|
||||||
|
"conflicts": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependency-groups": null
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"dependency-groups": null
|
|
||||||
}
|
}
|
||||||
}
|
"###);
|
||||||
}
|
|
||||||
"###);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -620,7 +620,7 @@ pub(crate) async fn add(
|
||||||
let lock_state = state.fork();
|
let lock_state = state.fork();
|
||||||
let sync_state = state;
|
let sync_state = state;
|
||||||
|
|
||||||
match lock_and_sync(
|
match Box::pin(lock_and_sync(
|
||||||
target,
|
target,
|
||||||
&mut toml,
|
&mut toml,
|
||||||
&edits,
|
&edits,
|
||||||
|
|
@ -638,7 +638,7 @@ pub(crate) async fn add(
|
||||||
cache,
|
cache,
|
||||||
printer,
|
printer,
|
||||||
preview,
|
preview,
|
||||||
)
|
))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(()) => Ok(ExitStatus::Success),
|
Ok(()) => Ok(ExitStatus::Success),
|
||||||
|
|
|
||||||
|
|
@ -420,6 +420,41 @@ async fn do_lock(
|
||||||
environments
|
environments
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Collect the list of required platforms.
|
||||||
|
let required_environments = if let Some(required_environments) = target.required_environments()
|
||||||
|
{
|
||||||
|
// Ensure that the environments are disjoint.
|
||||||
|
for (lhs, rhs) in required_environments
|
||||||
|
.as_markers()
|
||||||
|
.iter()
|
||||||
|
.zip(required_environments.as_markers().iter().skip(1))
|
||||||
|
{
|
||||||
|
if !lhs.is_disjoint(*rhs) {
|
||||||
|
let mut hint = lhs.negate();
|
||||||
|
hint.and(*rhs);
|
||||||
|
|
||||||
|
let lhs = lhs
|
||||||
|
.contents()
|
||||||
|
.map(|contents| contents.to_string())
|
||||||
|
.unwrap_or_else(|| "true".to_string());
|
||||||
|
let rhs = rhs
|
||||||
|
.contents()
|
||||||
|
.map(|contents| contents.to_string())
|
||||||
|
.unwrap_or_else(|| "true".to_string());
|
||||||
|
let hint = hint
|
||||||
|
.contents()
|
||||||
|
.map(|contents| contents.to_string())
|
||||||
|
.unwrap_or_else(|| "true".to_string());
|
||||||
|
|
||||||
|
return Err(ProjectError::OverlappingMarkers(lhs, rhs, hint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(required_environments)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
// Determine the supported Python range. If no range is defined, and warn and default to the
|
// Determine the supported Python range. If no range is defined, and warn and default to the
|
||||||
// current minor version.
|
// current minor version.
|
||||||
let requires_python = target.requires_python()?;
|
let requires_python = target.requires_python()?;
|
||||||
|
|
@ -517,6 +552,7 @@ async fn do_lock(
|
||||||
.exclude_newer(exclude_newer)
|
.exclude_newer(exclude_newer)
|
||||||
.index_strategy(index_strategy)
|
.index_strategy(index_strategy)
|
||||||
.build_options(build_options.clone())
|
.build_options(build_options.clone())
|
||||||
|
.required_environments(required_environments.cloned().unwrap_or_default())
|
||||||
.build();
|
.build();
|
||||||
let hasher = HashStrategy::Generate(HashGeneration::Url);
|
let hasher = HashStrategy::Generate(HashGeneration::Url);
|
||||||
|
|
||||||
|
|
@ -573,6 +609,7 @@ async fn do_lock(
|
||||||
&overrides,
|
&overrides,
|
||||||
&conflicts,
|
&conflicts,
|
||||||
environments,
|
environments,
|
||||||
|
required_environments,
|
||||||
dependency_metadata,
|
dependency_metadata,
|
||||||
interpreter,
|
interpreter,
|
||||||
&requires_python,
|
&requires_python,
|
||||||
|
|
@ -741,6 +778,12 @@ async fn do_lock(
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(SupportedEnvironments::into_markers)
|
.map(SupportedEnvironments::into_markers)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
|
.with_required_environments(
|
||||||
|
required_environments
|
||||||
|
.cloned()
|
||||||
|
.map(SupportedEnvironments::into_markers)
|
||||||
|
.unwrap_or_default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(LockResult::Changed(previous, lock))
|
Ok(LockResult::Changed(previous, lock))
|
||||||
|
|
@ -775,6 +818,7 @@ impl ValidatedLock {
|
||||||
overrides: &[Requirement],
|
overrides: &[Requirement],
|
||||||
conflicts: &Conflicts,
|
conflicts: &Conflicts,
|
||||||
environments: Option<&SupportedEnvironments>,
|
environments: Option<&SupportedEnvironments>,
|
||||||
|
required_environments: Option<&SupportedEnvironments>,
|
||||||
dependency_metadata: &DependencyMetadata,
|
dependency_metadata: &DependencyMetadata,
|
||||||
interpreter: &Interpreter,
|
interpreter: &Interpreter,
|
||||||
requires_python: &RequiresPython,
|
requires_python: &RequiresPython,
|
||||||
|
|
@ -891,6 +935,23 @@ impl ValidatedLock {
|
||||||
return Ok(Self::Versions(lock));
|
return Ok(Self::Versions(lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the set of required platforms has changed, we have to perform a clean resolution.
|
||||||
|
let expected = lock.simplified_required_environments();
|
||||||
|
let actual = required_environments
|
||||||
|
.map(SupportedEnvironments::as_markers)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|marker| lock.simplify_environment(marker))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
if expected != actual {
|
||||||
|
debug!(
|
||||||
|
"Ignoring existing lockfile due to change in supported environments: `{:?}` vs. `{:?}`",
|
||||||
|
expected, actual
|
||||||
|
);
|
||||||
|
return Ok(Self::Versions(lock));
|
||||||
|
}
|
||||||
|
|
||||||
// If the conflicting group config has changed, we have to perform a clean resolution.
|
// If the conflicting group config has changed, we have to perform a clean resolution.
|
||||||
if conflicts != lock.conflicts() {
|
if conflicts != lock.conflicts() {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,17 @@ impl<'lock> LockTarget<'lock> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the set of required platforms for the [`LockTarget`].
|
||||||
|
pub(crate) fn required_environments(self) -> Option<&'lock SupportedEnvironments> {
|
||||||
|
match self {
|
||||||
|
Self::Workspace(workspace) => workspace.required_environments(),
|
||||||
|
Self::Script(_) => {
|
||||||
|
// TODO(charlie): Add support for environments in scripts.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the set of conflicts for the [`LockTarget`].
|
/// Returns the set of conflicts for the [`LockTarget`].
|
||||||
pub(crate) fn conflicts(self) -> Conflicts {
|
pub(crate) fn conflicts(self) -> Conflicts {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
|
|
@ -22883,7 +22883,7 @@ fn lock_self_marker_incompatible() -> Result<()> {
|
||||||
/// Windows. This may change in the future.
|
/// Windows. This may change in the future.
|
||||||
#[test]
|
#[test]
|
||||||
fn lock_split_on_windows() -> Result<()> {
|
fn lock_split_on_windows() -> Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12").with_exclude_newer("2024-12-18T00:00:00Z");
|
||||||
|
|
||||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
pyproject_toml.write_str(
|
pyproject_toml.write_str(
|
||||||
|
|
@ -22893,6 +22893,9 @@ fn lock_split_on_windows() -> Result<()> {
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
dependencies = ["pyqt5-qt5"]
|
dependencies = ["pyqt5-qt5"]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
required-environments = ["sys_platform == 'win32'"]
|
||||||
"#,
|
"#,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
@ -22902,7 +22905,7 @@ fn lock_split_on_windows() -> Result<()> {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Resolved 2 packages in [TIME]
|
Resolved 3 packages in [TIME]
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
let lock = context.read("uv.lock");
|
let lock = context.read("uv.lock");
|
||||||
|
|
@ -22915,16 +22918,24 @@ fn lock_split_on_windows() -> Result<()> {
|
||||||
version = 1
|
version = 1
|
||||||
revision = 1
|
revision = 1
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
resolution-markers = [
|
||||||
|
"sys_platform != 'win32'",
|
||||||
|
"sys_platform == 'win32'",
|
||||||
|
]
|
||||||
|
required-markers = [
|
||||||
|
"sys_platform == 'win32'",
|
||||||
|
]
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
exclude-newer = "2024-03-25T00:00:00Z"
|
exclude-newer = "2024-12-18T00:00:00Z"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "project"
|
name = "project"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "pyqt5-qt5" },
|
{ name = "pyqt5-qt5", version = "5.15.2", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'win32'" },
|
||||||
|
{ name = "pyqt5-qt5", version = "5.15.15", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'win32'" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
|
|
@ -22932,11 +22943,27 @@ fn lock_split_on_windows() -> Result<()> {
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyqt5-qt5"
|
name = "pyqt5-qt5"
|
||||||
version = "5.15.13"
|
version = "5.15.2"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
resolution-markers = [
|
||||||
|
"sys_platform == 'win32'",
|
||||||
|
]
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/dc/96d9d0ba0d13256343b53efffe8729f278e62409ab4c937bb22e70ab98ac/PyQt5_Qt5-5.15.13-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:92575a9e96a27c4ed67c56c7048ded7461a1655d5d21f0e05064664e6e9fcbdf", size = 38771962 },
|
{ url = "https://files.pythonhosted.org/packages/1c/7e/ce7c66a541a105fa98b41d6405fe84940564695e29fc7dccf6d9e8c5f898/PyQt5_Qt5-5.15.2-py3-none-win32.whl", hash = "sha256:9cc7a768b1921f4b982ebc00a318ccb38578e44e45316c7a4a850e953e1dd327", size = 43447358 },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c9/8b/4441c208c8ca29b50fab6467ebfa32b6401d16c5c915a031a48dc85dfa7a/PyQt5_Qt5-5.15.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:141859f2ffe04cc6c5db970e2b6ad9f98897805d886a14c52614e3799daab6d6", size = 36663754 },
|
{ url = "https://files.pythonhosted.org/packages/37/97/5d3b222b924fa2ed4c2488925155cd0b03fd5d09ee1cfcf7c553c11c9f66/PyQt5_Qt5-5.15.2-py3-none-win_amd64.whl", hash = "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962", size = 50075158 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyqt5-qt5"
|
||||||
|
version = "5.15.15"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
resolution-markers = [
|
||||||
|
"sys_platform != 'win32'",
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4a/6e/a5789bac6310208756fc6a36fd7e01caa86ea6ae7abbb5922dcea003a215/PyQt5_Qt5-5.15.15-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:eb74072935958a830887115b1de1ff26341fc2d5881b28129de39612b10a260e", size = 39147807 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/4c/c9026ca280f2cd4bef562cfb0a5050eb23f1e7fe1b85aa8455eb6ea437bf/PyQt5_Qt5-5.15.15-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f8b174725fbe29c1a22f8acce5798933a65c8a083f1d9833ff212479ec2b3c14", size = 36953104 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/95/70/1ba9b828387f42e0812b496ed637a950bf57a5d59b844d034841e8f9fb4f/PyQt5_Qt5-5.15.15-py3-none-manylinux2014_x86_64.whl", hash = "sha256:611505d04ffb06a5e5bcf98f5ff0e4e15ba7785565ccbe7bd3b2e40642ea3bdd", size = 59827278 },
|
||||||
]
|
]
|
||||||
"#
|
"#
|
||||||
);
|
);
|
||||||
|
|
@ -24661,3 +24688,382 @@ fn lock_pytorch_preferences() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lock_intel_mac() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12").with_exclude_newer("2024-12-18T00:00:00Z");
|
||||||
|
|
||||||
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "project"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = ["torch>1.13"]
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
required-environments = [
|
||||||
|
"sys_platform == 'darwin' and platform_machine == 'x86_64'"
|
||||||
|
]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.lock(), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 25 packages in [TIME]
|
||||||
|
"###);
|
||||||
|
|
||||||
|
let lock = context.read("uv.lock");
|
||||||
|
|
||||||
|
insta::with_settings!({
|
||||||
|
filters => context.filters(),
|
||||||
|
}, {
|
||||||
|
assert_snapshot!(
|
||||||
|
lock, @r###"
|
||||||
|
version = 1
|
||||||
|
revision = 1
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
resolution-markers = [
|
||||||
|
"(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.12' and sys_platform != 'darwin')",
|
||||||
|
"(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin')",
|
||||||
|
"platform_machine == 'x86_64' and sys_platform == 'darwin'",
|
||||||
|
]
|
||||||
|
required-markers = [
|
||||||
|
"platform_machine == 'x86_64' and sys_platform == 'darwin'",
|
||||||
|
]
|
||||||
|
|
||||||
|
[options]
|
||||||
|
exclude-newer = "2024-12-18T00:00:00Z"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filelock"
|
||||||
|
version = "3.16.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fsspec"
|
||||||
|
version = "2024.10.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/a0/52/f16a068ebadae42526484c31f4398e62962504e5724a8ba5dc3409483df2/fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493", size = 286853 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c6/b2/454d6e7f0158951d8a78c2e1eb4f69ae81beb8dca5fee9809c6c99e9d0d0/fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871", size = 179641 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jinja2"
|
||||||
|
version = "3.1.4"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "markupsafe" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markupsafe"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mpmath"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "networkx"
|
||||||
|
version = "3.4.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cublas-cu12"
|
||||||
|
version = "12.4.5.8"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ae/71/1c91302526c45ab494c23f61c7a84aa568b8c1f9d196efa5993957faf906/nvidia_cublas_cu12-12.4.5.8-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2fc8da60df463fdefa81e323eef2e36489e1c94335b5358bcb38360adf75ac9b", size = 363438805 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cuda-cupti-cu12"
|
||||||
|
version = "12.4.127"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/67/42/f4f60238e8194a3106d06a058d494b18e006c10bb2b915655bd9f6ea4cb1/nvidia_cuda_cupti_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9dec60f5ac126f7bb551c055072b69d85392b13311fcc1bcda2202d172df30fb", size = 13813957 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cuda-nvrtc-cu12"
|
||||||
|
version = "12.4.127"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2c/14/91ae57cd4db3f9ef7aa99f4019cfa8d54cb4caa7e00975df6467e9725a9f/nvidia_cuda_nvrtc_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a178759ebb095827bd30ef56598ec182b85547f1508941a3d560eb7ea1fbf338", size = 24640306 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cuda-runtime-cu12"
|
||||||
|
version = "12.4.127"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ea/27/1795d86fe88ef397885f2e580ac37628ed058a92ed2c39dc8eac3adf0619/nvidia_cuda_runtime_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:64403288fa2136ee8e467cdc9c9427e0434110899d07c779f25b5c068934faa5", size = 883737 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cudnn-cu12"
|
||||||
|
version = "9.1.0.70"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "nvidia-cublas-cu12", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/fd/713452cd72343f682b1c7b9321e23829f00b842ceaedcda96e742ea0b0b3/nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f", size = 664752741 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cufft-cu12"
|
||||||
|
version = "11.2.1.3"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/27/94/3266821f65b92b3138631e9c8e7fe1fb513804ac934485a8d05776e1dd43/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f083fc24912aa410be21fa16d157fed2055dab1cc4b6934a0e03cba69eb242b9", size = 211459117 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-curand-cu12"
|
||||||
|
version = "10.3.5.147"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8a/6d/44ad094874c6f1b9c654f8ed939590bdc408349f137f9b98a3a23ccec411/nvidia_curand_cu12-10.3.5.147-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a88f583d4e0bb643c49743469964103aa59f7f708d862c3ddb0fc07f851e3b8b", size = 56305206 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cusolver-cu12"
|
||||||
|
version = "11.6.1.9"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "nvidia-cublas-cu12", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "nvidia-cusparse-cu12", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3a/e1/5b9089a4b2a4790dfdea8b3a006052cfecff58139d5a4e34cb1a51df8d6f/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_x86_64.whl", hash = "sha256:19e33fa442bcfd085b3086c4ebf7e8debc07cfe01e11513cc6d332fd918ac260", size = 127936057 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-cusparse-cu12"
|
||||||
|
version = "12.3.1.170"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "nvidia-nvjitlink-cu12", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/db/f7/97a9ea26ed4bbbfc2d470994b8b4f338ef663be97b8f677519ac195e113d/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ea4f11a2904e2a8dc4b1833cc1b5181cde564edd0d5cd33e3c168eff2d1863f1", size = 207454763 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-nccl-cu12"
|
||||||
|
version = "2.21.5"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/df/99/12cd266d6233f47d00daf3a72739872bdc10267d0383508b0b9c84a18bb6/nvidia_nccl_cu12-2.21.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:8579076d30a8c24988834445f8d633c697d42397e92ffc3f63fa26766d25e0a0", size = 188654414 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-nvjitlink-cu12"
|
||||||
|
version = "12.4.127"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ff/ff/847841bacfbefc97a00036e0fce5a0f086b640756dc38caea5e1bb002655/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57", size = 21066810 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nvidia-nvtx-cu12"
|
||||||
|
version = "12.4.127"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/87/20/199b8713428322a2f22b722c62b8cc278cc53dffa9705d744484b5035ee9/nvidia_nvtx_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:781e950d9b9f60d8241ccea575b32f5105a5baf4c2351cab5256a24869f12a1a", size = 99144 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "project"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = { virtual = "." }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "torch", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
{ name = "torch", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "torch", specifier = ">1.13" }]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "setuptools"
|
||||||
|
version = "75.6.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/43/54/292f26c208734e9a7f067aea4a7e282c080750c4546559b58e2e45413ca0/setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", size = 1337429 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/55/21/47d163f615df1d30c094f6c8bbb353619274edccf0327b185cc2493c2c33/setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d", size = 1224032 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sympy"
|
||||||
|
version = "1.13.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "mpmath" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", size = 7533040 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "torch"
|
||||||
|
version = "2.2.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
resolution-markers = [
|
||||||
|
"platform_machine == 'x86_64' and sys_platform == 'darwin'",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
{ name = "filelock", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
{ name = "fsspec", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
{ name = "jinja2", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
{ name = "networkx", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
{ name = "sympy", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
{ name = "typing-extensions", marker = "platform_machine == 'x86_64' and sys_platform == 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3f/14/e105b8ef6d324e789c1589e95cb0ab63f3e07c2216d68b1178b7c21b7d2a/torch-2.2.2-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:95b9b44f3bcebd8b6cd8d37ec802048c872d9c567ba52c894bba90863a439059", size = 150796474 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/79/78/29dcab24a344ffd9ee9549ec0ab2c7885c13df61cde4c65836ee275efaeb/torch-2.2.2-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:eb4d6e9d3663e26cd27dc3ad266b34445a16b54908e74725adb241aa56987533", size = 150797270 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "torch"
|
||||||
|
version = "2.5.1"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
resolution-markers = [
|
||||||
|
"(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.12' and sys_platform != 'darwin')",
|
||||||
|
"(python_full_version < '3.12' and platform_machine != 'x86_64') or (python_full_version < '3.12' and sys_platform != 'darwin')",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
{ name = "filelock", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "fsspec", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "jinja2", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "networkx", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "setuptools", marker = "(python_full_version >= '3.12' and platform_machine != 'x86_64') or (python_full_version >= '3.12' and sys_platform != 'darwin')" },
|
||||||
|
{ name = "sympy", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
{ name = "triton", marker = "python_full_version < '3.13' and platform_machine == 'x86_64' and sys_platform == 'linux'" },
|
||||||
|
{ name = "typing-extensions", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d1/35/e8b2daf02ce933e4518e6f5682c72fd0ed66c15910ea1fb4168f442b71c4/torch-2.5.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:de5b7d6740c4b636ef4db92be922f0edc425b65ed78c5076c43c42d362a45457", size = 906474467 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/40/04/bd91593a4ca178ece93ca55f27e2783aa524aaccbfda66831d59a054c31e/torch-2.5.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:340ce0432cad0d37f5a31be666896e16788f1adf8ad7be481196b503dad675b9", size = 91919450 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/0d/4a/e51420d46cfc90562e85af2fee912237c662ab31140ab179e49bd69401d6/torch-2.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:603c52d2fe06433c18b747d25f5c333f9c1d58615620578c326d66f258686f9a", size = 203098237 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d0/db/5d9cbfbc7968d79c5c09a0bc0bc3735da079f2fd07cc10498a62b320a480/torch-2.5.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:31f8c39660962f9ae4eeec995e3049b5492eb7360dd4f07377658ef4d728fa4c", size = 63884466 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8b/5c/36c114d120bfe10f9323ed35061bc5878cc74f3f594003854b0ea298942f/torch-2.5.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:ed231a4b3a5952177fafb661213d690a72caaad97d5824dd4fc17ab9e15cec03", size = 906389343 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6d/69/d8ada8b6e0a4257556d5b4ddeb4345ea8eeaaef3c98b60d1cca197c7ad8e/torch-2.5.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:3f4b7f10a247e0dcd7ea97dc2d3bfbfc90302ed36d7f3952b0008d0df264e697", size = 91811673 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5f/ba/607d013b55b9fd805db2a5c2662ec7551f1910b4eef39653eeaba182c5b2/torch-2.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:73e58e78f7d220917c5dbfad1a40e09df9929d3b95d25e57d9f8558f84c9a11c", size = 203046841 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/57/6c/bf52ff061da33deb9f94f4121fde7ff3058812cb7d2036c97bc167793bd1/torch-2.5.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:8c712df61101964eb11910a846514011f0b6f5920c55dbf567bff8a34163d5b1", size = 63858109 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/69/72/20cb30f3b39a9face296491a86adb6ff8f1a47a897e4d14667e6cf89d5c3/torch-2.5.1-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:9b61edf3b4f6e3b0e0adda8b3960266b9009d02b37555971f4d1c8f7a05afed7", size = 906393265 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "triton"
|
||||||
|
version = "3.1.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "filelock", marker = "platform_machine != 'x86_64' or sys_platform != 'darwin'" },
|
||||||
|
]
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/86/17/d9a5cf4fcf46291856d1e90762e36cbabd2a56c7265da0d1d9508c8e3943/triton-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f34f6e7885d1bf0eaaf7ba875a5f0ce6f3c13ba98f9503651c1e6dc6757ed5c", size = 209506424 },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/78/eb/65f5ba83c2a123f6498a3097746607e5b2f16add29e36765305e4ac7fdd8/triton-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8182f42fd8080a7d39d666814fa36c5e30cc00ea7eeeb1a2983dbb4c99a0fdc", size = 209551444 },
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.12.2"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
|
||||||
|
]
|
||||||
|
"###
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3793,7 +3793,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
||||||
|
|
|
|
||||||
1 | [project]
|
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`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `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`, `publish-url`, `trusted-publishing`, `check-url`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-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`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `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`, `publish-url`, `trusted-publishing`, `check-url`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`, `build-backend`
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,45 @@ package = false
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### [`required-environments`](#required-environments) {: #required-environments }
|
||||||
|
|
||||||
|
A list of required platforms, for packages that lack source distributions.
|
||||||
|
|
||||||
|
When a package does not have a source distribution, it's availability will be limited to
|
||||||
|
the platforms supported by its built distributions (wheels). For example, if a package only
|
||||||
|
publishes wheels for Linux, then it won't be installable on macOS or Windows.
|
||||||
|
|
||||||
|
By default, uv requires each package to include at least one wheel that is compatible with
|
||||||
|
the designated Python version. The `required-environments` setting can be used to ensure that
|
||||||
|
the resulting resolution contains wheels for specific platforms, or fails if no such wheels
|
||||||
|
are available.
|
||||||
|
|
||||||
|
While the `environments` setting _limits_ the set of environments that uv will consider when
|
||||||
|
resolving dependencies, `required-environments` _expands_ the set of platforms that uv _must_
|
||||||
|
support when resolving dependencies.
|
||||||
|
|
||||||
|
For example, `environments = ["sys_platform == 'darwin'"]` would limit uv to solving for
|
||||||
|
macOS (and ignoring Linux and Windows). On the other hand, `required-environments = ["sys_platform == 'darwin'"]`
|
||||||
|
would _require_ that any package without a source distribution include a wheel for macOS in
|
||||||
|
order to be installable.
|
||||||
|
|
||||||
|
**Default value**: `[]`
|
||||||
|
|
||||||
|
**Type**: `str | list[str]`
|
||||||
|
|
||||||
|
**Example usage**:
|
||||||
|
|
||||||
|
```toml title="pyproject.toml"
|
||||||
|
[tool.uv]
|
||||||
|
# Require that the package is available for macOS ARM and x86 (Intel).
|
||||||
|
required-environments = [
|
||||||
|
"sys_platform == 'darwin' and platform_machine == 'arm64'",
|
||||||
|
"sys_platform == 'darwin' and platform_machine == 'x86_64'",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### [`sources`](#sources) {: #sources }
|
### [`sources`](#sources) {: #sources }
|
||||||
|
|
||||||
The sources to use when resolving dependencies.
|
The sources to use when resolving dependencies.
|
||||||
|
|
|
||||||
10
uv.schema.json
generated
10
uv.schema.json
generated
|
|
@ -443,6 +443,16 @@
|
||||||
"$ref": "#/definitions/PackageName"
|
"$ref": "#/definitions/PackageName"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"required-environments": {
|
||||||
|
"description": "A list of environment markers, e.g., `sys_platform == 'darwin'.",
|
||||||
|
"type": [
|
||||||
|
"array",
|
||||||
|
"null"
|
||||||
|
],
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"required-version": {
|
"required-version": {
|
||||||
"description": "Enforce a requirement on the version of uv.\n\nIf the version of uv does not meet the requirement at runtime, uv will exit with an error.\n\nAccepts a [PEP 440](https://peps.python.org/pep-0440/) specifier, like `==0.5.0` or `>=0.5.0`.",
|
"description": "Enforce a requirement on the version of uv.\n\nIf the version of uv does not meet the requirement at runtime, uv will exit with an error.\n\nAccepts a [PEP 440](https://peps.python.org/pep-0440/) specifier, like `==0.5.0` or `>=0.5.0`.",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue