mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-01 09:32:18 +00:00
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.
This commit is contained in:
parent
359f39ca0f
commit
e3f345ce09
30 changed files with 5641 additions and 2546 deletions
|
@ -10,7 +10,7 @@ use pep440_rs::VersionSpecifiers;
|
||||||
use pep508_rs::{
|
use pep508_rs::{
|
||||||
marker, MarkerEnvironment, MarkerTree, RequirementOrigin, VerbatimUrl, VersionOrUrl,
|
marker, MarkerEnvironment, MarkerTree, RequirementOrigin, VerbatimUrl, VersionOrUrl,
|
||||||
};
|
};
|
||||||
use uv_fs::PortablePathBuf;
|
use uv_fs::{PortablePathBuf, CWD};
|
||||||
use uv_git::{GitReference, GitSha, GitUrl};
|
use uv_git::{GitReference, GitSha, GitUrl};
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::{ExtraName, PackageName};
|
||||||
|
|
||||||
|
@ -66,6 +66,45 @@ impl Requirement {
|
||||||
pub fn is_editable(&self) -> bool {
|
pub fn is_editable(&self) -> bool {
|
||||||
self.source.is_editable()
|
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<Requirement> for pep508_rs::Requirement<VerbatimUrl> {
|
impl From<Requirement> for pep508_rs::Requirement<VerbatimUrl> {
|
||||||
|
@ -554,6 +593,10 @@ impl From<RequirementSource> for RequirementSourceWire {
|
||||||
} => {
|
} => {
|
||||||
let mut url = repository;
|
let mut url = repository;
|
||||||
|
|
||||||
|
// Redact the credentials.
|
||||||
|
let _ = url.set_username("");
|
||||||
|
let _ = url.set_password(None);
|
||||||
|
|
||||||
// Clear out any existing state.
|
// Clear out any existing state.
|
||||||
url.set_fragment(None);
|
url.set_fragment(None);
|
||||||
url.set_query(None);
|
url.set_query(None);
|
||||||
|
@ -595,26 +638,26 @@ impl From<RequirementSource> for RequirementSourceWire {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RequirementSource::Path {
|
RequirementSource::Path {
|
||||||
install_path,
|
install_path: _,
|
||||||
lock_path: _,
|
lock_path,
|
||||||
ext: _,
|
ext: _,
|
||||||
url: _,
|
url: _,
|
||||||
} => Self::Path {
|
} => Self::Path {
|
||||||
path: PortablePathBuf::from(install_path),
|
path: PortablePathBuf::from(lock_path),
|
||||||
},
|
},
|
||||||
RequirementSource::Directory {
|
RequirementSource::Directory {
|
||||||
install_path,
|
install_path: _,
|
||||||
lock_path: _,
|
lock_path,
|
||||||
editable,
|
editable,
|
||||||
url: _,
|
url: _,
|
||||||
} => {
|
} => {
|
||||||
if editable {
|
if editable {
|
||||||
Self::Editable {
|
Self::Editable {
|
||||||
editable: PortablePathBuf::from(install_path),
|
editable: PortablePathBuf::from(lock_path),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self::Directory {
|
Self::Directory {
|
||||||
directory: PortablePathBuf::from(install_path),
|
directory: PortablePathBuf::from(lock_path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,31 +674,46 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
||||||
Ok(Self::Registry { specifier, index })
|
Ok(Self::Registry { specifier, index })
|
||||||
}
|
}
|
||||||
RequirementSourceWire::Git { git } => {
|
RequirementSourceWire::Git { git } => {
|
||||||
let mut url = Url::parse(&git)?;
|
let mut repository = Url::parse(&git)?;
|
||||||
|
|
||||||
let mut reference = GitReference::DefaultBranch;
|
let mut reference = GitReference::DefaultBranch;
|
||||||
let mut subdirectory = None;
|
let mut subdirectory = None;
|
||||||
for (key, val) in url.query_pairs() {
|
for (key, val) in repository.query_pairs() {
|
||||||
match &*key {
|
match &*key {
|
||||||
"tag" => reference = GitReference::Tag(val.into_owned()),
|
"tag" => reference = GitReference::Tag(val.into_owned()),
|
||||||
"branch" => reference = GitReference::Branch(val.into_owned()),
|
"branch" => reference = GitReference::Branch(val.into_owned()),
|
||||||
"rev" => reference = GitReference::from_rev(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,
|
_ => continue,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let precise = url.fragment().map(GitSha::from_str).transpose()?;
|
let precise = repository.fragment().map(GitSha::from_str).transpose()?;
|
||||||
|
|
||||||
url.set_query(None);
|
// Clear out any existing state.
|
||||||
url.set_fragment(None);
|
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 {
|
Ok(Self::Git {
|
||||||
repository: url.clone(),
|
repository,
|
||||||
reference,
|
reference,
|
||||||
precise,
|
precise,
|
||||||
subdirectory,
|
subdirectory: subdirectory.map(PathBuf::from),
|
||||||
url: VerbatimUrl::from_url(url),
|
url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
RequirementSourceWire::Direct { url, subdirectory } => Ok(Self::Url {
|
RequirementSourceWire::Direct { url, subdirectory } => Ok(Self::Url {
|
||||||
|
@ -665,32 +723,38 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
||||||
ext: DistExtension::from_path(url.path())
|
ext: DistExtension::from_path(url.path())
|
||||||
.map_err(|err| ParsedUrlError::MissingExtensionUrl(url.to_string(), err))?,
|
.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 } => {
|
RequirementSourceWire::Path { path } => {
|
||||||
let path = PathBuf::from(path);
|
let path = PathBuf::from(path);
|
||||||
|
let url = VerbatimUrl::parse_path(&path, &*CWD)?;
|
||||||
Ok(Self::Path {
|
Ok(Self::Path {
|
||||||
url: VerbatimUrl::from_path(path.as_path())?,
|
|
||||||
ext: DistExtension::from_path(path.as_path())
|
ext: DistExtension::from_path(path.as_path())
|
||||||
.map_err(|err| ParsedUrlError::MissingExtensionPath(path.clone(), err))?,
|
.map_err(|err| ParsedUrlError::MissingExtensionPath(path.clone(), err))?,
|
||||||
install_path: path.clone(),
|
install_path: path.clone(),
|
||||||
lock_path: path,
|
lock_path: path,
|
||||||
|
url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
RequirementSourceWire::Directory { directory } => {
|
RequirementSourceWire::Directory { directory } => {
|
||||||
let directory = PathBuf::from(directory);
|
let directory = PathBuf::from(directory);
|
||||||
|
let url = VerbatimUrl::parse_path(&directory, &*CWD)?;
|
||||||
Ok(Self::Directory {
|
Ok(Self::Directory {
|
||||||
url: VerbatimUrl::from_path(directory.as_path())?,
|
|
||||||
install_path: directory.clone(),
|
install_path: directory.clone(),
|
||||||
lock_path: directory,
|
lock_path: directory,
|
||||||
editable: false,
|
editable: false,
|
||||||
|
url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
RequirementSourceWire::Editable { editable } => {
|
RequirementSourceWire::Editable { editable } => {
|
||||||
let editable = PathBuf::from(editable);
|
let editable = PathBuf::from(editable);
|
||||||
|
let url = VerbatimUrl::parse_path(&editable, &*CWD)?;
|
||||||
Ok(Self::Directory {
|
Ok(Self::Directory {
|
||||||
url: VerbatimUrl::from_path(editable.as_path())?,
|
|
||||||
install_path: editable.clone(),
|
install_path: editable.clone(),
|
||||||
lock_path: editable,
|
lock_path: editable,
|
||||||
editable: true,
|
editable: true,
|
||||||
|
url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ pub use error::{NoSolutionError, NoSolutionHeader, ResolveError};
|
||||||
pub use exclude_newer::ExcludeNewer;
|
pub use exclude_newer::ExcludeNewer;
|
||||||
pub use exclusions::Exclusions;
|
pub use exclusions::Exclusions;
|
||||||
pub use flat_index::FlatIndex;
|
pub use flat_index::FlatIndex;
|
||||||
pub use lock::{Lock, LockError, TreeDisplay};
|
pub use lock::{Lock, LockError, ResolverManifest, TreeDisplay};
|
||||||
pub use manifest::Manifest;
|
pub use manifest::Manifest;
|
||||||
pub use options::{Options, OptionsBuilder};
|
pub use options::{Options, OptionsBuilder};
|
||||||
pub use preferences::{Preference, PreferenceError, Preferences};
|
pub use preferences::{Preference, PreferenceError, Preferences};
|
||||||
|
|
|
@ -2,49 +2,40 @@ use std::borrow::Cow;
|
||||||
use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
use std::collections::{BTreeMap, BTreeSet, VecDeque};
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use std::hash::BuildHasherDefault;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use petgraph::visit::EdgeRef;
|
use petgraph::visit::EdgeRef;
|
||||||
use pubgrub::Range;
|
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 toml_edit::{value, Array, ArrayOfTables, InlineTable, Item, Table, Value};
|
||||||
|
use tracing::debug;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use cache_key::RepositoryUrl;
|
use cache_key::RepositoryUrl;
|
||||||
use distribution_filename::{DistExtension, ExtensionError, SourceDistExtension, WheelFilename};
|
use distribution_filename::{DistExtension, ExtensionError, SourceDistExtension, WheelFilename};
|
||||||
use distribution_types::{
|
use distribution_types::{
|
||||||
BuiltDist, DirectUrlBuiltDist, DirectUrlSourceDist, DirectorySourceDist, Dist,
|
BuiltDist, DirectUrlBuiltDist, DirectUrlSourceDist, DirectorySourceDist, Dist,
|
||||||
DistributionMetadata, FileLocation, GitSourceDist, HashComparison, IndexUrl, Name,
|
DistributionMetadata, FileLocation, GitSourceDist, HashPolicy, IndexUrl, Name, PathBuiltDist,
|
||||||
PathBuiltDist, PathSourceDist, PrioritizedDist, RegistryBuiltDist, RegistryBuiltWheel,
|
PathSourceDist, RegistryBuiltDist, RegistryBuiltWheel, RegistrySourceDist, RemoteSource,
|
||||||
RegistrySourceDist, RemoteSource, Resolution, ResolvedDist, SourceDistCompatibility,
|
Resolution, ResolvedDist, ToUrlError, UrlString,
|
||||||
ToUrlError, UrlString, VersionId, WheelCompatibility,
|
|
||||||
};
|
|
||||||
use pep440_rs::{Version, VersionSpecifier};
|
|
||||||
use pep508_rs::{
|
|
||||||
ExtraOperator, MarkerEnvironment, MarkerExpression, MarkerTree, VerbatimUrl, VerbatimUrlError,
|
|
||||||
};
|
};
|
||||||
|
use pep440_rs::Version;
|
||||||
|
use pep508_rs::{MarkerEnvironment, MarkerTree, VerbatimUrl, VerbatimUrlError};
|
||||||
use platform_tags::{TagCompatibility, TagPriority, Tags};
|
use platform_tags::{TagCompatibility, TagPriority, Tags};
|
||||||
use pypi_types::{
|
use pypi_types::{HashDigest, ParsedArchiveUrl, ParsedGitUrl, Requirement, RequirementSource};
|
||||||
HashDigest, ParsedArchiveUrl, ParsedGitUrl, ParsedUrl, Requirement, RequirementSource,
|
use uv_configuration::ExtrasSpecification;
|
||||||
};
|
use uv_distribution::DistributionDatabase;
|
||||||
use uv_configuration::{ExtrasSpecification, Upgrade};
|
use uv_fs::{relative_to, PortablePath, PortablePathBuf, Simplified};
|
||||||
use uv_distribution::{ArchiveMetadata, Metadata};
|
|
||||||
use uv_fs::{PortablePath, PortablePathBuf, Simplified};
|
|
||||||
use uv_git::{GitReference, GitSha, RepositoryReference, ResolvedRepositoryReference};
|
use uv_git::{GitReference, GitSha, RepositoryReference, ResolvedRepositoryReference};
|
||||||
use uv_normalize::{ExtraName, GroupName, PackageName};
|
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::resolution::{AnnotatedDist, ResolutionGraphNode};
|
||||||
use crate::resolver::FxOnceMap;
|
use crate::{ExcludeNewer, PrereleaseMode, RequiresPython, ResolutionGraph, ResolutionMode};
|
||||||
use crate::{
|
|
||||||
ExcludeNewer, InMemoryIndex, MetadataResponse, PrereleaseMode, RequiresPython, ResolutionGraph,
|
|
||||||
ResolutionMode, VersionMap, VersionsResponse,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// The current version of the lockfile format.
|
/// The current version of the lockfile format.
|
||||||
const VERSION: u32 = 1;
|
const VERSION: u32 = 1;
|
||||||
|
@ -58,7 +49,7 @@ pub struct Lock {
|
||||||
fork_markers: Vec<MarkerTree>,
|
fork_markers: Vec<MarkerTree>,
|
||||||
/// The range of supported Python versions.
|
/// The range of supported Python versions.
|
||||||
requires_python: Option<RequiresPython>,
|
requires_python: Option<RequiresPython>,
|
||||||
/// We discard the lockfile if these options match.
|
/// We discard the lockfile if these options don't match.
|
||||||
options: ResolverOptions,
|
options: ResolverOptions,
|
||||||
/// The actual locked version and their metadata.
|
/// The actual locked version and their metadata.
|
||||||
packages: Vec<Package>,
|
packages: Vec<Package>,
|
||||||
|
@ -74,6 +65,8 @@ pub struct Lock {
|
||||||
/// that exists in this map. That is, there are no dependencies that don't
|
/// that exists in this map. That is, there are no dependencies that don't
|
||||||
/// have a corresponding locked package entry in the same lockfile.
|
/// have a corresponding locked package entry in the same lockfile.
|
||||||
by_id: FxHashMap<PackageId, usize>,
|
by_id: FxHashMap<PackageId, usize>,
|
||||||
|
/// The input requirements to the resolution.
|
||||||
|
manifest: ResolverManifest,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Lock {
|
impl Lock {
|
||||||
|
@ -208,6 +201,7 @@ impl Lock {
|
||||||
packages,
|
packages,
|
||||||
requires_python,
|
requires_python,
|
||||||
options,
|
options,
|
||||||
|
ResolverManifest::default(),
|
||||||
graph.fork_markers.clone(),
|
graph.fork_markers.clone(),
|
||||||
)?;
|
)?;
|
||||||
Ok(lock)
|
Ok(lock)
|
||||||
|
@ -219,6 +213,7 @@ impl Lock {
|
||||||
mut packages: Vec<Package>,
|
mut packages: Vec<Package>,
|
||||||
requires_python: Option<RequiresPython>,
|
requires_python: Option<RequiresPython>,
|
||||||
options: ResolverOptions,
|
options: ResolverOptions,
|
||||||
|
manifest: ResolverManifest,
|
||||||
fork_markers: Vec<MarkerTree>,
|
fork_markers: Vec<MarkerTree>,
|
||||||
) -> Result<Self, LockError> {
|
) -> Result<Self, LockError> {
|
||||||
// Put all dependencies for each package in a canonical order and
|
// Put all dependencies for each package in a canonical order and
|
||||||
|
@ -379,9 +374,27 @@ impl Lock {
|
||||||
options,
|
options,
|
||||||
packages,
|
packages,
|
||||||
by_id,
|
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.
|
/// Returns the [`Package`] entries in this lock.
|
||||||
pub fn packages(&self) -> &[Package] {
|
pub fn packages(&self) -> &[Package] {
|
||||||
&self.packages
|
&self.packages
|
||||||
|
@ -527,7 +540,7 @@ impl Lock {
|
||||||
// Write the settings that were used to generate the resolution.
|
// Write the settings that were used to generate the resolution.
|
||||||
// This enables us to invalidate the lockfile if the user changes
|
// This enables us to invalidate the lockfile if the user changes
|
||||||
// their settings.
|
// their settings.
|
||||||
if self.options != ResolverOptions::default() {
|
{
|
||||||
let mut options_table = Table::new();
|
let mut options_table = Table::new();
|
||||||
|
|
||||||
if self.options.resolution_mode != ResolutionMode::default() {
|
if self.options.resolution_mode != ResolutionMode::default() {
|
||||||
|
@ -545,7 +558,71 @@ impl Lock {
|
||||||
if let Some(exclude_newer) = self.options.exclude_newer {
|
if let Some(exclude_newer) = self.options.exclude_newer {
|
||||||
options_table.insert("exclude-newer", value(exclude_newer.to_string()));
|
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::<Result<Vec<_>, _>>()?;
|
||||||
|
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::<Result<Vec<_>, _>>()?;
|
||||||
|
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
|
// Count the number of packages for each package name. When
|
||||||
|
@ -588,62 +665,207 @@ impl Lock {
|
||||||
dist
|
dist
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the [`Lock`] to a [`InMemoryIndex`] that can be used for resolution.
|
/// Convert the [`Lock`] to a [`Resolution`] using the given marker environment, tags, and root.
|
||||||
///
|
pub async fn satisfies<Context: BuildContext>(
|
||||||
/// Any packages specified to be upgraded will be ignored.
|
|
||||||
pub fn to_index(
|
|
||||||
&self,
|
&self,
|
||||||
install_path: &Path,
|
workspace: &Workspace,
|
||||||
upgrade: &Upgrade,
|
members: &[PackageName],
|
||||||
) -> Result<InMemoryIndex, LockError> {
|
constraints: &[Requirement],
|
||||||
let distributions =
|
overrides: &[Requirement],
|
||||||
FxOnceMap::with_capacity_and_hasher(self.packages.len(), BuildHasherDefault::default());
|
tags: &Tags,
|
||||||
let mut packages: FxHashMap<_, BTreeMap<Version, PrioritizedDist>> =
|
database: &DistributionDatabase<'_, Context>,
|
||||||
FxHashMap::with_capacity_and_hasher(self.packages.len(), FxBuildHasher);
|
) -> Result<bool, LockError> {
|
||||||
|
let mut queue: VecDeque<&Package> = VecDeque::new();
|
||||||
|
let mut seen = FxHashSet::default();
|
||||||
|
|
||||||
for package in &self.packages {
|
// Validate that the lockfile was generated with the same root members.
|
||||||
// Skip packages that may be upgraded from their pinned version.
|
{
|
||||||
if upgrade.contains(package.name()) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match package.id.source {
|
// Get the metadata for the distribution.
|
||||||
Source::Registry(..) | Source::Git(..) => {}
|
let dist = package.to_dist(workspace.install_path(), tags)?;
|
||||||
// Skip local and direct URL dependencies, as their metadata may have been mutated
|
|
||||||
// without a version change.
|
let Ok(archive) = database
|
||||||
Source::Path(..)
|
.get_or_build_wheel_metadata(&dist, HashPolicy::None)
|
||||||
| Source::Directory(..)
|
.await
|
||||||
| Source::Editable(..)
|
else {
|
||||||
| Source::Direct(..) => continue,
|
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.
|
// Validate the `dev-dependencies` metadata.
|
||||||
if let Some(prioritized_dist) = package.to_prioritized_dist(install_path)? {
|
{
|
||||||
packages
|
let expected: BTreeMap<GroupName, Vec<Requirement>> = archive
|
||||||
.entry(package.name().clone())
|
.metadata
|
||||||
.or_default()
|
.dev_dependencies
|
||||||
.insert(package.id.version.clone(), prioritized_dist);
|
.into_iter()
|
||||||
|
.map(|(group, requirements)| {
|
||||||
|
(
|
||||||
|
group,
|
||||||
|
requirements
|
||||||
|
.into_iter()
|
||||||
|
.map(|requirement| normalize_requirement(requirement, workspace))
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let actual: BTreeMap<GroupName, Vec<Requirement>> = 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.
|
// Recurse.
|
||||||
let version_id = package.version_id(install_path)?;
|
// TODO(charlie): Do we care about extras here, or any other fields on the `Dependency`?
|
||||||
let hashes = package.hashes();
|
// Should we instead recurse on `requires_dist`?
|
||||||
let metadata = package.to_metadata(install_path)?;
|
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.
|
for dependencies in package.optional_dependencies.values() {
|
||||||
let response = MetadataResponse::Found(ArchiveMetadata::with_hashes(metadata, hashes));
|
for dep in dependencies {
|
||||||
distributions.done(version_id, Arc::new(response));
|
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
|
Ok(true)
|
||||||
.into_iter()
|
|
||||||
.map(|(name, versions)| {
|
|
||||||
let response = VersionsResponse::Found(vec![VersionMap::from(versions)]);
|
|
||||||
(name, Arc::new(response))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(InMemoryIndex::with(packages, distributions))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,6 +883,34 @@ struct ResolverOptions {
|
||||||
exclude_newer: Option<ExcludeNewer>,
|
exclude_newer: Option<ExcludeNewer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[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<PackageName>,
|
||||||
|
/// The constraints provided to the resolver.
|
||||||
|
#[serde(default)]
|
||||||
|
constraints: Vec<Requirement>,
|
||||||
|
/// The overrides provided to the resolver.
|
||||||
|
#[serde(default)]
|
||||||
|
overrides: Vec<Requirement>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResolverManifest {
|
||||||
|
pub fn new(
|
||||||
|
members: Vec<PackageName>,
|
||||||
|
constraints: Vec<Requirement>,
|
||||||
|
overrides: Vec<Requirement>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
members,
|
||||||
|
constraints,
|
||||||
|
overrides,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
struct LockWire {
|
struct LockWire {
|
||||||
|
@ -674,6 +924,8 @@ struct LockWire {
|
||||||
/// We discard the lockfile if these options match.
|
/// We discard the lockfile if these options match.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
options: ResolverOptions,
|
options: ResolverOptions,
|
||||||
|
#[serde(default)]
|
||||||
|
manifest: ResolverManifest,
|
||||||
#[serde(rename = "package", alias = "distribution", default)]
|
#[serde(rename = "package", alias = "distribution", default)]
|
||||||
packages: Vec<PackageWire>,
|
packages: Vec<PackageWire>,
|
||||||
}
|
}
|
||||||
|
@ -685,6 +937,7 @@ impl From<Lock> for LockWire {
|
||||||
requires_python: lock.requires_python,
|
requires_python: lock.requires_python,
|
||||||
fork_markers: lock.fork_markers,
|
fork_markers: lock.fork_markers,
|
||||||
options: lock.options,
|
options: lock.options,
|
||||||
|
manifest: lock.manifest,
|
||||||
packages: lock.packages.into_iter().map(PackageWire::from).collect(),
|
packages: lock.packages.into_iter().map(PackageWire::from).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,6 +974,7 @@ impl TryFrom<LockWire> for Lock {
|
||||||
packages,
|
packages,
|
||||||
wire.requires_python,
|
wire.requires_python,
|
||||||
wire.options,
|
wire.options,
|
||||||
|
wire.manifest,
|
||||||
wire.fork_markers,
|
wire.fork_markers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -737,9 +991,14 @@ pub struct Package {
|
||||||
///
|
///
|
||||||
/// Named `environment-markers` in `uv.lock`.
|
/// Named `environment-markers` in `uv.lock`.
|
||||||
fork_markers: Vec<MarkerTree>,
|
fork_markers: Vec<MarkerTree>,
|
||||||
|
/// The resolved dependencies of the package.
|
||||||
dependencies: Vec<Dependency>,
|
dependencies: Vec<Dependency>,
|
||||||
|
/// The resolved optional dependencies of the package.
|
||||||
optional_dependencies: BTreeMap<ExtraName, Vec<Dependency>>,
|
optional_dependencies: BTreeMap<ExtraName, Vec<Dependency>>,
|
||||||
|
/// The resolved development dependencies of the package.
|
||||||
dev_dependencies: BTreeMap<GroupName, Vec<Dependency>>,
|
dev_dependencies: BTreeMap<GroupName, Vec<Dependency>>,
|
||||||
|
/// The exact requirements from the package metadata.
|
||||||
|
metadata: PackageMetadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Package {
|
impl Package {
|
||||||
|
@ -750,6 +1009,16 @@ impl Package {
|
||||||
let id = PackageId::from_annotated_dist(annotated_dist);
|
let id = PackageId::from_annotated_dist(annotated_dist);
|
||||||
let sdist = SourceDist::from_annotated_dist(&id, annotated_dist)?;
|
let sdist = SourceDist::from_annotated_dist(&id, annotated_dist)?;
|
||||||
let wheels = Wheel::from_annotated_dist(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 {
|
Ok(Package {
|
||||||
id,
|
id,
|
||||||
sdist,
|
sdist,
|
||||||
|
@ -758,6 +1027,11 @@ impl Package {
|
||||||
dependencies: vec![],
|
dependencies: vec![],
|
||||||
optional_dependencies: BTreeMap::default(),
|
optional_dependencies: BTreeMap::default(),
|
||||||
dev_dependencies: BTreeMap::default(),
|
dev_dependencies: BTreeMap::default(),
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist,
|
||||||
|
|
||||||
|
requires_dev,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,119 +1275,6 @@ impl Package {
|
||||||
Ok(Some(sdist))
|
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<Option<PrioritizedDist>, 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<Metadata, LockError> {
|
|
||||||
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::<Result<Vec<_>, 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::<Result<Vec<_>, 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::<Result<_, LockError>>()?;
|
|
||||||
|
|
||||||
Ok(Metadata {
|
|
||||||
name,
|
|
||||||
version,
|
|
||||||
requires_dist,
|
|
||||||
dev_dependencies,
|
|
||||||
provides_extras,
|
|
||||||
requires_python: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_toml(&self, dist_count_by_name: &FxHashMap<PackageName, u64>) -> anyhow::Result<Table> {
|
fn to_toml(&self, dist_count_by_name: &FxHashMap<PackageName, u64>) -> anyhow::Result<Table> {
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
|
|
||||||
|
@ -1145,9 +1306,13 @@ impl Package {
|
||||||
deps.iter()
|
deps.iter()
|
||||||
.map(|dep| dep.to_toml(dist_count_by_name).into_inline_table()),
|
.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() {
|
if !self.dev_dependencies.is_empty() {
|
||||||
|
@ -1157,9 +1322,13 @@ impl Package {
|
||||||
deps.iter()
|
deps.iter()
|
||||||
.map(|dep| dep.to_toml(dist_count_by_name).into_inline_table()),
|
.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 {
|
if let Some(ref sdist) = self.sdist {
|
||||||
|
@ -1177,6 +1346,61 @@ impl Package {
|
||||||
table.insert("wheels", value(wheels));
|
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::<Result<Vec<_>, _>>()?;
|
||||||
|
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::<Result<Vec<_>, _>>()?;
|
||||||
|
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)
|
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<VersionId, LockError> {
|
|
||||||
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`].
|
/// Returns all the hashes associated with this [`Package`].
|
||||||
fn hashes(&self) -> Vec<HashDigest> {
|
fn hashes(&self) -> Vec<HashDigest> {
|
||||||
let mut hashes = Vec::new();
|
let mut hashes = Vec::new();
|
||||||
|
@ -1279,6 +1492,8 @@ struct PackageWire {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
id: PackageId,
|
id: PackageId,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
metadata: PackageMetadata,
|
||||||
|
#[serde(default)]
|
||||||
sdist: Option<SourceDist>,
|
sdist: Option<SourceDist>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
wheels: Vec<Wheel>,
|
wheels: Vec<Wheel>,
|
||||||
|
@ -1292,6 +1507,15 @@ struct PackageWire {
|
||||||
dev_dependencies: BTreeMap<GroupName, Vec<DependencyWire>>,
|
dev_dependencies: BTreeMap<GroupName, Vec<DependencyWire>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default, Debug, Eq, PartialEq, serde::Deserialize)]
|
||||||
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
struct PackageMetadata {
|
||||||
|
#[serde(default)]
|
||||||
|
requires_dist: Vec<Requirement>,
|
||||||
|
#[serde(default)]
|
||||||
|
requires_dev: BTreeMap<GroupName, Vec<Requirement>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl PackageWire {
|
impl PackageWire {
|
||||||
fn unwire(
|
fn unwire(
|
||||||
self,
|
self,
|
||||||
|
@ -1304,6 +1528,7 @@ impl PackageWire {
|
||||||
};
|
};
|
||||||
Ok(Package {
|
Ok(Package {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
|
metadata: self.metadata,
|
||||||
sdist: self.sdist,
|
sdist: self.sdist,
|
||||||
wheels: self.wheels,
|
wheels: self.wheels,
|
||||||
fork_markers: self.fork_markers,
|
fork_markers: self.fork_markers,
|
||||||
|
@ -1329,6 +1554,7 @@ impl From<Package> for PackageWire {
|
||||||
};
|
};
|
||||||
PackageWire {
|
PackageWire {
|
||||||
id: dist.id,
|
id: dist.id,
|
||||||
|
metadata: dist.metadata,
|
||||||
sdist: dist.sdist,
|
sdist: dist.sdist,
|
||||||
wheels: dist.wheels,
|
wheels: dist.wheels,
|
||||||
fork_markers: dist.fork_markers,
|
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<PackageName, Vec<ExtraName>>,
|
|
||||||
) -> Result<Option<Requirement>, 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.
|
/// Returns the TOML representation of this dependency.
|
||||||
fn to_toml(&self, dist_count_by_name: &FxHashMap<PackageName, u64>) -> Table {
|
fn to_toml(&self, dist_count_by_name: &FxHashMap<PackageName, u64>) -> Table {
|
||||||
let mut table = Table::new();
|
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)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
pub struct LockError(Box<LockErrorKind>);
|
pub struct LockError(Box<LockErrorKind>);
|
||||||
|
|
|
@ -59,7 +59,6 @@ pub(crate) use crate::resolver::availability::{
|
||||||
};
|
};
|
||||||
use crate::resolver::batch_prefetch::BatchPrefetcher;
|
use crate::resolver::batch_prefetch::BatchPrefetcher;
|
||||||
use crate::resolver::groups::Groups;
|
use crate::resolver::groups::Groups;
|
||||||
pub(crate) use crate::resolver::index::FxOnceMap;
|
|
||||||
pub use crate::resolver::index::InMemoryIndex;
|
pub use crate::resolver::index::InMemoryIndex;
|
||||||
pub use crate::resolver::provider::{
|
pub use crate::resolver::provider::{
|
||||||
DefaultResolverProvider, MetadataResponse, PackageVersionsResult, ResolverProvider,
|
DefaultResolverProvider, MetadataResponse, PackageVersionsResult, ResolverProvider,
|
||||||
|
|
|
@ -57,6 +57,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -72,5 +76,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -64,6 +64,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -79,5 +83,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -62,6 +62,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -75,5 +79,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,6 +50,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Package {
|
Package {
|
||||||
id: PackageId {
|
id: PackageId {
|
||||||
|
@ -104,6 +108,10 @@ Ok(
|
||||||
],
|
],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -130,5 +138,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 1,
|
}: 1,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,6 +50,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Package {
|
Package {
|
||||||
id: PackageId {
|
id: PackageId {
|
||||||
|
@ -104,6 +108,10 @@ Ok(
|
||||||
],
|
],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -130,5 +138,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 1,
|
}: 1,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,6 +50,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Package {
|
Package {
|
||||||
id: PackageId {
|
id: PackageId {
|
||||||
|
@ -104,6 +108,10 @@ Ok(
|
||||||
],
|
],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -130,5 +138,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 1,
|
}: 1,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -36,6 +36,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -56,5 +60,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -34,6 +34,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -52,5 +56,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,6 +29,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -42,5 +46,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,6 +29,10 @@ Ok(
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
optional_dependencies: {},
|
optional_dependencies: {},
|
||||||
dev_dependencies: {},
|
dev_dependencies: {},
|
||||||
|
metadata: PackageMetadata {
|
||||||
|
requires_dist: [],
|
||||||
|
requires_dev: {},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
by_id: {
|
by_id: {
|
||||||
|
@ -42,5 +46,10 @@ Ok(
|
||||||
),
|
),
|
||||||
}: 0,
|
}: 0,
|
||||||
},
|
},
|
||||||
|
manifest: ResolverManifest {
|
||||||
|
members: [],
|
||||||
|
constraints: [],
|
||||||
|
overrides: [],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,7 +9,7 @@ use rustc_hash::{FxBuildHasher, FxHashMap};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use distribution_types::{
|
use distribution_types::{
|
||||||
Diagnostic, FlatIndexLocation, IndexUrl, UnresolvedRequirementSpecification, UrlString,
|
FlatIndexLocation, IndexUrl, UnresolvedRequirementSpecification, UrlString,
|
||||||
};
|
};
|
||||||
use pep440_rs::Version;
|
use pep440_rs::Version;
|
||||||
use uv_auth::store_credentials_from_url;
|
use uv_auth::store_credentials_from_url;
|
||||||
|
@ -17,13 +17,16 @@ use uv_cache::Cache;
|
||||||
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
|
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
|
||||||
use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode, Reinstall, SetupPyStrategy};
|
use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode, Reinstall, SetupPyStrategy};
|
||||||
use uv_dispatch::BuildDispatch;
|
use uv_dispatch::BuildDispatch;
|
||||||
|
use uv_distribution::DistributionDatabase;
|
||||||
use uv_fs::CWD;
|
use uv_fs::CWD;
|
||||||
use uv_git::ResolvedRepositoryReference;
|
use uv_git::ResolvedRepositoryReference;
|
||||||
use uv_normalize::{PackageName, DEV_DEPENDENCIES};
|
use uv_normalize::{PackageName, DEV_DEPENDENCIES};
|
||||||
use uv_python::{Interpreter, PythonDownloads, PythonEnvironment, PythonPreference, PythonRequest};
|
use uv_python::{Interpreter, PythonDownloads, PythonEnvironment, PythonPreference, PythonRequest};
|
||||||
use uv_requirements::upgrade::{read_lock_requirements, LockedRequirements};
|
use uv_requirements::upgrade::{read_lock_requirements, LockedRequirements};
|
||||||
|
use uv_requirements::NamedRequirementsResolver;
|
||||||
use uv_resolver::{
|
use uv_resolver::{
|
||||||
FlatIndex, Lock, OptionsBuilder, PythonRequirement, RequiresPython, ResolverMarkers,
|
FlatIndex, Lock, OptionsBuilder, PythonRequirement, RequiresPython, ResolverManifest,
|
||||||
|
ResolverMarkers,
|
||||||
};
|
};
|
||||||
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy};
|
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy};
|
||||||
use uv_warnings::{warn_user, warn_user_once};
|
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::pip::loggers::{DefaultResolveLogger, ResolveLogger, SummaryResolveLogger};
|
||||||
use crate::commands::project::{find_requires_python, FoundInterpreter, ProjectError, SharedState};
|
use crate::commands::project::{find_requires_python, FoundInterpreter, ProjectError, SharedState};
|
||||||
|
use crate::commands::reporters::ResolverReporter;
|
||||||
use crate::commands::{pip, ExitStatus};
|
use crate::commands::{pip, ExitStatus};
|
||||||
use crate::printer::Printer;
|
use crate::printer::Printer;
|
||||||
use crate::settings::{ResolverSettings, ResolverSettingsRef};
|
use crate::settings::{ResolverSettings, ResolverSettingsRef};
|
||||||
|
@ -260,6 +264,21 @@ async fn do_lock(
|
||||||
let dev = vec![DEV_DEPENDENCIES.clone()];
|
let dev = vec![DEV_DEPENDENCIES.clone()];
|
||||||
let source_trees = vec![];
|
let source_trees = vec![];
|
||||||
|
|
||||||
|
// Collect the list of members.
|
||||||
|
let members = {
|
||||||
|
let mut members = workspace.packages().keys().cloned().collect::<Vec<_>>();
|
||||||
|
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
|
// Determine the supported Python range. If no range is defined, and warn and default to the
|
||||||
// current minor version.
|
// current minor version.
|
||||||
let requires_python = find_requires_python(workspace)?;
|
let requires_python = find_requires_python(workspace)?;
|
||||||
|
@ -335,6 +354,43 @@ async fn do_lock(
|
||||||
FlatIndex::from_entries(entries, None, &hasher, build_options)
|
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.
|
// If any of the resolution-determining settings changed, invalidate the lock.
|
||||||
let existing_lock = existing_lock.filter(|lock| {
|
let existing_lock = existing_lock.filter(|lock| {
|
||||||
if lock.resolution_mode() != options.resolution_mode {
|
if lock.resolution_mode() != options.resolution_mode {
|
||||||
|
@ -401,19 +457,23 @@ async fn do_lock(
|
||||||
|
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
let requires_python = find_requires_python(workspace)?;
|
|
||||||
let existing_lock = existing_lock.filter(|lock| {
|
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
|
// 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
|
// Requires-Python bound in the workspace, we should have the necessary wheels to perform
|
||||||
// a locked resolution.
|
// a locked resolution.
|
||||||
(None, Some(_)) => true,
|
(None, _) => true,
|
||||||
(Some(locked), Some(specified)) if locked.bound() == specified.bound() => true,
|
(Some(locked), specified) => {
|
||||||
|
if locked.bound() == specified.bound() {
|
||||||
// On the other hand, if the bound in the lockfile is stricter, meaning the
|
true
|
||||||
// bound has since been weakened, we have to perform a clean resolution to ensure
|
} else {
|
||||||
// we fetch the necessary wheels.
|
// On the other hand, if the bound in the lockfile is stricter, meaning the
|
||||||
_ => false,
|
// 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.
|
// 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
|
// 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
|
// 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
|
true
|
||||||
});
|
});
|
||||||
|
|
||||||
let resolution = match existing_lock {
|
let existing_lock = match existing_lock {
|
||||||
None => None,
|
None => None,
|
||||||
|
|
||||||
// Try to resolve using metadata in the lockfile.
|
// 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
|
// 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.
|
// any outdated metadata we fall back to a clean resolve.
|
||||||
Some(lock) => {
|
Some(lock) => {
|
||||||
debug!("Resolving with existing `uv.lock`");
|
if lock
|
||||||
|
.satisfies(
|
||||||
// Prefill the index with the lockfile metadata.
|
workspace,
|
||||||
let index = lock.to_index(workspace.install_path(), upgrade)?;
|
&members,
|
||||||
|
&constraints,
|
||||||
// Create a build dispatch.
|
&overrides,
|
||||||
let build_dispatch = BuildDispatch::new(
|
interpreter.tags()?,
|
||||||
&client,
|
&database,
|
||||||
cache,
|
)
|
||||||
&build_constraints,
|
.await?
|
||||||
interpreter,
|
{
|
||||||
index_locations,
|
debug!("Existing `uv.lock` satisfies workspace requirements");
|
||||||
&flat_index,
|
Some(lock)
|
||||||
&index,
|
} else {
|
||||||
&state.git,
|
debug!("Existing `uv.lock` does not satisfy workspace requirements; ignoring...");
|
||||||
&state.in_flight,
|
None
|
||||||
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
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let resolution = match resolution {
|
match existing_lock {
|
||||||
// Resolution from the lockfile succeeded.
|
// 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
|
// The lockfile did not contain enough information to obtain a resolution, fallback
|
||||||
// to a fresh resolve.
|
// to a fresh resolve.
|
||||||
None => {
|
None => {
|
||||||
debug!("Starting clean resolution");
|
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.
|
// Resolve the requirements.
|
||||||
pip::operations::resolve(
|
let resolution = pip::operations::resolve(
|
||||||
requirements,
|
requirements,
|
||||||
constraints,
|
constraints.clone(),
|
||||||
overrides,
|
overrides
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.map(UnresolvedRequirementSpecification::from)
|
||||||
|
.collect(),
|
||||||
dev,
|
dev,
|
||||||
source_trees,
|
source_trees,
|
||||||
None,
|
None,
|
||||||
|
@ -619,17 +615,23 @@ async fn do_lock(
|
||||||
printer,
|
printer,
|
||||||
preview,
|
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.
|
/// Write the lockfile to disk.
|
||||||
|
|
|
@ -102,6 +102,9 @@ pub(crate) enum ProjectError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Tool(#[from] uv_tool::Error),
|
Tool(#[from] uv_tool::Error),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
NamedRequirements(#[from] uv_requirements::NamedRequirementsError),
|
||||||
|
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Fmt(#[from] std::fmt::Error),
|
Fmt(#[from] std::fmt::Error),
|
||||||
|
|
||||||
|
|
|
@ -710,7 +710,10 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
Commands::Project(project) => {
|
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")]
|
#[cfg(feature = "self-update")]
|
||||||
Commands::Self_(SelfNamespace {
|
Commands::Self_(SelfNamespace {
|
||||||
|
|
|
@ -226,6 +226,13 @@ fn root_package_splits_transitive_too() -> Result<()> {
|
||||||
{ name = "b" },
|
{ 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]]
|
[[package]]
|
||||||
name = "anyio"
|
name = "anyio"
|
||||||
version = "4.2.0"
|
version = "4.2.0"
|
||||||
|
@ -267,6 +274,12 @@ fn root_package_splits_transitive_too() -> Result<()> {
|
||||||
{ name = "b2", marker = "python_version >= '3.12'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "b1"
|
name = "b1"
|
||||||
version = "0.1.0"
|
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'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "b2"
|
name = "b2"
|
||||||
version = "0.1.0"
|
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'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "3.6"
|
version = "3.6"
|
||||||
|
@ -403,6 +422,14 @@ fn root_package_splits_other_dependencies_too() -> Result<()> {
|
||||||
{ name = "b2", marker = "python_version >= '3.12'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "anyio"
|
name = "anyio"
|
||||||
version = "4.2.0"
|
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'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "b2"
|
name = "b2"
|
||||||
version = "0.1.0"
|
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'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "3.6"
|
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'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "iniconfig"
|
name = "iniconfig"
|
||||||
version = "1.1.1"
|
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'" },
|
{ 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]]
|
[[package]]
|
||||||
name = "iniconfig"
|
name = "iniconfig"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
@ -744,6 +789,12 @@ fn dont_pre_visit_url_packages() -> Result<()> {
|
||||||
{ name = "c" },
|
{ name = "c" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [
|
||||||
|
{ name = "c", specifier = "==0.1.0" },
|
||||||
|
{ name = "b", directory = "b" },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "b"
|
name = "b"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -752,6 +803,9 @@ fn dont_pre_visit_url_packages() -> Result<()> {
|
||||||
{ name = "c" },
|
{ name = "c" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "c", directory = "../c" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "c"
|
name = "c"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -103,6 +103,9 @@ fn add_registry() -> Result<()> {
|
||||||
{ name = "anyio" },
|
{ name = "anyio" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "anyio", specifier = "==3.7.0" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -260,6 +263,12 @@ fn add_git() -> Result<()> {
|
||||||
{ name = "uv-public-pypackage" },
|
{ 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]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -363,6 +372,9 @@ fn add_git_private_source() -> Result<()> {
|
||||||
{ name = "uv-private-pypackage" },
|
{ name = "uv-private-pypackage" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "uv-private-pypackage", git = "https://github.com/astral-test/uv-private-pypackage" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uv-private-pypackage"
|
name = "uv-private-pypackage"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -459,6 +471,9 @@ fn add_git_private_raw() -> Result<()> {
|
||||||
{ name = "uv-private-pypackage" },
|
{ name = "uv-private-pypackage" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "uv-private-pypackage", git = "https://github.com/astral-test/uv-private-pypackage" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uv-private-pypackage"
|
name = "uv-private-pypackage"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -659,6 +674,12 @@ fn add_git_raw() -> Result<()> {
|
||||||
{ name = "uv-public-pypackage" },
|
{ 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]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -853,6 +874,9 @@ fn add_unnamed() -> Result<()> {
|
||||||
{ name = "uv-public-pypackage" },
|
{ 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]]
|
[[package]]
|
||||||
name = "uv-public-pypackage"
|
name = "uv-public-pypackage"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -972,6 +996,11 @@ fn add_remove_dev() -> Result<()> {
|
||||||
{ name = "anyio" },
|
{ name = "anyio" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
|
||||||
|
[package.metadata.requires-dev]
|
||||||
|
dev = [{ name = "anyio", specifier = "==3.7.0" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -1177,6 +1206,9 @@ fn add_remove_optional() -> Result<()> {
|
||||||
{ name = "anyio" },
|
{ name = "anyio" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "anyio", marker = "extra == 'io'", specifier = "==3.7.0" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -1390,6 +1422,12 @@ fn add_remove_workspace() -> Result<()> {
|
||||||
[options]
|
[options]
|
||||||
exclude-newer = "2024-03-25 00:00:00 UTC"
|
exclude-newer = "2024-03-25 00:00:00 UTC"
|
||||||
|
|
||||||
|
[manifest]
|
||||||
|
members = [
|
||||||
|
"child1",
|
||||||
|
"child2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "child1"
|
name = "child1"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1398,6 +1436,9 @@ fn add_remove_workspace() -> Result<()> {
|
||||||
{ name = "child2" },
|
{ name = "child2" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "child2", editable = "child2" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "child2"
|
name = "child2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1465,6 +1506,12 @@ fn add_remove_workspace() -> Result<()> {
|
||||||
[options]
|
[options]
|
||||||
exclude-newer = "2024-03-25 00:00:00 UTC"
|
exclude-newer = "2024-03-25 00:00:00 UTC"
|
||||||
|
|
||||||
|
[manifest]
|
||||||
|
members = [
|
||||||
|
"child1",
|
||||||
|
"child2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "child1"
|
name = "child1"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1576,6 +1623,12 @@ fn add_workspace_editable() -> Result<()> {
|
||||||
[options]
|
[options]
|
||||||
exclude-newer = "2024-03-25 00:00:00 UTC"
|
exclude-newer = "2024-03-25 00:00:00 UTC"
|
||||||
|
|
||||||
|
[manifest]
|
||||||
|
members = [
|
||||||
|
"child1",
|
||||||
|
"child2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "child1"
|
name = "child1"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1584,6 +1637,9 @@ fn add_workspace_editable() -> Result<()> {
|
||||||
{ name = "child2" },
|
{ name = "child2" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "child2", editable = "child2" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "child2"
|
name = "child2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1837,6 +1893,9 @@ fn update() -> Result<()> {
|
||||||
{ name = "requests", extra = ["socks", "use-chardet-on-py3"] },
|
{ 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]]
|
[[package]]
|
||||||
name = "pysocks"
|
name = "pysocks"
|
||||||
version = "1.7.1"
|
version = "1.7.1"
|
||||||
|
@ -1865,6 +1924,16 @@ fn update() -> Result<()> {
|
||||||
{ name = "chardet" },
|
{ 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]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
|
@ -2064,6 +2133,9 @@ fn add_no_clean() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "iniconfig" },
|
{ name = "iniconfig" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "iniconfig", specifier = "==2.0.0" }]
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -2835,6 +2907,9 @@ fn add_lower_bound_optional() -> Result<()> {
|
||||||
{ name = "anyio" },
|
{ name = "anyio" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "anyio", marker = "extra == 'io'" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sniffio"
|
name = "sniffio"
|
||||||
version = "1.3.1"
|
version = "1.3.1"
|
||||||
|
@ -2923,6 +2998,9 @@ fn add_lower_bound_local() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "local-simple-a" },
|
{ name = "local-simple-a" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "local-simple-a" }]
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -108,13 +108,34 @@ fn fork_allows_non_conflicting_non_overlapping_dependencies() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "package-a", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -216,13 +237,34 @@ fn fork_allows_non_conflicting_repeated_dependencies() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "package-a" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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-b", marker = "sys_platform == 'linux'" },
|
||||||
{ name = "package-c", marker = "sys_platform == 'darwin'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -780,13 +866,31 @@ fn fork_upgrade() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "package-foo" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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-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" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -1060,13 +1186,34 @@ fn fork_marker_accrue() -> Result<()> {
|
||||||
{ name = "package-a", marker = "implementation_name == 'cpython'" },
|
{ name = "package-a", marker = "implementation_name == 'cpython'" },
|
||||||
{ name = "package-b", marker = "implementation_name == 'pypy'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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-a", version = "2.0.0", source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }, marker = "sys_platform == 'linux'" },
|
||||||
{ name = "package-b" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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.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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -2637,13 +2976,34 @@ fn fork_non_fork_marker_transitive() -> Result<()> {
|
||||||
{ name = "package-a" },
|
{ name = "package-a" },
|
||||||
{ name = "package-b" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -2916,13 +3276,35 @@ fn fork_overlapping_markers_basic() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "package-a" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -3155,13 +3537,31 @@ fn preferences_dependent_forking_bistable() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "package-cleaver" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -3577,13 +3977,35 @@ fn preferences_dependent_forking_tristable() -> Result<()> {
|
||||||
{ name = "package-cleaver" },
|
{ name = "package-cleaver" },
|
||||||
{ name = "package-foo" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -3773,13 +4195,35 @@ fn preferences_dependent_forking() -> Result<()> {
|
||||||
{ name = "package-cleaver" },
|
{ name = "package-cleaver" },
|
||||||
{ name = "package-foo" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_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 = "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'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -4034,13 +4499,31 @@ fn fork_requires_python_full_prerelease() -> Result<()> {
|
||||||
name = "project"
|
name = "project"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = { editable = "." }
|
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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -4117,13 +4600,31 @@ fn fork_requires_python_full() -> Result<()> {
|
||||||
name = "project"
|
name = "project"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = { editable = "." }
|
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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -4216,13 +4717,31 @@ fn fork_requires_python_patch_overlap() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "package-a", marker = "python_version == '3.10'" },
|
{ 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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -4296,13 +4815,31 @@ fn fork_requires_python() -> Result<()> {
|
||||||
name = "project"
|
name = "project"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = { editable = "." }
|
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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
|
|
@ -202,6 +202,23 @@ uvloop = [
|
||||||
{ name = "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]]
|
[[package]]
|
||||||
name = "click"
|
name = "click"
|
||||||
version = "8.1.7"
|
version = "8.1.7"
|
||||||
|
|
|
@ -125,6 +125,25 @@ dev = [
|
||||||
{ name = "types-requests" },
|
{ 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]]
|
[[package]]
|
||||||
name = "h11"
|
name = "h11"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
|
|
@ -662,6 +662,49 @@ dependencies = [
|
||||||
{ name = "yarl" },
|
{ 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]]
|
[[package]]
|
||||||
name = "httpcore"
|
name = "httpcore"
|
||||||
version = "1.0.5"
|
version = "1.0.5"
|
||||||
|
|
|
@ -353,6 +353,26 @@ dev = [
|
||||||
{ name = "syrupy" },
|
{ 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]]
|
[[package]]
|
||||||
name = "pathspec"
|
name = "pathspec"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
|
|
|
@ -5866,6 +5866,280 @@ vision = [
|
||||||
{ name = "pillow" },
|
{ 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]]
|
[[package]]
|
||||||
name = "triton"
|
name = "triton"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
|
|
|
@ -4277,6 +4277,150 @@ dev = [
|
||||||
{ name = "webtest" },
|
{ 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]]
|
[[package]]
|
||||||
name = "watchdog"
|
name = "watchdog"
|
||||||
version = "4.0.1"
|
version = "4.0.1"
|
||||||
|
|
|
@ -757,6 +757,9 @@ fn sync_relative_wheel() -> Result<()> {
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "ok" },
|
{ name = "ok" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "ok", path = "wheels/ok-1.0.0-py3-none-any.whl" }]
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1088,6 +1088,12 @@ fn workspace_inherit_sources() -> Result<()> {
|
||||||
[options]
|
[options]
|
||||||
exclude-newer = "2024-03-25 00:00:00 UTC"
|
exclude-newer = "2024-03-25 00:00:00 UTC"
|
||||||
|
|
||||||
|
[manifest]
|
||||||
|
members = [
|
||||||
|
"leaf",
|
||||||
|
"workspace",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leaf"
|
name = "leaf"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1096,6 +1102,9 @@ fn workspace_inherit_sources() -> Result<()> {
|
||||||
{ name = "library" },
|
{ name = "library" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[package.metadata]
|
||||||
|
requires-dist = [{ name = "library", editable = "../library" }]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "library"
|
name = "library"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1374,7 +1383,7 @@ fn workspace_member_name_shadows_dependencies() -> Result<()> {
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Using Python 3.12.[X] interpreter at: [PYTHON-3.12]
|
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: Failed to parse entry for: `anyio`
|
||||||
Caused by: Package is not included as workspace package in `tool.uv.workspace`
|
Caused by: Package is not included as workspace package in `tool.uv.workspace`
|
||||||
"###
|
"###
|
||||||
|
|
|
@ -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
|
context
|
||||||
.lock()
|
.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")
|
.env_remove("UV_EXCLUDE_NEWER")
|
||||||
.arg("--index-url")
|
.arg("--index-url")
|
||||||
.arg(packse_index_url())
|
.arg(packse_index_url())
|
||||||
|
@ -81,6 +96,8 @@ fn {{module_name}}() -> Result<()> {
|
||||||
.success();
|
.success();
|
||||||
let lock2 = fs_err::read_to_string(context.temp_dir.join("uv.lock"))?;
|
let lock2 = fs_err::read_to_string(context.temp_dir.join("uv.lock"))?;
|
||||||
assert_eq!(lock2, lock);
|
assert_eq!(lock2, lock);
|
||||||
|
|
||||||
|
|
||||||
{{/expected.satisfiable}}
|
{{/expected.satisfiable}}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue