From e3f345ce09e47157af4d83aed76fb9275fbcf757 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 14 Aug 2024 20:00:15 -0400 Subject: [PATCH] Validate lockfile (rather than re-resolve) in `uv lock` (#6091) ## Summary Historically, in order to "resolve from a lockfile", we've taken the lockfile, used it to pre-populate the in-memory metadata index, then run a resolution. If the resolution didn't match our existing resolution, we re-resolved from scratch. This was an appealing approach because (in theory) it didn't require any dedicated logic beyond pre-populating the index. However, it's proven to be _really_ hard to get right, because it's a stricter requirement than we need. We just need the current lockfile to _satisfy_ the requirements provided by the user. We don't actually need a second resolution to produce the exact same result. And it's not uncommon that this second resolution differs, because we seed it with preferences, which fundamentally changes its course. We've worked hard to minimize those "instabilities", but they're still present. The approach here is intended to be much simpler. Instead of resolving from the lockfile, we just check if the current resolution satisfies the state of the workspace. Specifically, we check if the lockfile (1) contains all the relevant members, and (2) matches the metadata for all dependencies, recursively. (We skip registry dependencies, assuming that they're immutable.) This may actually be too conservative, since we can have resolutions that satisfy the requirements, even if the requirements have changed slightly. But we want to bias towards correctness for now. My hope is that this scheme will be more performant, simpler, and more robust. Closes https://github.com/astral-sh/uv/issues/6063. --- crates/pypi-types/src/requirement.rs | 104 +- crates/uv-resolver/src/lib.rs | 2 +- crates/uv-resolver/src/lock.rs | 793 ++- crates/uv-resolver/src/resolver/mod.rs | 1 - ...r__lock__tests__hash_optional_missing.snap | 9 + ...r__lock__tests__hash_optional_present.snap | 9 + ...r__lock__tests__hash_required_present.snap | 9 + ...missing_dependency_source_unambiguous.snap | 13 + ...dependency_source_version_unambiguous.snap | 13 + ...issing_dependency_version_unambiguous.snap | 13 + ...lock__tests__source_direct_has_subdir.snap | 9 + ..._lock__tests__source_direct_no_subdir.snap | 9 + ...solver__lock__tests__source_directory.snap | 9 + ...esolver__lock__tests__source_editable.snap | 9 + crates/uv/src/commands/project/lock.rs | 246 +- crates/uv/src/commands/project/mod.rs | 3 + crates/uv/src/lib.rs | 5 +- crates/uv/tests/branching_urls.rs | 54 + crates/uv/tests/edit.rs | 78 + crates/uv/tests/lock.rs | 5660 +++++++++++------ crates/uv/tests/lock_scenarios.rs | 589 +- .../snapshots/ecosystem__black-lock-file.snap | 17 + ...system__github-wikidata-bot-lock-file.snap | 19 + ...system__home-assistant-core-lock-file.snap | 43 + .../ecosystem__packse-lock-file.snap | 20 + .../ecosystem__transformers-lock-file.snap | 274 + .../ecosystem__warehouse-lock-file.snap | 144 + crates/uv/tests/sync.rs | 3 + crates/uv/tests/workspace.rs | 11 +- scripts/scenarios/templates/lock.mustache | 19 +- 30 files changed, 5641 insertions(+), 2546 deletions(-) diff --git a/crates/pypi-types/src/requirement.rs b/crates/pypi-types/src/requirement.rs index 58e9cea3f..677bec10c 100644 --- a/crates/pypi-types/src/requirement.rs +++ b/crates/pypi-types/src/requirement.rs @@ -10,7 +10,7 @@ use pep440_rs::VersionSpecifiers; use pep508_rs::{ marker, MarkerEnvironment, MarkerTree, RequirementOrigin, VerbatimUrl, VersionOrUrl, }; -use uv_fs::PortablePathBuf; +use uv_fs::{PortablePathBuf, CWD}; use uv_git::{GitReference, GitSha, GitUrl}; use uv_normalize::{ExtraName, PackageName}; @@ -66,6 +66,45 @@ impl Requirement { pub fn is_editable(&self) -> bool { self.source.is_editable() } + + /// Remove any sensitive credentials from the requirement. + #[must_use] + pub fn redact(self) -> Requirement { + match self.source { + RequirementSource::Git { + mut repository, + reference, + precise, + subdirectory, + url, + } => { + // Redact the repository URL. + let _ = repository.set_password(None); + let _ = repository.set_username(""); + + // Redact the PEP 508 URL. + let mut url = url.to_url(); + let _ = url.set_password(None); + let _ = url.set_username(""); + let url = VerbatimUrl::from_url(url); + + Self { + name: self.name, + extras: self.extras, + marker: self.marker, + source: RequirementSource::Git { + repository, + reference, + precise, + subdirectory, + url, + }, + origin: self.origin, + } + } + _ => self, + } + } } impl From for pep508_rs::Requirement { @@ -554,6 +593,10 @@ impl From for RequirementSourceWire { } => { let mut url = repository; + // Redact the credentials. + let _ = url.set_username(""); + let _ = url.set_password(None); + // Clear out any existing state. url.set_fragment(None); url.set_query(None); @@ -595,26 +638,26 @@ impl From for RequirementSourceWire { } } RequirementSource::Path { - install_path, - lock_path: _, + install_path: _, + lock_path, ext: _, url: _, } => Self::Path { - path: PortablePathBuf::from(install_path), + path: PortablePathBuf::from(lock_path), }, RequirementSource::Directory { - install_path, - lock_path: _, + install_path: _, + lock_path, editable, url: _, } => { if editable { Self::Editable { - editable: PortablePathBuf::from(install_path), + editable: PortablePathBuf::from(lock_path), } } else { Self::Directory { - directory: PortablePathBuf::from(install_path), + directory: PortablePathBuf::from(lock_path), } } } @@ -631,31 +674,46 @@ impl TryFrom for RequirementSource { Ok(Self::Registry { specifier, index }) } RequirementSourceWire::Git { git } => { - let mut url = Url::parse(&git)?; + let mut repository = Url::parse(&git)?; let mut reference = GitReference::DefaultBranch; let mut subdirectory = None; - for (key, val) in url.query_pairs() { + for (key, val) in repository.query_pairs() { match &*key { "tag" => reference = GitReference::Tag(val.into_owned()), "branch" => reference = GitReference::Branch(val.into_owned()), "rev" => reference = GitReference::from_rev(val.into_owned()), - "subdirectory" => subdirectory = Some(PathBuf::from(val.into_owned())), + "subdirectory" => subdirectory = Some(val.into_owned()), _ => continue, }; } - let precise = url.fragment().map(GitSha::from_str).transpose()?; + let precise = repository.fragment().map(GitSha::from_str).transpose()?; - url.set_query(None); - url.set_fragment(None); + // Clear out any existing state. + repository.set_fragment(None); + repository.set_query(None); + + // Redact the credentials. + let _ = repository.set_username(""); + let _ = repository.set_password(None); + + // Create a PEP 508-compatible URL. + let mut url = Url::parse(&format!("git+{repository}"))?; + if let Some(rev) = reference.as_str() { + url.set_path(&format!("{}@{}", url.path(), rev)); + } + if let Some(subdirectory) = &subdirectory { + url.set_fragment(Some(&format!("subdirectory={subdirectory}"))); + } + let url = VerbatimUrl::from_url(url); Ok(Self::Git { - repository: url.clone(), + repository, reference, precise, - subdirectory, - url: VerbatimUrl::from_url(url), + subdirectory: subdirectory.map(PathBuf::from), + url, }) } RequirementSourceWire::Direct { url, subdirectory } => Ok(Self::Url { @@ -665,32 +723,38 @@ impl TryFrom for RequirementSource { ext: DistExtension::from_path(url.path()) .map_err(|err| ParsedUrlError::MissingExtensionUrl(url.to_string(), err))?, }), + // TODO(charlie): The use of `CWD` here is incorrect. These should be resolved relative + // to the workspace root, but we don't have access to it here. When comparing these + // sources in the lockfile, we replace the URL anyway. RequirementSourceWire::Path { path } => { let path = PathBuf::from(path); + let url = VerbatimUrl::parse_path(&path, &*CWD)?; Ok(Self::Path { - url: VerbatimUrl::from_path(path.as_path())?, ext: DistExtension::from_path(path.as_path()) .map_err(|err| ParsedUrlError::MissingExtensionPath(path.clone(), err))?, install_path: path.clone(), lock_path: path, + url, }) } RequirementSourceWire::Directory { directory } => { let directory = PathBuf::from(directory); + let url = VerbatimUrl::parse_path(&directory, &*CWD)?; Ok(Self::Directory { - url: VerbatimUrl::from_path(directory.as_path())?, install_path: directory.clone(), lock_path: directory, editable: false, + url, }) } RequirementSourceWire::Editable { editable } => { let editable = PathBuf::from(editable); + let url = VerbatimUrl::parse_path(&editable, &*CWD)?; Ok(Self::Directory { - url: VerbatimUrl::from_path(editable.as_path())?, install_path: editable.clone(), lock_path: editable, editable: true, + url, }) } } diff --git a/crates/uv-resolver/src/lib.rs b/crates/uv-resolver/src/lib.rs index 6d9685da5..00154740e 100644 --- a/crates/uv-resolver/src/lib.rs +++ b/crates/uv-resolver/src/lib.rs @@ -3,7 +3,7 @@ pub use error::{NoSolutionError, NoSolutionHeader, ResolveError}; pub use exclude_newer::ExcludeNewer; pub use exclusions::Exclusions; pub use flat_index::FlatIndex; -pub use lock::{Lock, LockError, TreeDisplay}; +pub use lock::{Lock, LockError, ResolverManifest, TreeDisplay}; pub use manifest::Manifest; pub use options::{Options, OptionsBuilder}; pub use preferences::{Preference, PreferenceError, Preferences}; diff --git a/crates/uv-resolver/src/lock.rs b/crates/uv-resolver/src/lock.rs index 6a3b6a171..ae088db62 100644 --- a/crates/uv-resolver/src/lock.rs +++ b/crates/uv-resolver/src/lock.rs @@ -2,49 +2,40 @@ use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, VecDeque}; use std::convert::Infallible; use std::fmt::{Debug, Display}; -use std::hash::BuildHasherDefault; use std::path::{Path, PathBuf}; use std::str::FromStr; -use std::sync::Arc; use either::Either; use itertools::Itertools; use petgraph::visit::EdgeRef; use pubgrub::Range; -use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet}; +use rustc_hash::{FxHashMap, FxHashSet}; use toml_edit::{value, Array, ArrayOfTables, InlineTable, Item, Table, Value}; +use tracing::debug; use url::Url; use cache_key::RepositoryUrl; use distribution_filename::{DistExtension, ExtensionError, SourceDistExtension, WheelFilename}; use distribution_types::{ BuiltDist, DirectUrlBuiltDist, DirectUrlSourceDist, DirectorySourceDist, Dist, - DistributionMetadata, FileLocation, GitSourceDist, HashComparison, IndexUrl, Name, - PathBuiltDist, PathSourceDist, PrioritizedDist, RegistryBuiltDist, RegistryBuiltWheel, - RegistrySourceDist, RemoteSource, Resolution, ResolvedDist, SourceDistCompatibility, - ToUrlError, UrlString, VersionId, WheelCompatibility, -}; -use pep440_rs::{Version, VersionSpecifier}; -use pep508_rs::{ - ExtraOperator, MarkerEnvironment, MarkerExpression, MarkerTree, VerbatimUrl, VerbatimUrlError, + DistributionMetadata, FileLocation, GitSourceDist, HashPolicy, IndexUrl, Name, PathBuiltDist, + PathSourceDist, RegistryBuiltDist, RegistryBuiltWheel, RegistrySourceDist, RemoteSource, + Resolution, ResolvedDist, ToUrlError, UrlString, }; +use pep440_rs::Version; +use pep508_rs::{MarkerEnvironment, MarkerTree, VerbatimUrl, VerbatimUrlError}; use platform_tags::{TagCompatibility, TagPriority, Tags}; -use pypi_types::{ - HashDigest, ParsedArchiveUrl, ParsedGitUrl, ParsedUrl, Requirement, RequirementSource, -}; -use uv_configuration::{ExtrasSpecification, Upgrade}; -use uv_distribution::{ArchiveMetadata, Metadata}; -use uv_fs::{PortablePath, PortablePathBuf, Simplified}; +use pypi_types::{HashDigest, ParsedArchiveUrl, ParsedGitUrl, Requirement, RequirementSource}; +use uv_configuration::ExtrasSpecification; +use uv_distribution::DistributionDatabase; +use uv_fs::{relative_to, PortablePath, PortablePathBuf, Simplified}; use uv_git::{GitReference, GitSha, RepositoryReference, ResolvedRepositoryReference}; use uv_normalize::{ExtraName, GroupName, PackageName}; -use uv_workspace::VirtualProject; +use uv_types::BuildContext; +use uv_workspace::{VirtualProject, Workspace}; use crate::resolution::{AnnotatedDist, ResolutionGraphNode}; -use crate::resolver::FxOnceMap; -use crate::{ - ExcludeNewer, InMemoryIndex, MetadataResponse, PrereleaseMode, RequiresPython, ResolutionGraph, - ResolutionMode, VersionMap, VersionsResponse, -}; +use crate::{ExcludeNewer, PrereleaseMode, RequiresPython, ResolutionGraph, ResolutionMode}; /// The current version of the lockfile format. const VERSION: u32 = 1; @@ -58,7 +49,7 @@ pub struct Lock { fork_markers: Vec, /// The range of supported Python versions. requires_python: Option, - /// We discard the lockfile if these options match. + /// We discard the lockfile if these options don't match. options: ResolverOptions, /// The actual locked version and their metadata. packages: Vec, @@ -74,6 +65,8 @@ pub struct Lock { /// that exists in this map. That is, there are no dependencies that don't /// have a corresponding locked package entry in the same lockfile. by_id: FxHashMap, + /// The input requirements to the resolution. + manifest: ResolverManifest, } impl Lock { @@ -208,6 +201,7 @@ impl Lock { packages, requires_python, options, + ResolverManifest::default(), graph.fork_markers.clone(), )?; Ok(lock) @@ -219,6 +213,7 @@ impl Lock { mut packages: Vec, requires_python: Option, options: ResolverOptions, + manifest: ResolverManifest, fork_markers: Vec, ) -> Result { // Put all dependencies for each package in a canonical order and @@ -379,9 +374,27 @@ impl Lock { options, packages, by_id, + manifest, }) } + /// Record the requirements that were used to generate this lock. + #[must_use] + pub fn with_manifest(mut self, manifest: ResolverManifest) -> Self { + self.manifest = manifest; + self + } + + /// Returns the number of packages in the lockfile. + pub fn len(&self) -> usize { + self.packages.len() + } + + /// Returns `true` if the lockfile contains no packages. + pub fn is_empty(&self) -> bool { + self.packages.is_empty() + } + /// Returns the [`Package`] entries in this lock. pub fn packages(&self) -> &[Package] { &self.packages @@ -527,7 +540,7 @@ impl Lock { // Write the settings that were used to generate the resolution. // This enables us to invalidate the lockfile if the user changes // their settings. - if self.options != ResolverOptions::default() { + { let mut options_table = Table::new(); if self.options.resolution_mode != ResolutionMode::default() { @@ -545,7 +558,71 @@ impl Lock { if let Some(exclude_newer) = self.options.exclude_newer { options_table.insert("exclude-newer", value(exclude_newer.to_string())); } - doc.insert("options", Item::Table(options_table)); + + if !options_table.is_empty() { + doc.insert("options", Item::Table(options_table)); + } + } + + // Write the manifest that was used to generate the resolution. + { + let mut manifest_table = Table::new(); + + if !self.manifest.members.is_empty() { + manifest_table.insert( + "members", + value(each_element_on_its_line_array( + self.manifest + .members + .iter() + .map(std::string::ToString::to_string), + )), + ); + } + + if !self.manifest.constraints.is_empty() { + let constraints = self + .manifest + .constraints + .iter() + .map(|requirement| { + serde::Serialize::serialize( + &requirement, + toml_edit::ser::ValueSerializer::new(), + ) + }) + .collect::, _>>()?; + let constraints = match constraints.as_slice() { + [] => Array::new(), + [requirement] => Array::from_iter([requirement]), + constraints => each_element_on_its_line_array(constraints.iter()), + }; + manifest_table.insert("constraints", value(constraints)); + } + + if !self.manifest.overrides.is_empty() { + let overrides = self + .manifest + .overrides + .iter() + .map(|requirement| { + serde::Serialize::serialize( + &requirement, + toml_edit::ser::ValueSerializer::new(), + ) + }) + .collect::, _>>()?; + let overrides = match overrides.as_slice() { + [] => Array::new(), + [requirement] => Array::from_iter([requirement]), + overrides => each_element_on_its_line_array(overrides.iter()), + }; + manifest_table.insert("overrides", value(overrides)); + } + + if !manifest_table.is_empty() { + doc.insert("manifest", Item::Table(manifest_table)); + } } // Count the number of packages for each package name. When @@ -588,62 +665,207 @@ impl Lock { dist } - /// Convert the [`Lock`] to a [`InMemoryIndex`] that can be used for resolution. - /// - /// Any packages specified to be upgraded will be ignored. - pub fn to_index( + /// Convert the [`Lock`] to a [`Resolution`] using the given marker environment, tags, and root. + pub async fn satisfies( &self, - install_path: &Path, - upgrade: &Upgrade, - ) -> Result { - let distributions = - FxOnceMap::with_capacity_and_hasher(self.packages.len(), BuildHasherDefault::default()); - let mut packages: FxHashMap<_, BTreeMap> = - FxHashMap::with_capacity_and_hasher(self.packages.len(), FxBuildHasher); + workspace: &Workspace, + members: &[PackageName], + constraints: &[Requirement], + overrides: &[Requirement], + tags: &Tags, + database: &DistributionDatabase<'_, Context>, + ) -> Result { + let mut queue: VecDeque<&Package> = VecDeque::new(); + let mut seen = FxHashSet::default(); - for package in &self.packages { - // Skip packages that may be upgraded from their pinned version. - if upgrade.contains(package.name()) { + // Validate that the lockfile was generated with the same root members. + { + let expected = members; + let actual = &self.manifest.members; + if expected != actual { + debug!( + "Mismatched members:\n expected: {:?}\n found: {:?}", + expected, actual + ); + return Ok(false); + } + } + + // Validate that the lockfile was generated with the same constraints. + { + let expected: Vec<_> = constraints + .iter() + .cloned() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(); + let actual: Vec<_> = self + .manifest + .constraints + .iter() + .cloned() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(); + if expected != actual { + debug!( + "Mismatched constraints:\n expected: {:?}\n found: {:?}", + expected, actual + ); + return Ok(false); + } + } + + // Validate that the lockfile was generated with the same overrides. + { + let expected: Vec<_> = overrides + .iter() + .cloned() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(); + let actual: Vec<_> = self + .manifest + .overrides + .iter() + .cloned() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(); + if expected != actual { + debug!( + "Mismatched overrides:\n expected: {:?}\n found: {:?}", + expected, actual + ); + return Ok(false); + } + } + + // Add the workspace packages to the queue. + for root_name in workspace.packages().keys() { + let root = self + .find_by_name(root_name) + .expect("found too many packages matching root"); + + let Some(root) = root else { + // The package is not in the lockfile, so it can't be satisfied. + debug!("Workspace package `{root_name}` not found in lockfile"); + return Ok(false); + }; + + // Add the base package. + queue.push_back(root); + } + + while let Some(package) = queue.pop_front() { + // Assume that registry dependencies are immutable. + if matches!(package.id.source, Source::Registry(..)) { continue; } - match package.id.source { - Source::Registry(..) | Source::Git(..) => {} - // Skip local and direct URL dependencies, as their metadata may have been mutated - // without a version change. - Source::Path(..) - | Source::Directory(..) - | Source::Editable(..) - | Source::Direct(..) => continue, + // Get the metadata for the distribution. + let dist = package.to_dist(workspace.install_path(), tags)?; + + let Ok(archive) = database + .get_or_build_wheel_metadata(&dist, HashPolicy::None) + .await + else { + debug!("Failed to get metadata for: {}", package.id); + return Ok(false); + }; + + // Validate the `requires-dist` metadata. + { + let expected: Vec<_> = archive + .metadata + .requires_dist + .into_iter() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(); + let actual: Vec<_> = package + .metadata + .requires_dist + .iter() + .cloned() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(); + + if expected != actual { + debug!( + "Mismatched `requires-dist` for {}:\n expected: {:?}\n found: {:?}", + package.id, expected, actual + ); + return Ok(false); + } } - // Add registry distributions to the package index. - if let Some(prioritized_dist) = package.to_prioritized_dist(install_path)? { - packages - .entry(package.name().clone()) - .or_default() - .insert(package.id.version.clone(), prioritized_dist); + // Validate the `dev-dependencies` metadata. + { + let expected: BTreeMap> = archive + .metadata + .dev_dependencies + .into_iter() + .map(|(group, requirements)| { + ( + group, + requirements + .into_iter() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(), + ) + }) + .collect(); + let actual: BTreeMap> = package + .metadata + .requires_dev + .iter() + .map(|(group, requirements)| { + ( + group.clone(), + requirements + .iter() + .cloned() + .map(|requirement| normalize_requirement(requirement, workspace)) + .collect(), + ) + }) + .collect(); + + if expected != actual { + debug!( + "Mismatched `requires-dev` for {}:\n expected: {:?}\n found: {:?}", + package.id, expected, actual + ); + return Ok(false); + } } - // Extract the distribution metadata. - let version_id = package.version_id(install_path)?; - let hashes = package.hashes(); - let metadata = package.to_metadata(install_path)?; + // Recurse. + // TODO(charlie): Do we care about extras here, or any other fields on the `Dependency`? + // Should we instead recurse on `requires_dist`? + for dep in &package.dependencies { + if seen.insert(&dep.package_id) { + let dep_dist = self.find_by_id(&dep.package_id); + queue.push_back(dep_dist); + } + } - // Add metadata to the distributions index. - let response = MetadataResponse::Found(ArchiveMetadata::with_hashes(metadata, hashes)); - distributions.done(version_id, Arc::new(response)); + for dependencies in package.optional_dependencies.values() { + for dep in dependencies { + if seen.insert(&dep.package_id) { + let dep_dist = self.find_by_id(&dep.package_id); + queue.push_back(dep_dist); + } + } + } + + for dependencies in package.dev_dependencies.values() { + for dep in dependencies { + if seen.insert(&dep.package_id) { + let dep_dist = self.find_by_id(&dep.package_id); + queue.push_back(dep_dist); + } + } + } } - let packages = packages - .into_iter() - .map(|(name, versions)| { - let response = VersionsResponse::Found(vec![VersionMap::from(versions)]); - (name, Arc::new(response)) - }) - .collect(); - - Ok(InMemoryIndex::with(packages, distributions)) + Ok(true) } } @@ -661,6 +883,34 @@ struct ResolverOptions { exclude_newer: Option, } +#[derive(Clone, Debug, Default, serde::Deserialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub struct ResolverManifest { + /// The workspace members included in the lockfile. + #[serde(default)] + members: Vec, + /// The constraints provided to the resolver. + #[serde(default)] + constraints: Vec, + /// The overrides provided to the resolver. + #[serde(default)] + overrides: Vec, +} + +impl ResolverManifest { + pub fn new( + members: Vec, + constraints: Vec, + overrides: Vec, + ) -> Self { + Self { + members, + constraints, + overrides, + } + } +} + #[derive(Clone, Debug, serde::Deserialize)] #[serde(rename_all = "kebab-case")] struct LockWire { @@ -674,6 +924,8 @@ struct LockWire { /// We discard the lockfile if these options match. #[serde(default)] options: ResolverOptions, + #[serde(default)] + manifest: ResolverManifest, #[serde(rename = "package", alias = "distribution", default)] packages: Vec, } @@ -685,6 +937,7 @@ impl From for LockWire { requires_python: lock.requires_python, fork_markers: lock.fork_markers, options: lock.options, + manifest: lock.manifest, packages: lock.packages.into_iter().map(PackageWire::from).collect(), } } @@ -721,6 +974,7 @@ impl TryFrom for Lock { packages, wire.requires_python, wire.options, + wire.manifest, wire.fork_markers, ) } @@ -737,9 +991,14 @@ pub struct Package { /// /// Named `environment-markers` in `uv.lock`. fork_markers: Vec, + /// The resolved dependencies of the package. dependencies: Vec, + /// The resolved optional dependencies of the package. optional_dependencies: BTreeMap>, + /// The resolved development dependencies of the package. dev_dependencies: BTreeMap>, + /// The exact requirements from the package metadata. + metadata: PackageMetadata, } impl Package { @@ -750,6 +1009,16 @@ impl Package { let id = PackageId::from_annotated_dist(annotated_dist); let sdist = SourceDist::from_annotated_dist(&id, annotated_dist)?; let wheels = Wheel::from_annotated_dist(annotated_dist)?; + let requires_dist = if matches!(id.source, Source::Registry(..)) { + vec![] + } else { + annotated_dist.metadata.requires_dist.clone() + }; + let requires_dev = if matches!(id.source, Source::Registry(..)) { + BTreeMap::default() + } else { + annotated_dist.metadata.dev_dependencies.clone() + }; Ok(Package { id, sdist, @@ -758,6 +1027,11 @@ impl Package { dependencies: vec![], optional_dependencies: BTreeMap::default(), dev_dependencies: BTreeMap::default(), + metadata: PackageMetadata { + requires_dist, + + requires_dev, + }, }) } @@ -1001,119 +1275,6 @@ impl Package { Ok(Some(sdist)) } - /// Convert the [`Package`] to a [`PrioritizedDist`] that can be used for resolution, if - /// it has a registry source. - fn to_prioritized_dist( - &self, - workspace_root: &Path, - ) -> Result, LockError> { - let prioritized_dist = match &self.id.source { - Source::Registry(url) => { - let mut prioritized_dist = PrioritizedDist::default(); - - // Add the source distribution. - if let Some(distribution_types::SourceDist::Registry(sdist)) = - self.to_source_dist(workspace_root)? - { - // When resolving from a lockfile all sources are equally compatible. - let compat = SourceDistCompatibility::Compatible(HashComparison::Matched); - let hash = self - .sdist - .as_ref() - .and_then(|sdist| sdist.hash().map(|h| h.0.clone())); - prioritized_dist.insert_source(sdist, hash, compat); - }; - - // Add any wheels. - for wheel in &self.wheels { - let hash = wheel.hash.as_ref().map(|h| h.0.clone()); - let wheel = wheel.to_registry_dist(url.to_url())?; - let compat = - WheelCompatibility::Compatible(HashComparison::Matched, None, None); - prioritized_dist.insert_built(wheel, hash, compat); - } - - prioritized_dist - } - _ => return Ok(None), - }; - - Ok(Some(prioritized_dist)) - } - - /// Convert the [`Package`] to [`Metadata`] that can be used for resolution. - pub fn to_metadata(&self, workspace_root: &Path) -> Result { - let name = self.name().clone(); - let version = self.id.version.clone(); - let provides_extras = self.optional_dependencies.keys().cloned().collect(); - - let mut dependency_extras = FxHashMap::default(); - let mut requires_dist = self - .dependencies - .iter() - .filter_map(|dep| { - dep.to_requirement(workspace_root, &mut dependency_extras) - .transpose() - }) - .collect::, LockError>>()?; - - // Denormalize optional dependencies. - for (extra, deps) in &self.optional_dependencies { - for dep in deps { - if let Some(mut dep) = dep.to_requirement(workspace_root, &mut dependency_extras)? { - // Add back the extra marker expression. - dep.marker - .and(MarkerTree::expression(MarkerExpression::Extra { - operator: ExtraOperator::Equal, - name: extra.clone(), - })); - - requires_dist.push(dep); - } - } - } - - // Denormalize extras for each dependency. - for req in &mut requires_dist { - if let Some(extras) = dependency_extras.remove(&req.name) { - req.extras = extras; - } - } - - let dev_dependencies = self - .dev_dependencies - .iter() - .map(|(group, deps)| { - let mut dependency_extras = FxHashMap::default(); - let mut deps = deps - .iter() - .filter_map(|dep| { - dep.to_requirement(workspace_root, &mut dependency_extras) - .transpose() - }) - .collect::, LockError>>()?; - - // Denormalize extras for each development dependency. - for dep in &mut deps { - if let Some(extras) = dependency_extras.remove(&dep.name) { - dep.extras = extras; - } - } - - Ok((group.clone(), deps)) - }) - .collect::>()?; - - Ok(Metadata { - name, - version, - requires_dist, - dev_dependencies, - provides_extras, - requires_python: None, - }) - } - fn to_toml(&self, dist_count_by_name: &FxHashMap) -> anyhow::Result { let mut table = Table::new(); @@ -1145,9 +1306,13 @@ impl Package { deps.iter() .map(|dep| dep.to_toml(dist_count_by_name).into_inline_table()), ); - optional_deps.insert(extra.as_ref(), value(deps)); + if !deps.is_empty() { + optional_deps.insert(extra.as_ref(), value(deps)); + } + } + if !optional_deps.is_empty() { + table.insert("optional-dependencies", Item::Table(optional_deps)); } - table.insert("optional-dependencies", Item::Table(optional_deps)); } if !self.dev_dependencies.is_empty() { @@ -1157,9 +1322,13 @@ impl Package { deps.iter() .map(|dep| dep.to_toml(dist_count_by_name).into_inline_table()), ); - dev_dependencies.insert(extra.as_ref(), value(deps)); + if !deps.is_empty() { + dev_dependencies.insert(extra.as_ref(), value(deps)); + } + } + if !dev_dependencies.is_empty() { + table.insert("dev-dependencies", Item::Table(dev_dependencies)); } - table.insert("dev-dependencies", Item::Table(dev_dependencies)); } if let Some(ref sdist) = self.sdist { @@ -1177,6 +1346,61 @@ impl Package { table.insert("wheels", value(wheels)); } + // Write the package metadata, if non-empty. + { + let mut metadata_table = Table::new(); + + if !self.metadata.requires_dist.is_empty() { + let requires_dist = self + .metadata + .requires_dist + .iter() + .map(|requirement| { + serde::Serialize::serialize( + &requirement, + toml_edit::ser::ValueSerializer::new(), + ) + }) + .collect::, _>>()?; + let requires_dist = match requires_dist.as_slice() { + [] => Array::new(), + [requirement] => Array::from_iter([requirement]), + requires_dist => each_element_on_its_line_array(requires_dist.iter()), + }; + metadata_table.insert("requires-dist", value(requires_dist)); + } + + if !self.metadata.requires_dev.is_empty() { + let mut requires_dev = Table::new(); + for (extra, deps) in &self.metadata.requires_dev { + let deps = deps + .iter() + .map(|requirement| { + serde::Serialize::serialize( + &requirement, + toml_edit::ser::ValueSerializer::new(), + ) + }) + .collect::, _>>()?; + let deps = match deps.as_slice() { + [] => Array::new(), + [requirement] => Array::from_iter([requirement]), + deps => each_element_on_its_line_array(deps.iter()), + }; + if !deps.is_empty() { + requires_dev.insert(extra.as_ref(), value(deps)); + } + } + if !requires_dev.is_empty() { + metadata_table.insert("requires-dev", Item::Table(requires_dev)); + } + } + + if !metadata_table.is_empty() { + table.insert("metadata", Item::Table(metadata_table)); + } + } + Ok(table) } @@ -1223,17 +1447,6 @@ impl Package { } } - /// Returns a [`VersionId`] for this package that can be used for resolution. - fn version_id(&self, workspace_root: &Path) -> Result { - match &self.id.source { - Source::Registry(_) => Ok(VersionId::NameVersion( - self.name().clone(), - self.id.version.clone(), - )), - _ => Ok(self.to_source_dist(workspace_root)?.unwrap().version_id()), - } - } - /// Returns all the hashes associated with this [`Package`]. fn hashes(&self) -> Vec { let mut hashes = Vec::new(); @@ -1279,6 +1492,8 @@ struct PackageWire { #[serde(flatten)] id: PackageId, #[serde(default)] + metadata: PackageMetadata, + #[serde(default)] sdist: Option, #[serde(default)] wheels: Vec, @@ -1292,6 +1507,15 @@ struct PackageWire { dev_dependencies: BTreeMap>, } +#[derive(Clone, Default, Debug, Eq, PartialEq, serde::Deserialize)] +#[serde(rename_all = "kebab-case")] +struct PackageMetadata { + #[serde(default)] + requires_dist: Vec, + #[serde(default)] + requires_dev: BTreeMap>, +} + impl PackageWire { fn unwire( self, @@ -1304,6 +1528,7 @@ impl PackageWire { }; Ok(Package { id: self.id, + metadata: self.metadata, sdist: self.sdist, wheels: self.wheels, fork_markers: self.fork_markers, @@ -1329,6 +1554,7 @@ impl From for PackageWire { }; PackageWire { id: dist.id, + metadata: dist.metadata, sdist: dist.sdist, wheels: dist.wheels, fork_markers: dist.fork_markers, @@ -2322,82 +2548,6 @@ impl Dependency { } } - /// Convert the [`Dependency`] to a [`Requirement`] that can be used for resolution. - pub(crate) fn to_requirement( - &self, - workspace_root: &Path, - extras: &mut FxHashMap>, - ) -> Result, LockError> { - // Keep track of extras, these will be denormalized later. - if !self.extra.is_empty() { - extras - .entry(self.package_id.name.clone()) - .or_default() - .extend(self.extra.iter().cloned()); - } - - // Reconstruct the `RequirementSource` from the `Source`. - let source = match &self.package_id.source { - Source::Registry(_) => RequirementSource::Registry { - // We don't store the version specifier that was originally used for resolution in - // the lockfile, so this might be too restrictive. However, this is the only version - // we have the metadata for, so if resolution fails we will need to fallback to a - // clean resolve. - specifier: VersionSpecifier::equals_version(self.package_id.version.clone()).into(), - index: None, - }, - Source::Git(repository, git) => { - let git_url = uv_git::GitUrl::from_commit( - repository.to_url(), - GitReference::from(git.kind.clone()), - git.precise, - ); - - let parsed_url = ParsedUrl::Git(ParsedGitUrl { - url: git_url.clone(), - subdirectory: git.subdirectory.as_ref().map(PathBuf::from), - }); - RequirementSource::from_verbatim_parsed_url(parsed_url) - } - Source::Direct(url, direct) => { - let parsed_url = ParsedUrl::Archive(ParsedArchiveUrl { - url: url.to_url(), - subdirectory: direct.subdirectory.as_ref().map(PathBuf::from), - ext: DistExtension::from_path(url.as_ref())?, - }); - RequirementSource::from_verbatim_parsed_url(parsed_url) - } - Source::Path(ref path) => RequirementSource::Path { - lock_path: path.clone(), - install_path: workspace_root.join(path), - url: verbatim_url(workspace_root.join(path), &self.package_id)?, - ext: DistExtension::from_path(path)?, - }, - Source::Directory(ref path) => RequirementSource::Directory { - editable: false, - lock_path: path.clone(), - install_path: workspace_root.join(path), - url: verbatim_url(workspace_root.join(path), &self.package_id)?, - }, - Source::Editable(ref path) => RequirementSource::Directory { - editable: true, - lock_path: path.clone(), - install_path: workspace_root.join(path), - url: verbatim_url(workspace_root.join(path), &self.package_id)?, - }, - }; - - let requirement = Requirement { - name: self.package_id.name.clone(), - marker: self.marker.clone(), - origin: None, - extras: Vec::new(), - source, - }; - - Ok(Some(requirement)) - } - /// Returns the TOML representation of this dependency. fn to_toml(&self, dist_count_by_name: &FxHashMap) -> Table { let mut table = Table::new(); @@ -2520,6 +2670,101 @@ impl<'de> serde::Deserialize<'de> for Hash { } } +/// Normalize a [`Requirement`], which could come from a lockfile, a `pyproject.toml`, etc. +/// +/// Performs the following steps: +/// +/// 1. Removes any sensitive credentials. +/// 2. Ensures that the lock and install paths are appropriately framed with respect to the +/// current [`Workspace`]. +/// 3. Removes the `origin` field, which is only used in `requirements.txt`. +fn normalize_requirement(requirement: Requirement, workspace: &Workspace) -> Requirement { + match requirement.source { + RequirementSource::Git { + mut repository, + reference, + precise, + subdirectory, + url, + } => { + // Redact the repository URL. + let _ = repository.set_password(None); + let _ = repository.set_username(""); + + // Redact the PEP 508 URL. + let mut url = url.to_url(); + let _ = url.set_password(None); + let _ = url.set_username(""); + let url = VerbatimUrl::from_url(url); + + Requirement { + name: requirement.name, + extras: requirement.extras, + marker: requirement.marker, + source: RequirementSource::Git { + repository, + reference, + precise, + subdirectory, + url, + }, + origin: None, + } + } + RequirementSource::Path { + install_path, + lock_path, + ext, + url: _, + } => { + let install_path = uv_fs::normalize_path(&workspace.install_path().join(install_path)); + let lock_path = relative_to(workspace.lock_path(), &lock_path).unwrap(); + let url = VerbatimUrl::from_path(&install_path).unwrap(); + Requirement { + name: requirement.name, + extras: requirement.extras, + marker: requirement.marker, + source: RequirementSource::Path { + install_path, + lock_path, + ext, + url, + }, + origin: None, + } + } + RequirementSource::Directory { + install_path, + lock_path, + editable, + url: _, + } => { + let install_path = uv_fs::normalize_path(&workspace.install_path().join(install_path)); + let lock_path = relative_to(workspace.lock_path(), &lock_path).unwrap(); + let url = VerbatimUrl::from_path(&install_path).unwrap(); + Requirement { + name: requirement.name, + extras: requirement.extras, + marker: requirement.marker, + source: RequirementSource::Directory { + install_path, + lock_path, + editable, + url, + }, + origin: None, + } + } + _ => Requirement { + name: requirement.name, + extras: requirement.extras, + marker: requirement.marker, + source: requirement.source, + origin: None, + }, + } +} + #[derive(Debug, thiserror::Error)] #[error(transparent)] pub struct LockError(Box); diff --git a/crates/uv-resolver/src/resolver/mod.rs b/crates/uv-resolver/src/resolver/mod.rs index 5afc1129a..1963dae41 100644 --- a/crates/uv-resolver/src/resolver/mod.rs +++ b/crates/uv-resolver/src/resolver/mod.rs @@ -59,7 +59,6 @@ pub(crate) use crate::resolver::availability::{ }; use crate::resolver::batch_prefetch::BatchPrefetcher; use crate::resolver::groups::Groups; -pub(crate) use crate::resolver::index::FxOnceMap; pub use crate::resolver::index::InMemoryIndex; pub use crate::resolver::provider::{ DefaultResolverProvider, MetadataResponse, PackageVersionsResult, ResolverProvider, diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap index d090283f2..5561686e3 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_missing.snap @@ -57,6 +57,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -72,5 +76,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_present.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_present.snap index 94dbce712..16709bb8f 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_present.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_optional_present.snap @@ -64,6 +64,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -79,5 +83,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_required_present.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_required_present.snap index 655a3ca72..db3920c09 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_required_present.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__hash_required_present.snap @@ -62,6 +62,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -75,5 +79,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap index 86cd2a8aa..4c2909fd4 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_unambiguous.snap @@ -50,6 +50,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, Package { id: PackageId { @@ -104,6 +108,10 @@ Ok( ], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -130,5 +138,10 @@ Ok( ), }: 1, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap index 86cd2a8aa..4c2909fd4 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_source_version_unambiguous.snap @@ -50,6 +50,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, Package { id: PackageId { @@ -104,6 +108,10 @@ Ok( ], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -130,5 +138,10 @@ Ok( ), }: 1, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap index 86cd2a8aa..4c2909fd4 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__missing_dependency_version_unambiguous.snap @@ -50,6 +50,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, Package { id: PackageId { @@ -104,6 +108,10 @@ Ok( ], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -130,5 +138,10 @@ Ok( ), }: 1, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap index 0590bdca6..5d44e58ae 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_has_subdir.snap @@ -36,6 +36,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -56,5 +60,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap index 376dadca9..e90c14db0 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_direct_no_subdir.snap @@ -34,6 +34,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -52,5 +56,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_directory.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_directory.snap index c6821a45e..82791c609 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_directory.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_directory.snap @@ -29,6 +29,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -42,5 +46,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_editable.snap b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_editable.snap index cf1eaaf43..f3f4b8fdb 100644 --- a/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_editable.snap +++ b/crates/uv-resolver/src/snapshots/uv_resolver__lock__tests__source_editable.snap @@ -29,6 +29,10 @@ Ok( dependencies: [], optional_dependencies: {}, dev_dependencies: {}, + metadata: PackageMetadata { + requires_dist: [], + requires_dev: {}, + }, }, ], by_id: { @@ -42,5 +46,10 @@ Ok( ), }: 0, }, + manifest: ResolverManifest { + members: [], + constraints: [], + overrides: [], + }, }, ) diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index 8b39afc1a..b928cbad6 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -9,7 +9,7 @@ use rustc_hash::{FxBuildHasher, FxHashMap}; use tracing::debug; use distribution_types::{ - Diagnostic, FlatIndexLocation, IndexUrl, UnresolvedRequirementSpecification, UrlString, + FlatIndexLocation, IndexUrl, UnresolvedRequirementSpecification, UrlString, }; use pep440_rs::Version; use uv_auth::store_credentials_from_url; @@ -17,13 +17,16 @@ use uv_cache::Cache; use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode, Reinstall, SetupPyStrategy}; use uv_dispatch::BuildDispatch; +use uv_distribution::DistributionDatabase; use uv_fs::CWD; use uv_git::ResolvedRepositoryReference; use uv_normalize::{PackageName, DEV_DEPENDENCIES}; use uv_python::{Interpreter, PythonDownloads, PythonEnvironment, PythonPreference, PythonRequest}; use uv_requirements::upgrade::{read_lock_requirements, LockedRequirements}; +use uv_requirements::NamedRequirementsResolver; use uv_resolver::{ - FlatIndex, Lock, OptionsBuilder, PythonRequirement, RequiresPython, ResolverMarkers, + FlatIndex, Lock, OptionsBuilder, PythonRequirement, RequiresPython, ResolverManifest, + ResolverMarkers, }; use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy}; use uv_warnings::{warn_user, warn_user_once}; @@ -31,6 +34,7 @@ use uv_workspace::{DiscoveryOptions, Workspace}; use crate::commands::pip::loggers::{DefaultResolveLogger, ResolveLogger, SummaryResolveLogger}; use crate::commands::project::{find_requires_python, FoundInterpreter, ProjectError, SharedState}; +use crate::commands::reporters::ResolverReporter; use crate::commands::{pip, ExitStatus}; use crate::printer::Printer; use crate::settings::{ResolverSettings, ResolverSettingsRef}; @@ -260,6 +264,21 @@ async fn do_lock( let dev = vec![DEV_DEPENDENCIES.clone()]; let source_trees = vec![]; + // Collect the list of members. + let members = { + let mut members = workspace.packages().keys().cloned().collect::>(); + members.sort(); + + // If this is a non-virtual project with a single member, we can omit it from the lockfile. + // If any members are added or removed, it will inherently mismatch. If the member is + // renamed, it will also mismatch. + if members.len() == 1 && !workspace.is_virtual() { + members.clear(); + } + + members + }; + // Determine the supported Python range. If no range is defined, and warn and default to the // current minor version. let requires_python = find_requires_python(workspace)?; @@ -335,6 +354,43 @@ async fn do_lock( FlatIndex::from_entries(entries, None, &hasher, build_options) }; + // Create a build dispatch. + let build_dispatch = BuildDispatch::new( + &client, + cache, + &build_constraints, + interpreter, + index_locations, + &flat_index, + &state.index, + &state.git, + &state.in_flight, + index_strategy, + setup_py, + config_setting, + build_isolation, + link_mode, + build_options, + exclude_newer, + sources, + concurrency, + preview, + ); + + let database = + DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads, preview); + + // Annoyingly, we have to resolve any unnamed overrides upfront. + let overrides = NamedRequirementsResolver::new( + overrides, + &hasher, + &state.index, + DistributionDatabase::new(&client, &build_dispatch, concurrency.downloads, preview), + ) + .with_reporter(ResolverReporter::from(printer)) + .resolve() + .await?; + // If any of the resolution-determining settings changed, invalidate the lock. let existing_lock = existing_lock.filter(|lock| { if lock.resolution_mode() != options.resolution_mode { @@ -401,19 +457,23 @@ async fn do_lock( let start = std::time::Instant::now(); - let requires_python = find_requires_python(workspace)?; let existing_lock = existing_lock.filter(|lock| { - match (lock.requires_python(), requires_python.as_ref()) { + match (lock.requires_python(), requires_python) { // If the Requires-Python bound in the lockfile is weaker or equivalent to the // Requires-Python bound in the workspace, we should have the necessary wheels to perform // a locked resolution. - (None, Some(_)) => true, - (Some(locked), Some(specified)) if locked.bound() == specified.bound() => true, - - // On the other hand, if the bound in the lockfile is stricter, meaning the - // bound has since been weakened, we have to perform a clean resolution to ensure - // we fetch the necessary wheels. - _ => false, + (None, _) => true, + (Some(locked), specified) => { + if locked.bound() == specified.bound() { + true + } else { + // On the other hand, if the bound in the lockfile is stricter, meaning the + // bound has since been weakened, we have to perform a clean resolution to ensure + // we fetch the necessary wheels. + debug!("Ignoring existing lockfile due to change in `requires-python`"); + false + } + } } }); @@ -432,7 +492,10 @@ async fn do_lock( }); // If any upgrades are specified, don't use the existing lockfile. - let existing_lock = existing_lock.filter(|_| upgrade.is_none()); + let existing_lock = existing_lock.filter(|_| { + debug!("Ignoring existing lockfile due to `--upgrade`"); + upgrade.is_none() + }); // If the user provided at least one index URL (from the command line, or from a configuration // file), don't use the existing lockfile if it references any registries that are no longer @@ -477,7 +540,7 @@ async fn do_lock( true }); - let resolution = match existing_lock { + let existing_lock = match existing_lock { None => None, // Try to resolve using metadata in the lockfile. @@ -486,117 +549,50 @@ async fn do_lock( // but we rely on the lockfile for the metadata of any existing distributions. If we have // any outdated metadata we fall back to a clean resolve. Some(lock) => { - debug!("Resolving with existing `uv.lock`"); - - // Prefill the index with the lockfile metadata. - let index = lock.to_index(workspace.install_path(), upgrade)?; - - // Create a build dispatch. - let build_dispatch = BuildDispatch::new( - &client, - cache, - &build_constraints, - interpreter, - index_locations, - &flat_index, - &index, - &state.git, - &state.in_flight, - index_strategy, - setup_py, - config_setting, - build_isolation, - link_mode, - build_options, - exclude_newer, - sources, - concurrency, - preview, - ); - - // Resolve the requirements. - pip::operations::resolve( - requirements.clone(), - constraints.clone(), - overrides.clone(), - dev.clone(), - source_trees.clone(), - None, - &extras, - preferences.clone(), - EmptyInstalledPackages, - &hasher, - &Reinstall::default(), - upgrade, - None, - resolver_markers.clone(), - python_requirement.clone(), - &client, - &flat_index, - &index, - &build_dispatch, - concurrency, - options, - Box::new(SummaryResolveLogger), - printer, - preview, - ) - .await - .inspect_err(|err| debug!("Resolution with `uv.lock` failed: {err}")) - .ok() - .filter(|resolution| { - // Ensure no diagnostics were emitted that may be caused by stale metadata in the lockfile. - if resolution.diagnostics().is_empty() { - return true; - } - - debug!("Resolution with `uv.lock` failed due to diagnostics:"); - for diagnostic in resolution.diagnostics() { - debug!("- {}", diagnostic.message()); - } - - false - }) + if lock + .satisfies( + workspace, + &members, + &constraints, + &overrides, + interpreter.tags()?, + &database, + ) + .await? + { + debug!("Existing `uv.lock` satisfies workspace requirements"); + Some(lock) + } else { + debug!("Existing `uv.lock` does not satisfy workspace requirements; ignoring..."); + None + } } }; - let resolution = match resolution { + match existing_lock { // Resolution from the lockfile succeeded. - Some(resolution) => resolution, + Some(lock) => { + // Print the success message after completing resolution. + logger.on_complete(lock.len(), start, printer)?; + + // TODO(charlie): Avoid cloning here. + Ok(lock.clone()) + } // The lockfile did not contain enough information to obtain a resolution, fallback // to a fresh resolve. None => { debug!("Starting clean resolution"); - // Create a build dispatch. - let build_dispatch = BuildDispatch::new( - &client, - cache, - &build_constraints, - interpreter, - index_locations, - &flat_index, - &state.index, - &state.git, - &state.in_flight, - index_strategy, - setup_py, - config_setting, - build_isolation, - link_mode, - build_options, - exclude_newer, - sources, - concurrency, - preview, - ); - // Resolve the requirements. - pip::operations::resolve( + let resolution = pip::operations::resolve( requirements, - constraints, - overrides, + constraints.clone(), + overrides + .iter() + .cloned() + .map(UnresolvedRequirementSpecification::from) + .collect(), dev, source_trees, None, @@ -619,17 +615,23 @@ async fn do_lock( printer, preview, ) - .await? + .await?; + + // Print the success message after completing resolution. + logger.on_complete(resolution.len(), start, printer)?; + + // Notify the user of any resolution diagnostics. + pip::operations::diagnose_resolution(resolution.diagnostics(), printer)?; + + Ok( + Lock::from_resolution_graph(&resolution)?.with_manifest(ResolverManifest::new( + members, + constraints, + overrides, + )), + ) } - }; - - // Print the success message after completing resolution. - logger.on_complete(resolution.len(), start, printer)?; - - // Notify the user of any resolution diagnostics. - pip::operations::diagnose_resolution(resolution.diagnostics(), printer)?; - - Ok(Lock::from_resolution_graph(&resolution)?) + } } /// Write the lockfile to disk. diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index 818d8f4e5..52a434ef4 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -102,6 +102,9 @@ pub(crate) enum ProjectError { #[error(transparent)] Tool(#[from] uv_tool::Error), + #[error(transparent)] + NamedRequirements(#[from] uv_requirements::NamedRequirementsError), + #[error(transparent)] Fmt(#[from] std::fmt::Error), diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index bf3c2db4d..8d05c177e 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -710,7 +710,10 @@ async fn run(cli: Cli) -> Result { .await } Commands::Project(project) => { - run_project(project, script, globals, filesystem, cache, printer).await + Box::pin(run_project( + project, script, globals, filesystem, cache, printer, + )) + .await } #[cfg(feature = "self-update")] Commands::Self_(SelfNamespace { diff --git a/crates/uv/tests/branching_urls.rs b/crates/uv/tests/branching_urls.rs index 03151177a..a6e55631b 100644 --- a/crates/uv/tests/branching_urls.rs +++ b/crates/uv/tests/branching_urls.rs @@ -226,6 +226,13 @@ fn root_package_splits_transitive_too() -> Result<()> { { name = "b" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio", marker = "python_version >= '3.12'", specifier = "==4.3.0" }, + { name = "anyio", marker = "python_version < '3.12'", specifier = "==4.2.0" }, + { name = "b", directory = "b" }, + ] + [[package]] name = "anyio" version = "4.2.0" @@ -267,6 +274,12 @@ fn root_package_splits_transitive_too() -> Result<()> { { name = "b2", marker = "python_version >= '3.12'" }, ] + [package.metadata] + requires-dist = [ + { name = "b1", marker = "python_version < '3.12'", directory = "../b1" }, + { name = "b2", marker = "python_version >= '3.12'", directory = "../b2" }, + ] + [[package]] name = "b1" version = "0.1.0" @@ -275,6 +288,9 @@ fn root_package_splits_transitive_too() -> Result<()> { { name = "iniconfig", version = "1.1.1", source = { url = "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl" }, marker = "python_version < '3.12'" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig", url = "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl" }] + [[package]] name = "b2" version = "0.1.0" @@ -283,6 +299,9 @@ fn root_package_splits_transitive_too() -> Result<()> { { name = "iniconfig", version = "2.0.0", source = { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl" }, marker = "python_version >= '3.12'" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig", url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl" }] + [[package]] name = "idna" version = "3.6" @@ -403,6 +422,14 @@ fn root_package_splits_other_dependencies_too() -> Result<()> { { name = "b2", marker = "python_version >= '3.12'" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio", marker = "python_version >= '3.12'", specifier = "==4.3.0" }, + { name = "anyio", marker = "python_version < '3.12'", specifier = "==4.2.0" }, + { name = "b1", marker = "python_version < '3.12'", directory = "b1" }, + { name = "b2", marker = "python_version >= '3.12'", directory = "b2" }, + ] + [[package]] name = "anyio" version = "4.2.0" @@ -443,6 +470,9 @@ fn root_package_splits_other_dependencies_too() -> Result<()> { { name = "iniconfig", version = "1.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_version < '3.12'" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig", specifier = "==1.1.1" }] + [[package]] name = "b2" version = "0.1.0" @@ -451,6 +481,9 @@ fn root_package_splits_other_dependencies_too() -> Result<()> { { name = "iniconfig", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_version >= '3.12'" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig", specifier = "==2.0.0" }] + [[package]] name = "idna" version = "3.6" @@ -548,6 +581,12 @@ fn branching_between_registry_and_direct_url() -> Result<()> { { name = "iniconfig", version = "2.0.0", source = { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl" }, marker = "python_version >= '3.12'" }, ] + [package.metadata] + requires-dist = [ + { name = "iniconfig", marker = "python_version < '3.12'", specifier = "==1.1.1" }, + { name = "iniconfig", marker = "python_version >= '3.12'", url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl" }, + ] + [[package]] name = "iniconfig" version = "1.1.1" @@ -627,6 +666,12 @@ fn branching_urls_of_different_sources_disjoint() -> Result<()> { { name = "iniconfig", version = "2.0.0", source = { git = "https://github.com/pytest-dev/iniconfig?rev=93f5930e668c0d1ddf4597e38dd0dea4e2665e7a#93f5930e668c0d1ddf4597e38dd0dea4e2665e7a" }, marker = "python_version >= '3.12'" }, ] + [package.metadata] + requires-dist = [ + { name = "iniconfig", marker = "python_version < '3.12'", url = "https://files.pythonhosted.org/packages/9b/dd/b3c12c6d707058fa947864b67f0c4e0c39ef8610988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl" }, + { name = "iniconfig", marker = "python_version >= '3.12'", git = "https://github.com/pytest-dev/iniconfig?rev=93f5930e668c0d1ddf4597e38dd0dea4e2665e7a#93f5930e668c0d1ddf4597e38dd0dea4e2665e7a" }, + ] + [[package]] name = "iniconfig" version = "1.1.1" @@ -744,6 +789,12 @@ fn dont_pre_visit_url_packages() -> Result<()> { { name = "c" }, ] + [package.metadata] + requires-dist = [ + { name = "c", specifier = "==0.1.0" }, + { name = "b", directory = "b" }, + ] + [[package]] name = "b" version = "0.1.0" @@ -752,6 +803,9 @@ fn dont_pre_visit_url_packages() -> Result<()> { { name = "c" }, ] + [package.metadata] + requires-dist = [{ name = "c", directory = "../c" }] + [[package]] name = "c" version = "0.1.0" diff --git a/crates/uv/tests/edit.rs b/crates/uv/tests/edit.rs index 309d8e4c9..23ac75268 100644 --- a/crates/uv/tests/edit.rs +++ b/crates/uv/tests/edit.rs @@ -103,6 +103,9 @@ fn add_registry() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + requires-dist = [{ name = "anyio", specifier = "==3.7.0" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -260,6 +263,12 @@ fn add_git() -> Result<()> { { name = "uv-public-pypackage" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio", specifier = "==3.7.0" }, + { name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1" }, + ] + [[package]] name = "sniffio" version = "1.3.1" @@ -363,6 +372,9 @@ fn add_git_private_source() -> Result<()> { { name = "uv-private-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-private-pypackage", git = "https://github.com/astral-test/uv-private-pypackage" }] + [[package]] name = "uv-private-pypackage" version = "0.1.0" @@ -459,6 +471,9 @@ fn add_git_private_raw() -> Result<()> { { name = "uv-private-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-private-pypackage", git = "https://github.com/astral-test/uv-private-pypackage" }] + [[package]] name = "uv-private-pypackage" version = "0.1.0" @@ -659,6 +674,12 @@ fn add_git_raw() -> Result<()> { { name = "uv-public-pypackage" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio", specifier = "==3.7.0" }, + { name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=0.0.1" }, + ] + [[package]] name = "sniffio" version = "1.3.1" @@ -853,6 +874,9 @@ fn add_unnamed() -> Result<()> { { name = "uv-public-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1" }] + [[package]] name = "uv-public-pypackage" version = "0.1.0" @@ -972,6 +996,11 @@ fn add_remove_dev() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + + [package.metadata.requires-dev] + dev = [{ name = "anyio", specifier = "==3.7.0" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -1177,6 +1206,9 @@ fn add_remove_optional() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + requires-dist = [{ name = "anyio", marker = "extra == 'io'", specifier = "==3.7.0" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -1390,6 +1422,12 @@ fn add_remove_workspace() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "child1", + "child2", + ] + [[package]] name = "child1" version = "0.1.0" @@ -1398,6 +1436,9 @@ fn add_remove_workspace() -> Result<()> { { name = "child2" }, ] + [package.metadata] + requires-dist = [{ name = "child2", editable = "child2" }] + [[package]] name = "child2" version = "0.1.0" @@ -1465,6 +1506,12 @@ fn add_remove_workspace() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "child1", + "child2", + ] + [[package]] name = "child1" version = "0.1.0" @@ -1576,6 +1623,12 @@ fn add_workspace_editable() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "child1", + "child2", + ] + [[package]] name = "child1" version = "0.1.0" @@ -1584,6 +1637,9 @@ fn add_workspace_editable() -> Result<()> { { name = "child2" }, ] + [package.metadata] + requires-dist = [{ name = "child2", editable = "child2" }] + [[package]] name = "child2" version = "0.1.0" @@ -1837,6 +1893,9 @@ fn update() -> Result<()> { { name = "requests", extra = ["socks", "use-chardet-on-py3"] }, ] + [package.metadata] + requires-dist = [{ name = "requests", extras = ["security", "socks", "use-chardet-on-py3"], marker = "python_version > '3.7'", git = "https://github.com/psf/requests?tag=v2.32.3" }] + [[package]] name = "pysocks" version = "1.7.1" @@ -1865,6 +1924,16 @@ fn update() -> Result<()> { { name = "chardet" }, ] + [package.metadata] + requires-dist = [ + { name = "charset-normalizer", specifier = "<4,>=2" }, + { name = "idna", specifier = "<4,>=2.5" }, + { name = "urllib3", specifier = "<3,>=1.21.1" }, + { name = "certifi", specifier = ">=2017.4.17" }, + { name = "pysocks", marker = "extra == 'socks'", specifier = "!=1.5.7,>=1.5.6" }, + { name = "chardet", marker = "extra == 'use-chardet-on-py3'", specifier = "<6,>=3.0.2" }, + ] + [[package]] name = "urllib3" version = "2.2.1" @@ -2064,6 +2133,9 @@ fn add_no_clean() -> Result<()> { dependencies = [ { name = "iniconfig" }, ] + + [package.metadata] + requires-dist = [{ name = "iniconfig", specifier = "==2.0.0" }] "### ); }); @@ -2835,6 +2907,9 @@ fn add_lower_bound_optional() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + requires-dist = [{ name = "anyio", marker = "extra == 'io'" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -2923,6 +2998,9 @@ fn add_lower_bound_local() -> Result<()> { dependencies = [ { name = "local-simple-a" }, ] + + [package.metadata] + requires-dist = [{ name = "local-simple-a" }] "### ); }); diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index 49523925f..ddbd63d2e 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -8,7 +8,7 @@ use insta::assert_snapshot; use std::io::BufReader; use url::Url; -use common::{deterministic_lock, uv_snapshot, TestContext}; +use common::{uv_snapshot, TestContext}; use uv_fs::Simplified; use crate::common::{build_vendor_links_url, decode_token, packse_index_url}; @@ -31,8 +31,7 @@ fn lock_wheel_registry() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -42,61 +41,63 @@ fn lock_wheel_registry() -> Result<()> { Resolved 4 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "anyio" - version = "3.7.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "idna" }, - { name = "sniffio" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/c6/b3/fefbf7e78ab3b805dec67d698dc18dd505af7a18a8dd08868c9b4fa736b5/anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce", size = 142737 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/68/fe/7ce1926952c8a403b35029e194555558514b365ad77d75125f521a2bec62/anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0", size = 80873 }, - ] + [[package]] + name = "anyio" + version = "3.7.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/c6/b3/fefbf7e78ab3b805dec67d698dc18dd505af7a18a8dd08868c9b4fa736b5/anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce", size = 142737 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/68/fe/7ce1926952c8a403b35029e194555558514b365ad77d75125f521a2bec62/anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0", size = 80873 }, + ] - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "anyio" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] - [[package]] - name = "sniffio" - version = "1.3.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, - ] - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "anyio", specifier = "==3.7.0" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -144,8 +145,7 @@ fn lock_sdist_registry() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock().env_remove("UV_EXCLUDE_NEWER"), @r###" + uv_snapshot!(context.filters(), context.lock().env_remove("UV_EXCLUDE_NEWER"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -155,33 +155,35 @@ fn lock_sdist_registry() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "source-distribution" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "source-distribution" }, + ] - [[package]] - name = "source-distribution" - version = "0.0.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz", hash = "sha256:1f83ed7498336c7f2ab9b002cf22583d91115ebc624053dc4eb3a45694490106", size = 2157 } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "source-distribution", specifier = "==0.0.1" }] + + [[package]] + name = "source-distribution" + version = "0.0.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/10/1f/57aa4cce1b1abf6b433106676e15f9fa2c92ed2bd4cf77c3b50a9e9ac773/source_distribution-0.0.1.tar.gz", hash = "sha256:1f83ed7498336c7f2ab9b002cf22583d91115ebc624053dc4eb3a45694490106", size = 2157 } + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked").env_remove("UV_EXCLUDE_NEWER"), @r###" @@ -231,8 +233,7 @@ fn lock_sdist_git() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -243,59 +244,49 @@ fn lock_sdist_git() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" - success: true - exit_code: 0 - ----- stdout ----- + success: true + exit_code: 0 + ----- stdout ----- - ----- stderr ----- - warning: `uv lock` is experimental and may change without warning - warning: `uv.sources` is experimental and may change without warning - Resolved 2 packages in [TIME] - "###); - - // Re-run with `--locked`. - uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" - success: true - exit_code: 0 - ----- stdout ----- - - ----- stderr ----- - warning: `uv lock` is experimental and may change without warning - warning: `uv.sources` is experimental and may change without warning - Resolved 2 packages in [TIME] - "###); + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + warning: `uv.sources` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); // Install from the lockfile. uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###" @@ -326,8 +317,7 @@ fn lock_sdist_git() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -338,35 +328,37 @@ fn lock_sdist_git() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } + "### + ); + }); // Re-lock with a different commit. let pyproject_toml = context.temp_dir.child("pyproject.toml"); @@ -383,8 +375,7 @@ fn lock_sdist_git() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -395,35 +386,37 @@ fn lock_sdist_git() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=b270df1a2fb5d012294e9aaf05e7e0bab1e6a389#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=b270df1a2fb5d012294e9aaf05e7e0bab1e6a389#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); // Re-lock with a different tag (which matches the new commit). let pyproject_toml = context.temp_dir.child("pyproject.toml"); @@ -440,8 +433,7 @@ fn lock_sdist_git() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -452,35 +444,37 @@ fn lock_sdist_git() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.2#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.2" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.2#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); Ok(()) } @@ -502,8 +496,7 @@ fn lock_sdist_git_subdirectory() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -513,35 +506,37 @@ fn lock_sdist_git_subdirectory() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "example-pkg-a" - version = "1" - source = { git = "https://github.com/pypa/sample-namespace-packages.git?subdirectory=pkg_resources%2Fpkg_a&rev=df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45" } + [[package]] + name = "example-pkg-a" + version = "1" + source = { git = "https://github.com/pypa/sample-namespace-packages.git?subdirectory=pkg_resources%2Fpkg_a&rev=df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45" } - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "example-pkg-a" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "example-pkg-a" }, + ] + + [package.metadata] + requires-dist = [{ name = "example-pkg-a", git = "https://github.com/pypa/sample-namespace-packages.git?subdirectory=pkg_resources%2Fpkg_a&rev=df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45#df7530eeb8fa0cb7dbb8ecb28363e8e36bfa2f45" }] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -588,8 +583,7 @@ fn lock_sdist_git_pep508() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -599,35 +593,37 @@ fn lock_sdist_git_pep508() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0.0.1" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0.0.1#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -652,8 +648,7 @@ fn lock_sdist_git_pep508() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -663,35 +658,37 @@ fn lock_sdist_git_pep508() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } + "### + ); + }); // Re-lock with a different commit. let pyproject_toml = context.temp_dir.child("pyproject.toml"); @@ -705,8 +702,7 @@ fn lock_sdist_git_pep508() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -716,35 +712,37 @@ fn lock_sdist_git_pep508() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=b270df1a2fb5d012294e9aaf05e7e0bab1e6a389#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage.git?rev=b270df1a2fb5d012294e9aaf05e7e0bab1e6a389#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=b270df1a2fb5d012294e9aaf05e7e0bab1e6a389#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); // Re-lock with a different tag (which matches the new commit). let pyproject_toml = context.temp_dir.child("pyproject.toml"); @@ -758,8 +756,7 @@ fn lock_sdist_git_pep508() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -769,35 +766,37 @@ fn lock_sdist_git_pep508() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0.0.2#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0.0.2" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage.git?rev=0.0.2#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); Ok(()) } @@ -818,8 +817,7 @@ fn lock_wheel_url() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -829,60 +827,84 @@ fn lock_wheel_url() -> Result<()> { Resolved 4 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "anyio" - version = "4.3.0" - source = { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl" } - dependencies = [ - { name = "idna" }, - { name = "sniffio" }, - ] - wheels = [ - { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8" }, - ] + [[package]] + name = "anyio" + version = "4.3.0" + source = { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8" }, + ] - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [package.metadata] + requires-dist = [ + { name = "idna", specifier = ">=2.8" }, + { name = "sniffio", specifier = ">=1.1" }, + { name = "exceptiongroup", marker = "python_version < '3.11'", specifier = ">=1.0.2" }, + { name = "typing-extensions", marker = "python_version < '3.11'", specifier = ">=4.1" }, + { name = "packaging", marker = "extra == 'doc'" }, + { name = "sphinx", marker = "extra == 'doc'", specifier = ">=7" }, + { name = "sphinx-rtd-theme", marker = "extra == 'doc'" }, + { name = "sphinx-autodoc-typehints", marker = "extra == 'doc'", specifier = ">=1.2.0" }, + { name = "anyio", extras = ["trio"], marker = "extra == 'test'" }, + { name = "coverage", extras = ["toml"], marker = "extra == 'test'", specifier = ">=7" }, + { name = "exceptiongroup", marker = "extra == 'test'", specifier = ">=1.2.0" }, + { name = "hypothesis", marker = "extra == 'test'", specifier = ">=4.0" }, + { name = "psutil", marker = "extra == 'test'", specifier = ">=5.9" }, + { name = "pytest", marker = "extra == 'test'", specifier = ">=7.0" }, + { name = "pytest-mock", marker = "extra == 'test'", specifier = ">=3.6.1" }, + { name = "trustme", marker = "extra == 'test'" }, + { name = "uvloop", marker = "platform_python_implementation == 'CPython' and platform_system != 'Windows' and extra == 'test'", specifier = ">=0.17" }, + { name = "trio", marker = "extra == 'trio'", specifier = ">=0.23" }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "anyio" }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "sniffio" - version = "1.3.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio", url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -930,8 +952,7 @@ fn lock_sdist_url() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -941,58 +962,82 @@ fn lock_sdist_url() -> Result<()> { Resolved 4 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "anyio" - version = "4.3.0" - source = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz" } - dependencies = [ - { name = "idna" }, - { name = "sniffio" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } + [[package]] + name = "anyio" + version = "4.3.0" + source = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [package.metadata] + requires-dist = [ + { name = "idna", specifier = ">=2.8" }, + { name = "sniffio", specifier = ">=1.1" }, + { name = "exceptiongroup", marker = "python_version < '3.11'", specifier = ">=1.0.2" }, + { name = "typing-extensions", marker = "python_version < '3.11'", specifier = ">=4.1" }, + { name = "packaging", marker = "extra == 'doc'" }, + { name = "sphinx", marker = "extra == 'doc'", specifier = ">=7" }, + { name = "sphinx-rtd-theme", marker = "extra == 'doc'" }, + { name = "sphinx-autodoc-typehints", marker = "extra == 'doc'", specifier = ">=1.2.0" }, + { name = "anyio", extras = ["trio"], marker = "extra == 'test'" }, + { name = "coverage", extras = ["toml"], marker = "extra == 'test'", specifier = ">=7" }, + { name = "exceptiongroup", marker = "extra == 'test'", specifier = ">=1.2.0" }, + { name = "hypothesis", marker = "extra == 'test'", specifier = ">=4.0" }, + { name = "psutil", marker = "extra == 'test'", specifier = ">=5.9" }, + { name = "pytest", marker = "extra == 'test'", specifier = ">=7.0" }, + { name = "pytest-mock", marker = "extra == 'test'", specifier = ">=3.6.1" }, + { name = "trustme", marker = "extra == 'test'" }, + { name = "uvloop", marker = "platform_python_implementation == 'CPython' and platform_system != 'Windows' and extra == 'test'", specifier = ">=0.17" }, + { name = "trio", marker = "extra == 'trio'", specifier = ">=0.23" }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "anyio" }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "sniffio" - version = "1.3.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio", url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -1043,8 +1088,7 @@ fn lock_project_extra() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1054,75 +1098,91 @@ fn lock_project_extra() -> Result<()> { Resolved 5 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "anyio" - version = "3.7.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "idna" }, - { name = "sniffio" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/c6/b3/fefbf7e78ab3b805dec67d698dc18dd505af7a18a8dd08868c9b4fa736b5/anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce", size = 142737 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/68/fe/7ce1926952c8a403b35029e194555558514b365ad77d75125f521a2bec62/anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0", size = 80873 }, - ] + [[package]] + name = "anyio" + version = "3.7.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/c6/b3/fefbf7e78ab3b805dec67d698dc18dd505af7a18a8dd08868c9b4fa736b5/anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce", size = 142737 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/68/fe/7ce1926952c8a403b35029e194555558514b365ad77d75125f521a2bec62/anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0", size = 80873 }, + ] - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "iniconfig" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - 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 = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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 = "anyio" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] - [package.optional-dependencies] - test = [ - { name = "iniconfig" }, - ] + [package.optional-dependencies] + test = [ + { name = "iniconfig" }, + ] - [[package]] - name = "sniffio" - version = "1.3.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, - ] - "### - ); - }); - } + [package.metadata] + requires-dist = [ + { name = "anyio", specifier = "==3.7.0" }, + { name = "iniconfig", marker = "extra == 'test'" }, + ] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 5 packages in [TIME] + "###); // Install the base dependencies from the lockfile. uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###" @@ -1184,6 +1244,17 @@ fn lock_project_with_overrides() -> Result<()> { Resolved 9 packages in [TIME] "###); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 9 packages in [TIME] + "###); + // Install the base dependencies from the lockfile. uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###" success: true @@ -1236,6 +1307,17 @@ fn lock_project_with_constraints() -> Result<()> { Resolved 4 packages in [TIME] "###); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + // Install the base dependencies from the lockfile. uv_snapshot!(context.filters(), context.sync().arg("--frozen"), @r###" success: true @@ -1271,8 +1353,7 @@ fn lock_dependency_extra() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1282,141 +1363,143 @@ fn lock_dependency_extra() -> Result<()> { Resolved 10 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "blinker" - version = "1.7.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068 }, - ] + [[package]] + name = "blinker" + version = "1.7.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068 }, + ] - [[package]] - name = "click" - version = "8.1.7" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, - ] + [[package]] + name = "click" + version = "8.1.7" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + ] - [[package]] - name = "colorama" - version = "0.4.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, - ] + [[package]] + name = "colorama" + version = "0.4.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + ] - [[package]] - name = "flask" - version = "3.0.2" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "blinker" }, - { name = "click" }, - { name = "itsdangerous" }, - { name = "jinja2" }, - { name = "werkzeug" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/3f/e0/a89e8120faea1edbfca1a9b171cff7f2bf62ec860bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/93/a6/aa98bfe0eb9b8b15d36cdfd03c8ca86a03968a87f27ce224fb4f766acb23/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }, - ] + [[package]] + name = "flask" + version = "3.0.2" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "blinker" }, + { name = "click" }, + { name = "itsdangerous" }, + { name = "jinja2" }, + { name = "werkzeug" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/3f/e0/a89e8120faea1edbfca1a9b171cff7f2bf62ec860bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/93/a6/aa98bfe0eb9b8b15d36cdfd03c8ca86a03968a87f27ce224fb4f766acb23/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }, + ] - [package.optional-dependencies] - dotenv = [ - { name = "python-dotenv" }, - ] + [package.optional-dependencies] + dotenv = [ + { name = "python-dotenv" }, + ] - [[package]] - name = "itsdangerous" - version = "2.1.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749 }, - ] + [[package]] + name = "itsdangerous" + version = "2.1.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749 }, + ] - [[package]] - name = "jinja2" - version = "3.1.3" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "markupsafe" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/b2/5e/3a21abf3cd467d7876045335e681d276ac32492febe6d98ad89562d1a7e1/Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90", size = 268261 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/30/6d/6de6be2d02603ab56e72997708809e8a5b0fbfee080735109b40a3564843/Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", size = 133236 }, - ] + [[package]] + name = "jinja2" + version = "3.1.3" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "markupsafe" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/b2/5e/3a21abf3cd467d7876045335e681d276ac32492febe6d98ad89562d1a7e1/Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90", size = 268261 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/30/6d/6de6be2d02603ab56e72997708809e8a5b0fbfee080735109b40a3564843/Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", size = 133236 }, + ] - [[package]] - name = "markupsafe" - version = "2.1.5" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, - { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, - { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, - { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, - { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, - { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, - { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, - { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, - { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, - { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, - ] + [[package]] + name = "markupsafe" + version = "2.1.5" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "flask", extra = ["dotenv"] }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "flask", extra = ["dotenv"] }, + ] - [[package]] - name = "python-dotenv" - version = "1.0.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, - ] + [package.metadata] + requires-dist = [{ name = "flask", extras = ["dotenv"] }] - [[package]] - name = "werkzeug" - version = "3.0.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "markupsafe" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/0d/cc/ff1904eb5eb4b455e442834dabf9427331ac0fa02853bf83db817a7dd53d/werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", size = 801436 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10", size = 226669 }, - ] - "### - ); - }); - } + [[package]] + name = "python-dotenv" + version = "1.0.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, + ] + + [[package]] + name = "werkzeug" + version = "3.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "markupsafe" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/0d/cc/ff1904eb5eb4b455e442834dabf9427331ac0fa02853bf83db817a7dd53d/werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", size = 801436 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10", size = 226669 }, + ] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -1471,8 +1554,7 @@ fn lock_conditional_dependency_extra() -> Result<()> { let lockfile = context.temp_dir.join("uv.lock"); - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1482,188 +1564,193 @@ fn lock_conditional_dependency_extra() -> Result<()> { Resolved 7 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.7" - environment-markers = [ - "python_version < '3.10'", - "python_version >= '3.10'", - ] + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.7" + environment-markers = [ + "python_version < '3.10'", + "python_version >= '3.10'", + ] - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "certifi" - version = "2024.2.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/71/da/e94e26401b62acd6d91df2b52954aceb7f561743aa5ccc32152886c76c96/certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", size = 164886 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/06/a07f096c664aeb9f01624f858c3add0a4e913d6c96257acb4fce61e7de14/certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1", size = 163774 }, - ] + [[package]] + name = "certifi" + version = "2024.2.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/71/da/e94e26401b62acd6d91df2b52954aceb7f561743aa5ccc32152886c76c96/certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", size = 164886 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/06/a07f096c664aeb9f01624f858c3add0a4e913d6c96257acb4fce61e7de14/certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1", size = 163774 }, + ] - [[package]] - name = "charset-normalizer" - version = "3.3.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, - { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, - { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, - { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, - { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, - { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, - { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, - { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, - { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, - { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, - { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, - { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, - { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, - { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, - { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, - { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, - { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, - { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, - { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, - { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, - { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, - { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, - { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, - { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, - { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, - { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, - { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, - { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, - { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, - { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, - { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, - { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, - { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, - { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, - { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, - { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, - { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, - { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, - { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, - { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, - { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, - { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, - { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, - { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, - { url = "https://files.pythonhosted.org/packages/4f/d1/d547cc26acdb0cc458b152f79b2679d7422f29d41581e6fa907861e88af1/charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", size = 118254 }, - { url = "https://files.pythonhosted.org/packages/f6/d3/bfc699ab2c4f9245867060744e8136d359412ff1e5ad93be38a46d160f9d/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", size = 133657 }, - { url = "https://files.pythonhosted.org/packages/58/a2/0c63d5d7ffac3104b86631b7f2690058c97bf72d3145c0a9cd4fb90c58c2/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", size = 142965 }, - { url = "https://files.pythonhosted.org/packages/2e/37/9223632af0872c86d8b851787f0edd3fe66be4a5378f51242b25212f8374/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", size = 136078 }, - { url = "https://files.pythonhosted.org/packages/c9/7a/6d8767fac16f2c80c7fa9f14e0f53d4638271635c306921844dc0b5fd8a6/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", size = 136822 }, - { url = "https://files.pythonhosted.org/packages/b2/62/5a5dcb9a71390a9511a253bde19c9c89e0b20118e41080185ea69fb2c209/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", size = 139545 }, - { url = "https://files.pythonhosted.org/packages/f2/0e/e06bc07ef4673e4d24dc461333c254586bb759fdd075031539bab6514d07/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", size = 134128 }, - { url = "https://files.pythonhosted.org/packages/8d/b7/9e95102e9a8cce6654b85770794b582dda2921ec1fd924c10fbcf215ad31/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", size = 140017 }, - { url = "https://files.pythonhosted.org/packages/13/f8/eefae0629fa9260f83b826ee3363e311bb03cfdd518dad1bd10d57cb2d84/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", size = 144367 }, - { url = "https://files.pythonhosted.org/packages/91/95/e2cfa7ce962e6c4b59a44a6e19e541c3a0317e543f0e0923f844e8d7d21d/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", size = 136883 }, - { url = "https://files.pythonhosted.org/packages/a0/b1/4e72ef73d68ebdd4748f2df97130e8428c4625785f2b6ece31f555590c2d/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", size = 136977 }, - { url = "https://files.pythonhosted.org/packages/c8/ce/09d6845504246d95c7443b8c17d0d3911ec5fdc838c3213e16c5e47dee44/charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", size = 91300 }, - { url = "https://files.pythonhosted.org/packages/96/fc/0cae31c0f150cd1205a2a208079de865f69a8fd052a98856c40c99e36b3c/charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", size = 98127 }, - { url = "https://files.pythonhosted.org/packages/ef/d4/a1d72a8f6aa754fdebe91b848912025d30ab7dced61e9ed8aabbf791ed65/charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", size = 191415 }, - { url = "https://files.pythonhosted.org/packages/13/82/83c188028b6f38d39538442dd127dc794c602ae6d45d66c469f4063a4c30/charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", size = 121051 }, - { url = "https://files.pythonhosted.org/packages/16/ea/a9e284aa38cccea06b7056d4cbc7adf37670b1f8a668a312864abf1ff7c6/charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", size = 119143 }, - { url = "https://files.pythonhosted.org/packages/34/2a/f392457d45e24a0c9bfc012887ed4f3c54bf5d4d05a5deb970ffec4b7fc0/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", size = 137506 }, - { url = "https://files.pythonhosted.org/packages/be/4d/9e370f8281cec2fcc9452c4d1ac513324c32957c5f70c73dd2fa8442a21a/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", size = 147272 }, - { url = "https://files.pythonhosted.org/packages/33/95/ef68482e4a6adf781fae8d183fb48d6f2be8facb414f49c90ba6a5149cd1/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", size = 139734 }, - { url = "https://files.pythonhosted.org/packages/3d/09/d82fe4a34c5f0585f9ea1df090e2a71eb9bb1e469723053e1ee9f57c16f3/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", size = 141094 }, - { url = "https://files.pythonhosted.org/packages/81/b2/160893421adfa3c45554fb418e321ed342bb10c0a4549e855b2b2a3699cb/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", size = 144113 }, - { url = "https://files.pythonhosted.org/packages/9e/ef/cd47a63d3200b232792e361cd67530173a09eb011813478b1c0fb8aa7226/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", size = 138555 }, - { url = "https://files.pythonhosted.org/packages/a8/6f/4ff299b97da2ed6358154b6eb3a2db67da2ae204e53d205aacb18a7e4f34/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", size = 144944 }, - { url = "https://files.pythonhosted.org/packages/d1/2f/0d1efd07c74c52b6886c32a3b906fb8afd2fecf448650e73ecb90a5a27f1/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", size = 148925 }, - { url = "https://files.pythonhosted.org/packages/bd/28/7ea29e73eea52c7e15b4b9108d0743fc9e4cc2cdb00d275af1df3d46d360/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", size = 140732 }, - { url = "https://files.pythonhosted.org/packages/b3/c1/ebca8e87c714a6a561cfee063f0655f742e54b8ae6e78151f60ba8708b3a/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", size = 141288 }, - { url = "https://files.pythonhosted.org/packages/74/20/8923a06f15eb3d7f6a306729360bd58f9ead1dc39bc7ea8831f4b407e4ae/charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", size = 92373 }, - { url = "https://files.pythonhosted.org/packages/db/fb/d29e343e7c57bbf1231275939f6e75eb740cd47a9d7cb2c52ffeb62ef869/charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", size = 99577 }, - { url = "https://files.pythonhosted.org/packages/f7/9d/bcf4a449a438ed6f19790eee543a86a740c77508fbc5ddab210ab3ba3a9a/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", size = 194198 }, - { url = "https://files.pythonhosted.org/packages/66/fe/c7d3da40a66a6bf2920cce0f436fa1f62ee28aaf92f412f0bf3b84c8ad6c/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", size = 122494 }, - { url = "https://files.pythonhosted.org/packages/2a/9d/a6d15bd1e3e2914af5955c8eb15f4071997e7078419328fee93dfd497eb7/charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", size = 120393 }, - { url = "https://files.pythonhosted.org/packages/3d/85/5b7416b349609d20611a64718bed383b9251b5a601044550f0c8983b8900/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", size = 138331 }, - { url = "https://files.pythonhosted.org/packages/79/66/8946baa705c588521afe10b2d7967300e49380ded089a62d38537264aece/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", size = 148097 }, - { url = "https://files.pythonhosted.org/packages/44/80/b339237b4ce635b4af1c73742459eee5f97201bd92b2371c53e11958392e/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", size = 140711 }, - { url = "https://files.pythonhosted.org/packages/98/69/5d8751b4b670d623aa7a47bef061d69c279e9f922f6705147983aa76c3ce/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", size = 142251 }, - { url = "https://files.pythonhosted.org/packages/1f/8d/33c860a7032da5b93382cbe2873261f81467e7b37f4ed91e25fed62fd49b/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", size = 144636 }, - { url = "https://files.pythonhosted.org/packages/c2/65/52aaf47b3dd616c11a19b1052ce7fa6321250a7a0b975f48d8c366733b9f/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", size = 139514 }, - { url = "https://files.pythonhosted.org/packages/51/fd/0ee5b1c2860bb3c60236d05b6e4ac240cf702b67471138571dad91bcfed8/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", size = 145528 }, - { url = "https://files.pythonhosted.org/packages/e1/9c/60729bf15dc82e3aaf5f71e81686e42e50715a1399770bcde1a9e43d09db/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", size = 149804 }, - { url = "https://files.pythonhosted.org/packages/53/cd/aa4b8a4d82eeceb872f83237b2d27e43e637cac9ffaef19a1321c3bafb67/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", size = 141708 }, - { url = "https://files.pythonhosted.org/packages/54/7f/cad0b328759630814fcf9d804bfabaf47776816ad4ef2e9938b7e1123d04/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561", size = 142708 }, - { url = "https://files.pythonhosted.org/packages/c1/9d/254a2f1bcb0ce9acad838e94ed05ba71a7cb1e27affaa4d9e1ca3958cdb6/charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", size = 92830 }, - { url = "https://files.pythonhosted.org/packages/2f/0e/d7303ccae9735ff8ff01e36705ad6233ad2002962e8668a970fc000c5e1b/charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", size = 100376 }, - { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, - ] + [[package]] + name = "charset-normalizer" + version = "3.3.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, + { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, + { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, + { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, + { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, + { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, + { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, + { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, + { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, + { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, + { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, + { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, + { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, + { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, + { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, + { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, + { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, + { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, + { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, + { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, + { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, + { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, + { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, + { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, + { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, + { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, + { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, + { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, + { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, + { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, + { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, + { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, + { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, + { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, + { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, + { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, + { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, + { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, + { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, + { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, + { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, + { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, + { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, + { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, + { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, + { url = "https://files.pythonhosted.org/packages/4f/d1/d547cc26acdb0cc458b152f79b2679d7422f29d41581e6fa907861e88af1/charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c", size = 118254 }, + { url = "https://files.pythonhosted.org/packages/f6/d3/bfc699ab2c4f9245867060744e8136d359412ff1e5ad93be38a46d160f9d/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5", size = 133657 }, + { url = "https://files.pythonhosted.org/packages/58/a2/0c63d5d7ffac3104b86631b7f2690058c97bf72d3145c0a9cd4fb90c58c2/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985", size = 142965 }, + { url = "https://files.pythonhosted.org/packages/2e/37/9223632af0872c86d8b851787f0edd3fe66be4a5378f51242b25212f8374/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6", size = 136078 }, + { url = "https://files.pythonhosted.org/packages/c9/7a/6d8767fac16f2c80c7fa9f14e0f53d4638271635c306921844dc0b5fd8a6/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714", size = 136822 }, + { url = "https://files.pythonhosted.org/packages/b2/62/5a5dcb9a71390a9511a253bde19c9c89e0b20118e41080185ea69fb2c209/charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786", size = 139545 }, + { url = "https://files.pythonhosted.org/packages/f2/0e/e06bc07ef4673e4d24dc461333c254586bb759fdd075031539bab6514d07/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5", size = 134128 }, + { url = "https://files.pythonhosted.org/packages/8d/b7/9e95102e9a8cce6654b85770794b582dda2921ec1fd924c10fbcf215ad31/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c", size = 140017 }, + { url = "https://files.pythonhosted.org/packages/13/f8/eefae0629fa9260f83b826ee3363e311bb03cfdd518dad1bd10d57cb2d84/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8", size = 144367 }, + { url = "https://files.pythonhosted.org/packages/91/95/e2cfa7ce962e6c4b59a44a6e19e541c3a0317e543f0e0923f844e8d7d21d/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711", size = 136883 }, + { url = "https://files.pythonhosted.org/packages/a0/b1/4e72ef73d68ebdd4748f2df97130e8428c4625785f2b6ece31f555590c2d/charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811", size = 136977 }, + { url = "https://files.pythonhosted.org/packages/c8/ce/09d6845504246d95c7443b8c17d0d3911ec5fdc838c3213e16c5e47dee44/charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4", size = 91300 }, + { url = "https://files.pythonhosted.org/packages/96/fc/0cae31c0f150cd1205a2a208079de865f69a8fd052a98856c40c99e36b3c/charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99", size = 98127 }, + { url = "https://files.pythonhosted.org/packages/ef/d4/a1d72a8f6aa754fdebe91b848912025d30ab7dced61e9ed8aabbf791ed65/charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a", size = 191415 }, + { url = "https://files.pythonhosted.org/packages/13/82/83c188028b6f38d39538442dd127dc794c602ae6d45d66c469f4063a4c30/charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac", size = 121051 }, + { url = "https://files.pythonhosted.org/packages/16/ea/a9e284aa38cccea06b7056d4cbc7adf37670b1f8a668a312864abf1ff7c6/charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a", size = 119143 }, + { url = "https://files.pythonhosted.org/packages/34/2a/f392457d45e24a0c9bfc012887ed4f3c54bf5d4d05a5deb970ffec4b7fc0/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33", size = 137506 }, + { url = "https://files.pythonhosted.org/packages/be/4d/9e370f8281cec2fcc9452c4d1ac513324c32957c5f70c73dd2fa8442a21a/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238", size = 147272 }, + { url = "https://files.pythonhosted.org/packages/33/95/ef68482e4a6adf781fae8d183fb48d6f2be8facb414f49c90ba6a5149cd1/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a", size = 139734 }, + { url = "https://files.pythonhosted.org/packages/3d/09/d82fe4a34c5f0585f9ea1df090e2a71eb9bb1e469723053e1ee9f57c16f3/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2", size = 141094 }, + { url = "https://files.pythonhosted.org/packages/81/b2/160893421adfa3c45554fb418e321ed342bb10c0a4549e855b2b2a3699cb/charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8", size = 144113 }, + { url = "https://files.pythonhosted.org/packages/9e/ef/cd47a63d3200b232792e361cd67530173a09eb011813478b1c0fb8aa7226/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898", size = 138555 }, + { url = "https://files.pythonhosted.org/packages/a8/6f/4ff299b97da2ed6358154b6eb3a2db67da2ae204e53d205aacb18a7e4f34/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99", size = 144944 }, + { url = "https://files.pythonhosted.org/packages/d1/2f/0d1efd07c74c52b6886c32a3b906fb8afd2fecf448650e73ecb90a5a27f1/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d", size = 148925 }, + { url = "https://files.pythonhosted.org/packages/bd/28/7ea29e73eea52c7e15b4b9108d0743fc9e4cc2cdb00d275af1df3d46d360/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04", size = 140732 }, + { url = "https://files.pythonhosted.org/packages/b3/c1/ebca8e87c714a6a561cfee063f0655f742e54b8ae6e78151f60ba8708b3a/charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087", size = 141288 }, + { url = "https://files.pythonhosted.org/packages/74/20/8923a06f15eb3d7f6a306729360bd58f9ead1dc39bc7ea8831f4b407e4ae/charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25", size = 92373 }, + { url = "https://files.pythonhosted.org/packages/db/fb/d29e343e7c57bbf1231275939f6e75eb740cd47a9d7cb2c52ffeb62ef869/charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b", size = 99577 }, + { url = "https://files.pythonhosted.org/packages/f7/9d/bcf4a449a438ed6f19790eee543a86a740c77508fbc5ddab210ab3ba3a9a/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", size = 194198 }, + { url = "https://files.pythonhosted.org/packages/66/fe/c7d3da40a66a6bf2920cce0f436fa1f62ee28aaf92f412f0bf3b84c8ad6c/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", size = 122494 }, + { url = "https://files.pythonhosted.org/packages/2a/9d/a6d15bd1e3e2914af5955c8eb15f4071997e7078419328fee93dfd497eb7/charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", size = 120393 }, + { url = "https://files.pythonhosted.org/packages/3d/85/5b7416b349609d20611a64718bed383b9251b5a601044550f0c8983b8900/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", size = 138331 }, + { url = "https://files.pythonhosted.org/packages/79/66/8946baa705c588521afe10b2d7967300e49380ded089a62d38537264aece/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", size = 148097 }, + { url = "https://files.pythonhosted.org/packages/44/80/b339237b4ce635b4af1c73742459eee5f97201bd92b2371c53e11958392e/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", size = 140711 }, + { url = "https://files.pythonhosted.org/packages/98/69/5d8751b4b670d623aa7a47bef061d69c279e9f922f6705147983aa76c3ce/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", size = 142251 }, + { url = "https://files.pythonhosted.org/packages/1f/8d/33c860a7032da5b93382cbe2873261f81467e7b37f4ed91e25fed62fd49b/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", size = 144636 }, + { url = "https://files.pythonhosted.org/packages/c2/65/52aaf47b3dd616c11a19b1052ce7fa6321250a7a0b975f48d8c366733b9f/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", size = 139514 }, + { url = "https://files.pythonhosted.org/packages/51/fd/0ee5b1c2860bb3c60236d05b6e4ac240cf702b67471138571dad91bcfed8/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", size = 145528 }, + { url = "https://files.pythonhosted.org/packages/e1/9c/60729bf15dc82e3aaf5f71e81686e42e50715a1399770bcde1a9e43d09db/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", size = 149804 }, + { url = "https://files.pythonhosted.org/packages/53/cd/aa4b8a4d82eeceb872f83237b2d27e43e637cac9ffaef19a1321c3bafb67/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", size = 141708 }, + { url = "https://files.pythonhosted.org/packages/54/7f/cad0b328759630814fcf9d804bfabaf47776816ad4ef2e9938b7e1123d04/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561", size = 142708 }, + { url = "https://files.pythonhosted.org/packages/c1/9d/254a2f1bcb0ce9acad838e94ed05ba71a7cb1e27affaa4d9e1ca3958cdb6/charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", size = 92830 }, + { url = "https://files.pythonhosted.org/packages/2f/0e/d7303ccae9735ff8ff01e36705ad6233ad2002962e8668a970fc000c5e1b/charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", size = 100376 }, + { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, + ] - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "requests" }, - { name = "requests", extra = ["socks"], marker = "python_version < '3.10'" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "requests" }, + { name = "requests", extra = ["socks"], marker = "python_version < '3.10'" }, + ] - [[package]] - name = "pysocks" - version = "1.7.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725 }, - ] + [package.metadata] + requires-dist = [ + { name = "requests" }, + { name = "requests", extras = ["socks"], marker = "python_version < '3.10'" }, + ] - [[package]] - name = "requests" - version = "2.31.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1", size = 110794 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", size = 62574 }, - ] + [[package]] + name = "pysocks" + version = "1.7.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bd/11/293dd436aea955d45fc4e8a35b6ae7270f5b8e00b53cf6c024c83b657a11/PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0", size = 284429 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/59/b4572118e098ac8e46e399a1dd0f2d85403ce8bbaad9ec79373ed6badaf9/PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", size = 16725 }, + ] - [package.optional-dependencies] - socks = [ - { name = "pysocks", marker = "python_version < '3.10'" }, - ] + [[package]] + name = "requests" + version = "2.31.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1", size = 110794 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", size = 62574 }, + ] - [[package]] - name = "urllib3" - version = "2.0.7" - source = { registry = "https://pypi.org/simple" } - 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.optional-dependencies] + socks = [ + { name = "pysocks", marker = "python_version < '3.10'" }, + ] + + [[package]] + name = "urllib3" + version = "2.0.7" + source = { registry = "https://pypi.org/simple" } + 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 }, + ] + "### + ); + }); // TODO(charlie): This test became non-deterministic in https://github.com/astral-sh/uv/pull/6065. // But that fix is correct, and the non-determinism itself is a bug. @@ -1752,8 +1839,7 @@ fn lock_dependency_non_existent_extra() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1764,127 +1850,129 @@ fn lock_dependency_non_existent_extra() -> Result<()> { warning: The package `flask==3.0.2` does not have an extra named `foo` "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "blinker" - version = "1.7.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068 }, - ] + [[package]] + name = "blinker" + version = "1.7.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a1/13/6df5fc090ff4e5d246baf1f45fe9e5623aa8565757dfa5bd243f6a545f9e/blinker-1.7.0.tar.gz", hash = "sha256:e6820ff6fa4e4d1d8e2747c2283749c3f547e4fee112b98555cdcdae32996182", size = 28134 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/2a/7f3714cbc6356a0efec525ce7a0613d581072ed6eb53eb7b9754f33db807/blinker-1.7.0-py3-none-any.whl", hash = "sha256:c3f865d4d54db7abc53758a01601cf343fe55b84c1de4e3fa910e420b438d5b9", size = 13068 }, + ] - [[package]] - name = "click" - version = "8.1.7" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, - ] + [[package]] + name = "click" + version = "8.1.7" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + ] - [[package]] - name = "colorama" - version = "0.4.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, - ] + [[package]] + name = "colorama" + version = "0.4.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + ] - [[package]] - name = "flask" - version = "3.0.2" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "blinker" }, - { name = "click" }, - { name = "itsdangerous" }, - { name = "jinja2" }, - { name = "werkzeug" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/3f/e0/a89e8120faea1edbfca1a9b171cff7f2bf62ec860bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/93/a6/aa98bfe0eb9b8b15d36cdfd03c8ca86a03968a87f27ce224fb4f766acb23/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }, - ] + [[package]] + name = "flask" + version = "3.0.2" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "blinker" }, + { name = "click" }, + { name = "itsdangerous" }, + { name = "jinja2" }, + { name = "werkzeug" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/3f/e0/a89e8120faea1edbfca1a9b171cff7f2bf62ec860bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/93/a6/aa98bfe0eb9b8b15d36cdfd03c8ca86a03968a87f27ce224fb4f766acb23/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }, + ] - [[package]] - name = "itsdangerous" - version = "2.1.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749 }, - ] + [[package]] + name = "itsdangerous" + version = "2.1.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a", size = 56143 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", size = 15749 }, + ] - [[package]] - name = "jinja2" - version = "3.1.3" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "markupsafe" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/b2/5e/3a21abf3cd467d7876045335e681d276ac32492febe6d98ad89562d1a7e1/Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90", size = 268261 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/30/6d/6de6be2d02603ab56e72997708809e8a5b0fbfee080735109b40a3564843/Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", size = 133236 }, - ] + [[package]] + name = "jinja2" + version = "3.1.3" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "markupsafe" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/b2/5e/3a21abf3cd467d7876045335e681d276ac32492febe6d98ad89562d1a7e1/Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90", size = 268261 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/30/6d/6de6be2d02603ab56e72997708809e8a5b0fbfee080735109b40a3564843/Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", size = 133236 }, + ] - [[package]] - name = "markupsafe" - version = "2.1.5" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, - { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, - { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, - { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, - { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, - { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, - { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, - { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, - { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, - { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, - ] + [[package]] + name = "markupsafe" + version = "2.1.5" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "flask" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "flask" }, + ] - [[package]] - name = "werkzeug" - version = "3.0.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "markupsafe" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/0d/cc/ff1904eb5eb4b455e442834dabf9427331ac0fa02853bf83db817a7dd53d/werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", size = 801436 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10", size = 226669 }, - ] - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "flask", extras = ["foo"] }] + + [[package]] + name = "werkzeug" + version = "3.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "markupsafe" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/0d/cc/ff1904eb5eb4b455e442834dabf9427331ac0fa02853bf83db817a7dd53d/werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc", size = 801436 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/fc/254c3e9b5feb89ff5b9076a23218dafbc99c96ac5941e900b71206e6313b/werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10", size = 226669 }, + ] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -1895,7 +1983,6 @@ fn lock_dependency_non_existent_extra() -> Result<()> { ----- stderr ----- warning: `uv lock` is experimental and may change without warning Resolved 9 packages in [TIME] - warning: The package `flask==3.0.2` does not have an extra named `foo` "###); // Install from the lockfile. @@ -1937,8 +2024,7 @@ fn lock_upgrade_log() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -1948,46 +2034,51 @@ fn lock_upgrade_log() -> Result<()> { Resolved 3 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "iniconfig" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - 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 = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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 = "markupsafe" - version = "1.1.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", size = 19151 } + [[package]] + name = "markupsafe" + version = "1.1.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", size = 19151 } - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "iniconfig" }, - { name = "markupsafe" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig" }, + { name = "markupsafe" }, + ] + + [package.metadata] + requires-dist = [ + { name = "markupsafe", specifier = "<2" }, + { name = "iniconfig" }, + ] + "### + ); + }); // Run with `--upgrade`; ensure that nothing is changed. uv_snapshot!(context.filters(), context.lock().arg("--upgrade"), @r###" @@ -2066,6 +2157,12 @@ fn lock_upgrade_log() -> Result<()> { { name = "typing-extensions" }, ] + [package.metadata] + requires-dist = [ + { name = "markupsafe" }, + { name = "typing-extensions" }, + ] + [[package]] name = "typing-extensions" version = "4.10.0" @@ -2098,8 +2195,7 @@ fn lock_upgrade_log_multi_version() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2109,53 +2205,58 @@ fn lock_upgrade_log_multi_version() -> Result<()> { Resolved 3 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" - environment-markers = [ - "sys_platform != 'win32'", - "sys_platform == 'win32'", - ] + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + environment-markers = [ + "sys_platform != 'win32'", + "sys_platform == 'win32'", + ] - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "markupsafe" - version = "1.1.1" - source = { registry = "https://pypi.org/simple" } - environment-markers = [ - "sys_platform != 'win32'", - ] - sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", size = 19151 } + [[package]] + name = "markupsafe" + version = "1.1.1" + source = { registry = "https://pypi.org/simple" } + environment-markers = [ + "sys_platform != 'win32'", + ] + sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", size = 19151 } - [[package]] - name = "markupsafe" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - environment-markers = [ - "sys_platform == 'win32'", - ] - sdist = { url = "https://files.pythonhosted.org/packages/67/6a/5b3ed5c122e20c33d2562df06faf895a6b91b0a6b96a4626440ffe1d5c8e/MarkupSafe-2.0.0.tar.gz", hash = "sha256:4fae0677f712ee090721d8b17f412f1cbceefbf0dc180fe91bab3232f38b4527", size = 18466 } + [[package]] + name = "markupsafe" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + environment-markers = [ + "sys_platform == 'win32'", + ] + sdist = { url = "https://files.pythonhosted.org/packages/67/6a/5b3ed5c122e20c33d2562df06faf895a6b91b0a6b96a4626440ffe1d5c8e/MarkupSafe-2.0.0.tar.gz", hash = "sha256:4fae0677f712ee090721d8b17f412f1cbceefbf0dc180fe91bab3232f38b4527", size = 18466 } - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "markupsafe", version = "1.1.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'win32'" }, - { name = "markupsafe", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'win32'" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "markupsafe", version = "1.1.1", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'win32'" }, + { name = "markupsafe", version = "2.0.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'win32'" }, + ] + + [package.metadata] + requires-dist = [ + { name = "markupsafe", marker = "sys_platform != 'win32'", specifier = "<2" }, + { name = "markupsafe", marker = "sys_platform == 'win32'", specifier = "==2.0.0" }, + ] + "### + ); + }); // Run with `--upgrade`; ensure that nothing is changed. uv_snapshot!(context.filters(), context.lock().arg("--upgrade"), @r###" @@ -2229,6 +2330,9 @@ fn lock_upgrade_log_multi_version() -> Result<()> { dependencies = [ { name = "markupsafe" }, ] + + [package.metadata] + requires-dist = [{ name = "markupsafe" }] "### ); }); @@ -2252,8 +2356,7 @@ fn lock_preference() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2263,39 +2366,41 @@ fn lock_preference() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "iniconfig" - version = "1.1.1" - source = { registry = "https://pypi.org/simple" } - 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 = "1.1.1" + source = { registry = "https://pypi.org/simple" } + 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 = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "iniconfig" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig" }, + ] + + [package.metadata] + requires-dist = [{ name = "iniconfig", specifier = "<2" }] + "### + ); + }); // Modify the `pyproject.toml` to loosen the requirement. pyproject_toml.write_str( @@ -2350,6 +2455,9 @@ fn lock_preference() -> Result<()> { dependencies = [ { name = "iniconfig" }, ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] "### ); }); @@ -2394,6 +2502,9 @@ fn lock_preference() -> Result<()> { dependencies = [ { name = "iniconfig" }, ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] "### ); }); @@ -2419,9 +2530,7 @@ fn lock_git_sha() -> Result<()> { "#, )?; - let mut lock = String::new(); - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2431,34 +2540,36 @@ fn lock_git_sha() -> Result<()> { Resolved 2 packages in [TIME] "###); - lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" } + "### + ); + }); // Rewrite the lockfile, as if it were locked against `main`. let lock = lock.replace("rev=0dacfd662c64cb4ceb16e6cf65a157a8b715b979", "rev=main"); @@ -2481,6 +2592,9 @@ fn lock_git_sha() -> Result<()> { { name = "uv-public-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=main#0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }] + [[package]] name = "uv-public-pypackage" version = "0.1.0" @@ -2537,6 +2651,9 @@ fn lock_git_sha() -> Result<()> { { name = "uv-public-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=main" }] + [[package]] name = "uv-public-pypackage" version = "0.1.0" @@ -2545,9 +2662,8 @@ fn lock_git_sha() -> Result<()> { ); }); - deterministic_lock! { context => - // Relock with `--upgrade`. - uv_snapshot!(context.filters(), context.lock().arg("--upgrade-package").arg("uv-public-pypackage"), @r###" + // Relock with `--upgrade`. + uv_snapshot!(context.filters(), context.lock().arg("--upgrade-package").arg("uv-public-pypackage"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2557,37 +2673,39 @@ fn lock_git_sha() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - // The lockfile should resolve to `b270df1a2fb5d012294e9aaf05e7e0bab1e6a389`, the latest commit - // on `main`. - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + // The lockfile should resolve to `b270df1a2fb5d012294e9aaf05e7e0bab1e6a389`, the latest commit + // on `main`. + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "uv-public-pypackage" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "uv-public-pypackage" }, + ] - [[package]] - name = "uv-public-pypackage" - version = "0.1.0" - source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=main#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?rev=main" }] + + [[package]] + name = "uv-public-pypackage" + version = "0.1.0" + source = { git = "https://github.com/astral-test/uv-public-pypackage?rev=main#b270df1a2fb5d012294e9aaf05e7e0bab1e6a389" } + "### + ); + }); Ok(()) } @@ -2611,8 +2729,7 @@ fn lock_requires_python() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: false exit_code: 1 ----- stdout ----- @@ -2636,7 +2753,6 @@ fn lock_requires_python() -> Result<()> { hint: The `requires-python` value (>=3.7) includes Python versions that are not supported by your dependencies (e.g., pygls>=1.1.0,<=1.2.1 only supports >=3.7.9, <4). Consider using a more restrictive `requires-python` value (like >=3.7.9, <4). "###); - } // Require >=3.7, and allow locking to a version of `pygls` that is compatible (==1.0.1). pyproject_toml.write_str( @@ -2649,8 +2765,7 @@ fn lock_requires_python() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2660,131 +2775,133 @@ fn lock_requires_python() -> Result<()> { Resolved 10 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.7" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.7" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "attrs" - version = "23.2.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "importlib-metadata", marker = "python_version < '3.8'" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, - ] + [[package]] + name = "attrs" + version = "23.2.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "importlib-metadata", marker = "python_version < '3.8'" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, + ] - [[package]] - name = "cattrs" - version = "23.1.2" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - { name = "exceptiongroup", marker = "python_version < '3.11'" }, - { name = "typing-extensions", marker = "python_version < '3.11'" }, - ] - 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.1.2" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + { name = "exceptiongroup", marker = "python_version < '3.11'" }, + { name = "typing-extensions", marker = "python_version < '3.11'" }, + ] + 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 = "exceptiongroup" - version = "1.2.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210 }, - ] + [[package]] + name = "exceptiongroup" + version = "1.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210 }, + ] - [[package]] - name = "importlib-metadata" - version = "6.7.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "typing-extensions", marker = "python_version < '3.8'" }, - { name = "zipp" }, - ] - 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 = "importlib-metadata" + version = "6.7.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "typing-extensions", marker = "python_version < '3.8'" }, + { name = "zipp" }, + ] + 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.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - { name = "cattrs" }, - ] - 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 = "lsprotocol" + version = "2023.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + { name = "cattrs" }, + ] + 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" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "pygls" }, + ] - [[package]] - name = "pygls" - version = "1.0.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "lsprotocol" }, - { name = "typeguard" }, - ] - 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.metadata] + requires-dist = [{ name = "pygls" }] - [[package]] - name = "typeguard" - version = "2.13.3" - source = { registry = "https://pypi.org/simple" } - 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 = "pygls" + version = "1.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "lsprotocol" }, + { name = "typeguard" }, + ] + 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 = "typing-extensions" - version = "4.7.1" - source = { registry = "https://pypi.org/simple" } - 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 = "typeguard" + version = "2.13.3" + source = { registry = "https://pypi.org/simple" } + 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 = "zipp" - version = "3.15.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758 }, - ] - "### - ); - }); - } + [[package]] + name = "typing-extensions" + version = "4.7.1" + source = { registry = "https://pypi.org/simple" } + 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 = "zipp" + version = "3.15.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758 }, + ] + "### + ); + }); // Remove the lockfile. fs_err::remove_file(&lockfile)?; @@ -2800,8 +2917,7 @@ fn lock_requires_python() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2811,121 +2927,123 @@ fn lock_requires_python() -> Result<()> { Resolved 9 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.7.9" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.7.9" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "attrs" - version = "23.2.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "importlib-metadata", marker = "python_version < '3.8'" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, - ] + [[package]] + name = "attrs" + version = "23.2.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "importlib-metadata", marker = "python_version < '3.8'" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, + ] - [[package]] - name = "cattrs" - version = "23.1.2" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - { name = "exceptiongroup", marker = "python_version < '3.11'" }, - { name = "typing-extensions", marker = "python_version < '3.11'" }, - ] - 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.1.2" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + { name = "exceptiongroup", marker = "python_version < '3.11'" }, + { name = "typing-extensions", marker = "python_version < '3.11'" }, + ] + 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 = "exceptiongroup" - version = "1.2.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210 }, - ] + [[package]] + name = "exceptiongroup" + version = "1.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/8e/1c/beef724eaf5b01bb44b6338c8c3494eff7cab376fab4904cfbbc3585dc79/exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68", size = 26264 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/9a/5028fd52db10e600f1c4674441b968cf2ea4959085bfb5b99fb1250e5f68/exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14", size = 16210 }, + ] - [[package]] - name = "importlib-metadata" - version = "6.7.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "typing-extensions", marker = "python_version < '3.8'" }, - { name = "zipp" }, - ] - 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 = "importlib-metadata" + version = "6.7.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "typing-extensions", marker = "python_version < '3.8'" }, + { name = "zipp" }, + ] + 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" } - dependencies = [ - { name = "attrs" }, - { name = "cattrs" }, - ] - 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.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + { name = "cattrs" }, + ] + 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 = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "pygls" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "pygls" }, + ] - [[package]] - name = "pygls" - version = "1.2.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "lsprotocol" }, - ] - 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.metadata] + requires-dist = [{ name = "pygls" }] - [[package]] - name = "typing-extensions" - version = "4.7.1" - source = { registry = "https://pypi.org/simple" } - 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 = "pygls" + version = "1.2.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "lsprotocol" }, + ] + 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 = "zipp" - version = "3.15.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758 }, - ] - "### - ); - }); - } + [[package]] + name = "typing-extensions" + version = "4.7.1" + source = { registry = "https://pypi.org/simple" } + 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 = "zipp" + version = "3.15.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", size = 18454 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/fa/c9e82bbe1af6266adf08afb563905eb87cab83fde00a0a08963510621047/zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556", size = 6758 }, + ] + "### + ); + }); // Remove the lockfile. fs_err::remove_file(&lockfile)?; @@ -2941,8 +3059,7 @@ fn lock_requires_python() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -2952,77 +3069,79 @@ fn lock_requires_python() -> Result<()> { Resolved 5 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "attrs" - version = "23.2.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, - ] + [[package]] + name = "attrs" + version = "23.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, + ] - [[package]] - name = "cattrs" - version = "23.2.3" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - ] - 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 = "cattrs" + version = "23.2.3" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + ] + 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 = "lsprotocol" - version = "2023.0.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - { name = "cattrs" }, - ] - 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 = "lsprotocol" + version = "2023.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + { name = "cattrs" }, + ] + 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" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "pygls" }, + ] - [[package]] - name = "pygls" - version = "1.3.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "cattrs" }, - { name = "lsprotocol" }, - ] - 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.metadata] + requires-dist = [{ name = "pygls" }] + + [[package]] + name = "pygls" + version = "1.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "cattrs" }, + { name = "lsprotocol" }, + ] + 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 }, + ] + "### + ); + }); // Validate that attempting to install with an unsupported Python version raises an error. let context38 = TestContext::new("3.8"); @@ -3083,8 +3202,7 @@ fn lock_requires_python_wheels() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3095,54 +3213,68 @@ fn lock_requires_python_wheels() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12, <3.13" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12, <3.13" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "frozenlist" - version = "1.4.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", size = 93937 }, - { url = "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", size = 53656 }, - { url = "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", size = 51868 }, - { url = "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", size = 280652 }, - { url = "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", size = 286739 }, - { url = "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", size = 289447 }, - { url = "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", size = 265466 }, - { url = "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", size = 281530 }, - { url = "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", size = 281295 }, - { url = "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", size = 268054 }, - { url = "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", size = 286904 }, - { url = "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", size = 290754 }, - { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602 }, - { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063 }, - { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452 }, - { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552 }, - ] + [[package]] + name = "frozenlist" + version = "1.4.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", size = 93937 }, + { url = "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", size = 53656 }, + { url = "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", size = 51868 }, + { url = "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", size = 280652 }, + { url = "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", size = 286739 }, + { url = "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", size = 289447 }, + { url = "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", size = 265466 }, + { url = "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", size = 281530 }, + { url = "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", size = 281295 }, + { url = "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", size = 268054 }, + { url = "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", size = 286904 }, + { url = "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", size = 290754 }, + { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602 }, + { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063 }, + { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452 }, + { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "frozenlist" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "frozenlist" }, + ] + + [package.metadata] + requires-dist = [{ name = "frozenlist" }] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + Resolved 2 packages in [TIME] + "###); // Change to ==3.11.*, which should different wheels in the lockfile. pyproject_toml.write_str( @@ -3155,8 +3287,7 @@ fn lock_requires_python_wheels() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3167,69 +3298,83 @@ fn lock_requires_python_wheels() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.11, <3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.11, <3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "frozenlist" - version = "1.4.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/01/bc/8d33f2d84b9368da83e69e42720cff01c5e199b5a868ba4486189a4d8fa9/frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", size = 97060 }, - { url = "https://files.pythonhosted.org/packages/af/b2/904500d6a162b98a70e510e743e7ea992241b4f9add2c8063bf666ca21df/frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", size = 55347 }, - { url = "https://files.pythonhosted.org/packages/5b/9c/f12b69997d3891ddc0d7895999a00b0c6a67f66f79498c0e30f27876435d/frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", size = 53374 }, - { url = "https://files.pythonhosted.org/packages/ac/6e/e0322317b7c600ba21dec224498c0c5959b2bce3865277a7c0badae340a9/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", size = 273288 }, - { url = "https://files.pythonhosted.org/packages/a7/76/180ee1b021568dad5b35b7678616c24519af130ed3fa1e0f1ed4014e0f93/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", size = 284737 }, - { url = "https://files.pythonhosted.org/packages/05/08/40159d706a6ed983c8aca51922a93fc69f3c27909e82c537dd4054032674/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", size = 280267 }, - { url = "https://files.pythonhosted.org/packages/e0/18/9f09f84934c2b2aa37d539a322267939770362d5495f37783440ca9c1b74/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", size = 258778 }, - { url = "https://files.pythonhosted.org/packages/b3/c9/0bc5ee7e1f5cc7358ab67da0b7dfe60fbd05c254cea5c6108e7d1ae28c63/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", size = 272276 }, - { url = "https://files.pythonhosted.org/packages/12/5d/147556b73a53ad4df6da8bbb50715a66ac75c491fdedac3eca8b0b915345/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", size = 272424 }, - { url = "https://files.pythonhosted.org/packages/83/61/2087bbf24070b66090c0af922685f1d0596c24bb3f3b5223625bdeaf03ca/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", size = 260881 }, - { url = "https://files.pythonhosted.org/packages/a8/be/a235bc937dd803258a370fe21b5aa2dd3e7bfe0287a186a4bec30c6cccd6/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", size = 282327 }, - { url = "https://files.pythonhosted.org/packages/5d/e7/b2469e71f082948066b9382c7b908c22552cc705b960363c390d2e23f587/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74", size = 281502 }, - { url = "https://files.pythonhosted.org/packages/db/1b/6a5b970e55dffc1a7d0bb54f57b184b2a2a2ad0b7bca16a97ca26d73c5b5/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", size = 272292 }, - { url = "https://files.pythonhosted.org/packages/1a/05/ebad68130e6b6eb9b287dacad08ea357c33849c74550c015b355b75cc714/frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", size = 44446 }, - { url = "https://files.pythonhosted.org/packages/b3/21/c5aaffac47fd305d69df46cfbf118768cdf049a92ee6b0b5cb029d449dcf/frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", size = 50459 }, - { url = "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", size = 93937 }, - { url = "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", size = 53656 }, - { url = "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", size = 51868 }, - { url = "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", size = 280652 }, - { url = "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", size = 286739 }, - { url = "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", size = 289447 }, - { url = "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", size = 265466 }, - { url = "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", size = 281530 }, - { url = "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", size = 281295 }, - { url = "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", size = 268054 }, - { url = "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", size = 286904 }, - { url = "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", size = 290754 }, - { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602 }, - { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063 }, - { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452 }, - { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552 }, - ] + [[package]] + name = "frozenlist" + version = "1.4.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/01/bc/8d33f2d84b9368da83e69e42720cff01c5e199b5a868ba4486189a4d8fa9/frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", size = 97060 }, + { url = "https://files.pythonhosted.org/packages/af/b2/904500d6a162b98a70e510e743e7ea992241b4f9add2c8063bf666ca21df/frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", size = 55347 }, + { url = "https://files.pythonhosted.org/packages/5b/9c/f12b69997d3891ddc0d7895999a00b0c6a67f66f79498c0e30f27876435d/frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", size = 53374 }, + { url = "https://files.pythonhosted.org/packages/ac/6e/e0322317b7c600ba21dec224498c0c5959b2bce3865277a7c0badae340a9/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", size = 273288 }, + { url = "https://files.pythonhosted.org/packages/a7/76/180ee1b021568dad5b35b7678616c24519af130ed3fa1e0f1ed4014e0f93/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", size = 284737 }, + { url = "https://files.pythonhosted.org/packages/05/08/40159d706a6ed983c8aca51922a93fc69f3c27909e82c537dd4054032674/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", size = 280267 }, + { url = "https://files.pythonhosted.org/packages/e0/18/9f09f84934c2b2aa37d539a322267939770362d5495f37783440ca9c1b74/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", size = 258778 }, + { url = "https://files.pythonhosted.org/packages/b3/c9/0bc5ee7e1f5cc7358ab67da0b7dfe60fbd05c254cea5c6108e7d1ae28c63/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", size = 272276 }, + { url = "https://files.pythonhosted.org/packages/12/5d/147556b73a53ad4df6da8bbb50715a66ac75c491fdedac3eca8b0b915345/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", size = 272424 }, + { url = "https://files.pythonhosted.org/packages/83/61/2087bbf24070b66090c0af922685f1d0596c24bb3f3b5223625bdeaf03ca/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", size = 260881 }, + { url = "https://files.pythonhosted.org/packages/a8/be/a235bc937dd803258a370fe21b5aa2dd3e7bfe0287a186a4bec30c6cccd6/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", size = 282327 }, + { url = "https://files.pythonhosted.org/packages/5d/e7/b2469e71f082948066b9382c7b908c22552cc705b960363c390d2e23f587/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74", size = 281502 }, + { url = "https://files.pythonhosted.org/packages/db/1b/6a5b970e55dffc1a7d0bb54f57b184b2a2a2ad0b7bca16a97ca26d73c5b5/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", size = 272292 }, + { url = "https://files.pythonhosted.org/packages/1a/05/ebad68130e6b6eb9b287dacad08ea357c33849c74550c015b355b75cc714/frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", size = 44446 }, + { url = "https://files.pythonhosted.org/packages/b3/21/c5aaffac47fd305d69df46cfbf118768cdf049a92ee6b0b5cb029d449dcf/frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", size = 50459 }, + { url = "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", size = 93937 }, + { url = "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", size = 53656 }, + { url = "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", size = 51868 }, + { url = "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", size = 280652 }, + { url = "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", size = 286739 }, + { url = "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", size = 289447 }, + { url = "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", size = 265466 }, + { url = "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", size = 281530 }, + { url = "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", size = 281295 }, + { url = "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", size = 268054 }, + { url = "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", size = 286904 }, + { url = "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", size = 290754 }, + { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602 }, + { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063 }, + { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452 }, + { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "frozenlist" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "frozenlist" }, + ] + + [package.metadata] + requires-dist = [{ name = "frozenlist" }] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Using Python 3.11.[X] interpreter at: [PYTHON-3.11] + Resolved 2 packages in [TIME] + "###); Ok(()) } @@ -3253,8 +3398,7 @@ fn lock_requires_python_star() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3264,83 +3408,96 @@ fn lock_requires_python_star() -> Result<()> { Resolved 6 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.11, <3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.11, <3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "attrs" - version = "23.2.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, - ] + [[package]] + name = "attrs" + version = "23.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, + ] - [[package]] - name = "cattrs" - version = "23.2.3" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - ] - 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 = "cattrs" + version = "23.2.3" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + ] + 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 = "linehaul" - version = "1.0.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "cattrs" }, - { name = "packaging" }, - { name = "pyparsing" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/f8/e7/74d1bd36ed26ac43bfe22e97129edaa7066f7af4bf76084b9493cd581d58/linehaul-1.0.1.tar.gz", hash = "sha256:09d71b1f6a9ab92dd8c763b3d099e4ae05c2845ee783a02d5fe731e6e2a6a997", size = 19410 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/03/73/c73588052198be06462d1a7c4653b602a109a0df0208c59e58075dc3bc73/linehaul-1.0.1-py3-none-any.whl", hash = "sha256:d19ca669008dad910868dfae7f904dfc5362583729bda344799cf7ea2ad5ef12", size = 27848 }, - ] + [[package]] + name = "linehaul" + version = "1.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "cattrs" }, + { name = "packaging" }, + { name = "pyparsing" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/f8/e7/74d1bd36ed26ac43bfe22e97129edaa7066f7af4bf76084b9493cd581d58/linehaul-1.0.1.tar.gz", hash = "sha256:09d71b1f6a9ab92dd8c763b3d099e4ae05c2845ee783a02d5fe731e6e2a6a997", size = 19410 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/03/73/c73588052198be06462d1a7c4653b602a109a0df0208c59e58075dc3bc73/linehaul-1.0.1-py3-none-any.whl", hash = "sha256:d19ca669008dad910868dfae7f904dfc5362583729bda344799cf7ea2ad5ef12", size = 27848 }, + ] - [[package]] - name = "packaging" - version = "24.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, - ] + [[package]] + name = "packaging" + version = "24.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "linehaul" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "linehaul" }, + ] - [[package]] - name = "pyparsing" - version = "3.1.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/46/3a/31fd28064d016a2182584d579e033ec95b809d8e220e74c4af6f0f2e8842/pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad", size = 889571 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/ea/6d76df31432a0e6fdf81681a895f009a4bb47b3c39036db3e1b528191d52/pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742", size = 103245 }, - ] - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "linehaul" }] + + [[package]] + name = "pyparsing" + version = "3.1.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/46/3a/31fd28064d016a2182584d579e033ec95b809d8e220e74c4af6f0f2e8842/pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad", size = 889571 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/ea/6d76df31432a0e6fdf81681a895f009a4bb47b3c39036db3e1b528191d52/pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742", size = 103245 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 6 packages in [TIME] + "###); Ok(()) } @@ -3365,8 +3522,7 @@ fn lock_requires_python_pre() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3376,83 +3532,96 @@ fn lock_requires_python_pre() -> Result<()> { Resolved 6 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.11" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.11" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "attrs" - version = "23.2.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, - ] + [[package]] + name = "attrs" + version = "23.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, + ] - [[package]] - name = "cattrs" - version = "23.2.3" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "attrs" }, - ] - 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 = "cattrs" + version = "23.2.3" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "attrs" }, + ] + 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 = "linehaul" - version = "1.0.1" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "cattrs" }, - { name = "packaging" }, - { name = "pyparsing" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/f8/e7/74d1bd36ed26ac43bfe22e97129edaa7066f7af4bf76084b9493cd581d58/linehaul-1.0.1.tar.gz", hash = "sha256:09d71b1f6a9ab92dd8c763b3d099e4ae05c2845ee783a02d5fe731e6e2a6a997", size = 19410 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/03/73/c73588052198be06462d1a7c4653b602a109a0df0208c59e58075dc3bc73/linehaul-1.0.1-py3-none-any.whl", hash = "sha256:d19ca669008dad910868dfae7f904dfc5362583729bda344799cf7ea2ad5ef12", size = 27848 }, - ] + [[package]] + name = "linehaul" + version = "1.0.1" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "cattrs" }, + { name = "packaging" }, + { name = "pyparsing" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/f8/e7/74d1bd36ed26ac43bfe22e97129edaa7066f7af4bf76084b9493cd581d58/linehaul-1.0.1.tar.gz", hash = "sha256:09d71b1f6a9ab92dd8c763b3d099e4ae05c2845ee783a02d5fe731e6e2a6a997", size = 19410 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/03/73/c73588052198be06462d1a7c4653b602a109a0df0208c59e58075dc3bc73/linehaul-1.0.1-py3-none-any.whl", hash = "sha256:d19ca669008dad910868dfae7f904dfc5362583729bda344799cf7ea2ad5ef12", size = 27848 }, + ] - [[package]] - name = "packaging" - version = "24.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, - ] + [[package]] + name = "packaging" + version = "24.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9", size = 147882 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", size = 53488 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "linehaul" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "linehaul" }, + ] - [[package]] - name = "pyparsing" - version = "3.1.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/46/3a/31fd28064d016a2182584d579e033ec95b809d8e220e74c4af6f0f2e8842/pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad", size = 889571 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/ea/6d76df31432a0e6fdf81681a895f009a4bb47b3c39036db3e1b528191d52/pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742", size = 103245 }, - ] - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "linehaul" }] + + [[package]] + name = "pyparsing" + version = "3.1.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/46/3a/31fd28064d016a2182584d579e033ec95b809d8e220e74c4af6f0f2e8842/pyparsing-3.1.2.tar.gz", hash = "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad", size = 889571 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/ea/6d76df31432a0e6fdf81681a895f009a4bb47b3c39036db3e1b528191d52/pyparsing-3.1.2-py3-none-any.whl", hash = "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742", size = 103245 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 6 packages in [TIME] + "###); Ok(()) } @@ -3475,8 +3644,7 @@ fn lock_requires_python_unbounded() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3487,39 +3655,53 @@ fn lock_requires_python_unbounded() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(&lockfile).unwrap(); + let lock = fs_err::read_to_string(&lockfile).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = "<=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = "<=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "iniconfig" - version = "1.1.1" - source = { registry = "https://pypi.org/simple" } - 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 = "1.1.1" + source = { registry = "https://pypi.org/simple" } + 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 = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "iniconfig" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig" }, + ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + warning: The workspace `requires-python` value does not contain a lower bound: `<=3.12`. Set a lower bound to indicate the minimum compatible Python version (e.g., `>=3.11`). + Resolved 2 packages in [TIME] + "###); Ok(()) } @@ -3572,70 +3754,79 @@ fn lock_python_version_marker_complement() -> Result<()> { }, { assert_snapshot!( lock, @r###" - version = 1 - requires-python = ">=3.8" - environment-markers = [ - "python_full_version <= '3.10' and python_version > '3.10'", - "python_full_version <= '3.10' and python_version == '3.10'", - "python_full_version <= '3.10' and python_version < '3.10'", - "python_full_version > '3.10' and python_version > '3.10'", - "python_full_version > '3.10' and python_version == '3.10'", - "python_full_version > '3.10' and python_version < '3.10'", - ] + version = 1 + requires-python = ">=3.8" + environment-markers = [ + "python_full_version <= '3.10' and python_version > '3.10'", + "python_full_version <= '3.10' and python_version == '3.10'", + "python_full_version <= '3.10' and python_version < '3.10'", + "python_full_version > '3.10' and python_version > '3.10'", + "python_full_version > '3.10' and python_version == '3.10'", + "python_full_version > '3.10' and python_version < '3.10'", + ] - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "attrs" - version = "23.2.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, - ] + [[package]] + name = "attrs" + version = "23.2.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/e3/fc/f800d51204003fa8ae392c4e8278f256206e7a919b708eef054f5f4b650d/attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", size = 780820 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1", size = 60752 }, + ] - [[package]] - name = "iniconfig" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - 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 = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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 = "attrs" }, - { name = "iniconfig" }, - { name = "typing-extensions" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "attrs" }, + { name = "iniconfig" }, + { name = "typing-extensions" }, + ] - [[package]] - name = "typing-extensions" - version = "4.10.0" - source = { registry = "https://pypi.org/simple" } - 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.metadata] + requires-dist = [ + { name = "iniconfig", marker = "python_version >= '3.10'" }, + { name = "iniconfig", marker = "python_version < '3.10'" }, + { name = "attrs", marker = "python_version > '3.10'" }, + { name = "attrs", marker = "python_version <= '3.10'" }, + { name = "typing-extensions", marker = "python_full_version > '3.10'" }, + { name = "typing-extensions", marker = "python_full_version <= '3.10'" }, + ] + + [[package]] + name = "typing-extensions" + version = "4.10.0" + source = { registry = "https://pypi.org/simple" } + 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 }, + ] + "### ); }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" - success: false - exit_code: 2 + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- warning: `uv lock` is experimental and may change without warning Resolved 4 packages in [TIME] - error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "###); Ok(()) @@ -3660,8 +3851,7 @@ fn lock_dev() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3671,52 +3861,68 @@ fn lock_dev() -> Result<()> { Resolved 3 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "iniconfig" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - 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 = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig" }, + ] - [package.dev-dependencies] - dev = [ - { name = "typing-extensions" }, - ] + [package.dev-dependencies] + dev = [ + { name = "typing-extensions" }, + ] - [[package]] - name = "typing-extensions" - version = "4.12.2" - source = { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" } - wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d" }, - ] - "### - ); - }); - } + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + + [package.metadata.requires-dev] + dev = [{ name = "typing-extensions", url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" }] + + [[package]] + name = "typing-extensions" + version = "4.12.2" + source = { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" } + wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d" }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 3 packages in [TIME] + "###); // Install from the lockfile, excluding development dependencies. uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--no-dev"), @r###" @@ -3763,8 +3969,7 @@ fn lock_conditional_unconditional() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3774,39 +3979,55 @@ fn lock_conditional_unconditional() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "iniconfig" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - 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 = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig" }, + ] + + [package.metadata] + requires-dist = [ + { name = "iniconfig" }, + { name = "iniconfig", marker = "python_version < '3.12'" }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); Ok(()) } @@ -3827,8 +4048,7 @@ fn lock_multiple_markers() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3838,39 +4058,55 @@ fn lock_multiple_markers() -> Result<()> { Resolved 2 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "iniconfig" - version = "2.0.0" - source = { registry = "https://pypi.org/simple" } - 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 = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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", marker = "implementation_name == 'cpython'" }, - ] - "### - ); - }); - } + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig", marker = "implementation_name == 'cpython'" }, + ] + + [package.metadata] + requires-dist = [ + { name = "iniconfig", marker = "implementation_name == 'cpython'" }, + { name = "iniconfig", marker = "python_version < '3.12'" }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); Ok(()) } @@ -3932,8 +4168,7 @@ fn lock_relative_and_absolute_paths() -> Result<()> { "#})?; context.temp_dir.child("c/c/__init__.py").touch()?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock().arg("--preview"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--preview"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -3942,41 +4177,58 @@ fn lock_relative_and_absolute_paths() -> Result<()> { Resolved 3 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.11, <3.13" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.11, <3.13" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "a" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "b" }, - { name = "c" }, - ] + [[package]] + name = "a" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "b" }, + { name = "c" }, + ] - [[package]] - name = "b" - version = "0.1.0" - source = { directory = "b" } + [package.metadata] + requires-dist = [ + { name = "b", directory = "b" }, + { name = "c", directory = "[TEMP_DIR]/c" }, + ] - [[package]] - name = "c" - version = "0.1.0" - source = { directory = "[TEMP_DIR]/c" } - "### - ); - }); - } + [[package]] + name = "b" + version = "0.1.0" + source = { directory = "b" } + + [[package]] + name = "c" + version = "0.1.0" + source = { directory = "[TEMP_DIR]/c" } + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + warning: `uv.sources` is experimental and may change without warning + Resolved 3 packages in [TIME] + "###); Ok(()) } @@ -3997,8 +4249,7 @@ fn lock_cycles() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r###" success: true exit_code: 0 ----- stdout ----- @@ -4008,143 +4259,148 @@ fn lock_cycles() -> Result<()> { Resolved 11 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "argparse" - version = "1.4.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", size = 70508 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314", size = 23000 }, - ] + [[package]] + name = "argparse" + version = "1.4.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/18/dd/e617cfc3f6210ae183374cd9f6a26b20514bbb5a792af97949c5aacddf0f/argparse-1.4.0.tar.gz", hash = "sha256:62b089a55be1d8949cd2bc7e0df0bddb9e028faefc8c32038cc84862aefdd6e4", size = 70508 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl", hash = "sha256:c31647edb69fd3d465a847ea3157d37bed1f95f19760b11a47aa91c04b666314", size = 23000 }, + ] - [[package]] - name = "extras" - version = "1.0.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/be/18/0b7283f0ebf6ad4bb6b9937538495eadf05ef097b102946b9445c4242636/extras-1.0.0.tar.gz", hash = "sha256:132e36de10b9c91d5d4cc620160a476e0468a88f16c9431817a6729611a81b4e", size = 6759 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/03/e9/e915af1f97914cd0bc021e125fd1bfd4106de614a275e4b6866dd9a209ac/extras-1.0.0-py2.py3-none-any.whl", hash = "sha256:f689f08df47e2decf76aa6208c081306e7bd472630eb1ec8a875c67de2366e87", size = 7279 }, - ] + [[package]] + name = "extras" + version = "1.0.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/be/18/0b7283f0ebf6ad4bb6b9937538495eadf05ef097b102946b9445c4242636/extras-1.0.0.tar.gz", hash = "sha256:132e36de10b9c91d5d4cc620160a476e0468a88f16c9431817a6729611a81b4e", size = 6759 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/03/e9/e915af1f97914cd0bc021e125fd1bfd4106de614a275e4b6866dd9a209ac/extras-1.0.0-py2.py3-none-any.whl", hash = "sha256:f689f08df47e2decf76aa6208c081306e7bd472630eb1ec8a875c67de2366e87", size = 7279 }, + ] - [[package]] - name = "fixtures" - version = "3.0.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "pbr" }, - { name = "six" }, - { name = "testtools" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/84/be/94ecbc3f2487bd14aa8b44852f498086219b7cc0c8250ee65a03e2c63119/fixtures-3.0.0.tar.gz", hash = "sha256:fcf0d60234f1544da717a9738325812de1f42c2fa085e2d9252d8fff5712b2ef", size = 56629 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/28/7eed6bf76792f418029a18d5b2ace87ce7562927cdd00f1cefe481cd148f/fixtures-3.0.0-py2.py3-none-any.whl", hash = "sha256:2a551b0421101de112d9497fb5f6fd25e5019391c0fbec9bad591ecae981420d", size = 67478 }, - ] + [[package]] + name = "fixtures" + version = "3.0.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "pbr" }, + { name = "six" }, + { name = "testtools" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/84/be/94ecbc3f2487bd14aa8b44852f498086219b7cc0c8250ee65a03e2c63119/fixtures-3.0.0.tar.gz", hash = "sha256:fcf0d60234f1544da717a9738325812de1f42c2fa085e2d9252d8fff5712b2ef", size = 56629 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/28/7eed6bf76792f418029a18d5b2ace87ce7562927cdd00f1cefe481cd148f/fixtures-3.0.0-py2.py3-none-any.whl", hash = "sha256:2a551b0421101de112d9497fb5f6fd25e5019391c0fbec9bad591ecae981420d", size = 67478 }, + ] - [[package]] - name = "linecache2" - version = "1.0.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/44/b0/963c352372c242f9e40db02bbc6a39ae51bde15dddee8523fe4aca94a97e/linecache2-1.0.0.tar.gz", hash = "sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c", size = 11013 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/a3/c5da2a44c85bfbb6eebcfc1dde24933f8704441b98fdde6528f4831757a6/linecache2-1.0.0-py2.py3-none-any.whl", hash = "sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef", size = 12967 }, - ] + [[package]] + name = "linecache2" + version = "1.0.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/44/b0/963c352372c242f9e40db02bbc6a39ae51bde15dddee8523fe4aca94a97e/linecache2-1.0.0.tar.gz", hash = "sha256:4b26ff4e7110db76eeb6f5a7b64a82623839d595c2038eeda662f2a2db78e97c", size = 11013 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/a3/c5da2a44c85bfbb6eebcfc1dde24933f8704441b98fdde6528f4831757a6/linecache2-1.0.0-py2.py3-none-any.whl", hash = "sha256:e78be9c0a0dfcbac712fe04fbf92b96cddae80b1b842f24248214c8496f006ef", size = 12967 }, + ] - [[package]] - name = "pbr" - version = "6.0.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/8d/c2/ee43b3b11bf2b40e56536183fc9f22afbb04e882720332b6276ee2454c24/pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9", size = 123150 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/64/dd/171c9fb653591cf265bcc89c436eec75c9bde3dec921cc236fa71e5698df/pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", size = 107506 }, - ] + [[package]] + name = "pbr" + version = "6.0.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/8d/c2/ee43b3b11bf2b40e56536183fc9f22afbb04e882720332b6276ee2454c24/pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9", size = 123150 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/64/dd/171c9fb653591cf265bcc89c436eec75c9bde3dec921cc236fa71e5698df/pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda", size = 107506 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "fixtures" }, - { name = "testtools" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "fixtures" }, + { name = "testtools" }, + ] - [[package]] - name = "python-mimeparse" - version = "1.6.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/0f/40/ac5f9e44a55b678c3cd881b4c3376e5b002677dbeab6fb3a50bac5d50d29/python-mimeparse-1.6.0.tar.gz", hash = "sha256:76e4b03d700a641fd7761d3cd4fdbbdcd787eade1ebfac43f877016328334f78", size = 6541 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/26/2e/03bce213a9bf02a2750dcb04e761785e9c763fc11071edc4b447eacbb842/python_mimeparse-1.6.0-py2.py3-none-any.whl", hash = "sha256:a295f03ff20341491bfe4717a39cd0a8cc9afad619ba44b77e86b0ab8a2b8282", size = 6057 }, - ] + [package.metadata] + requires-dist = [ + { name = "testtools", specifier = "==2.3.0" }, + { name = "fixtures", specifier = "==3.0.0" }, + ] - [[package]] - name = "six" - version = "1.16.0" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, - ] + [[package]] + name = "python-mimeparse" + version = "1.6.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/0f/40/ac5f9e44a55b678c3cd881b4c3376e5b002677dbeab6fb3a50bac5d50d29/python-mimeparse-1.6.0.tar.gz", hash = "sha256:76e4b03d700a641fd7761d3cd4fdbbdcd787eade1ebfac43f877016328334f78", size = 6541 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/26/2e/03bce213a9bf02a2750dcb04e761785e9c763fc11071edc4b447eacbb842/python_mimeparse-1.6.0-py2.py3-none-any.whl", hash = "sha256:a295f03ff20341491bfe4717a39cd0a8cc9afad619ba44b77e86b0ab8a2b8282", size = 6057 }, + ] - [[package]] - name = "testtools" - version = "2.3.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "extras" }, - { name = "fixtures" }, - { name = "pbr" }, - { name = "python-mimeparse" }, - { name = "six" }, - { name = "traceback2" }, - { name = "unittest2" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/e5/d4/9b22df94d0d5c83affe2517295c85fa2d9917f3cafa7dc7f6b1ce4135b00/testtools-2.3.0.tar.gz", hash = "sha256:5827ec6cf8233e0f29f51025addd713ca010061204fdea77484a2934690a0559", size = 231559 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/87/74/a4d55da28d7bba6d6f49430f22a62afd8472cb24a63fa61daef80d3e821b/testtools-2.3.0-py2.py3-none-any.whl", hash = "sha256:a2be448869171b6e0f26d9544088b8b98439ec180ce272040236d570a40bcbed", size = 184636 }, - ] + [[package]] + name = "six" + version = "1.16.0" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, + ] - [[package]] - name = "traceback2" - version = "1.4.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "linecache2" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/eb/7f/e20ba11390bdfc55117c8c6070838ec914e6f0053a602390a598057884eb/traceback2-1.4.0.tar.gz", hash = "sha256:05acc67a09980c2ecfedd3423f7ae0104839eccb55fc645773e1caa0951c3030", size = 15872 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/17/0a/6ac05a3723017a967193456a2efa0aa9ac4b51456891af1e2353bb9de21e/traceback2-1.4.0-py2.py3-none-any.whl", hash = "sha256:8253cebec4b19094d67cc5ed5af99bf1dba1285292226e98a31929f87a5d6b23", size = 16793 }, - ] + [[package]] + name = "testtools" + version = "2.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "extras" }, + { name = "fixtures" }, + { name = "pbr" }, + { name = "python-mimeparse" }, + { name = "six" }, + { name = "traceback2" }, + { name = "unittest2" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/e5/d4/9b22df94d0d5c83affe2517295c85fa2d9917f3cafa7dc7f6b1ce4135b00/testtools-2.3.0.tar.gz", hash = "sha256:5827ec6cf8233e0f29f51025addd713ca010061204fdea77484a2934690a0559", size = 231559 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/87/74/a4d55da28d7bba6d6f49430f22a62afd8472cb24a63fa61daef80d3e821b/testtools-2.3.0-py2.py3-none-any.whl", hash = "sha256:a2be448869171b6e0f26d9544088b8b98439ec180ce272040236d570a40bcbed", size = 184636 }, + ] - [[package]] - name = "unittest2" - version = "1.1.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "argparse" }, - { name = "six" }, - { name = "traceback2" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/7f/c4/2b0e2d185d9d60772c10350d9853646832609d2f299a8300ab730f199db4/unittest2-1.1.0.tar.gz", hash = "sha256:22882a0e418c284e1f718a822b3b022944d53d2d908e1690b319a9d3eb2c0579", size = 81432 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/72/20/7f0f433060a962200b7272b8c12ba90ef5b903e218174301d0abfd523813/unittest2-1.1.0-py2.py3-none-any.whl", hash = "sha256:13f77d0875db6d9b435e1d4f41e74ad4cc2eb6e1d5c824996092b3430f088bb8", size = 96379 }, - ] - "### - ); - }); - } + [[package]] + name = "traceback2" + version = "1.4.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "linecache2" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/eb/7f/e20ba11390bdfc55117c8c6070838ec914e6f0053a602390a598057884eb/traceback2-1.4.0.tar.gz", hash = "sha256:05acc67a09980c2ecfedd3423f7ae0104839eccb55fc645773e1caa0951c3030", size = 15872 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/17/0a/6ac05a3723017a967193456a2efa0aa9ac4b51456891af1e2353bb9de21e/traceback2-1.4.0-py2.py3-none-any.whl", hash = "sha256:8253cebec4b19094d67cc5ed5af99bf1dba1285292226e98a31929f87a5d6b23", size = 16793 }, + ] + + [[package]] + name = "unittest2" + version = "1.1.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "argparse" }, + { name = "six" }, + { name = "traceback2" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/7f/c4/2b0e2d185d9d60772c10350d9853646832609d2f299a8300ab730f199db4/unittest2-1.1.0.tar.gz", hash = "sha256:22882a0e418c284e1f718a822b3b022944d53d2d908e1690b319a9d3eb2c0579", size = 81432 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/72/20/7f0f433060a962200b7272b8c12ba90ef5b903e218174301d0abfd523813/unittest2-1.1.0-py2.py3-none-any.whl", hash = "sha256:13f77d0875db6d9b435e1d4f41e74ad4cc2eb6e1d5c824996092b3430f088bb8", size = 96379 }, + ] + "### + ); + }); // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" @@ -4199,8 +4455,7 @@ fn lock_new_extras() -> Result<()> { "#, )?; - deterministic_lock! { context => - uv_snapshot!(context.filters(), context.lock().arg("--preview"), @r###" + uv_snapshot!(context.filters(), context.lock().arg("--preview"), @r###" success: true exit_code: 0 ----- stdout ----- @@ -4209,96 +4464,109 @@ fn lock_new_extras() -> Result<()> { Resolved 6 packages in [TIME] "###); - let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); - insta::with_settings!({ - filters => context.filters(), - }, { - assert_snapshot!( - lock, @r###" - version = 1 - requires-python = ">=3.12" + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "certifi" - version = "2024.2.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/71/da/e94e26401b62acd6d91df2b52954aceb7f561743aa5ccc32152886c76c96/certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", size = 164886 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/06/a07f096c664aeb9f01624f858c3add0a4e913d6c96257acb4fce61e7de14/certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1", size = 163774 }, - ] + [[package]] + name = "certifi" + version = "2024.2.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/71/da/e94e26401b62acd6d91df2b52954aceb7f561743aa5ccc32152886c76c96/certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", size = 164886 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/06/a07f096c664aeb9f01624f858c3add0a4e913d6c96257acb4fce61e7de14/certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1", size = 163774 }, + ] - [[package]] - name = "charset-normalizer" - version = "3.3.2" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, - { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, - { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, - { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, - { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, - { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, - { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, - { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, - { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, - { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, - { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, - { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, - { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, - { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, - { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, - { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, - ] + [[package]] + name = "charset-normalizer" + version = "3.3.2" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, + { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, + { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, + { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, + { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, + { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, + { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, + { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, + { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, + { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, + { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, + { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, + { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, + { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, + { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, + { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, + ] - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "requests" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "requests" }, + ] - [[package]] - name = "requests" - version = "2.31.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1", size = 110794 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", size = 62574 }, - ] + [package.metadata] + requires-dist = [{ name = "requests", specifier = "==2.31.0" }] - [[package]] - name = "urllib3" - version = "2.2.1" - source = { registry = "https://pypi.org/simple" } - 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 }, - ] - "### - ); - }); - } + [[package]] + name = "requests" + version = "2.31.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1", size = 110794 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", size = 62574 }, + ] + + [[package]] + name = "urllib3" + version = "2.2.1" + source = { registry = "https://pypi.org/simple" } + 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 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 6 packages in [TIME] + "###); // Enable a new extra. pyproject_toml.write_str( @@ -4384,6 +4652,9 @@ fn lock_new_extras() -> Result<()> { { name = "requests", extra = ["socks"] }, ] + [package.metadata] + requires-dist = [{ name = "requests", extras = ["socks"], specifier = "==2.31.0" }] + [[package]] name = "pysocks" version = "1.7.1" @@ -4425,6 +4696,17 @@ fn lock_new_extras() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 7 packages in [TIME] + "###); + Ok(()) } @@ -4447,6 +4729,7 @@ fn lock_invalid_hash() -> Result<()> { )?; let lock = context.temp_dir.child("uv.lock"); + lock.write_str(r#" version = 1 requires-python = ">=3.12" @@ -4480,6 +4763,7 @@ fn lock_invalid_hash() -> Result<()> { dependencies = [ { name = "anyio" }, ] + requires-dist = [{ name = "anyio", specifier = "==3.7.0" }] [[package]] name = "sniffio" @@ -4493,13 +4777,14 @@ fn lock_invalid_hash() -> Result<()> { // Re-run with `--locked`. uv_snapshot!(context.filters(), context.lock().arg("--locked").env_remove("UV_EXCLUDE_NEWER"), @r###" - success: true - exit_code: 0 + success: false + exit_code: 2 ----- stdout ----- ----- stderr ----- warning: `uv lock` is experimental and may change without warning Resolved 4 packages in [TIME] + error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. "###); // Install from the lockfile. @@ -4558,64 +4843,67 @@ fn lock_resolution_mode() -> Result<()> { }, { assert_snapshot!( lock, @r###" - version = 1 - requires-python = ">=3.12" + version = 1 + requires-python = ">=3.12" - [options] - exclude-newer = "2024-03-25 00:00:00 UTC" + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" - [[package]] - name = "anyio" - version = "4.3.0" - source = { registry = "https://pypi.org/simple" } - dependencies = [ - { name = "idna" }, - { name = "sniffio" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 }, - ] + [[package]] + name = "anyio" + version = "4.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 }, + ] - [[package]] - name = "idna" - version = "3.6" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, - ] + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] - [[package]] - name = "project" - version = "0.1.0" - source = { editable = "." } - dependencies = [ - { name = "anyio" }, - ] + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] - [[package]] - name = "sniffio" - version = "1.3.1" - source = { registry = "https://pypi.org/simple" } - sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, - ] - "### + [package.metadata] + requires-dist = [{ name = "anyio", specifier = ">=3" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### ); }); - // Locking again should be a no-op. - uv_snapshot!(context.filters(), context.lock(), @r###" - success: true - exit_code: 0 - ----- stdout ----- + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- - ----- stderr ----- - warning: `uv lock` is experimental and may change without warning - Resolved 4 packages in [TIME] - "###); + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); // Locking with `lowest-direct` should ignore the existing lockfile. uv_snapshot!(context.filters(), context.lock().arg("--resolution").arg("lowest-direct"), @r###" @@ -4674,6 +4962,9 @@ fn lock_resolution_mode() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + requires-dist = [{ name = "anyio", specifier = ">=3" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -4686,6 +4977,17 @@ fn lock_resolution_mode() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--resolution").arg("lowest-direct").arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + Ok(()) } @@ -4839,6 +5141,9 @@ fn lock_same_version_multiple_urls() -> Result<()> { { name = "anyio", version = "3.7.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform == 'darwin'" }, ] + [package.metadata] + requires-dist = [{ name = "anyio", specifier = "==3.7.0" }] + [[package]] name = "dependency" version = "0.0.1" @@ -4850,6 +5155,9 @@ fn lock_same_version_multiple_urls() -> Result<()> { { name = "anyio", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "sys_platform != 'darwin'" }, ] + [package.metadata] + requires-dist = [{ name = "anyio", specifier = "==3.0.0" }] + [[package]] name = "idna" version = "3.6" @@ -4868,6 +5176,12 @@ fn lock_same_version_multiple_urls() -> Result<()> { { name = "dependency", version = "0.0.1", source = { directory = "[TEMP_DIR]/v2" }, marker = "sys_platform != 'darwin'" }, ] + [package.metadata] + requires-dist = [ + { name = "dependency", marker = "sys_platform == 'darwin'", directory = "[TEMP_DIR]/v1" }, + { name = "dependency", marker = "sys_platform != 'darwin'", directory = "[TEMP_DIR]/v2" }, + ] + [[package]] name = "sniffio" version = "1.3.1" @@ -4880,6 +5194,17 @@ fn lock_same_version_multiple_urls() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 7 packages in [TIME] + "###); + Ok(()) } @@ -4914,6 +5239,17 @@ fn lock_unsafe_lowest() -> Result<()> { Resolved 2 packages in [TIME] "###); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--resolution").arg("lowest-direct").arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); + Ok(()) } @@ -4987,6 +5323,9 @@ fn lock_exclusion() -> Result<()> { { name = "project" }, ] + [package.metadata] + requires-dist = [{ name = "project", directory = "../" }] + [[package]] name = "project" version = "0.1.0" @@ -4995,6 +5334,17 @@ fn lock_exclusion() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + error: Unable to find lockfile at `uv.lock`. To create a lockfile, run `uv lock` or `uv sync`. + "###); + Ok(()) } @@ -5084,6 +5434,12 @@ fn lock_dev_transitive() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "bar", + "baz", + ] + [[package]] name = "bar" version = "0.1.0" @@ -5094,6 +5450,13 @@ fn lock_dev_transitive() -> Result<()> { { name = "iniconfig" }, ] + [package.metadata] + requires-dist = [ + { name = "foo", directory = "../foo" }, + { name = "baz", editable = "baz" }, + { name = "iniconfig", specifier = ">1" }, + ] + [[package]] name = "baz" version = "0.1.0" @@ -5104,11 +5467,21 @@ fn lock_dev_transitive() -> Result<()> { { name = "typing-extensions" }, ] + [package.metadata] + + [package.metadata.requires-dev] + dev = [{ name = "typing-extensions", specifier = ">4" }] + [[package]] name = "foo" version = "0.1.0" source = { directory = "../foo" } + [package.metadata] + + [package.metadata.requires-dev] + dev = [{ name = "anyio" }] + [[package]] name = "iniconfig" version = "2.0.0" @@ -5130,6 +5503,17 @@ fn lock_dev_transitive() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + error: No `pyproject.toml` found in current directory or any parent directory + "###); + Ok(()) } @@ -5181,6 +5565,9 @@ fn lock_redact_https() -> Result<()> { { name = "iniconfig" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + [[package]] name = "iniconfig" version = "2.0.0" @@ -5193,6 +5580,17 @@ fn lock_redact_https() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); + // Installing from the lockfile should fail without credentials. uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--index-url").arg("https://pypi-proxy.fly.dev/basic-auth/simple"), @r###" success: false @@ -5319,6 +5717,9 @@ fn lock_redact_git() -> Result<()> { { name = "uv-private-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-private-pypackage", git = "https://github.com/astral-test/uv-private-pypackage" }] + [[package]] name = "uv-private-pypackage" version = "0.1.0" @@ -5405,6 +5806,9 @@ fn lock_relative_index() -> Result<()> { { name = "iniconfig" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + [[package]] name = "iniconfig" version = "2.0.0" @@ -5510,6 +5914,9 @@ fn lock_no_sources() -> Result<()> { { name = "iniconfig" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + [[package]] name = "iniconfig" version = "2.0.0" @@ -5526,10 +5933,25 @@ fn lock_no_sources() -> Result<()> { dependencies = [ { name = "anyio" }, ] + + [package.metadata] + requires-dist = [{ name = "anyio", directory = "anyio" }] "### ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + warning: `uv.sources` is experimental and may change without warning + Resolved 3 packages in [TIME] + "###); + // Lock the root package with `tool.uv.sources` disabled. uv_snapshot!(context.filters(), context.lock().arg("--no-sources"), @r###" success: true @@ -5588,6 +6010,9 @@ fn lock_no_sources() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + requires-dist = [{ name = "anyio" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -5600,6 +6025,17 @@ fn lock_no_sources() -> Result<()> { ); }); + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--no-sources").arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + Ok(()) } @@ -5727,6 +6163,9 @@ fn lock_migrate() -> Result<()> { { name = "anyio" }, ] + [package.metadata] + requires-dist = [{ name = "anyio" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -5825,6 +6264,12 @@ fn lock_upgrade_package() -> Result<()> { { name = "idna" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio", specifier = "<=2" }, + { name = "idna", specifier = "<=3" }, + ] + [[package]] name = "sniffio" version = "1.3.1" @@ -5916,6 +6361,12 @@ fn lock_upgrade_package() -> Result<()> { { name = "idna" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio" }, + { name = "idna" }, + ] + [[package]] name = "sniffio" version = "1.3.1" @@ -5995,6 +6446,12 @@ fn lock_upgrade_package() -> Result<()> { { name = "idna" }, ] + [package.metadata] + requires-dist = [ + { name = "anyio" }, + { name = "idna" }, + ] + [[package]] name = "sniffio" version = "1.3.1" @@ -6131,6 +6588,9 @@ fn lock_find_links_local_wheel() -> Result<()> { { name = "tqdm" }, ] + [package.metadata] + requires-dist = [{ name = "tqdm", specifier = "==1000.0.0" }] + [[package]] name = "tqdm" version = "1000.0.0" @@ -6220,6 +6680,9 @@ fn lock_find_links_local_sdist() -> Result<()> { { name = "tqdm" }, ] + [package.metadata] + requires-dist = [{ name = "tqdm", specifier = "==999.0.0" }] + [[package]] name = "tqdm" version = "999.0.0" @@ -6316,6 +6779,9 @@ fn lock_find_links_http_wheel() -> Result<()> { dependencies = [ { name = "packaging" }, ] + + [package.metadata] + requires-dist = [{ name = "packaging", specifier = "==23.2" }] "### ); }); @@ -6407,6 +6873,9 @@ fn lock_find_links_http_sdist() -> Result<()> { dependencies = [ { name = "packaging" }, ] + + [package.metadata] + requires-dist = [{ name = "packaging", specifier = "==23.2" }] "### ); }); @@ -6519,6 +6988,9 @@ fn lock_local_index() -> Result<()> { { name = "tqdm" }, ] + [package.metadata] + requires-dist = [{ name = "tqdm" }] + [[package]] name = "tqdm" version = "1000.0.0" @@ -6631,6 +7103,9 @@ fn lock_sources_url() -> Result<()> { { name = "workspace" }, ] + [package.metadata] + requires-dist = [{ name = "workspace", url = "https://github.com/user-attachments/files/16592193/workspace.zip" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -6648,6 +7123,9 @@ fn lock_sources_url() -> Result<()> { { name = "anyio" }, ] sdist = { url = "https://github.com/user-attachments/files/16592193/workspace.zip", hash = "sha256:ba690a925dc3d1b53e0675201c9ec26ab59eeec72ab271562f53297bf1817263" } + + [package.metadata] + requires-dist = [{ name = "anyio" }] "### ); }); @@ -6764,6 +7242,9 @@ fn lock_sources_archive() -> Result<()> { { name = "workspace" }, ] + [package.metadata] + requires-dist = [{ name = "workspace", path = "[TEMP_DIR]/workspace.zip" }] + [[package]] name = "sniffio" version = "1.3.1" @@ -6780,6 +7261,9 @@ fn lock_sources_archive() -> Result<()> { dependencies = [ { name = "anyio" }, ] + + [package.metadata] + requires-dist = [{ name = "anyio" }] "### ); }); @@ -6895,6 +7379,9 @@ fn lock_sources_source_tree() -> Result<()> { { name = "workspace" }, ] + [package.metadata] + requires-dist = [{ name = "workspace", directory = "[TEMP_DIR]/workspace" }] + [[package]] name = "workspace" version = "0.1.0" @@ -6902,6 +7389,9 @@ fn lock_sources_source_tree() -> Result<()> { dependencies = [ { name = "anyio" }, ] + + [package.metadata] + requires-dist = [{ name = "anyio", editable = "[TEMP_DIR]/workspace/anyio" }] "### ); }); @@ -7009,6 +7499,12 @@ fn lock_editable() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "leaf", + "workspace", + ] + [[package]] name = "leaf" version = "0.1.0" @@ -7017,6 +7513,9 @@ fn lock_editable() -> Result<()> { { name = "library" }, ] + [package.metadata] + requires-dist = [{ name = "library", directory = "library" }] + [[package]] name = "library" version = "0.1.0" @@ -7029,6 +7528,9 @@ fn lock_editable() -> Result<()> { dependencies = [ { name = "library" }, ] + + [package.metadata] + requires-dist = [{ name = "library", directory = "library" }] "### ); }); @@ -7080,6 +7582,12 @@ fn lock_editable() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "leaf", + "workspace", + ] + [[package]] name = "leaf" version = "0.1.0" @@ -7088,6 +7596,9 @@ fn lock_editable() -> Result<()> { { name = "library" }, ] + [package.metadata] + requires-dist = [{ name = "library", editable = "library" }] + [[package]] name = "library" version = "0.1.0" @@ -7100,6 +7611,9 @@ fn lock_editable() -> Result<()> { dependencies = [ { name = "library" }, ] + + [package.metadata] + requires-dist = [{ name = "library", directory = "library" }] "### ); }); @@ -7229,6 +7743,12 @@ fn lock_mixed_extras() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "leaf1", + "workspace1", + ] + [[package]] name = "iniconfig" version = "2.0.0" @@ -7248,11 +7768,17 @@ fn lock_mixed_extras() -> Result<()> { { name = "iniconfig" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig", marker = "extra == 'async'", specifier = ">=2" }] + [[package]] name = "leaf2" version = "0.1.0" source = { editable = "../workspace2/packages/leaf2" } + [package.metadata] + requires-dist = [{ name = "packaging", marker = "extra == 'async'", specifier = ">=24" }] + [[package]] name = "typing-extensions" version = "4.10.0" @@ -7276,6 +7802,13 @@ fn lock_mixed_extras() -> Result<()> { { name = "typing-extensions" }, ] + [package.metadata] + requires-dist = [ + { name = "leaf1", editable = "packages/leaf1" }, + { name = "workspace2", directory = "../workspace2" }, + { name = "typing-extensions", marker = "extra == 'async'", specifier = ">=4" }, + ] + [[package]] name = "workspace2" version = "0.1.0" @@ -7283,6 +7816,9 @@ fn lock_mixed_extras() -> Result<()> { dependencies = [ { name = "leaf2" }, ] + + [package.metadata] + requires-dist = [{ name = "leaf2", editable = "../workspace2/packages/leaf2" }] "### ); }); @@ -7403,6 +7939,12 @@ fn lock_transitive_extra() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "leaf", + "workspace", + ] + [[package]] name = "iniconfig" version = "2.0.0" @@ -7422,6 +7964,9 @@ fn lock_transitive_extra() -> Result<()> { { name = "iniconfig" }, ] + [package.metadata] + requires-dist = [{ name = "iniconfig", marker = "extra == 'async'", specifier = ">=2" }] + [[package]] name = "typing-extensions" version = "4.10.0" @@ -7445,6 +7990,13 @@ fn lock_transitive_extra() -> Result<()> { { name = "leaf", extra = ["async"] }, { name = "typing-extensions" }, ] + + [package.metadata] + requires-dist = [ + { name = "leaf", editable = "packages/leaf" }, + { name = "typing-extensions", marker = "extra == 'async'", specifier = ">=4" }, + { name = "leaf", extras = ["async"], marker = "extra == 'async'", editable = "packages/leaf" }, + ] "### ); }); @@ -7591,6 +8143,9 @@ fn lock_mismatched_versions() -> Result<()> { { name = "uv-public-pypackage" }, ] + [package.metadata] + requires-dist = [{ name = "uv-public-pypackage", git = "https://github.com/astral-test/uv-public-pypackage?tag=0.0.1" }] + [[package]] name = "uv-public-pypackage" version = "0.1.0" @@ -7718,6 +8273,9 @@ fn lock_change_index() -> Result<()> { dependencies = [ { name = "iniconfig" }, ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] "### ); }); @@ -7763,6 +8321,9 @@ fn lock_change_index() -> Result<()> { dependencies = [ { name = "iniconfig" }, ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] "### ); }); @@ -7780,3 +8341,904 @@ fn lock_change_index() -> Result<()> { Ok(()) } + +/// Lock a `pyproject.toml`, add a remove a workspace member, and ensure that the lockfile is +/// updated on the next run. +#[test] +fn lock_remove_member() -> Result<()> { + let context = TestContext::new("3.12"); + + // Create a workspace member. + let leaf = context.temp_dir.child("leaf"); + leaf.child("pyproject.toml").write_str( + r#" + [project] + name = "leaf" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["anyio>3"] + "#, + )?; + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["leaf"] + + [tool.uv.workspace] + members = ["leaf"] + + [tool.uv.sources] + leaf = { workspace = true } + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + warning: `uv.sources` is experimental and may change without warning + Resolved 5 packages in [TIME] + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [manifest] + members = [ + "leaf", + "project", + ] + + [[package]] + name = "anyio" + version = "4.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 }, + ] + + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] + + [[package]] + name = "leaf" + version = "0.1.0" + source = { editable = "leaf" } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio", specifier = ">3" }] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "leaf" }, + ] + + [package.metadata] + requires-dist = [{ name = "leaf", editable = "leaf" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + warning: `uv.sources` is experimental and may change without warning + Resolved 5 packages in [TIME] + "###); + + // Remove the member. + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + "#, + )?; + + // Re-run with `--locked`. This should fail. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 1 package in [TIME] + error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "###); + + // Re-run without `--locked`. + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 1 package in [TIME] + Removed anyio v4.3.0 + Removed idna v3.6 + Removed leaf v0.1.0 + Removed sniffio v1.3.1 + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + "### + ); + }); + + Ok(()) +} + +/// Lock a `pyproject.toml`, add a workspace member that _isn't_ a dependency of the root, and +/// ensure that the lockfile is updated on the next run. +/// +/// This test would fail if we didn't write the list of workspace members to the lockfile, since +/// we wouldn't be able to determine that a new member was added. +#[test] +fn lock_add_member() -> Result<()> { + let context = TestContext::new("3.12"); + + // Create a workspace member. + let leaf = context.temp_dir.child("leaf"); + leaf.child("pyproject.toml").write_str( + r#" + [project] + name = "leaf" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["anyio>3"] + "#, + )?; + + // Create a workspace, but don't add the member. + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + + [tool.uv.workspace] + members = [] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 1 package in [TIME] + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 1 package in [TIME] + "###); + + // Add the member to the workspace, but not as a dependency of the root. + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + + [tool.uv.workspace] + members = ["leaf"] + "#, + )?; + + // Re-run with `--locked`. This should fail. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 5 packages in [TIME] + error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "###); + + // Re-run without `--locked`. + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 5 packages in [TIME] + Added anyio v4.3.0 + Added idna v3.6 + Added leaf v0.1.0 + Added sniffio v1.3.1 + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [manifest] + members = [ + "leaf", + "project", + ] + + [[package]] + name = "anyio" + version = "4.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 }, + ] + + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] + + [[package]] + name = "leaf" + version = "0.1.0" + source = { editable = "leaf" } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio", specifier = ">3" }] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); + + Ok(()) +} + +/// Lock a `pyproject.toml`, add a new constraint, and ensure that the lockfile is updated on the +/// next run. +#[test] +fn lock_new_constraints() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["anyio"] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [[package]] + name = "anyio" + version = "4.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 }, + ] + + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + + // Add a constraint. + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["anyio"] + + [tool.uv] + constraint-dependencies = [ + "anyio < 4.3", + ] + "#, + )?; + + // Re-run with `--locked`. This should fail. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "###); + + // Re-run without `--locked`. + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + Updated anyio v4.3.0 -> v4.2.0 + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [manifest] + constraints = [{ name = "anyio", specifier = "<4.3" }] + + [[package]] + name = "anyio" + version = "4.2.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/2d/b8/7333d87d5f03247215d86a86362fd3e324111788c6cdd8d2e6196a6ba833/anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f", size = 158770 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/cd/d6d9bb1dadf73e7af02d18225cbd2c93f8552e13130484f1c8dcfece292b/anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee", size = 85481 }, + ] + + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); + + Ok(()) +} + +/// Lock a `pyproject.toml`, add a new constraint, and ensure that the lockfile is updated on the +/// next run. +#[test] +fn lock_remove_member_virtual() -> Result<()> { + let context = TestContext::new("3.12"); + + // Create a virtual workspace root. + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [tool.uv.workspace] + members = ["leaf"] + "#, + )?; + + // Create a workspace member. + let leaf = context.temp_dir.child("leaf"); + leaf.child("pyproject.toml").write_str( + r#" + [project] + name = "leaf" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["anyio>3"] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [manifest] + members = [ + "leaf", + ] + + [[package]] + name = "anyio" + version = "4.3.0" + source = { registry = "https://pypi.org/simple" } + dependencies = [ + { name = "idna" }, + { name = "sniffio" }, + ] + sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 }, + ] + + [[package]] + name = "idna" + version = "3.6" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", size = 175426 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f", size = 61567 }, + ] + + [[package]] + name = "leaf" + version = "0.1.0" + source = { editable = "leaf" } + dependencies = [ + { name = "anyio" }, + ] + + [package.metadata] + requires-dist = [{ name = "anyio", specifier = ">3" }] + + [[package]] + name = "sniffio" + version = "1.3.1" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + ] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 4 packages in [TIME] + "###); + + // Remove the member. + pyproject_toml.write_str( + r" + [tool.uv.workspace] + members = [] + ", + )?; + + // Re-run with `--locked`. This should fail. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 0 packages in [TIME] + error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "###); + + // Re-run without `--locked`. + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 0 packages in [TIME] + Removed anyio v4.3.0 + Removed idna v3.6 + Removed leaf v0.1.0 + Removed sniffio v1.3.1 + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + "### + ); + }); + + Ok(()) +} + +/// Lock a `pyproject.toml`, then rename the project, and ensure that the lockfile is updated on +/// the next run. +#[test] +fn lock_rename_project() -> Result<()> { + let context = TestContext::new("3.12"); + + // Create a workspace, but don't add the member. + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["iniconfig"] + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [[package]] + name = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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" }, + ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + "### + ); + }); + + // Re-run with `--locked`. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + "###); + + // Rename the project. + pyproject_toml.write_str( + r#" + [project] + name = "renamed" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = ["iniconfig"] + "#, + )?; + + // Re-run with `--locked`. This should fail. + uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`. + "###); + + // Re-run without `--locked`. + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Resolved 2 packages in [TIME] + Removed project v0.1.0 + Added renamed v0.1.0 + "###); + + let lock = fs_err::read_to_string(context.temp_dir.join("uv.lock")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + + [options] + exclude-newer = "2024-03-25 00:00:00 UTC" + + [[package]] + name = "iniconfig" + version = "2.0.0" + source = { registry = "https://pypi.org/simple" } + 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 = "renamed" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "iniconfig" }, + ] + + [package.metadata] + requires-dist = [{ name = "iniconfig" }] + "### + ); + }); + + Ok(()) +} diff --git a/crates/uv/tests/lock_scenarios.rs b/crates/uv/tests/lock_scenarios.rs index f6972bdc9..ba92bd67c 100644 --- a/crates/uv/tests/lock_scenarios.rs +++ b/crates/uv/tests/lock_scenarios.rs @@ -108,13 +108,34 @@ fn fork_allows_non_conflicting_non_overlapping_dependencies() -> Result<()> { dependencies = [ { name = "package-a", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=1" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -216,13 +237,34 @@ fn fork_allows_non_conflicting_repeated_dependencies() -> Result<()> { dependencies = [ { name = "package-a" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", specifier = ">=1" }, + { name = "package-a", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -332,13 +374,34 @@ fn fork_basic() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -667,13 +730,36 @@ fn fork_filter_sibling_dependencies() -> Result<()> { { name = "package-b", marker = "sys_platform == 'linux'" }, { name = "package-c", marker = "sys_platform == 'darwin'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = "==4.4.0" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "==4.3.0" }, + { name = "package-b", marker = "sys_platform == 'linux'", specifier = "==1.0.0" }, + { name = "package-c", marker = "sys_platform == 'darwin'", specifier = "==1.0.0" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -780,13 +866,31 @@ fn fork_upgrade() -> Result<()> { dependencies = [ { name = "package-foo" }, ] + + [package.metadata] + requires-dist = [{ name = "package-foo" }] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -930,13 +1034,35 @@ fn fork_incomplete_markers() -> Result<()> { { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "python_version >= '3.11'" }, { name = "package-b" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "python_version < '3.10'", specifier = "==1" }, + { name = "package-a", marker = "python_version >= '3.11'", specifier = "==2" }, + { name = "package-b" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -1060,13 +1186,34 @@ fn fork_marker_accrue() -> Result<()> { { name = "package-a", marker = "implementation_name == 'cpython'" }, { name = "package-b", marker = "implementation_name == 'pypy'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "implementation_name == 'cpython'", specifier = "==1.0.0" }, + { name = "package-b", marker = "implementation_name == 'pypy'", specifier = "==1.0.0" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -1301,13 +1448,34 @@ fn fork_marker_inherit_combined_allowed() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -1465,13 +1633,34 @@ fn fork_marker_inherit_combined_disallowed() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -1630,13 +1819,34 @@ fn fork_marker_inherit_combined() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -1768,13 +1978,34 @@ fn fork_marker_inherit_isolated() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -1924,13 +2155,34 @@ fn fork_marker_inherit_transitive() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -2052,13 +2304,34 @@ fn fork_marker_inherit() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -2208,13 +2481,35 @@ fn fork_marker_limited_inherit() -> Result<()> { { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, { name = "package-b" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'darwin'", specifier = "<2" }, + { name = "package-b" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -2346,13 +2641,35 @@ fn fork_marker_selection() -> Result<()> { { name = "package-b", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-b", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a" }, + { name = "package-b", marker = "sys_platform == 'linux'", specifier = ">=2" }, + { name = "package-b", marker = "sys_platform == 'darwin'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -2508,13 +2825,35 @@ fn fork_marker_track() -> Result<()> { { name = "package-b", version = "2.7", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'darwin'" }, { name = "package-b", version = "2.8", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a" }, + { name = "package-b", marker = "sys_platform == 'linux'", specifier = ">=2.8" }, + { name = "package-b", marker = "sys_platform == 'darwin'", specifier = "<2.8" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -2637,13 +2976,34 @@ fn fork_non_fork_marker_transitive() -> Result<()> { { name = "package-a" }, { name = "package-b" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", specifier = "==1.0.0" }, + { name = "package-b", specifier = "==1.0.0" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -2916,13 +3276,35 @@ fn fork_overlapping_markers_basic() -> Result<()> { dependencies = [ { name = "package-a" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "python_version < '3.10'", specifier = ">=1.0.0" }, + { name = "package-a", marker = "python_version >= '3.10'", specifier = ">=1.1.0" }, + { name = "package-a", marker = "python_version >= '3.11'", specifier = ">=1.2.0" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -3155,13 +3537,31 @@ fn preferences_dependent_forking_bistable() -> Result<()> { dependencies = [ { name = "package-cleaver" }, ] + + [package.metadata] + requires-dist = [{ name = "package-cleaver" }] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -3577,13 +3977,35 @@ fn preferences_dependent_forking_tristable() -> Result<()> { { name = "package-cleaver" }, { name = "package-foo" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-cleaver" }, + { name = "package-foo" }, + { name = "package-bar" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -3773,13 +4195,35 @@ fn preferences_dependent_forking() -> Result<()> { { name = "package-cleaver" }, { name = "package-foo" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-cleaver" }, + { name = "package-foo" }, + { name = "package-bar" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -3951,13 +4395,34 @@ fn fork_remaining_universe_partitioning() -> Result<()> { { name = "package-a", version = "1.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'illumos'" }, { name = "package-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'windows'" }, ] + + [package.metadata] + requires-dist = [ + { name = "package-a", marker = "sys_platform == 'windows'", specifier = ">=2" }, + { name = "package-a", marker = "sys_platform == 'illumos'", specifier = "<2" }, + ] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -4034,13 +4499,31 @@ fn fork_requires_python_full_prerelease() -> Result<()> { name = "project" version = "0.1.0" source = { editable = "." } + + [package.metadata] + requires-dist = [{ name = "package-a", marker = "python_full_version == '3.9'", specifier = "==1.0.0" }] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -4117,13 +4600,31 @@ fn fork_requires_python_full() -> Result<()> { name = "project" version = "0.1.0" source = { editable = "." } + + [package.metadata] + requires-dist = [{ name = "package-a", marker = "python_full_version == '3.9'", specifier = "==1.0.0" }] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -4216,13 +4717,31 @@ fn fork_requires_python_patch_overlap() -> Result<()> { dependencies = [ { name = "package-a", marker = "python_version == '3.10'" }, ] + + [package.metadata] + requires-dist = [{ name = "package-a", marker = "python_version == '3.10'", specifier = "==1.0.0" }] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -4296,13 +4815,31 @@ fn fork_requires_python() -> Result<()> { name = "project" version = "0.1.0" source = { editable = "." } + + [package.metadata] + requires-dist = [{ name = "package-a", marker = "python_version == '3.9'", specifier = "==1.0.0" }] "### ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) diff --git a/crates/uv/tests/snapshots/ecosystem__black-lock-file.snap b/crates/uv/tests/snapshots/ecosystem__black-lock-file.snap index 73476b2c0..1161ffa49 100644 --- a/crates/uv/tests/snapshots/ecosystem__black-lock-file.snap +++ b/crates/uv/tests/snapshots/ecosystem__black-lock-file.snap @@ -202,6 +202,23 @@ uvloop = [ { name = "uvloop" }, ] +[package.metadata] +requires-dist = [ + { name = "click", specifier = ">=8.0.0" }, + { name = "mypy-extensions", specifier = ">=0.4.3" }, + { name = "packaging", specifier = ">=22.0" }, + { name = "pathspec", specifier = ">=0.9.0" }, + { name = "platformdirs", specifier = ">=2" }, + { name = "tomli", marker = "python_version < '3.11'", specifier = ">=1.1.0" }, + { name = "typing-extensions", marker = "python_version < '3.11'", specifier = ">=4.0.1" }, + { name = "colorama", marker = "extra == 'colorama'", specifier = ">=0.4.3" }, + { name = "aiohttp", marker = "implementation_name == 'pypy' and sys_platform == 'win32' and extra == 'd'", specifier = "!=3.9.0,>=3.7.4" }, + { name = "aiohttp", marker = "(implementation_name != 'pypy' and extra == 'd') or (sys_platform != 'win32' and extra == 'd')", specifier = ">=3.7.4" }, + { name = "ipython", marker = "extra == 'jupyter'", specifier = ">=7.8.0" }, + { name = "tokenize-rt", marker = "extra == 'jupyter'", specifier = ">=3.2.0" }, + { name = "uvloop", marker = "extra == 'uvloop'", specifier = ">=0.15.2" }, +] + [[package]] name = "click" version = "8.1.7" diff --git a/crates/uv/tests/snapshots/ecosystem__github-wikidata-bot-lock-file.snap b/crates/uv/tests/snapshots/ecosystem__github-wikidata-bot-lock-file.snap index 93c218a87..750256239 100644 --- a/crates/uv/tests/snapshots/ecosystem__github-wikidata-bot-lock-file.snap +++ b/crates/uv/tests/snapshots/ecosystem__github-wikidata-bot-lock-file.snap @@ -125,6 +125,25 @@ dev = [ { name = "types-requests" }, ] +[package.metadata] +requires-dist = [ + { name = "cachecontrol", extras = ["filecache"], specifier = ">=0.14,<0.15" }, + { name = "mwparserfromhell", specifier = ">=0.6.4,<0.7" }, + { name = "pydantic", specifier = ">=2.7.1" }, + { name = "pywikibot", specifier = ">=9.1.2,<10" }, + { name = "sentry-sdk", specifier = ">=2.0.1,<3" }, + { name = "yarl", specifier = ">=1.9,<2" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "httpx", specifier = ">=0.27.0,<0.28" }, + { name = "pytest", specifier = ">=8.0.0,<9" }, + { name = "ruff", specifier = ">=0.5.0,<0.6" }, + { name = "tqdm", specifier = ">=4.66.4,<4.67" }, + { name = "types-requests", specifier = ">=2.31.0.20240406,<3" }, +] + [[package]] name = "h11" version = "0.14.0" diff --git a/crates/uv/tests/snapshots/ecosystem__home-assistant-core-lock-file.snap b/crates/uv/tests/snapshots/ecosystem__home-assistant-core-lock-file.snap index f1a7dcdb6..2d17ec2d2 100644 --- a/crates/uv/tests/snapshots/ecosystem__home-assistant-core-lock-file.snap +++ b/crates/uv/tests/snapshots/ecosystem__home-assistant-core-lock-file.snap @@ -662,6 +662,49 @@ dependencies = [ { name = "yarl" }, ] +[package.metadata] +requires-dist = [ + { name = "aiodns", specifier = "==3.2.0" }, + { name = "aiohttp", specifier = "==3.9.5" }, + { name = "aiohttp-cors", specifier = "==0.7.0" }, + { name = "aiohttp-fast-url-dispatcher", specifier = "==0.3.0" }, + { name = "aiohttp-fast-zlib", specifier = "==0.1.0" }, + { name = "aiozoneinfo", specifier = "==0.2.0" }, + { name = "astral", specifier = "==2.2" }, + { name = "async-interrupt", specifier = "==1.1.1" }, + { name = "attrs", specifier = "==23.2.0" }, + { name = "atomicwrites-homeassistant", specifier = "==1.4.1" }, + { name = "awesomeversion", specifier = "==24.2.0" }, + { name = "bcrypt", specifier = "==4.1.2" }, + { name = "certifi", specifier = ">=2021.5.30" }, + { name = "ciso8601", specifier = "==2.3.1" }, + { name = "fnv-hash-fast", specifier = "==0.5.0" }, + { name = "hass-nabucasa", specifier = "==0.81.1" }, + { name = "httpx", specifier = "==0.27.0" }, + { name = "home-assistant-bluetooth", specifier = "==1.12.1" }, + { name = "ifaddr", specifier = "==0.2.0" }, + { name = "jinja2", specifier = "==3.1.4" }, + { name = "lru-dict", specifier = "==1.3.0" }, + { name = "pyjwt", specifier = "==2.8.0" }, + { name = "cryptography", specifier = "==42.0.8" }, + { name = "pillow", specifier = "==10.3.0" }, + { name = "pyopenssl", specifier = "==24.1.0" }, + { name = "orjson", specifier = "==3.9.15" }, + { name = "packaging", specifier = ">=23.1" }, + { name = "pip", specifier = ">=21.3.1" }, + { name = "psutil-home-assistant", specifier = "==0.0.1" }, + { name = "python-slugify", specifier = "==8.0.4" }, + { name = "pyyaml", specifier = "==6.0.1" }, + { name = "requests", specifier = "==2.32.3" }, + { name = "sqlalchemy", specifier = "==2.0.31" }, + { name = "typing-extensions", specifier = ">=4.12.2,<5.0" }, + { name = "ulid-transform", specifier = "==0.9.0" }, + { name = "urllib3", specifier = ">=1.26.5,<2" }, + { name = "voluptuous", specifier = "==0.13.1" }, + { name = "voluptuous-serialize", specifier = "==2.6.0" }, + { name = "yarl", specifier = "==1.9.4" }, +] + [[package]] name = "httpcore" version = "1.0.5" diff --git a/crates/uv/tests/snapshots/ecosystem__packse-lock-file.snap b/crates/uv/tests/snapshots/ecosystem__packse-lock-file.snap index b2d017ecd..f37eed066 100644 --- a/crates/uv/tests/snapshots/ecosystem__packse-lock-file.snap +++ b/crates/uv/tests/snapshots/ecosystem__packse-lock-file.snap @@ -353,6 +353,26 @@ dev = [ { name = "syrupy" }, ] +[package.metadata] +requires-dist = [ + { name = "msgspec", specifier = ">=0.18.4" }, + { name = "twine", specifier = ">=4.0.2" }, + { name = "hatchling", specifier = ">=1.20.0" }, + { name = "chevron-blue", specifier = ">=0.2.1" }, + { name = "setuptools", specifier = ">=69.1.1" }, + { name = "pyyaml", specifier = ">=6.0.1" }, + { name = "pypiserver", marker = "extra == 'index'", specifier = ">=2.0.1" }, + { name = "packse", extras = ["index"], marker = "extra == 'serve'" }, + { name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "syrupy", specifier = ">=4.6.0" }, + { name = "pytest", specifier = ">=7.4.3" }, + { name = "psutil", specifier = ">=5.9.7" }, +] + [[package]] name = "pathspec" version = "0.12.1" diff --git a/crates/uv/tests/snapshots/ecosystem__transformers-lock-file.snap b/crates/uv/tests/snapshots/ecosystem__transformers-lock-file.snap index b8e142b9c..0a3bbf2ea 100644 --- a/crates/uv/tests/snapshots/ecosystem__transformers-lock-file.snap +++ b/crates/uv/tests/snapshots/ecosystem__transformers-lock-file.snap @@ -5866,6 +5866,280 @@ vision = [ { name = "pillow" }, ] +[package.metadata] +requires-dist = [ + { name = "filelock" }, + { name = "huggingface-hub", specifier = ">=0.19.3,<1.0" }, + { name = "numpy", specifier = ">=1.17" }, + { name = "packaging", specifier = ">=20.0" }, + { name = "pyyaml", specifier = ">=5.1" }, + { name = "regex", specifier = "!=2019.12.17" }, + { name = "requests" }, + { name = "tokenizers", specifier = ">=0.14,<0.19" }, + { name = "safetensors", specifier = ">=0.4.1" }, + { name = "tqdm", specifier = ">=4.27" }, + { name = "fugashi", marker = "extra == 'ja'", specifier = ">=1.0" }, + { name = "ipadic", marker = "extra == 'ja'", specifier = ">=1.0.0,<2.0" }, + { name = "unidic-lite", marker = "extra == 'ja'", specifier = ">=1.0.7" }, + { name = "unidic", marker = "extra == 'ja'", specifier = ">=1.0.2" }, + { name = "sudachipy", marker = "extra == 'ja'", specifier = ">=0.6.6" }, + { name = "sudachidict-core", marker = "extra == 'ja'", specifier = ">=20220729" }, + { name = "rhoknp", marker = "extra == 'ja'", specifier = ">=1.1.0,<1.3.1" }, + { name = "scikit-learn", marker = "extra == 'sklearn'" }, + { name = "tensorflow", marker = "extra == 'tf'", specifier = ">=2.6,<2.16" }, + { name = "onnxconverter-common", marker = "extra == 'tf'" }, + { name = "tf2onnx", marker = "extra == 'tf'" }, + { name = "tensorflow-text", marker = "extra == 'tf'", specifier = "<2.16" }, + { name = "keras-nlp", marker = "extra == 'tf'", specifier = ">=0.3.1" }, + { name = "tensorflow-cpu", marker = "extra == 'tf-cpu'", specifier = ">=2.6,<2.16" }, + { name = "onnxconverter-common", marker = "extra == 'tf-cpu'" }, + { name = "tf2onnx", marker = "extra == 'tf-cpu'" }, + { name = "tensorflow-text", marker = "extra == 'tf-cpu'", specifier = "<2.16" }, + { name = "keras-nlp", marker = "extra == 'tf-cpu'", specifier = ">=0.3.1" }, + { name = "torch", marker = "extra == 'torch'" }, + { name = "accelerate", marker = "extra == 'torch'", specifier = ">=0.21.0" }, + { name = "accelerate", marker = "extra == 'accelerate'", specifier = ">=0.21.0" }, + { name = "faiss-cpu", marker = "extra == 'retrieval'" }, + { name = "datasets", marker = "extra == 'retrieval'", specifier = "!=2.5.0" }, + { name = "jax", marker = "extra == 'flax'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "jaxlib", marker = "extra == 'flax'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "flax", marker = "extra == 'flax'", specifier = ">=0.4.1,<=0.7.0" }, + { name = "optax", marker = "extra == 'flax'", specifier = ">=0.0.8,<=0.1.4" }, + { name = "tokenizers", marker = "extra == 'tokenizers'", specifier = ">=0.14,<0.19" }, + { name = "ftfy", marker = "extra == 'ftfy'" }, + { name = "onnxruntime", marker = "extra == 'onnxruntime'", specifier = ">=1.4.0" }, + { name = "onnxruntime-tools", marker = "extra == 'onnxruntime'", specifier = ">=1.4.2" }, + { name = "onnxconverter-common", marker = "extra == 'onnx'" }, + { name = "tf2onnx", marker = "extra == 'onnx'" }, + { name = "onnxruntime", marker = "extra == 'onnx'", specifier = ">=1.4.0" }, + { name = "onnxruntime-tools", marker = "extra == 'onnx'", specifier = ">=1.4.2" }, + { name = "cookiecutter", marker = "extra == 'modelcreation'", specifier = "==1.7.3" }, + { name = "sagemaker", marker = "extra == 'sagemaker'", specifier = "==2.226.1" }, + { name = "deepspeed", marker = "extra == 'deepspeed'", specifier = ">=0.9.3" }, + { name = "accelerate", marker = "extra == 'deepspeed'", specifier = ">=0.21.0" }, + { name = "optuna", marker = "extra == 'optuna'" }, + { name = "ray", extras = ["tune"], marker = "extra == 'ray'", specifier = ">=2.7.0" }, + { name = "sigopt", marker = "extra == 'sigopt'" }, + { name = "optuna", marker = "extra == 'integrations'" }, + { name = "ray", extras = ["tune"], marker = "extra == 'integrations'", specifier = ">=2.7.0" }, + { name = "sigopt", marker = "extra == 'integrations'" }, + { name = "pydantic", marker = "extra == 'serving'" }, + { name = "uvicorn", marker = "extra == 'serving'" }, + { name = "fastapi", marker = "extra == 'serving'" }, + { name = "starlette", marker = "extra == 'serving'" }, + { name = "librosa", marker = "extra == 'audio'" }, + { name = "pyctcdecode", marker = "extra == 'audio'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'audio'" }, + { name = "kenlm", marker = "extra == 'audio'" }, + { name = "torchaudio", marker = "extra == 'speech'" }, + { name = "librosa", marker = "extra == 'speech'" }, + { name = "pyctcdecode", marker = "extra == 'speech'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'speech'" }, + { name = "kenlm", marker = "extra == 'speech'" }, + { name = "torchaudio", marker = "extra == 'torch-speech'" }, + { name = "librosa", marker = "extra == 'torch-speech'" }, + { name = "pyctcdecode", marker = "extra == 'torch-speech'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'torch-speech'" }, + { name = "kenlm", marker = "extra == 'torch-speech'" }, + { name = "librosa", marker = "extra == 'tf-speech'" }, + { name = "pyctcdecode", marker = "extra == 'tf-speech'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'tf-speech'" }, + { name = "kenlm", marker = "extra == 'tf-speech'" }, + { name = "librosa", marker = "extra == 'flax-speech'" }, + { name = "pyctcdecode", marker = "extra == 'flax-speech'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'flax-speech'" }, + { name = "kenlm", marker = "extra == 'flax-speech'" }, + { name = "pillow", marker = "extra == 'vision'", specifier = ">=10.0.1,<=15.0" }, + { name = "timm", marker = "extra == 'timm'" }, + { name = "torchvision", marker = "extra == 'torch-vision'" }, + { name = "pillow", marker = "extra == 'torch-vision'", specifier = ">=10.0.1,<=15.0" }, + { name = "codecarbon", marker = "extra == 'codecarbon'", specifier = "==1.2.0" }, + { name = "decord", marker = "extra == 'video'", specifier = "==0.6.0" }, + { name = "av", marker = "extra == 'video'", specifier = "==9.2.0" }, + { name = "sentencepiece", marker = "extra == 'sentencepiece'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "protobuf", marker = "extra == 'sentencepiece'" }, + { name = "deepspeed", marker = "extra == 'deepspeed-testing'", specifier = ">=0.9.3" }, + { name = "accelerate", marker = "extra == 'deepspeed-testing'", specifier = ">=0.21.0" }, + { name = "pytest", marker = "extra == 'deepspeed-testing'", specifier = ">=7.2.0,<8.0.0" }, + { name = "pytest-xdist", marker = "extra == 'deepspeed-testing'" }, + { name = "timeout-decorator", marker = "extra == 'deepspeed-testing'" }, + { name = "parameterized", marker = "extra == 'deepspeed-testing'" }, + { name = "psutil", marker = "extra == 'deepspeed-testing'" }, + { name = "datasets", marker = "extra == 'deepspeed-testing'", specifier = "!=2.5.0" }, + { name = "dill", marker = "extra == 'deepspeed-testing'", specifier = "<0.3.5" }, + { name = "evaluate", marker = "extra == 'deepspeed-testing'", specifier = ">=0.2.0" }, + { name = "pytest-timeout", marker = "extra == 'deepspeed-testing'" }, + { name = "ruff", marker = "extra == 'deepspeed-testing'", specifier = "==0.1.5" }, + { name = "sacrebleu", marker = "extra == 'deepspeed-testing'", specifier = ">=1.4.12,<2.0.0" }, + { name = "rouge-score", marker = "extra == 'deepspeed-testing'", specifier = "!=0.0.7,!=0.0.8,!=0.1,!=0.1.1" }, + { name = "nltk", marker = "extra == 'deepspeed-testing'" }, + { name = "gitpython", marker = "extra == 'deepspeed-testing'", specifier = "<3.1.19" }, + { name = "hf-doc-builder", marker = "extra == 'deepspeed-testing'", specifier = ">=0.3.0" }, + { name = "protobuf", marker = "extra == 'deepspeed-testing'" }, + { name = "sacremoses", marker = "extra == 'deepspeed-testing'" }, + { name = "rjieba", marker = "extra == 'deepspeed-testing'" }, + { name = "beautifulsoup4", marker = "extra == 'deepspeed-testing'" }, + { name = "tensorboard", marker = "extra == 'deepspeed-testing'" }, + { name = "pydantic", marker = "extra == 'deepspeed-testing'" }, + { name = "faiss-cpu", marker = "extra == 'deepspeed-testing'" }, + { name = "datasets", marker = "extra == 'deepspeed-testing'", specifier = "!=2.5.0" }, + { name = "cookiecutter", marker = "extra == 'deepspeed-testing'", specifier = "==1.7.3" }, + { name = "optuna", marker = "extra == 'deepspeed-testing'" }, + { name = "sentencepiece", marker = "extra == 'deepspeed-testing'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "protobuf", marker = "extra == 'deepspeed-testing'" }, + { name = "datasets", marker = "extra == 'quality'", specifier = "!=2.5.0" }, + { name = "isort", marker = "extra == 'quality'", specifier = ">=5.5.4" }, + { name = "ruff", marker = "extra == 'quality'", specifier = "==0.1.5" }, + { name = "gitpython", marker = "extra == 'quality'", specifier = "<3.1.19" }, + { name = "hf-doc-builder", marker = "extra == 'quality'", specifier = ">=0.3.0" }, + { name = "urllib3", marker = "extra == 'quality'", specifier = "<2.0.0" }, + { name = "tensorflow", marker = "extra == 'all'", specifier = ">=2.6,<2.16" }, + { name = "onnxconverter-common", marker = "extra == 'all'" }, + { name = "tf2onnx", marker = "extra == 'all'" }, + { name = "tensorflow-text", marker = "extra == 'all'", specifier = "<2.16" }, + { name = "keras-nlp", marker = "extra == 'all'", specifier = ">=0.3.1" }, + { name = "torch", marker = "extra == 'all'" }, + { name = "accelerate", marker = "extra == 'all'", specifier = ">=0.21.0" }, + { name = "jax", marker = "extra == 'all'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "jaxlib", marker = "extra == 'all'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "flax", marker = "extra == 'all'", specifier = ">=0.4.1,<=0.7.0" }, + { name = "optax", marker = "extra == 'all'", specifier = ">=0.0.8,<=0.1.4" }, + { name = "sentencepiece", marker = "extra == 'all'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "protobuf", marker = "extra == 'all'" }, + { name = "tokenizers", marker = "extra == 'all'", specifier = ">=0.14,<0.19" }, + { name = "torchaudio", marker = "extra == 'all'" }, + { name = "librosa", marker = "extra == 'all'" }, + { name = "pyctcdecode", marker = "extra == 'all'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'all'" }, + { name = "kenlm", marker = "extra == 'all'" }, + { name = "pillow", marker = "extra == 'all'", specifier = ">=10.0.1,<=15.0" }, + { name = "optuna", marker = "extra == 'all'" }, + { name = "ray", extras = ["tune"], marker = "extra == 'all'", specifier = ">=2.7.0" }, + { name = "sigopt", marker = "extra == 'all'" }, + { name = "timm", marker = "extra == 'all'" }, + { name = "torchvision", marker = "extra == 'all'" }, + { name = "pillow", marker = "extra == 'all'", specifier = ">=10.0.1,<=15.0" }, + { name = "codecarbon", marker = "extra == 'all'", specifier = "==1.2.0" }, + { name = "accelerate", marker = "extra == 'all'", specifier = ">=0.21.0" }, + { name = "decord", marker = "extra == 'all'", specifier = "==0.6.0" }, + { name = "av", marker = "extra == 'all'", specifier = "==9.2.0" }, + { name = "hf-doc-builder", marker = "extra == 'docs-specific'" }, + { name = "tensorflow", marker = "extra == 'docs'", specifier = ">=2.6,<2.16" }, + { name = "onnxconverter-common", marker = "extra == 'docs'" }, + { name = "tf2onnx", marker = "extra == 'docs'" }, + { name = "tensorflow-text", marker = "extra == 'docs'", specifier = "<2.16" }, + { name = "keras-nlp", marker = "extra == 'docs'", specifier = ">=0.3.1" }, + { name = "torch", marker = "extra == 'docs'" }, + { name = "accelerate", marker = "extra == 'docs'", specifier = ">=0.21.0" }, + { name = "jax", marker = "extra == 'docs'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "jaxlib", marker = "extra == 'docs'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "flax", marker = "extra == 'docs'", specifier = ">=0.4.1,<=0.7.0" }, + { name = "optax", marker = "extra == 'docs'", specifier = ">=0.0.8,<=0.1.4" }, + { name = "sentencepiece", marker = "extra == 'docs'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "protobuf", marker = "extra == 'docs'" }, + { name = "tokenizers", marker = "extra == 'docs'", specifier = ">=0.14,<0.19" }, + { name = "torchaudio", marker = "extra == 'docs'" }, + { name = "librosa", marker = "extra == 'docs'" }, + { name = "pyctcdecode", marker = "extra == 'docs'", specifier = ">=0.4.0" }, + { name = "phonemizer", marker = "extra == 'docs'" }, + { name = "kenlm", marker = "extra == 'docs'" }, + { name = "pillow", marker = "extra == 'docs'", specifier = ">=10.0.1,<=15.0" }, + { name = "optuna", marker = "extra == 'docs'" }, + { name = "ray", extras = ["tune"], marker = "extra == 'docs'", specifier = ">=2.7.0" }, + { name = "sigopt", marker = "extra == 'docs'" }, + { name = "timm", marker = "extra == 'docs'" }, + { name = "torchvision", marker = "extra == 'docs'" }, + { name = "pillow", marker = "extra == 'docs'", specifier = ">=10.0.1,<=15.0" }, + { name = "codecarbon", marker = "extra == 'docs'", specifier = "==1.2.0" }, + { name = "accelerate", marker = "extra == 'docs'", specifier = ">=0.21.0" }, + { name = "decord", marker = "extra == 'docs'", specifier = "==0.6.0" }, + { name = "av", marker = "extra == 'docs'", specifier = "==9.2.0" }, + { name = "hf-doc-builder", marker = "extra == 'docs'" }, + { name = "filelock", marker = "extra == 'torchhub'" }, + { name = "huggingface-hub", marker = "extra == 'torchhub'", specifier = ">=0.19.3,<1.0" }, + { name = "importlib-metadata", marker = "extra == 'torchhub'" }, + { name = "numpy", marker = "extra == 'torchhub'", specifier = ">=1.17" }, + { name = "packaging", marker = "extra == 'torchhub'", specifier = ">=20.0" }, + { name = "protobuf", marker = "extra == 'torchhub'" }, + { name = "regex", marker = "extra == 'torchhub'", specifier = "!=2019.12.17" }, + { name = "requests", marker = "extra == 'torchhub'" }, + { name = "sentencepiece", marker = "extra == 'torchhub'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "torch", marker = "extra == 'torchhub'" }, + { name = "tokenizers", marker = "extra == 'torchhub'", specifier = ">=0.14,<0.19" }, + { name = "tqdm", marker = "extra == 'torchhub'", specifier = ">=4.27" }, + { name = "diffusers", marker = "extra == 'agents'" }, + { name = "accelerate", marker = "extra == 'agents'", specifier = ">=0.21.0" }, + { name = "datasets", marker = "extra == 'agents'", specifier = "!=2.5.0" }, + { name = "torch", marker = "extra == 'agents'" }, + { name = "sentencepiece", marker = "extra == 'agents'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "opencv-python", marker = "extra == 'agents'" }, + { name = "pillow", marker = "extra == 'agents'", specifier = ">=10.0.1,<=15.0" }, + { name = "gitpython", marker = "extra == 'dev-dependencies'", specifier = "<3.1.19" }, + { name = "pillow", marker = "extra == 'dev-dependencies'", specifier = ">=10.0.1,<=15.0" }, + { name = "accelerate", marker = "extra == 'dev-dependencies'", specifier = ">=0.21.0" }, + { name = "av", marker = "extra == 'dev-dependencies'", specifier = "==9.2.0" }, + { name = "beautifulsoup4", marker = "extra == 'dev-dependencies'" }, + { name = "codecarbon", marker = "extra == 'dev-dependencies'", specifier = "==1.2.0" }, + { name = "codecarbon", marker = "extra == 'dev-dependencies'", specifier = "==1.2.0" }, + { name = "cookiecutter", marker = "extra == 'dev-dependencies'", specifier = "==1.7.3" }, + { name = "datasets", marker = "extra == 'dev-dependencies'", specifier = "!=2.5.0" }, + { name = "decord", marker = "extra == 'dev-dependencies'", specifier = "==0.6.0" }, + { name = "dill", marker = "extra == 'dev-dependencies'", specifier = "<0.3.5" }, + { name = "evaluate", marker = "extra == 'dev-dependencies'", specifier = ">=0.2.0" }, + { name = "faiss-cpu", marker = "extra == 'dev-dependencies'" }, + { name = "flax", marker = "extra == 'dev-dependencies'", specifier = ">=0.4.1,<=0.7.0" }, + { name = "fugashi", marker = "extra == 'dev-dependencies'", specifier = ">=1.0" }, + { name = "hf-doc-builder", marker = "extra == 'dev-dependencies'" }, + { name = "hf-doc-builder", marker = "extra == 'dev-dependencies'", specifier = ">=0.3.0" }, + { name = "ipadic", marker = "extra == 'dev-dependencies'", specifier = ">=1.0.0,<2.0" }, + { name = "isort", marker = "extra == 'dev-dependencies'", specifier = ">=5.5.4" }, + { name = "jax", marker = "extra == 'dev-dependencies'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "jaxlib", marker = "extra == 'dev-dependencies'", specifier = ">=0.4.1,<=0.4.13" }, + { name = "kenlm", marker = "extra == 'dev-dependencies'" }, + { name = "keras-nlp", marker = "extra == 'dev-dependencies'", specifier = ">=0.3.1" }, + { name = "librosa", marker = "extra == 'dev-dependencies'" }, + { name = "nltk", marker = "extra == 'dev-dependencies'" }, + { name = "onnxconverter-common", marker = "extra == 'dev-dependencies'" }, + { name = "onnxruntime-tools", marker = "extra == 'dev-dependencies'", specifier = ">=1.4.2" }, + { name = "onnxruntime", marker = "extra == 'dev-dependencies'", specifier = ">=1.4.0" }, + { name = "optax", marker = "extra == 'dev-dependencies'", specifier = ">=0.0.8,<=0.1.4" }, + { name = "optuna", marker = "extra == 'dev-dependencies'" }, + { name = "parameterized", marker = "extra == 'dev-dependencies'" }, + { name = "phonemizer", marker = "extra == 'dev-dependencies'" }, + { name = "protobuf", marker = "extra == 'dev-dependencies'" }, + { name = "psutil", marker = "extra == 'dev-dependencies'" }, + { name = "pyctcdecode", marker = "extra == 'dev-dependencies'", specifier = ">=0.4.0" }, + { name = "pydantic", marker = "extra == 'dev-dependencies'" }, + { name = "pytest-timeout", marker = "extra == 'dev-dependencies'" }, + { name = "pytest-xdist", marker = "extra == 'dev-dependencies'" }, + { name = "pytest", marker = "extra == 'dev-dependencies'", specifier = ">=7.2.0,<8.0.0" }, + { name = "ray", extras = ["tune"], marker = "extra == 'dev-dependencies'", specifier = ">=2.7.0" }, + { name = "rhoknp", marker = "extra == 'dev-dependencies'", specifier = ">=1.1.0,<1.3.1" }, + { name = "rjieba", marker = "extra == 'dev-dependencies'" }, + { name = "rouge-score", marker = "extra == 'dev-dependencies'", specifier = "!=0.0.7,!=0.0.8,!=0.1,!=0.1.1" }, + { name = "ruff", marker = "extra == 'dev-dependencies'", specifier = "==0.1.5" }, + { name = "sacrebleu", marker = "extra == 'dev-dependencies'", specifier = ">=1.4.12,<2.0.0" }, + { name = "sacremoses", marker = "extra == 'dev-dependencies'" }, + { name = "scikit-learn", marker = "extra == 'dev-dependencies'" }, + { name = "sentencepiece", marker = "extra == 'dev-dependencies'", specifier = ">=0.1.91,!=0.1.92" }, + { name = "sigopt", marker = "extra == 'dev-dependencies'" }, + { name = "sudachidict-core", marker = "extra == 'dev-dependencies'", specifier = ">=20220729" }, + { name = "sudachipy", marker = "extra == 'dev-dependencies'", specifier = ">=0.6.6" }, + { name = "tensorboard", marker = "extra == 'dev-dependencies'" }, + { name = "tensorflow-text", marker = "extra == 'dev-dependencies'", specifier = "<2.16" }, + { name = "tensorflow", marker = "extra == 'dev-dependencies'", specifier = ">=2.6,<2.16" }, + { name = "tf2onnx", marker = "extra == 'dev-dependencies'" }, + { name = "timeout-decorator", marker = "extra == 'dev-dependencies'" }, + { name = "timm", marker = "extra == 'dev-dependencies'" }, + { name = "tokenizers", marker = "extra == 'dev-dependencies'", specifier = ">=0.14,<0.19" }, + { name = "torch", marker = "extra == 'dev-dependencies'" }, + { name = "torchaudio", marker = "extra == 'dev-dependencies'" }, + { name = "torchvision", marker = "extra == 'dev-dependencies'" }, + { name = "unidic", marker = "extra == 'dev-dependencies'", specifier = ">=1.0.2" }, + { name = "unidic-lite", marker = "extra == 'dev-dependencies'", specifier = ">=1.0.7" }, + { name = "urllib3", marker = "extra == 'dev-dependencies'", specifier = "<2.0.0" }, +] + [[package]] name = "triton" version = "3.0.0" diff --git a/crates/uv/tests/snapshots/ecosystem__warehouse-lock-file.snap b/crates/uv/tests/snapshots/ecosystem__warehouse-lock-file.snap index e0a6f1199..31ae22370 100644 --- a/crates/uv/tests/snapshots/ecosystem__warehouse-lock-file.snap +++ b/crates/uv/tests/snapshots/ecosystem__warehouse-lock-file.snap @@ -4277,6 +4277,150 @@ dev = [ { name = "webtest" }, ] +[package.metadata] +requires-dist = [ + { name = "alembic", specifier = ">=0.7.0" }, + { name = "alembic-postgresql-enum" }, + { name = "automat" }, + { name = "argon2-cffi" }, + { name = "b2sdk" }, + { name = "babel" }, + { name = "bcrypt" }, + { name = "boto3" }, + { name = "celery", extras = ["sqs"], specifier = ">=5.2.2,<5.3.2" }, + { name = "celery-redbeat" }, + { name = "certifi" }, + { name = "click" }, + { name = "cryptography" }, + { name = "datadog", specifier = ">=0.19.0" }, + { name = "disposable-email-domains" }, + { name = "elasticsearch", specifier = ">=7.0.0,<7.11.0" }, + { name = "elasticsearch-dsl", specifier = ">=7.0.0,<8.0.0" }, + { name = "first" }, + { name = "forcediphttpsadapter" }, + { name = "github-reserved-names", specifier = ">=1.0.0" }, + { name = "google-cloud-bigquery" }, + { name = "google-cloud-storage" }, + { name = "hiredis" }, + { name = "html5lib" }, + { name = "humanize" }, + { name = "itsdangerous" }, + { name = "jinja2", specifier = ">=2.8" }, + { name = "kombu", extras = ["sqs"], specifier = "<5.3.2" }, + { name = "limits" }, + { name = "linehaul" }, + { name = "lxml" }, + { name = "mistune" }, + { name = "msgpack" }, + { name = "natsort" }, + { name = "orjson" }, + { name = "packaging", specifier = ">=23.2" }, + { name = "packaging-legacy" }, + { name = "paginate", specifier = ">=0.5.2" }, + { name = "paginate-sqlalchemy" }, + { name = "passlib", specifier = ">=1.6.4" }, + { name = "premailer" }, + { name = "psycopg", extras = ["c"] }, + { name = "pycurl" }, + { name = "pydantic" }, + { name = "pyqrcode" }, + { name = "pyramid", specifier = ">=2.0" }, + { name = "pymacaroons" }, + { name = "pyramid-jinja2", specifier = ">=2.5" }, + { name = "pyramid-mailer", specifier = ">=0.14.1" }, + { name = "pyramid-openapi3", specifier = ">=0.17.1" }, + { name = "pyramid-retry", specifier = ">=0.3" }, + { name = "pyramid-rpc", specifier = ">=0.7" }, + { name = "pyramid-services", specifier = ">=2.1" }, + { name = "pyramid-tm", specifier = ">=0.12" }, + { name = "python-slugify" }, + { name = "pytz" }, + { name = "pyjwt", extras = ["crypto"], specifier = ">=2.8.0" }, + { name = "readme-renderer", extras = ["md"], specifier = ">=36.0" }, + { name = "requests" }, + { name = "requests-aws4auth" }, + { name = "redis", specifier = ">=2.8.0,<6.0.0" }, + { name = "rfc3986" }, + { name = "sentry-sdk" }, + { name = "setuptools" }, + { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0,<3.0" }, + { name = "stdlib-list" }, + { name = "stripe" }, + { name = "structlog" }, + { name = "transaction" }, + { name = "trove-classifiers" }, + { name = "ua-parser" }, + { name = "urllib3", specifier = "<2" }, + { name = "webauthn", specifier = ">=1.0.0,<3.0.0" }, + { name = "whitenoise" }, + { name = "wtforms", extras = ["email"], specifier = ">=2.0.0" }, + { name = "zope-sqlalchemy" }, + { name = "zxcvbn" }, + { name = "gunicorn", marker = "extra == 'deploy'", specifier = "==22.0.0" }, + { name = "ddtrace", marker = "extra == 'deploy'", specifier = "==2.8.5" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "sphinx" }, + { name = "asyncudp", specifier = ">=0.7" }, + { name = "black", specifier = "==24.4.2" }, + { name = "cairosvg" }, + { name = "celery-types" }, + { name = "coverage" }, + { name = "curlylint" }, + { name = "doc8", specifier = ">=1.1.0" }, + { name = "factory-boy" }, + { name = "flake8" }, + { name = "freezegun" }, + { name = "furo" }, + { name = "hupper", specifier = ">=1.9" }, + { name = "isort", specifier = ">=5.13.1" }, + { name = "mkdocs" }, + { name = "mkdocs-macros-plugin" }, + { name = "mkdocs-material" }, + { name = "mkdocs-rss-plugin" }, + { name = "msgpack-types" }, + { name = "mypy" }, + { name = "mypy-zope" }, + { name = "myst-parser" }, + { name = "pep8-naming" }, + { name = "pillow" }, + { name = "pip-api" }, + { name = "pip-tools", specifier = ">=1.0" }, + { name = "pretend" }, + { name = "pyramid-debugtoolbar", specifier = ">=2.5" }, + { name = "pytest-icdiff" }, + { name = "pytest-postgresql", specifier = ">=3.1.3,<7.0.0" }, + { name = "pytest-randomly" }, + { name = "pytest-socket" }, + { name = "pytest", specifier = ">=3.0.0" }, + { name = "pytz" }, + { name = "pyupgrade" }, + { name = "repository-service-tuf" }, + { name = "responses", specifier = ">=0.5.1" }, + { name = "sphinx-autobuild" }, + { name = "sphinxcontrib-httpdomain" }, + { name = "sphinxcontrib-mermaid" }, + { name = "types-wtforms" }, + { name = "types-webob" }, + { name = "types-babel" }, + { name = "types-boto3" }, + { name = "types-certifi" }, + { name = "types-first" }, + { name = "types-html5lib" }, + { name = "types-itsdangerous" }, + { name = "types-passlib" }, + { name = "types-python-slugify" }, + { name = "types-pytz" }, + { name = "types-redis" }, + { name = "types-requests", specifier = "==2.31.0.6" }, + { name = "types-setuptools" }, + { name = "types-stripe" }, + { name = "types-zxcvbn" }, + { name = "webtest" }, +] + [[package]] name = "watchdog" version = "4.0.1" diff --git a/crates/uv/tests/sync.rs b/crates/uv/tests/sync.rs index f50e6b313..a4717e0ae 100644 --- a/crates/uv/tests/sync.rs +++ b/crates/uv/tests/sync.rs @@ -757,6 +757,9 @@ fn sync_relative_wheel() -> Result<()> { dependencies = [ { name = "ok" }, ] + + [package.metadata] + requires-dist = [{ name = "ok", path = "wheels/ok-1.0.0-py3-none-any.whl" }] "### ); } diff --git a/crates/uv/tests/workspace.rs b/crates/uv/tests/workspace.rs index 3a7e91f2d..f4ebfc3d3 100644 --- a/crates/uv/tests/workspace.rs +++ b/crates/uv/tests/workspace.rs @@ -1088,6 +1088,12 @@ fn workspace_inherit_sources() -> Result<()> { [options] exclude-newer = "2024-03-25 00:00:00 UTC" + [manifest] + members = [ + "leaf", + "workspace", + ] + [[package]] name = "leaf" version = "0.1.0" @@ -1096,6 +1102,9 @@ fn workspace_inherit_sources() -> Result<()> { { name = "library" }, ] + [package.metadata] + requires-dist = [{ name = "library", editable = "../library" }] + [[package]] name = "library" version = "0.1.0" @@ -1374,7 +1383,7 @@ fn workspace_member_name_shadows_dependencies() -> Result<()> { ----- stderr ----- Using Python 3.12.[X] interpreter at: [PYTHON-3.12] - error: Failed to download and build: `foo @ file://[TEMP_DIR]/workspace/packages/foo` + error: Failed to build: `foo @ file://[TEMP_DIR]/workspace/packages/foo` Caused by: Failed to parse entry for: `anyio` Caused by: Package is not included as workspace package in `tool.uv.workspace` "### diff --git a/scripts/scenarios/templates/lock.mustache b/scripts/scenarios/templates/lock.mustache index 4277a5011..8dc0f593c 100644 --- a/scripts/scenarios/templates/lock.mustache +++ b/scripts/scenarios/templates/lock.mustache @@ -71,9 +71,24 @@ fn {{module_name}}() -> Result<()> { ); }); - // Assert the idempotence of `uv lock` + // Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`). context .lock() + .arg("--locked") + .env_remove("UV_EXCLUDE_NEWER") + .arg("--index-url") + .arg(packse_index_url()) + .assert() + .success(); + + // Assert the idempotence of `uv lock` when resolving with the lockfile preferences, + // by upgrading an irrelevant package. + // TODO(charlie): This should use `--locked`, but currently fails due to differences in + // URL fragments that are removed when writing to disk. + context + .lock() + .arg("--upgrade-package") + .arg("packse") .env_remove("UV_EXCLUDE_NEWER") .arg("--index-url") .arg(packse_index_url()) @@ -81,6 +96,8 @@ fn {{module_name}}() -> Result<()> { .success(); let lock2 = fs_err::read_to_string(context.temp_dir.join("uv.lock"))?; assert_eq!(lock2, lock); + + {{/expected.satisfiable}} Ok(())