Fork version selection based on requires-python requirements (#9827)

## Summary

This PR addresses a significant limitation in the resolver whereby we
avoid choosing the latest versions of packages when the user supports a
wider range.

For example, with NumPy, the latest versions only support Python 3.10
and later. If you lock a project with `requires-python = ">=3.8"`, we
pick the last NumPy version that supported Python 3.8, and use that for
_all_ Python versions. So you get `1.24.4` for all versions, rather than
`2.2.0`. And we'll never upgrade you unless you bump your
`requires-python`. (Even worse, those versions don't have wheels for
Python 3.12, etc., so you end up building from source.)

(As-is, this is intentional. We optimize for minimizing the number of
selected versions, and the current logic does that well!)

Instead, we know recognize when a version has an elevated
`requires-python` specifier and fork. This is a new fork point, since we
need to fork once we have the package metadata, as opposed to when we
see the dependencies.

In this iteration, I've made this behavior the default. I'm sort of
undecided on whether I want to push on that... Previously, I'd suggested
making it opt-in via a setting
(https://github.com/astral-sh/uv/pull/8686).

Closes https://github.com/astral-sh/uv/issues/8492.
This commit is contained in:
Charlie Marsh 2024-12-13 15:33:46 -05:00 committed by GitHub
parent dc0525ddd0
commit 0ee21146f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 940 additions and 203 deletions

View file

@ -60,6 +60,18 @@ pub enum CompatibleDist<'a> {
},
}
impl CompatibleDist<'_> {
/// Return the `requires-python` specifier for the distribution, if any.
pub fn requires_python(&self) -> Option<&VersionSpecifiers> {
match self {
CompatibleDist::InstalledDist(_) => None,
CompatibleDist::SourceDist { sdist, .. } => sdist.file.requires_python.as_ref(),
CompatibleDist::CompatibleWheel { wheel, .. } => wheel.file.requires_python.as_ref(),
CompatibleDist::IncompatibleWheel { sdist, .. } => sdist.file.requires_python.as_ref(),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum IncompatibleDist {
/// An incompatible wheel is available.

View file

@ -1,3 +1,5 @@
use std::collections::Bound;
use uv_pep440::Version;
use uv_pep508::{MarkerEnvironment, MarkerTree};
use uv_python::{Interpreter, PythonVersion};
@ -84,6 +86,28 @@ impl PythonRequirement {
})
}
/// Split the [`PythonRequirement`] at the given version.
///
/// For example, if the current requirement is `>=3.10`, and the split point is `3.11`, then
/// the result will be `>=3.10 and <3.11` and `>=3.11`.
pub fn split(&self, at: Bound<Version>) -> Option<(Self, Self)> {
let (lower, upper) = self.target.split(at)?;
Some((
Self {
exact: self.exact.clone(),
installed: self.installed.clone(),
target: lower,
source: self.source,
},
Self {
exact: self.exact.clone(),
installed: self.installed.clone(),
target: upper,
source: self.source,
},
))
}
/// Returns `true` if the minimum version of Python required by the target is greater than the
/// installed version.
pub fn raises(&self, target: &RequiresPythonRange) -> bool {

View file

@ -1,8 +1,9 @@
use pubgrub::Range;
use std::cmp::Ordering;
use std::collections::Bound;
use std::ops::Deref;
use pubgrub::Range;
use uv_distribution_filename::WheelFilename;
use uv_pep440::{release_specifiers_to_ranges, Version, VersionSpecifier, VersionSpecifiers};
use uv_pep508::{MarkerExpression, MarkerTree, MarkerValueVersion};
@ -73,24 +74,43 @@ impl RequiresPython {
}
})?;
// Extract the bounds.
let (lower_bound, upper_bound) = range
.bounding_range()
.map(|(lower_bound, upper_bound)| {
(
LowerBound(lower_bound.cloned()),
UpperBound(upper_bound.cloned()),
)
})
.unwrap_or((LowerBound::default(), UpperBound::default()));
// Convert back to PEP 440 specifiers.
let specifiers = VersionSpecifiers::from_release_only_bounds(range.iter());
Some(Self {
specifiers,
range: RequiresPythonRange(lower_bound, upper_bound),
})
// Extract the bounds.
let range = RequiresPythonRange::from_range(&range);
Some(Self { specifiers, range })
}
/// Split the [`RequiresPython`] at the given version.
///
/// For example, if the current requirement is `>=3.10`, and the split point is `3.11`, then
/// the result will be `>=3.10 and <3.11` and `>=3.11`.
pub fn split(&self, bound: Bound<Version>) -> Option<(Self, Self)> {
let RequiresPythonRange(.., upper) = &self.range;
let upper = Range::from_range_bounds((bound, upper.clone().into()));
let lower = upper.complement();
// Intersect left and right with the existing range.
let lower = lower.intersection(&Range::from(self.range.clone()));
let upper = upper.intersection(&Range::from(self.range.clone()));
if lower.is_empty() || upper.is_empty() {
None
} else {
Some((
Self {
specifiers: VersionSpecifiers::from_release_only_bounds(lower.iter()),
range: RequiresPythonRange::from_range(&lower),
},
Self {
specifiers: VersionSpecifiers::from_release_only_bounds(upper.iter()),
range: RequiresPythonRange::from_range(&upper),
},
))
}
}
/// Narrow the [`RequiresPython`] by computing the intersection with the given range.
@ -489,14 +509,9 @@ impl serde::Serialize for RequiresPython {
impl<'de> serde::Deserialize<'de> for RequiresPython {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let specifiers = VersionSpecifiers::deserialize(deserializer)?;
let (lower_bound, upper_bound) = release_specifiers_to_ranges(specifiers.clone())
.bounding_range()
.map(|(lower_bound, upper_bound)| (lower_bound.cloned(), upper_bound.cloned()))
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
Ok(Self {
specifiers,
range: RequiresPythonRange(LowerBound(lower_bound), UpperBound(upper_bound)),
})
let range = release_specifiers_to_ranges(specifiers.clone());
let range = RequiresPythonRange::from_range(&range);
Ok(Self { specifiers, range })
}
}
@ -504,6 +519,15 @@ impl<'de> serde::Deserialize<'de> for RequiresPython {
pub struct RequiresPythonRange(LowerBound, UpperBound);
impl RequiresPythonRange {
/// Initialize a [`RequiresPythonRange`] from a [`Range`].
pub fn from_range(range: &Range<Version>) -> Self {
let (lower, upper) = range
.bounding_range()
.map(|(lower_bound, upper_bound)| (lower_bound.cloned(), upper_bound.cloned()))
.unwrap_or((Bound::Unbounded, Bound::Unbounded));
Self(LowerBound(lower), UpperBound(upper))
}
/// Initialize a [`RequiresPythonRange`] with the given bounds.
pub fn new(lower: LowerBound, upper: UpperBound) -> Self {
Self(lower, upper)
@ -967,4 +991,68 @@ mod tests {
assert_eq!(requires_python.is_exact_without_patch(), expected);
}
}
#[test]
fn split_version() {
// Splitting `>=3.10` on `>3.12` should result in `>=3.10, <=3.12` and `>3.12`.
let version_specifiers = VersionSpecifiers::from_str(">=3.10").unwrap();
let requires_python = RequiresPython::from_specifiers(&version_specifiers);
let (lower, upper) = requires_python
.split(Bound::Excluded(Version::new([3, 12])))
.unwrap();
assert_eq!(
lower,
RequiresPython::from_specifiers(
&VersionSpecifiers::from_str(">=3.10, <=3.12").unwrap()
)
);
assert_eq!(
upper,
RequiresPython::from_specifiers(&VersionSpecifiers::from_str(">3.12").unwrap())
);
// Splitting `>=3.10` on `>=3.12` should result in `>=3.10, <3.12` and `>=3.12`.
let version_specifiers = VersionSpecifiers::from_str(">=3.10").unwrap();
let requires_python = RequiresPython::from_specifiers(&version_specifiers);
let (lower, upper) = requires_python
.split(Bound::Included(Version::new([3, 12])))
.unwrap();
assert_eq!(
lower,
RequiresPython::from_specifiers(&VersionSpecifiers::from_str(">=3.10, <3.12").unwrap())
);
assert_eq!(
upper,
RequiresPython::from_specifiers(&VersionSpecifiers::from_str(">=3.12").unwrap())
);
// Splitting `>=3.10` on `>=3.9` should return `None`.
let version_specifiers = VersionSpecifiers::from_str(">=3.10").unwrap();
let requires_python = RequiresPython::from_specifiers(&version_specifiers);
assert!(requires_python
.split(Bound::Included(Version::new([3, 9])))
.is_none());
// Splitting `>=3.10` on `>=3.10` should return `None`.
let version_specifiers = VersionSpecifiers::from_str(">=3.10").unwrap();
let requires_python = RequiresPython::from_specifiers(&version_specifiers);
assert!(requires_python
.split(Bound::Included(Version::new([3, 10])))
.is_none());
// Splitting `>=3.9, <3.13` on `>=3.11` should result in `>=3.9, <3.11` and `>=3.11, <3.13`.
let version_specifiers = VersionSpecifiers::from_str(">=3.9, <3.13").unwrap();
let requires_python = RequiresPython::from_specifiers(&version_specifiers);
let (lower, upper) = requires_python
.split(Bound::Included(Version::new([3, 11])))
.unwrap();
assert_eq!(
lower,
RequiresPython::from_specifiers(&VersionSpecifiers::from_str(">=3.9, <3.11").unwrap())
);
assert_eq!(
upper,
RequiresPython::from_specifiers(&VersionSpecifiers::from_str(">=3.11, <3.13").unwrap())
);
}
}

View file

@ -1,9 +1,11 @@
use std::fmt::{Display, Formatter};
use crate::resolver::MetadataUnavailable;
use uv_distribution_types::IncompatibleDist;
use uv_pep440::{Version, VersionSpecifiers};
use crate::resolver::MetadataUnavailable;
use crate::ResolverEnvironment;
/// The reason why a package or a version cannot be used.
#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) enum UnavailableReason {
@ -164,8 +166,10 @@ impl From<&MetadataUnavailable> for UnavailablePackage {
#[derive(Debug, Clone)]
pub(crate) enum ResolverVersion {
/// A usable version
Available(Version),
/// A version that is not usable for some reason
Unavailable(Version, UnavailableVersion),
/// A usable version
Unforked(Version),
/// A set of forks.
Forked(Vec<ResolverEnvironment>),
}

View file

@ -1,5 +1,6 @@
use std::sync::Arc;
use tracing::trace;
use uv_pep440::VersionSpecifiers;
use uv_pep508::{MarkerEnvironment, MarkerTree};
use uv_pypi_types::{ConflictItem, ConflictItemRef, ResolverMarkerEnvironment};
@ -7,7 +8,7 @@ use crate::pubgrub::{PubGrubDependency, PubGrubPackage};
use crate::requires_python::RequiresPythonRange;
use crate::resolver::ForkState;
use crate::universal_marker::{ConflictMarker, UniversalMarker};
use crate::PythonRequirement;
use crate::{PythonRequirement, RequiresPython};
/// Represents one or more marker environments for a resolution.
///
@ -510,6 +511,50 @@ impl<'d> Forker<'d> {
}
}
/// Fork the resolver based on a `Requires-Python` specifier.
pub(crate) fn fork_python_requirement(
requires_python: &VersionSpecifiers,
python_requirement: &PythonRequirement,
env: &ResolverEnvironment,
) -> Vec<ResolverEnvironment> {
let requires_python = RequiresPython::from_specifiers(requires_python);
let lower = requires_python.range().lower().clone();
// Attempt to split the current Python requirement based on the `requires-python` specifier.
//
// For example, if the current requirement is `>=3.10`, and the split point is `>=3.11`, then
// the result will be `>=3.10 and <3.11` and `>=3.11`.
//
// However, if the current requirement is `>=3.10`, and the split point is `>=3.9`, then the
// lower segment will be empty, so we should return an empty list.
let Some((lower, upper)) = python_requirement.split(lower.into()) else {
trace!(
"Unable to split Python requirement `{}` via `Requires-Python` specifier `{}`",
python_requirement.target(),
requires_python,
);
return vec![];
};
let Kind::Universal {
markers: ref env_marker,
..
} = env.kind
else {
panic!("resolver must be in universal mode for forking")
};
let mut envs = vec![];
if !env_marker.is_disjoint(lower.to_marker_tree()) {
envs.push(env.narrow_environment(lower.to_marker_tree()));
}
if !env_marker.is_disjoint(upper.to_marker_tree()) {
envs.push(env.narrow_environment(upper.to_marker_tree()));
}
debug_assert!(!envs.is_empty(), "at least one fork should be produced");
envs
}
#[cfg(test)]
mod tests {
use std::ops::Bound;

View file

@ -30,7 +30,7 @@ use uv_distribution_types::{
};
use uv_git::GitResolver;
use uv_normalize::{ExtraName, GroupName, PackageName};
use uv_pep440::{release_specifiers_to_ranges, Version, MIN_VERSION};
use uv_pep440::{release_specifiers_to_ranges, Version, VersionSpecifiers, MIN_VERSION};
use uv_pep508::MarkerTree;
use uv_platform_tags::Tags;
use uv_pypi_types::{
@ -59,8 +59,8 @@ pub(crate) use crate::resolver::availability::{
};
use crate::resolver::batch_prefetch::BatchPrefetcher;
pub use crate::resolver::derivation::DerivationChainBuilder;
use crate::resolver::environment::ForkingPossibility;
pub use crate::resolver::environment::ResolverEnvironment;
use crate::resolver::environment::{fork_python_requirement, ForkingPossibility};
pub(crate) use crate::resolver::fork_map::{ForkMap, ForkSet};
pub(crate) use crate::resolver::urls::Urls;
use crate::universal_marker::{ConflictMarker, UniversalMarker};
@ -323,82 +323,90 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
}
let start = Instant::now();
loop {
// Run unit propagation.
if let Err(err) = state.pubgrub.unit_propagation(state.next) {
return Err(self.convert_no_solution_err(
err,
state.fork_urls,
&state.fork_indexes,
state.env,
&visited,
&self.locations,
&self.capabilities,
));
}
// Pre-visit all candidate packages, to allow metadata to be fetched in parallel.
if self.dependency_mode.is_transitive() {
Self::pre_visit(
state
.pubgrub
.partial_solution
.prioritized_packages()
.map(|(id, range)| (&state.pubgrub.package_store[id], range)),
&self.urls,
&self.indexes,
&state.python_requirement,
&request_sink,
)?;
}
// Choose a package version.
let Some(highest_priority_pkg) = state
.pubgrub
.partial_solution
.pick_highest_priority_pkg(|id, _range| {
state.priorities.get(&state.pubgrub.package_store[id])
})
else {
// All packages have been assigned, the fork has been successfully resolved
if tracing::enabled!(Level::DEBUG) {
prefetcher.log_tried_versions();
}
debug!(
"{} resolution took {:.3}s",
state.env,
start.elapsed().as_secs_f32()
);
let resolution = state.into_resolution();
// Walk over the selected versions, and mark them as preferences. We have to
// add forks back as to not override the preferences from the lockfile for
// the next fork
//
// If we're using a resolution mode that varies based on whether a dependency is
// direct or transitive, skip preferences, as we risk adding a preference from
// one fork (in which it's a transitive dependency) to another fork (in which
// it's direct).
if matches!(
self.options.resolution_mode,
ResolutionMode::Lowest | ResolutionMode::Highest
) {
for (package, version) in &resolution.nodes {
preferences.insert(
package.name.clone(),
package.index.clone(),
resolution
.env
.try_universal_markers()
.unwrap_or(UniversalMarker::TRUE),
version.clone(),
);
let highest_priority_pkg =
if let Some(initial) = state.initial.take() {
// If we just forked based on `requires-python`, we can skip unit
// propagation, since we already propagated the package that initiated
// the fork.
initial
} else {
// Run unit propagation.
if let Err(err) = state.pubgrub.unit_propagation(state.next) {
return Err(self.convert_no_solution_err(
err,
state.fork_urls,
&state.fork_indexes,
state.env,
&visited,
&self.locations,
&self.capabilities,
));
}
}
resolutions.push(resolution);
continue 'FORK;
};
// Pre-visit all candidate packages, to allow metadata to be fetched in parallel.
if self.dependency_mode.is_transitive() {
Self::pre_visit(
state
.pubgrub
.partial_solution
.prioritized_packages()
.map(|(id, range)| (&state.pubgrub.package_store[id], range)),
&self.urls,
&self.indexes,
&state.python_requirement,
&request_sink,
)?;
}
// Choose a package.
let Some(highest_priority_pkg) =
state.pubgrub.partial_solution.pick_highest_priority_pkg(
|id, _range| state.priorities.get(&state.pubgrub.package_store[id]),
)
else {
// All packages have been assigned, the fork has been successfully resolved
if tracing::enabled!(Level::DEBUG) {
prefetcher.log_tried_versions();
}
debug!(
"{} resolution took {:.3}s",
state.env,
start.elapsed().as_secs_f32()
);
let resolution = state.into_resolution();
// Walk over the selected versions, and mark them as preferences. We have to
// add forks back as to not override the preferences from the lockfile for
// the next fork
//
// If we're using a resolution mode that varies based on whether a dependency is
// direct or transitive, skip preferences, as we risk adding a preference from
// one fork (in which it's a transitive dependency) to another fork (in which
// it's direct).
if matches!(
self.options.resolution_mode,
ResolutionMode::Lowest | ResolutionMode::Highest
) {
for (package, version) in &resolution.nodes {
preferences.insert(
package.name.clone(),
package.index.clone(),
resolution
.env
.try_universal_markers()
.unwrap_or(UniversalMarker::TRUE),
version.clone(),
);
}
}
resolutions.push(resolution);
continue 'FORK;
};
highest_priority_pkg
};
state.next = highest_priority_pkg;
@ -481,8 +489,16 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
}
Some(version) => version,
};
let version = match version {
ResolverVersion::Available(version) => version,
ResolverVersion::Unforked(version) => version,
ResolverVersion::Forked(forks) => {
for mut fork in self.version_forks_to_fork_states(state, forks) {
fork.initial = Some(next_id);
forked_states.push(fork);
}
continue 'FORK;
}
ResolverVersion::Unavailable(version, reason) => {
state.add_unavailable_version(version, reason);
continue;
@ -742,6 +758,31 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
})
}
/// Convert the dependency [`Fork`]s into [`ForkState`]s.
#[allow(clippy::unused_self)]
fn version_forks_to_fork_states(
&self,
current_state: ForkState,
forks: Vec<ResolverEnvironment>,
) -> impl Iterator<Item = ForkState> + '_ {
// This is a somewhat tortured technique to ensure
// that our resolver state is only cloned as much
// as it needs to be. We basically move the state
// into `forked_states`, and then only clone it if
// there is at least one more fork to visit.
let mut cur_state = Some(current_state);
let forks_len = forks.len();
forks.into_iter().enumerate().map(move |(i, fork)| {
let is_last = i == forks_len - 1;
let forked_state = cur_state.take().unwrap();
if !is_last {
cur_state = Some(forked_state.clone());
}
forked_state.with_env(fork)
})
}
/// Visit a [`PubGrubPackage`] prior to selection. This should be called on a [`PubGrubPackage`]
/// before it is selected, to allow metadata to be fetched in parallel.
fn visit_package(
@ -864,7 +905,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
) -> Result<Option<ResolverVersion>, ResolveError> {
match &**package {
PubGrubPackageInner::Root(_) => {
Ok(Some(ResolverVersion::Available(MIN_VERSION.clone())))
Ok(Some(ResolverVersion::Unforked(MIN_VERSION.clone())))
}
PubGrubPackageInner::Python(_) => {
@ -1000,7 +1041,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
}
}
Ok(Some(ResolverVersion::Available(version.clone())))
Ok(Some(ResolverVersion::Unforked(version.clone())))
}
/// Given a candidate registry requirement, choose the next version in range to try, or `None`
@ -1080,7 +1121,28 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
};
// Check whether the version is incompatible due to its Python requirement.
if let Some(incompatibility) = Self::check_requires_python(dist, python_requirement) {
if let Some((requires_python, incompatibility)) =
Self::check_requires_python(dist, python_requirement)
{
if env.marker_environment().is_none() {
let forks = fork_python_requirement(requires_python, python_requirement, env);
if !forks.is_empty() {
debug!(
"Forking Python requirement `{}` on `{}` for {}=={} ({})",
python_requirement.target(),
requires_python,
name,
candidate.version(),
forks
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(", ")
);
return Ok(Some(ResolverVersion::Forked(forks)));
}
}
return Ok(Some(ResolverVersion::Unavailable(
candidate.version().clone(),
UnavailableVersion::IncompatibleDist(incompatibility),
@ -1129,47 +1191,39 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
}
}
Ok(Some(ResolverVersion::Available(version)))
Ok(Some(ResolverVersion::Unforked(version)))
}
/// Check if the distribution is incompatible with the Python requirement, and if so, return
/// the incompatibility.
fn check_requires_python(
dist: &CompatibleDist,
fn check_requires_python<'dist>(
dist: &'dist CompatibleDist,
python_requirement: &PythonRequirement,
) -> Option<IncompatibleDist> {
let requires_python = match dist {
CompatibleDist::InstalledDist(_) => None,
CompatibleDist::SourceDist { sdist, .. }
| CompatibleDist::IncompatibleWheel { sdist, .. } => {
sdist.file.requires_python.as_ref()
}
CompatibleDist::CompatibleWheel { wheel, .. } => wheel.file.requires_python.as_ref(),
}?;
) -> Option<(&'dist VersionSpecifiers, IncompatibleDist)> {
let requires_python = dist.requires_python()?;
if python_requirement.target().is_contained_by(requires_python) {
None
} else {
if matches!(dist, CompatibleDist::CompatibleWheel { .. }) {
Some(IncompatibleDist::Wheel(IncompatibleWheel::RequiresPython(
let incompatibility = if matches!(dist, CompatibleDist::CompatibleWheel { .. }) {
IncompatibleDist::Wheel(IncompatibleWheel::RequiresPython(
requires_python.clone(),
if python_requirement.installed() == python_requirement.target() {
PythonRequirementKind::Installed
} else {
PythonRequirementKind::Target
},
)))
} else {
Some(IncompatibleDist::Source(
IncompatibleSource::RequiresPython(
requires_python.clone(),
if python_requirement.installed() == python_requirement.target() {
PythonRequirementKind::Installed
} else {
PythonRequirementKind::Target
},
),
))
}
} else {
IncompatibleDist::Source(IncompatibleSource::RequiresPython(
requires_python.clone(),
if python_requirement.installed() == python_requirement.target() {
PythonRequirementKind::Installed
} else {
PythonRequirementKind::Target
},
))
};
Some((requires_python, incompatibility))
}
}
@ -2078,6 +2132,9 @@ pub(crate) struct ForkState {
/// in this state. We also ultimately retrieve the final set of version
/// assignments (to packages) from this state's "partial solution."
pubgrub: State<UvDependencyProvider>,
/// The initial package to select. If set, the first iteration over this state will avoid
/// asking PubGrub for the highest-priority package, and will instead use the provided package.
initial: Option<Id<PubGrubPackage>>,
/// The next package on which to run unit propagation.
next: Id<PubGrubPackage>,
/// The set of pinned versions we accrue throughout resolution.
@ -2147,6 +2204,7 @@ impl ForkState {
python_requirement: PythonRequirement,
) -> Self {
Self {
initial: None,
next: pubgrub.root_package,
pubgrub,
pins: FilePins::default(),

View file

@ -1847,7 +1847,7 @@ fn lock_conditional_dependency_extra() -> Result<()> {
----- stdout -----
----- stderr -----
Resolved 7 packages in [TIME]
Resolved 8 packages in [TIME]
"###);
let lock = fs_err::read_to_string(&lockfile).unwrap();
@ -1860,7 +1860,8 @@ fn lock_conditional_dependency_extra() -> Result<()> {
version = 1
requires-python = ">=3.7"
resolution-markers = [
"python_full_version < '3.10'",
"python_full_version >= '3.8' and python_full_version < '3.10'",
"python_full_version < '3.8'",
"python_full_version >= '3.10'",
]
@ -2014,7 +2015,8 @@ fn lock_conditional_dependency_extra() -> Result<()> {
{ name = "certifi" },
{ name = "charset-normalizer" },
{ name = "idna" },
{ name = "urllib3" },
{ name = "urllib3", version = "2.0.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
{ name = "urllib3", version = "2.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1", size = 110794 }
wheels = [
@ -2030,10 +2032,26 @@ fn lock_conditional_dependency_extra() -> Result<()> {
name = "urllib3"
version = "2.0.7"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.8'",
]
sdist = { url = "https://files.pythonhosted.org/packages/af/47/b215df9f71b4fdba1025fc05a77db2ad243fa0926755a52c5e71659f4e3c/urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", size = 282546 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d2/b2/b157855192a68541a91ba7b2bbcb91f1b4faa51f8bae38d8005c034be524/urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e", size = 124213 },
]
[[package]]
name = "urllib3"
version = "2.2.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8' and python_full_version < '3.10'",
"python_full_version >= '3.10'",
]
sdist = { url = "https://files.pythonhosted.org/packages/7a/50/7fd50a27caa0652cd4caf224aa87741ea41d3265ad13f010886167cfcc79/urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19", size = 291020 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a2/73/a68704750a7679d0b6d3ad7aa8d4da8e14e151ae82e6fee774e6e0d05ec8/urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d", size = 121067 },
]
"###
);
});
@ -2065,7 +2083,7 @@ fn lock_conditional_dependency_extra() -> Result<()> {
+ idna==3.6
+ project==0.1.0 (from file://[TEMP_DIR]/)
+ requests==2.31.0
+ urllib3==2.0.7
+ urllib3==2.2.1
"###);
// Validate that the extra is included on relevant Python versions.
@ -2081,7 +2099,7 @@ fn lock_conditional_dependency_extra() -> Result<()> {
----- stdout -----
----- stderr -----
Resolved 7 packages in [TIME]
Resolved 8 packages in [TIME]
"###);
// Install from the lockfile.
@ -2099,7 +2117,7 @@ fn lock_conditional_dependency_extra() -> Result<()> {
+ project==0.1.0 (from file://[TEMP_DIR]/)
+ pysocks==1.7.1
+ requests==2.31.0
+ urllib3==2.0.7
+ urllib3==2.2.1
"###);
Ok(())
@ -3213,7 +3231,7 @@ fn lock_requires_python() -> Result<()> {
----- stdout -----
----- stderr -----
× No solution found when resolving dependencies:
× No solution found when resolving dependencies for split (python_full_version >= '3.7' and python_full_version < '3.7.9'):
Because the requested Python version (>=3.7) does not satisfy Python>=3.8 and the requested Python version (>=3.7) does not satisfy Python>=3.7.9,<3.8, we can conclude that Python>=3.7.9 is incompatible.
And because pygls>=1.1.0,<=1.2.1 depends on Python>=3.7.9,<4 and only pygls<=1.3.0 is available, we can conclude that all of:
pygls>=1.1.0,<1.3.0
@ -3253,7 +3271,7 @@ fn lock_requires_python() -> Result<()> {
----- stdout -----
----- stderr -----
Resolved 10 packages in [TIME]
Resolved 17 packages in [TIME]
"###);
let lock = fs_err::read_to_string(&lockfile).unwrap();
@ -3265,6 +3283,12 @@ fn lock_requires_python() -> Result<()> {
lock, @r###"
version = 1
requires-python = ">=3.7"
resolution-markers = [
"python_full_version >= '3.8'",
"python_full_version >= '3.7.9' and python_full_version < '3.8'",
"python_full_version >= '3.7.4' and python_full_version < '3.7.9'",
"python_full_version < '3.7.4'",
]
[options]
exclude-newer = "2024-03-25T00:00:00Z"
@ -3285,16 +3309,38 @@ fn lock_requires_python() -> Result<()> {
name = "cattrs"
version = "23.1.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7.9' and python_full_version < '3.8'",
"python_full_version >= '3.7.4' and python_full_version < '3.7.9'",
"python_full_version < '3.7.4'",
]
dependencies = [
{ name = "attrs" },
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
{ name = "attrs", marker = "python_full_version < '3.8'" },
{ name = "exceptiongroup", marker = "python_full_version < '3.8'" },
{ name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/68/d4/27f9fd840e74d51b6d6a024d39ff495b56ffde71d28eb82758b7b85d0617/cattrs-23.1.2.tar.gz", hash = "sha256:db1c821b8c537382b2c7c66678c3790091ca0275ac486c76f3c8f3920e83c657", size = 39998 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3a/ba/05df14efaa0624fac6b1510e87f5ce446208d2f6ce50270a89b6268aebfe/cattrs-23.1.2-py3-none-any.whl", hash = "sha256:b2bb14311ac17bed0d58785e5a60f022e5431aca3932e3fc5cc8ed8639de50a4", size = 50845 },
]
[[package]]
name = "cattrs"
version = "23.2.3"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
dependencies = [
{ name = "attrs", marker = "python_full_version >= '3.8'" },
{ name = "exceptiongroup", marker = "python_full_version >= '3.8' and python_full_version < '3.11'" },
{ name = "typing-extensions", version = "4.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8' and python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1e/57/c6ccd22658c4bcb3beb3f1c262e1f170cf136e913b122763d0ddd328d284/cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f", size = 610215 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/0d/cd4a4071c7f38385dc5ba91286723b4d1090b87815db48216212c6c6c30e/cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108", size = 57474 },
]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
@ -3309,21 +3355,43 @@ fn lock_requires_python() -> Result<()> {
version = "6.7.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions", marker = "python_full_version < '3.8'" },
{ name = "zipp" },
{ name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
{ name = "zipp", marker = "python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a3/82/f6e29c8d5c098b6be61460371c2c5591f4a335923639edec43b3830650a4/importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4", size = 53569 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ff/94/64287b38c7de4c90683630338cf28f129decbba0a44f0c6db35a873c73c4/importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5", size = 22934 },
]
[[package]]
name = "lsprotocol"
version = "2023.0.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7.9' and python_full_version < '3.8'",
]
dependencies = [
{ name = "attrs", marker = "python_full_version >= '3.7.9' and python_full_version < '3.8'" },
{ name = "cattrs", version = "23.1.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.9' and python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3e/fe/f7671a4fb28606ff1663bba60aff6af21b1e43a977c74c33db13cb83680f/lsprotocol-2023.0.0.tar.gz", hash = "sha256:c9d92e12a3f4ed9317d3068226592860aab5357d93cf5b2451dc244eee8f35f2", size = 69399 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2d/5b/f18eb1823a4cee9bed70cdcc25eed5a75845367c42e63a79010a7c34f8a7/lsprotocol-2023.0.0-py3-none-any.whl", hash = "sha256:e85fc87ee26c816adca9eb497bb3db1a7c79c477a11563626e712eaccf926a05", size = 70789 },
]
[[package]]
name = "lsprotocol"
version = "2023.0.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
"python_full_version >= '3.7.4' and python_full_version < '3.7.9'",
"python_full_version < '3.7.4'",
]
dependencies = [
{ name = "attrs" },
{ name = "cattrs" },
{ name = "attrs", marker = "python_full_version < '3.7.9' or python_full_version >= '3.8'" },
{ name = "cattrs", version = "23.1.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.7.9'" },
{ name = "cattrs", version = "23.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9d/f6/6e80484ec078d0b50699ceb1833597b792a6c695f90c645fbaf54b947e6f/lsprotocol-2023.0.1.tar.gz", hash = "sha256:cc5c15130d2403c18b734304339e51242d3018a05c4f7d0f198ad6e0cd21861d", size = 69434 }
wheels = [
@ -3335,7 +3403,10 @@ fn lock_requires_python() -> Result<()> {
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "pygls" },
{ name = "pygls", version = "1.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.7.4'" },
{ name = "pygls", version = "1.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.4' and python_full_version < '3.7.9'" },
{ name = "pygls", version = "1.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.9' and python_full_version < '3.8'" },
{ name = "pygls", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
[package.metadata]
@ -3345,33 +3416,119 @@ fn lock_requires_python() -> Result<()> {
name = "pygls"
version = "1.0.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.7.4'",
]
dependencies = [
{ name = "lsprotocol" },
{ name = "typeguard" },
{ name = "lsprotocol", version = "2023.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.7.4'" },
{ name = "typeguard", version = "2.13.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.7.4'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/8e/27/58ff0f76b379fc11a1d03e8d4b4e96fd0abb463d27709a7fb4193bcdbbc4/pygls-1.0.1.tar.gz", hash = "sha256:f3ee98ddbb4690eb5c755bc32ba7e129607f14cbd313575f33d0cea443b78cb2", size = 674546 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/da/9b/4fd77a060068f2f3f46f97ed6ba8762c5a73f11ef0c196cfd34f3a9be878/pygls-1.0.1-py3-none-any.whl", hash = "sha256:adacc96da77598c70f46acfdfd1481d3da90cd54f639f7eee52eb6e4dbd57b55", size = 40367 },
]
[[package]]
name = "pygls"
version = "1.0.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7.4' and python_full_version < '3.7.9'",
]
dependencies = [
{ name = "lsprotocol", version = "2023.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.4' and python_full_version < '3.7.9'" },
{ name = "typeguard", version = "3.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.4' and python_full_version < '3.7.9'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bb/c4/fc9c817ba0f1ad0fdbe1686bc8211a0dc2390ab11cf7780e9eeed718594b/pygls-1.0.2.tar.gz", hash = "sha256:888ed63d1f650b4fc64d603d73d37545386ec533c0caac921aed80f80ea946a4", size = 674931 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6d/c6/ed6aa6fb709abf57b1a75b83f7809792b79320247391dda8f04d2a003548/pygls-1.0.2-py3-none-any.whl", hash = "sha256:6d278d29fa6559b0f7a448263c85cb64ec6e9369548b02f1a7944060848b21f9", size = 38654 },
]
[[package]]
name = "pygls"
version = "1.2.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7.9' and python_full_version < '3.8'",
]
dependencies = [
{ name = "lsprotocol", version = "2023.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.9' and python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e6/94/534c11ba5475df09542e48d751a66e0448d52bbbb92cbef5541deef7760d/pygls-1.2.1.tar.gz", hash = "sha256:04f9b9c115b622dcc346fb390289066565343d60245a424eca77cb429b911ed8", size = 45274 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/36/31/3799444d3f072ffca1a35eb02a48f964384cc13f001125e87d9f0748687b/pygls-1.2.1-py3-none-any.whl", hash = "sha256:7dcfcf12b6f15beb606afa46de2ed348b65a279c340ef2242a9a35c22eeafe94", size = 55983 },
]
[[package]]
name = "pygls"
version = "1.3.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
dependencies = [
{ name = "cattrs", version = "23.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
{ name = "lsprotocol", version = "2023.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e9/8d/31b50ac0879464049d744a1ddf00dc6474433eb55d40fa0c8e8510591ad2/pygls-1.3.0.tar.gz", hash = "sha256:1b44ace89c9382437a717534f490eadc6fda7c0c6c16ac1eaaf5568e345e4fb8", size = 45539 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/1e/643070d8f5c851958662e7e5df16d9c3a068a598a7ee7bb2eb8d95b4e5d7/pygls-1.3.0-py3-none-any.whl", hash = "sha256:d4a01414b6ed4e34e7e8fd29b77d3e88c29615df7d0bbff49bf019e15ec04b8f", size = 56031 },
]
[[package]]
name = "typeguard"
version = "2.13.3"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.7.4'",
]
sdist = { url = "https://files.pythonhosted.org/packages/3a/38/c61bfcf62a7b572b5e9363a802ff92559cb427ee963048e1442e3aef7490/typeguard-2.13.3.tar.gz", hash = "sha256:00edaa8da3a133674796cf5ea87d9f4b4c367d77476e185e80251cc13dfbb8c4", size = 40604 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9a/bb/d43e5c75054e53efce310e79d63df0ac3f25e34c926be5dffb7d283fb2a8/typeguard-2.13.3-py3-none-any.whl", hash = "sha256:5e3e3be01e887e7eafae5af63d1f36c849aaa94e3a0112097312aabfa16284f1", size = 17605 },
]
[[package]]
name = "typeguard"
version = "3.0.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7.4' and python_full_version < '3.7.9'",
]
dependencies = [
{ name = "importlib-metadata", marker = "python_full_version >= '3.7.4' and python_full_version < '3.7.9'" },
{ name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7.4' and python_full_version < '3.7.9'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/af/40/3398497c6e6951c92abaf933492d6633e7ac4df0bfc9d81f304b3f977f15/typeguard-3.0.2.tar.gz", hash = "sha256:fee5297fdb28f8e9efcb8142b5ee219e02375509cd77ea9d270b5af826358d5a", size = 58171 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/e2/62/7d206b0ac6fcbb163215ecc622a54eb747f85ad86d14bc513a834442d0f6/typeguard-3.0.2-py3-none-any.whl", hash = "sha256:bbe993854385284ab42fd5bd3bee6f6556577ce8b50696d6cb956d704f286c8e", size = 30696 },
]
[[package]]
name = "typing-extensions"
version = "4.7.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7.9' and python_full_version < '3.8'",
"python_full_version >= '3.7.4' and python_full_version < '3.7.9'",
"python_full_version < '3.7.4'",
]
sdist = { url = "https://files.pythonhosted.org/packages/3c/8b/0111dd7d6c1478bf83baa1cab85c686426c7a6274119aceb2bd9d35395ad/typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2", size = 72876 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", size = 33232 },
]
[[package]]
name = "typing-extensions"
version = "4.10.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
sdist = { url = "https://files.pythonhosted.org/packages/16/3a/0d26ce356c7465a19c9ea8814b960f8a36c3b0d07c323176620b7b483e44/typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb", size = 77558 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f9/de/dc04a3ea60b22624b51c703a84bbe0184abcd1d0b9bc8074b5d6b7ab90bb/typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", size = 33926 },
]
[[package]]
name = "zipp"
version = "3.15.0"
@ -3408,7 +3565,7 @@ fn lock_requires_python() -> Result<()> {
----- stdout -----
----- stderr -----
Resolved 9 packages in [TIME]
Resolved 13 packages in [TIME]
"###);
let lock = fs_err::read_to_string(&lockfile).unwrap();
@ -3420,6 +3577,10 @@ fn lock_requires_python() -> Result<()> {
lock, @r###"
version = 1
requires-python = ">=3.7.9"
resolution-markers = [
"python_full_version >= '3.8'",
"python_full_version < '3.8'",
]
[options]
exclude-newer = "2024-03-25T00:00:00Z"
@ -3440,16 +3601,36 @@ fn lock_requires_python() -> Result<()> {
name = "cattrs"
version = "23.1.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.8'",
]
dependencies = [
{ name = "attrs" },
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
{ name = "attrs", marker = "python_full_version < '3.8'" },
{ name = "exceptiongroup", marker = "python_full_version < '3.8'" },
{ name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/68/d4/27f9fd840e74d51b6d6a024d39ff495b56ffde71d28eb82758b7b85d0617/cattrs-23.1.2.tar.gz", hash = "sha256:db1c821b8c537382b2c7c66678c3790091ca0275ac486c76f3c8f3920e83c657", size = 39998 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/3a/ba/05df14efaa0624fac6b1510e87f5ce446208d2f6ce50270a89b6268aebfe/cattrs-23.1.2-py3-none-any.whl", hash = "sha256:b2bb14311ac17bed0d58785e5a60f022e5431aca3932e3fc5cc8ed8639de50a4", size = 50845 },
]
[[package]]
name = "cattrs"
version = "23.2.3"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
dependencies = [
{ name = "attrs", marker = "python_full_version >= '3.8'" },
{ name = "exceptiongroup", marker = "python_full_version >= '3.8' and python_full_version < '3.11'" },
{ name = "typing-extensions", version = "4.10.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8' and python_full_version < '3.11'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/1e/57/c6ccd22658c4bcb3beb3f1c262e1f170cf136e913b122763d0ddd328d284/cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f", size = 610215 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/0d/cd4a4071c7f38385dc5ba91286723b4d1090b87815db48216212c6c6c30e/cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108", size = 57474 },
]
[[package]]
name = "exceptiongroup"
version = "1.2.0"
@ -3464,8 +3645,8 @@ fn lock_requires_python() -> Result<()> {
version = "6.7.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions", marker = "python_full_version < '3.8'" },
{ name = "zipp" },
{ name = "typing-extensions", version = "4.7.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
{ name = "zipp", marker = "python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a3/82/f6e29c8d5c098b6be61460371c2c5591f4a335923639edec43b3830650a4/importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4", size = 53569 }
wheels = [
@ -3476,21 +3657,41 @@ fn lock_requires_python() -> Result<()> {
name = "lsprotocol"
version = "2023.0.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.8'",
]
dependencies = [
{ name = "attrs" },
{ name = "cattrs" },
{ name = "attrs", marker = "python_full_version < '3.8'" },
{ name = "cattrs", version = "23.1.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3e/fe/f7671a4fb28606ff1663bba60aff6af21b1e43a977c74c33db13cb83680f/lsprotocol-2023.0.0.tar.gz", hash = "sha256:c9d92e12a3f4ed9317d3068226592860aab5357d93cf5b2451dc244eee8f35f2", size = 69399 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2d/5b/f18eb1823a4cee9bed70cdcc25eed5a75845367c42e63a79010a7c34f8a7/lsprotocol-2023.0.0-py3-none-any.whl", hash = "sha256:e85fc87ee26c816adca9eb497bb3db1a7c79c477a11563626e712eaccf926a05", size = 70789 },
]
[[package]]
name = "lsprotocol"
version = "2023.0.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
dependencies = [
{ name = "attrs", marker = "python_full_version >= '3.8'" },
{ name = "cattrs", version = "23.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9d/f6/6e80484ec078d0b50699ceb1833597b792a6c695f90c645fbaf54b947e6f/lsprotocol-2023.0.1.tar.gz", hash = "sha256:cc5c15130d2403c18b734304339e51242d3018a05c4f7d0f198ad6e0cd21861d", size = 69434 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/37/2351e48cb3309673492d3a8c59d407b75fb6630e560eb27ecd4da03adc9a/lsprotocol-2023.0.1-py3-none-any.whl", hash = "sha256:c75223c9e4af2f24272b14c6375787438279369236cd568f596d4951052a60f2", size = 70826 },
]
[[package]]
name = "project"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "pygls" },
{ name = "pygls", version = "1.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
{ name = "pygls", version = "1.3.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
[package.metadata]
@ -3500,23 +3701,57 @@ fn lock_requires_python() -> Result<()> {
name = "pygls"
version = "1.2.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.8'",
]
dependencies = [
{ name = "lsprotocol" },
{ name = "lsprotocol", version = "2023.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e6/94/534c11ba5475df09542e48d751a66e0448d52bbbb92cbef5541deef7760d/pygls-1.2.1.tar.gz", hash = "sha256:04f9b9c115b622dcc346fb390289066565343d60245a424eca77cb429b911ed8", size = 45274 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/36/31/3799444d3f072ffca1a35eb02a48f964384cc13f001125e87d9f0748687b/pygls-1.2.1-py3-none-any.whl", hash = "sha256:7dcfcf12b6f15beb606afa46de2ed348b65a279c340ef2242a9a35c22eeafe94", size = 55983 },
]
[[package]]
name = "pygls"
version = "1.3.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
dependencies = [
{ name = "cattrs", version = "23.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
{ name = "lsprotocol", version = "2023.0.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.8'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/e9/8d/31b50ac0879464049d744a1ddf00dc6474433eb55d40fa0c8e8510591ad2/pygls-1.3.0.tar.gz", hash = "sha256:1b44ace89c9382437a717534f490eadc6fda7c0c6c16ac1eaaf5568e345e4fb8", size = 45539 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/4e/1e/643070d8f5c851958662e7e5df16d9c3a068a598a7ee7bb2eb8d95b4e5d7/pygls-1.3.0-py3-none-any.whl", hash = "sha256:d4a01414b6ed4e34e7e8fd29b77d3e88c29615df7d0bbff49bf019e15ec04b8f", size = 56031 },
]
[[package]]
name = "typing-extensions"
version = "4.7.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.8'",
]
sdist = { url = "https://files.pythonhosted.org/packages/3c/8b/0111dd7d6c1478bf83baa1cab85c686426c7a6274119aceb2bd9d35395ad/typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2", size = 72876 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", size = 33232 },
]
[[package]]
name = "typing-extensions"
version = "4.10.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.8'",
]
sdist = { url = "https://files.pythonhosted.org/packages/16/3a/0d26ce356c7465a19c9ea8814b960f8a36c3b0d07c323176620b7b483e44/typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb", size = 77558 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f9/de/dc04a3ea60b22624b51c703a84bbe0184abcd1d0b9bc8074b5d6b7ab90bb/typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", size = 33926 },
]
[[package]]
name = "zipp"
version = "3.15.0"
@ -4513,7 +4748,7 @@ fn lock_requires_python_unbounded() -> Result<()> {
----- stderr -----
warning: The workspace `requires-python` value (`<=3.12`) does not contain a lower bound. Add a lower bound to indicate the minimum compatible Python version (e.g., `>=3.11`).
Resolved 2 packages in [TIME]
Resolved 3 packages in [TIME]
"###);
let lock = fs_err::read_to_string(&lockfile).unwrap();
@ -4525,6 +4760,10 @@ fn lock_requires_python_unbounded() -> Result<()> {
lock, @r###"
version = 1
requires-python = "<=3.12"
resolution-markers = [
"python_full_version >= '3.7'",
"python_full_version < '3.7'",
]
[options]
exclude-newer = "2024-03-25T00:00:00Z"
@ -4533,17 +4772,33 @@ fn lock_requires_python_unbounded() -> Result<()> {
name = "iniconfig"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.7'",
]
sdist = { url = "https://files.pythonhosted.org/packages/23/a2/97899f6bd0e873fed3a7e67ae8d3a08b21799430fb4da15cfedf10d6e2c2/iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32", size = 8104 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", size = 4990 },
]
[[package]]
name = "iniconfig"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.7'",
]
sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
]
[[package]]
name = "project"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "iniconfig" },
{ name = "iniconfig", version = "1.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.7'" },
{ name = "iniconfig", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.7'" },
]
[package.metadata]
@ -4560,7 +4815,166 @@ fn lock_requires_python_unbounded() -> Result<()> {
----- stderr -----
warning: The workspace `requires-python` value (`<=3.12`) does not contain a lower bound. Add a lower bound to indicate the minimum compatible Python version (e.g., `>=3.11`).
Resolved 2 packages in [TIME]
Resolved 3 packages in [TIME]
"###);
Ok(())
}
#[test]
fn lock_requires_python_maximum_version() -> Result<()> {
let context = TestContext::new("3.11");
let lockfile = context.temp_dir.join("uv.lock");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.8"
dependencies = ["numpy"]
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
"#,
)?;
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 3 packages in [TIME]
"###);
let lock = fs_err::read_to_string(&lockfile).unwrap();
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
lock, @r###"
version = 1
requires-python = ">=3.8"
resolution-markers = [
"python_full_version >= '3.9'",
"python_full_version < '3.9'",
]
[options]
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "numpy"
version = "1.24.4"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.9'",
]
sdist = { url = "https://files.pythonhosted.org/packages/a4/9b/027bec52c633f6556dba6b722d9a0befb40498b9ceddd29cbe67a45a127c/numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", size = 10911229 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6b/80/6cdfb3e275d95155a34659163b83c09e3a3ff9f1456880bec6cc63d71083/numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", size = 19789140 },
{ url = "https://files.pythonhosted.org/packages/64/5f/3f01d753e2175cfade1013eea08db99ba1ee4bdb147ebcf3623b75d12aa7/numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", size = 13854297 },
{ url = "https://files.pythonhosted.org/packages/5a/b3/2f9c21d799fa07053ffa151faccdceeb69beec5a010576b8991f614021f7/numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", size = 13995611 },
{ url = "https://files.pythonhosted.org/packages/10/be/ae5bf4737cb79ba437879915791f6f26d92583c738d7d960ad94e5c36adf/numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", size = 17282357 },
{ url = "https://files.pythonhosted.org/packages/c0/64/908c1087be6285f40e4b3e79454552a701664a079321cff519d8c7051d06/numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", size = 12429222 },
{ url = "https://files.pythonhosted.org/packages/22/55/3d5a7c1142e0d9329ad27cece17933b0e2ab4e54ddc5c1861fbfeb3f7693/numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", size = 14841514 },
{ url = "https://files.pythonhosted.org/packages/a9/cc/5ed2280a27e5dab12994c884f1f4d8c3bd4d885d02ae9e52a9d213a6a5e2/numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", size = 19775508 },
{ url = "https://files.pythonhosted.org/packages/c0/bc/77635c657a3668cf652806210b8662e1aff84b818a55ba88257abf6637a8/numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", size = 13840033 },
{ url = "https://files.pythonhosted.org/packages/a7/4c/96cdaa34f54c05e97c1c50f39f98d608f96f0677a6589e64e53104e22904/numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", size = 13991951 },
{ url = "https://files.pythonhosted.org/packages/22/97/dfb1a31bb46686f09e68ea6ac5c63fdee0d22d7b23b8f3f7ea07712869ef/numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", size = 17278923 },
{ url = "https://files.pythonhosted.org/packages/35/e2/76a11e54139654a324d107da1d98f99e7aa2a7ef97cfd7c631fba7dbde71/numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", size = 12422446 },
{ url = "https://files.pythonhosted.org/packages/d8/ec/ebef2f7d7c28503f958f0f8b992e7ce606fb74f9e891199329d5f5f87404/numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", size = 14834466 },
{ url = "https://files.pythonhosted.org/packages/11/10/943cfb579f1a02909ff96464c69893b1d25be3731b5d3652c2e0cf1281ea/numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", size = 19780722 },
{ url = "https://files.pythonhosted.org/packages/a7/ae/f53b7b265fdc701e663fbb322a8e9d4b14d9cb7b2385f45ddfabfc4327e4/numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", size = 13843102 },
{ url = "https://files.pythonhosted.org/packages/25/6f/2586a50ad72e8dbb1d8381f837008a0321a3516dfd7cb57fc8cf7e4bb06b/numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", size = 14039616 },
{ url = "https://files.pythonhosted.org/packages/98/5d/5738903efe0ecb73e51eb44feafba32bdba2081263d40c5043568ff60faf/numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", size = 17316263 },
{ url = "https://files.pythonhosted.org/packages/d1/57/8d328f0b91c733aa9aa7ee540dbc49b58796c862b4fbcb1146c701e888da/numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", size = 12455660 },
{ url = "https://files.pythonhosted.org/packages/69/65/0d47953afa0ad569d12de5f65d964321c208492064c38fe3b0b9744f8d44/numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", size = 14868112 },
{ url = "https://files.pythonhosted.org/packages/9a/cd/d5b0402b801c8a8b56b04c1e85c6165efab298d2f0ab741c2406516ede3a/numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", size = 19816549 },
{ url = "https://files.pythonhosted.org/packages/14/27/638aaa446f39113a3ed38b37a66243e21b38110d021bfcb940c383e120f2/numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", size = 13879950 },
{ url = "https://files.pythonhosted.org/packages/8f/27/91894916e50627476cff1a4e4363ab6179d01077d71b9afed41d9e1f18bf/numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9", size = 14030228 },
{ url = "https://files.pythonhosted.org/packages/7a/7c/d7b2a0417af6428440c0ad7cb9799073e507b1a465f827d058b826236964/numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", size = 17311170 },
{ url = "https://files.pythonhosted.org/packages/18/9d/e02ace5d7dfccee796c37b995c63322674daf88ae2f4a4724c5dd0afcc91/numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", size = 12454918 },
{ url = "https://files.pythonhosted.org/packages/63/38/6cc19d6b8bfa1d1a459daf2b3fe325453153ca7019976274b6f33d8b5663/numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", size = 14867441 },
{ url = "https://files.pythonhosted.org/packages/a4/fd/8dff40e25e937c94257455c237b9b6bf5a30d42dd1cc11555533be099492/numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", size = 19156590 },
{ url = "https://files.pythonhosted.org/packages/42/e7/4bf953c6e05df90c6d351af69966384fed8e988d0e8c54dad7103b59f3ba/numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", size = 16705744 },
{ url = "https://files.pythonhosted.org/packages/fc/dd/9106005eb477d022b60b3817ed5937a43dad8fd1f20b0610ea8a32fcb407/numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", size = 14734290 },
]
[[package]]
name = "numpy"
version = "1.26.4"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.9'",
]
sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468 },
{ url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411 },
{ url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016 },
{ url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889 },
{ url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746 },
{ url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620 },
{ url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659 },
{ url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905 },
{ url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554 },
{ url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127 },
{ url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994 },
{ url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005 },
{ url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297 },
{ url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567 },
{ url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812 },
{ url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913 },
{ url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901 },
{ url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868 },
{ url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109 },
{ url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613 },
{ url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172 },
{ url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643 },
{ url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803 },
{ url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 },
{ url = "https://files.pythonhosted.org/packages/7d/24/ce71dc08f06534269f66e73c04f5709ee024a1afe92a7b6e1d73f158e1f8/numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", size = 20636301 },
{ url = "https://files.pythonhosted.org/packages/ae/8c/ab03a7c25741f9ebc92684a20125fbc9fc1b8e1e700beb9197d750fdff88/numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", size = 13971216 },
{ url = "https://files.pythonhosted.org/packages/6d/64/c3bcdf822269421d85fe0d64ba972003f9bb4aa9a419da64b86856c9961f/numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", size = 14226281 },
{ url = "https://files.pythonhosted.org/packages/54/30/c2a907b9443cf42b90c17ad10c1e8fa801975f01cb9764f3f8eb8aea638b/numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3", size = 18249516 },
{ url = "https://files.pythonhosted.org/packages/43/12/01a563fc44c07095996d0129b8899daf89e4742146f7044cdbdb3101c57f/numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd", size = 13882132 },
{ url = "https://files.pythonhosted.org/packages/16/ee/9df80b06680aaa23fc6c31211387e0db349e0e36d6a63ba3bd78c5acdf11/numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c", size = 18084181 },
{ url = "https://files.pythonhosted.org/packages/28/7d/4b92e2fe20b214ffca36107f1a3e75ef4c488430e64de2d9af5db3a4637d/numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6", size = 5976360 },
{ url = "https://files.pythonhosted.org/packages/b5/42/054082bd8220bbf6f297f982f0a8f5479fcbc55c8b511d928df07b965869/numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea", size = 15814633 },
{ url = "https://files.pythonhosted.org/packages/3f/72/3df6c1c06fc83d9cfe381cccb4be2532bbd38bf93fbc9fad087b6687f1c0/numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30", size = 20455961 },
{ url = "https://files.pythonhosted.org/packages/8e/02/570545bac308b58ffb21adda0f4e220ba716fb658a63c151daecc3293350/numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c", size = 18061071 },
{ url = "https://files.pythonhosted.org/packages/f4/5f/fafd8c51235f60d49f7a88e2275e13971e90555b67da52dd6416caec32fe/numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0", size = 15709730 },
]
[[package]]
name = "project"
version = "0.1.0"
source = { editable = "." }
dependencies = [
{ name = "numpy", version = "1.24.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
{ name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" },
]
[package.metadata]
requires-dist = [{ name = "numpy" }]
"###
);
});
// Re-run with `--locked`.
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 3 packages in [TIME]
"###);
Ok(())
@ -15322,7 +15736,6 @@ fn lock_python_upper_bound() -> Result<()> {
version = "1.24.4"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.13'",
"python_full_version < '3.9'",
]
sdist = { url = "https://files.pythonhosted.org/packages/a4/9b/027bec52c633f6556dba6b722d9a0befb40498b9ceddd29cbe67a45a127c/numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", size = 10911229 }
@ -15409,8 +15822,8 @@ fn lock_python_upper_bound() -> Result<()> {
dependencies = [
{ name = "coloredlogs" },
{ name = "flatbuffers" },
{ name = "numpy", version = "1.24.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9' or python_full_version >= '3.13'" },
{ name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9' and python_full_version < '3.13'" },
{ name = "numpy", version = "1.24.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
{ name = "numpy", version = "1.26.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.9'" },
{ name = "packaging" },
{ name = "protobuf" },
{ name = "sympy" },

View file

@ -8640,7 +8640,9 @@ fn universal_no_repeated_unconditional_distributions_1() -> Result<()> {
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] requirements.in -p 3.8 --universal
alabaster==0.7.13
alabaster==0.7.13 ; python_full_version < '3.9'
# via sphinx
alabaster==0.7.16 ; python_full_version >= '3.9'
# via sphinx
astroid==3.1.0
# via pylint
@ -8686,19 +8688,31 @@ fn universal_no_repeated_unconditional_distributions_1() -> Result<()> {
# via sphinx
snowballstemmer==2.2.0
# via sphinx
sphinx==7.1.2
sphinx==7.1.2 ; python_full_version < '3.9'
# via -r requirements.in
sphinxcontrib-applehelp==1.0.4
sphinx==7.2.6 ; python_full_version >= '3.9'
# via -r requirements.in
sphinxcontrib-applehelp==1.0.4 ; python_full_version < '3.9'
# via sphinx
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-applehelp==1.0.8 ; python_full_version >= '3.9'
# via sphinx
sphinxcontrib-htmlhelp==2.0.1
sphinxcontrib-devhelp==1.0.2 ; python_full_version < '3.9'
# via sphinx
sphinxcontrib-devhelp==1.0.6 ; python_full_version >= '3.9'
# via sphinx
sphinxcontrib-htmlhelp==2.0.1 ; python_full_version < '3.9'
# via sphinx
sphinxcontrib-htmlhelp==2.0.5 ; python_full_version >= '3.9'
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-qthelp==1.0.3 ; python_full_version < '3.9'
# via sphinx
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-qthelp==1.0.7 ; python_full_version >= '3.9'
# via sphinx
sphinxcontrib-serializinghtml==1.1.5 ; python_full_version < '3.9'
# via sphinx
sphinxcontrib-serializinghtml==1.1.10 ; python_full_version >= '3.9'
# via sphinx
tomli==2.0.1 ; python_full_version < '3.11'
# via pylint
@ -8715,7 +8729,7 @@ fn universal_no_repeated_unconditional_distributions_1() -> Result<()> {
----- stderr -----
warning: The requested Python version 3.8 is not available; 3.12.[X] will be used to build dependencies instead.
Resolved 34 packages in [TIME]
Resolved 41 packages in [TIME]
"###
);
@ -8921,7 +8935,9 @@ fn universal_marker_propagation() -> Result<()> {
# via sympy
networkx==3.2.1
# via torch
numpy==1.26.3
numpy==1.26.3 ; python_full_version < '3.9'
# via torchvision
numpy==1.26.4 ; python_full_version >= '3.9'
# via torchvision
pillow==10.2.0
# via torchvision
@ -8953,7 +8969,7 @@ fn universal_marker_propagation() -> Result<()> {
----- stderr -----
warning: The requested Python version 3.8 is not available; 3.12.[X] will be used to build dependencies instead.
Resolved 23 packages in [TIME]
Resolved 24 packages in [TIME]
"###
);
@ -13319,7 +13335,9 @@ matplotlib
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] requirements.in --universal -p 3.8
contourpy==1.1.1
contourpy==1.1.1 ; python_full_version < '3.9'
# via matplotlib
contourpy==1.2.0 ; python_full_version >= '3.9'
# via matplotlib
coverage==7.4.4
# via -r requirements.in
@ -13331,21 +13349,25 @@ matplotlib
# via matplotlib
kiwisolver==1.4.5
# via matplotlib
matplotlib==3.7.5
matplotlib==3.7.5 ; python_full_version < '3.9'
# via -r requirements.in
numpy==1.24.4 ; python_full_version < '3.12'
matplotlib==3.8.3 ; python_full_version >= '3.9'
# via -r requirements.in
numpy==1.24.4 ; python_full_version < '3.9'
# via
# contourpy
# matplotlib
# pandas
numpy==1.26.4 ; python_full_version >= '3.12'
numpy==1.26.4 ; python_full_version >= '3.9'
# via
# contourpy
# matplotlib
# pandas
packaging==24.0
# via matplotlib
pandas==2.0.3
pandas==2.0.3 ; python_full_version < '3.9'
# via -r requirements.in
pandas==2.2.1 ; python_full_version >= '3.9'
# via -r requirements.in
pillow==10.2.0
# via matplotlib
@ -13365,7 +13387,7 @@ matplotlib
# via importlib-resources
----- stderr -----
Resolved [NUM] packages in [TIME]
Resolved 22 packages in [TIME]
"###);
Ok(())

View file

@ -5,8 +5,12 @@ expression: lock
version = 1
requires-python = ">=3.8"
resolution-markers = [
"implementation_name == 'pypy' and sys_platform == 'win32'",
"implementation_name != 'pypy' or sys_platform != 'win32'",
"python_full_version >= '3.10' and implementation_name == 'pypy' and sys_platform == 'win32'",
"python_full_version == '3.9.*' and implementation_name == 'pypy' and sys_platform == 'win32'",
"python_full_version < '3.9' and implementation_name == 'pypy' and sys_platform == 'win32'",
"(python_full_version >= '3.10' and implementation_name != 'pypy') or (python_full_version >= '3.10' and sys_platform != 'win32')",
"(python_full_version == '3.9.*' and implementation_name != 'pypy') or (python_full_version == '3.9.*' and sys_platform != 'win32')",
"(python_full_version < '3.9' and implementation_name != 'pypy') or (python_full_version < '3.9' and sys_platform != 'win32')",
]
[options]
@ -195,7 +199,9 @@ d = [
{ name = "aiohttp" },
]
jupyter = [
{ name = "ipython" },
{ name = "ipython", version = "8.12.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
{ name = "ipython", version = "8.18.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.9.*'" },
{ name = "ipython", version = "8.26.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
{ name = "tokenize-rt" },
]
uvloop = [
@ -249,6 +255,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 },
]
[[package]]
name = "exceptiongroup"
version = "1.2.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 },
]
[[package]]
name = "executing"
version = "2.0.1"
@ -355,26 +370,82 @@ wheels = [
name = "ipython"
version = "8.12.3"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version < '3.9' and implementation_name == 'pypy' and sys_platform == 'win32'",
"(python_full_version < '3.9' and implementation_name != 'pypy') or (python_full_version < '3.9' and sys_platform != 'win32')",
]
dependencies = [
{ name = "appnope", marker = "sys_platform == 'darwin'" },
{ name = "backcall" },
{ name = "colorama", marker = "sys_platform == 'win32'" },
{ name = "decorator" },
{ name = "jedi" },
{ name = "matplotlib-inline" },
{ name = "pexpect", marker = "sys_platform != 'win32'" },
{ name = "pickleshare" },
{ name = "prompt-toolkit" },
{ name = "pygments" },
{ name = "stack-data" },
{ name = "traitlets" },
{ name = "typing-extensions", marker = "python_full_version < '3.10'" },
{ name = "appnope", marker = "python_full_version < '3.9' and sys_platform == 'darwin'" },
{ name = "backcall", marker = "python_full_version < '3.9'" },
{ name = "colorama", marker = "python_full_version < '3.9' and sys_platform == 'win32'" },
{ name = "decorator", marker = "python_full_version < '3.9'" },
{ name = "jedi", marker = "python_full_version < '3.9'" },
{ name = "matplotlib-inline", marker = "python_full_version < '3.9'" },
{ name = "pexpect", marker = "python_full_version < '3.9' and sys_platform != 'win32'" },
{ name = "pickleshare", marker = "python_full_version < '3.9'" },
{ name = "prompt-toolkit", marker = "python_full_version < '3.9'" },
{ name = "pygments", marker = "python_full_version < '3.9'" },
{ name = "stack-data", marker = "python_full_version < '3.9'" },
{ name = "traitlets", marker = "python_full_version < '3.9'" },
{ name = "typing-extensions", marker = "python_full_version < '3.9'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9e/6a/44ef299b1762f5a73841e87fae8a73a8cc8aee538d6dc8c77a5afe1fd2ce/ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363", size = 5470171 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8d/97/8fe103906cd81bc42d3b0175b5534a9f67dccae47d6451131cf8d0d70bb2/ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c", size = 798307 },
]
[[package]]
name = "ipython"
version = "8.18.1"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version == '3.9.*' and implementation_name == 'pypy' and sys_platform == 'win32'",
"(python_full_version == '3.9.*' and implementation_name != 'pypy') or (python_full_version == '3.9.*' and sys_platform != 'win32')",
]
dependencies = [
{ name = "colorama", marker = "python_full_version == '3.9.*' and sys_platform == 'win32'" },
{ name = "decorator", marker = "python_full_version == '3.9.*'" },
{ name = "exceptiongroup", marker = "python_full_version == '3.9.*'" },
{ name = "jedi", marker = "python_full_version == '3.9.*'" },
{ name = "matplotlib-inline", marker = "python_full_version == '3.9.*'" },
{ name = "pexpect", marker = "python_full_version == '3.9.*' and sys_platform != 'win32'" },
{ name = "prompt-toolkit", marker = "python_full_version == '3.9.*'" },
{ name = "pygments", marker = "python_full_version == '3.9.*'" },
{ name = "stack-data", marker = "python_full_version == '3.9.*'" },
{ name = "traitlets", marker = "python_full_version == '3.9.*'" },
{ name = "typing-extensions", marker = "python_full_version == '3.9.*'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/b1/b9/3ba6c45a6df813c09a48bac313c22ff83efa26cbb55011218d925a46e2ad/ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27", size = 5486330 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/47/6b/d9fdcdef2eb6a23f391251fde8781c38d42acd82abe84d054cb74f7863b0/ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397", size = 808161 },
]
[[package]]
name = "ipython"
version = "8.26.0"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.10' and implementation_name == 'pypy' and sys_platform == 'win32'",
"(python_full_version >= '3.10' and implementation_name != 'pypy') or (python_full_version >= '3.10' and sys_platform != 'win32')",
]
dependencies = [
{ name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" },
{ name = "decorator", marker = "python_full_version >= '3.10'" },
{ name = "exceptiongroup", marker = "python_full_version == '3.10.*'" },
{ name = "jedi", marker = "python_full_version >= '3.10'" },
{ name = "matplotlib-inline", marker = "python_full_version >= '3.10'" },
{ name = "pexpect", marker = "python_full_version >= '3.10' and sys_platform != 'emscripten' and sys_platform != 'win32'" },
{ name = "prompt-toolkit", marker = "python_full_version >= '3.10'" },
{ name = "pygments", marker = "python_full_version >= '3.10'" },
{ name = "stack-data", marker = "python_full_version >= '3.10'" },
{ name = "traitlets", marker = "python_full_version >= '3.10'" },
{ name = "typing-extensions", marker = "python_full_version >= '3.10' and python_full_version < '3.12'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/7e/f4/dc45805e5c3e327a626139c023b296bafa4537e602a61055d377704ca54c/ipython-8.26.0.tar.gz", hash = "sha256:1cec0fbba8404af13facebe83d04436a7434c7400e59f47acf467c64abd0956c", size = 5493422 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/73/48/4d2818054671bb272d1b12ca65748a4145dc602a463683b5c21b260becee/ipython-8.26.0-py3-none-any.whl", hash = "sha256:e6b347c27bdf9c32ee9d31ae85defc525755a1869f14057e900675b9e8d6e6ff", size = 817939 },
]
[[package]]
name = "jedi"
version = "0.19.1"

View file

@ -1,5 +1,5 @@
---
source: crates/uv/tests/ecosystem.rs
source: crates/uv/tests/it/ecosystem.rs
expression: snapshot
---
success: true
@ -7,4 +7,4 @@ exit_code: 0
----- stdout -----
----- stderr -----
Resolved 39 packages in [TIME]
Resolved 42 packages in [TIME]