Rename dev dependencies to dependency groups in lockfile (#8391)

This is backwards compatible (we respect `dev-dependencies` as an
alias).

Part of https://github.com/astral-sh/uv/pull/8272.
This commit is contained in:
Charlie Marsh 2024-10-21 22:56:43 -04:00 committed by Zanie Blue
parent c7ccf88939
commit 5ab860be20
28 changed files with 273 additions and 130 deletions

View File

@ -66,7 +66,7 @@ pub struct Metadata {
pub requires_dist: Vec<uv_pypi_types::Requirement>,
pub requires_python: Option<VersionSpecifiers>,
pub provides_extras: Vec<ExtraName>,
pub dev_dependencies: BTreeMap<GroupName, Vec<uv_pypi_types::Requirement>>,
pub dependency_groups: BTreeMap<GroupName, Vec<uv_pypi_types::Requirement>>,
}
impl Metadata {
@ -83,7 +83,7 @@ impl Metadata {
.collect(),
requires_python: metadata.requires_python,
provides_extras: metadata.provides_extras,
dev_dependencies: BTreeMap::default(),
dependency_groups: BTreeMap::default(),
}
}
@ -101,7 +101,7 @@ impl Metadata {
name,
requires_dist,
provides_extras,
dev_dependencies,
dependency_groups,
} = RequiresDist::from_project_maybe_workspace(
uv_pypi_types::RequiresDist {
name: metadata.name,
@ -122,7 +122,7 @@ impl Metadata {
requires_dist,
requires_python: metadata.requires_python,
provides_extras,
dev_dependencies,
dependency_groups,
})
}
}

View File

@ -19,7 +19,7 @@ pub struct RequiresDist {
pub name: PackageName,
pub requires_dist: Vec<uv_pypi_types::Requirement>,
pub provides_extras: Vec<ExtraName>,
pub dev_dependencies: BTreeMap<GroupName, Vec<uv_pypi_types::Requirement>>,
pub dependency_groups: BTreeMap<GroupName, Vec<uv_pypi_types::Requirement>>,
}
impl RequiresDist {
@ -34,7 +34,7 @@ impl RequiresDist {
.map(uv_pypi_types::Requirement::from)
.collect(),
provides_extras: metadata.provides_extras,
dev_dependencies: BTreeMap::default(),
dependency_groups: BTreeMap::default(),
}
}
@ -101,7 +101,7 @@ impl RequiresDist {
SourceStrategy::Disabled => &empty,
};
let dev_dependencies = {
let dependency_groups = {
// First, collect `tool.uv.dev_dependencies`
let dev_dependencies = project_workspace
.current_project()
@ -218,7 +218,7 @@ impl RequiresDist {
Ok(Self {
name: metadata.name,
requires_dist,
dev_dependencies,
dependency_groups,
provides_extras: metadata.provides_extras,
})
}
@ -230,7 +230,7 @@ impl From<Metadata> for RequiresDist {
name: metadata.name,
requires_dist: metadata.requires_dist,
provides_extras: metadata.provides_extras,
dev_dependencies: metadata.dev_dependencies,
dependency_groups: metadata.dependency_groups,
}
}
}

View File

@ -195,7 +195,7 @@ impl<'a, Context: BuildContext> LookaheadResolver<'a, Context> {
.into_iter()
.chain(
metadata
.dev_dependencies
.dependency_groups
.into_iter()
.filter_map(|(group, dependencies)| {
if self.dev.contains(&group) {

View File

@ -211,7 +211,7 @@ impl Lock {
continue;
};
let marker = edge.weight().clone();
package.add_dev_dependency(
package.add_group_dependency(
&requires_python,
group.clone(),
dependency_dist,
@ -344,7 +344,7 @@ impl Lock {
}
// Perform the same validation for dev dependencies.
for (group, dependencies) in &mut package.dev_dependencies {
for (group, dependencies) in &mut package.dependency_groups {
dependencies.sort();
for windows in dependencies.windows(2) {
let (dep1, dep2) = (&windows[0], &windows[1]);
@ -390,7 +390,7 @@ impl Lock {
.dependencies
.iter_mut()
.chain(dist.optional_dependencies.values_mut().flatten())
.chain(dist.dev_dependencies.values_mut().flatten())
.chain(dist.dependency_groups.values_mut().flatten())
{
dep.extra.retain(|extra| {
extras_by_id
@ -428,7 +428,7 @@ impl Lock {
}
// Perform the same validation for dev dependencies.
for dependencies in dist.dev_dependencies.values() {
for dependencies in dist.dependency_groups.values() {
for dep in dependencies {
if !by_id.contains_key(&dep.package_id) {
return Err(LockErrorKind::UnrecognizedDependency {
@ -620,7 +620,7 @@ impl Lock {
// Add any dev dependencies.
for group in dev.iter() {
for dep in root.dev_dependencies.get(group).into_iter().flatten() {
for dep in root.dependency_groups.get(group).into_iter().flatten() {
if dep.complexified_marker.evaluate(marker_env, &[]) {
let dep_dist = self.find_by_id(&dep.package_id);
if seen.insert((&dep.package_id, None)) {
@ -1234,10 +1234,10 @@ impl Lock {
}
}
// Validate the `dev-dependencies` metadata.
// Validate the `dependency-groups` metadata.
{
let expected: BTreeMap<GroupName, BTreeSet<Requirement>> = metadata
.dev_dependencies
.dependency_groups
.into_iter()
.map(|(group, requirements)| {
Ok::<_, LockError>((
@ -1251,7 +1251,7 @@ impl Lock {
.collect::<Result<_, _>>()?;
let actual: BTreeMap<GroupName, BTreeSet<Requirement>> = package
.metadata
.requires_dev
.dependency_groups
.iter()
.map(|(group, requirements)| {
Ok::<_, LockError>((
@ -1266,7 +1266,7 @@ impl Lock {
.collect::<Result<_, _>>()?;
if expected != actual {
return Ok(SatisfiesResult::MismatchedDevDependencies(
return Ok(SatisfiesResult::MismatchedDependencyGroups(
&package.id.name,
&package.id.version,
expected,
@ -1294,7 +1294,7 @@ impl Lock {
}
}
for dependencies in package.dev_dependencies.values() {
for dependencies in package.dependency_groups.values() {
for dep in dependencies {
if seen.insert(&dep.package_id) {
let dep_dist = self.find_by_id(&dep.package_id);
@ -1358,8 +1358,8 @@ pub enum SatisfiesResult<'lock> {
BTreeSet<Requirement>,
BTreeSet<Requirement>,
),
/// A package in the lockfile contains different `dev-dependencies` metadata than expected.
MismatchedDevDependencies(
/// A package in the lockfile contains different `dependency-group` metadata than expected.
MismatchedDependencyGroups(
&'lock PackageName,
&'lock Version,
BTreeMap<GroupName, BTreeSet<Requirement>>,
@ -1544,8 +1544,8 @@ pub struct Package {
dependencies: Vec<Dependency>,
/// The resolved optional dependencies of the package.
optional_dependencies: BTreeMap<ExtraName, Vec<Dependency>>,
/// The resolved development dependencies of the package.
dev_dependencies: BTreeMap<GroupName, Vec<Dependency>>,
/// The resolved PEP 735 dependency groups of the package.
dependency_groups: BTreeMap<GroupName, Vec<Dependency>>,
/// The exact requirements from the package metadata.
metadata: PackageMetadata,
}
@ -1573,14 +1573,14 @@ impl Package {
.collect::<Result<_, _>>()
.map_err(LockErrorKind::RequirementRelativePath)?
};
let requires_dev = if id.source.is_immutable() {
let dependency_groups = if id.source.is_immutable() {
BTreeMap::default()
} else {
annotated_dist
.metadata
.as_ref()
.expect("metadata is present")
.dev_dependencies
.dependency_groups
.iter()
.map(|(group, requirements)| {
let requirements = requirements
@ -1600,10 +1600,10 @@ impl Package {
fork_markers,
dependencies: vec![],
optional_dependencies: BTreeMap::default(),
dev_dependencies: BTreeMap::default(),
dependency_groups: BTreeMap::default(),
metadata: PackageMetadata {
requires_dist,
requires_dev,
dependency_groups,
},
})
}
@ -1679,18 +1679,18 @@ impl Package {
Ok(())
}
/// Add the [`AnnotatedDist`] as a development dependency of the [`Package`].
fn add_dev_dependency(
/// Add the [`AnnotatedDist`] to a dependency group of the [`Package`].
fn add_group_dependency(
&mut self,
requires_python: &RequiresPython,
dev: GroupName,
group: GroupName,
annotated_dist: &AnnotatedDist,
marker: MarkerTree,
root: &Path,
) -> Result<(), LockError> {
let dep = Dependency::from_annotated_dist(requires_python, annotated_dist, marker, root)?;
let dev_deps = self.dev_dependencies.entry(dev).or_default();
for existing_dep in &mut *dev_deps {
let deps = self.dependency_groups.entry(group).or_default();
for existing_dep in &mut *deps {
if existing_dep.package_id == dep.package_id
// See note in add_dependency for why we use
// simplified markers here.
@ -1701,7 +1701,7 @@ impl Package {
}
}
dev_deps.push(dep);
deps.push(dep);
Ok(())
}
@ -2051,19 +2051,19 @@ impl Package {
}
}
if !self.dev_dependencies.is_empty() {
let mut dev_dependencies = Table::new();
for (extra, deps) in &self.dev_dependencies {
if !self.dependency_groups.is_empty() {
let mut dependency_groups = Table::new();
for (extra, deps) in &self.dependency_groups {
let deps = each_element_on_its_line_array(deps.iter().map(|dep| {
dep.to_toml(requires_python, dist_count_by_name)
.into_inline_table()
}));
if !deps.is_empty() {
dev_dependencies.insert(extra.as_ref(), value(deps));
dependency_groups.insert(extra.as_ref(), value(deps));
}
}
if !dev_dependencies.is_empty() {
table.insert("dev-dependencies", Item::Table(dev_dependencies));
if !dependency_groups.is_empty() {
table.insert("dependency-groups", Item::Table(dependency_groups));
}
}
@ -2106,9 +2106,9 @@ impl Package {
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 {
if !self.metadata.dependency_groups.is_empty() {
let mut dependency_groups = Table::new();
for (extra, deps) in &self.metadata.dependency_groups {
let deps = deps
.iter()
.map(|requirement| {
@ -2124,11 +2124,11 @@ impl Package {
deps => each_element_on_its_line_array(deps.iter()),
};
if !deps.is_empty() {
requires_dev.insert(extra.as_ref(), value(deps));
dependency_groups.insert(extra.as_ref(), value(deps));
}
}
if !requires_dev.is_empty() {
metadata_table.insert("requires-dev", Item::Table(requires_dev));
if !dependency_groups.is_empty() {
metadata_table.insert("dependency-groups", Item::Table(dependency_groups));
}
}
@ -2238,8 +2238,8 @@ struct PackageWire {
dependencies: Vec<DependencyWire>,
#[serde(default)]
optional_dependencies: BTreeMap<ExtraName, Vec<DependencyWire>>,
#[serde(default)]
dev_dependencies: BTreeMap<GroupName, Vec<DependencyWire>>,
#[serde(default, alias = "dev-dependencies")]
dependency_groups: BTreeMap<GroupName, Vec<DependencyWire>>,
}
#[derive(Clone, Default, Debug, Eq, PartialEq, serde::Deserialize)]
@ -2247,8 +2247,8 @@ struct PackageWire {
struct PackageMetadata {
#[serde(default)]
requires_dist: BTreeSet<Requirement>,
#[serde(default)]
requires_dev: BTreeMap<GroupName, BTreeSet<Requirement>>,
#[serde(default, alias = "requires-dev")]
dependency_groups: BTreeMap<GroupName, BTreeSet<Requirement>>,
}
impl PackageWire {
@ -2278,8 +2278,8 @@ impl PackageWire {
.into_iter()
.map(|(extra, deps)| Ok((extra, unwire_deps(deps)?)))
.collect::<Result<_, LockError>>()?,
dev_dependencies: self
.dev_dependencies
dependency_groups: self
.dependency_groups
.into_iter()
.map(|(group, deps)| Ok((group, unwire_deps(deps)?)))
.collect::<Result<_, LockError>>()?,

View File

@ -86,7 +86,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
// Add any dev dependencies.
for group in dev.iter() {
for dep in root.dev_dependencies.get(group).into_iter().flatten() {
for dep in root.dependency_groups.get(group).into_iter().flatten() {
let dep_dist = lock.find_by_id(&dep.package_id);
// Add the dependency to the graph.

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -78,10 +78,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -85,10 +85,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -81,10 +81,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -71,10 +71,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
Package {
@ -136,10 +136,10 @@ Ok(
},
],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -71,10 +71,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
Package {
@ -136,10 +136,10 @@ Ok(
},
],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -71,10 +71,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
Package {
@ -136,10 +136,10 @@ Ok(
},
],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -55,10 +55,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -53,10 +53,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -48,10 +48,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -1,5 +1,5 @@
---
source: crates/uv-resolver/src/lock/mod.rs
source: crates/uv-resolver/src/lock/tests.rs
expression: result
---
Ok(
@ -48,10 +48,10 @@ Ok(
fork_markers: [],
dependencies: [],
optional_dependencies: {},
dev_dependencies: {},
dependency_groups: {},
metadata: PackageMetadata {
requires_dist: {},
requires_dev: {},
dependency_groups: {},
},
},
],

View File

@ -104,7 +104,7 @@ impl<'env> TreeDisplay<'env> {
}
}
for (group, dependencies) in &package.dev_dependencies {
for (group, dependencies) in &package.dependency_groups {
for dependency in dependencies {
// Insert the package into the graph.
let package_node = if let Some(index) = inverse.get(&package.id) {

View File

@ -355,7 +355,7 @@ impl ResolutionGraph {
// Validate the development dependency group.
if let Some(dev) = dev {
if !metadata.dev_dependencies.contains_key(dev) {
if !metadata.dependency_groups.contains_key(dev) {
diagnostics.push(ResolutionDiagnostic::MissingDev {
dist: dist.clone(),
dev: dev.clone(),
@ -872,7 +872,7 @@ fn has_lower_bound(
for requirement in metadata
.requires_dist
.iter()
.chain(metadata.dev_dependencies.values().flatten())
.chain(metadata.dependency_groups.values().flatten())
{
if requirement.name != *package_name {
continue;

View File

@ -1341,7 +1341,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
let requirements = self.flatten_requirements(
&metadata.requires_dist,
&metadata.dev_dependencies,
&metadata.dependency_groups,
extra.as_ref(),
dev.as_ref(),
Some(name),
@ -1361,7 +1361,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
// enabled.
if extra.is_none() && dev.is_none() {
for group in self.groups.get(name).into_iter().flatten() {
if !metadata.dev_dependencies.contains_key(group) {
if !metadata.dependency_groups.contains_key(group) {
continue;
}
dependencies.push(PubGrubDependency {

View File

@ -905,7 +905,7 @@ impl ValidatedLock {
);
Ok(Self::Preferable(lock))
}
SatisfiesResult::MismatchedDevDependencies(name, version, expected, actual) => {
SatisfiesResult::MismatchedDependencyGroups(name, version, expected, actual) => {
debug!(
"Ignoring existing lockfile due to mismatched dev dependencies for: `{name}=={version}`\n Expected: {:?}\n Actual: {:?}",
expected, actual

View File

@ -1074,14 +1074,14 @@ fn add_remove_dev() -> Result<()> {
version = "0.1.0"
source = { editable = "." }
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "anyio" },
]
[package.metadata]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "anyio", specifier = "==3.7.0" }]
[[package]]

View File

@ -4541,7 +4541,7 @@ fn lock_dev() -> Result<()> {
{ name = "iniconfig" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "typing-extensions" },
]
@ -4549,7 +4549,7 @@ fn lock_dev() -> Result<()> {
[package.metadata]
requires-dist = [{ name = "iniconfig" }]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "typing-extensions", url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl" }]
[[package]]
@ -6153,14 +6153,14 @@ fn lock_dev_transitive() -> Result<()> {
version = "0.1.0"
source = { editable = "baz" }
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "typing-extensions" },
]
[package.metadata]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "typing-extensions", specifier = ">4" }]
[[package]]
@ -6170,7 +6170,7 @@ fn lock_dev_transitive() -> Result<()> {
[package.metadata]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "anyio" }]
[[package]]
@ -7080,7 +7080,7 @@ fn lock_no_sources() -> Result<()> {
{ name = "anyio" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "typing-extensions" },
]
@ -7088,7 +7088,7 @@ fn lock_no_sources() -> Result<()> {
[package.metadata]
requires-dist = [{ name = "anyio", directory = "anyio" }]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "typing-extensions", specifier = ">4" }]
[[package]]
@ -7170,7 +7170,7 @@ fn lock_no_sources() -> Result<()> {
{ name = "anyio" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "typing-extensions" },
]
@ -7178,7 +7178,7 @@ fn lock_no_sources() -> Result<()> {
[package.metadata]
requires-dist = [{ name = "anyio" }]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "typing-extensions", specifier = ">4" }]
[[package]]
@ -10903,6 +10903,149 @@ fn lock_missing_metadata() -> Result<()> {
Ok(())
}
/// Test backwards compatibility for `package.dev-dependencies`, which was renamed to
/// `package.dependency-groups`.
#[test]
fn lock_dev_dependencies_alias() -> Result<()> {
let context = TestContext::new("3.12");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
[tool.uv]
dev-dependencies = ["iniconfig"]
"#,
)?;
let lock = context.temp_dir.child("uv.lock");
// Write a lockfile with `[package.dev-dependencies]`.
lock.write_str(r#"
version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "project"
version = "0.1.0"
source = { virtual = "." }
[package.dev-dependencies]
dev = [{ name = "iniconfig" }]
[package.metadata]
[package.metadata.requires-dev]
dev = [{ name = "iniconfig" }]
[[package]]
name = "iniconfig"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
]
"#)?;
// Re-locking should be a no-op.
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
"###);
// If we add a package, re-locking should use `dependency-groups`.
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["typing-extensions"]
[tool.uv]
dev-dependencies = ["iniconfig"]
"#,
)?;
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 3 packages in [TIME]
Added typing-extensions v4.10.0
"###);
let lock = context.read("uv.lock");
insta::with_settings!({
filters => context.filters(),
}, {
assert_snapshot!(
lock, @r###"
version = 1
requires-python = ">=3.12"
[options]
exclude-newer = "2024-03-25T00:00:00Z"
[[package]]
name = "iniconfig"
version = "2.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 },
]
[[package]]
name = "project"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "typing-extensions" },
]
[package.dependency-groups]
dev = [
{ name = "iniconfig" },
]
[package.metadata]
requires-dist = [{ name = "typing-extensions" }]
[package.metadata.dependency-groups]
dev = [{ name = "iniconfig" }]
[[package]]
name = "typing-extensions"
version = "4.10.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/16/3a/0d26ce356c7465a19c9ea8814b960f8a36c3b0d07c323176620b7b483e44/typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb", size = 77558 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f9/de/dc04a3ea60b22624b51c703a84bbe0184abcd1d0b9bc8074b5d6b7ab90bb/typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", size = 33926 },
]
"###
);
});
Ok(())
}
/// Lock a `pyproject.toml`, reorder the dependencies, and ensure that the lockfile is _not_ updated
/// on the next run.
#[test]
@ -12272,14 +12415,14 @@ fn lock_dropped_dev_extra() -> Result<()> {
version = "0.1.0"
source = { editable = "." }
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "coverage" },
]
[package.metadata]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "coverage", extras = ["toml"] }]
"###
);
@ -13242,7 +13385,7 @@ fn lock_explicit_virtual_project() -> Result<()> {
{ name = "black" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "anyio" },
]
@ -13250,7 +13393,7 @@ fn lock_explicit_virtual_project() -> Result<()> {
[package.metadata]
requires-dist = [{ name = "black" }]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "anyio" }]
[[package]]
@ -13459,7 +13602,7 @@ fn lock_implicit_virtual_project() -> Result<()> {
{ name = "black" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "anyio" },
]
@ -13467,7 +13610,7 @@ fn lock_implicit_virtual_project() -> Result<()> {
[package.metadata]
requires-dist = [{ name = "black" }]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [{ name = "anyio" }]
[[package]]
@ -16410,7 +16553,7 @@ fn lock_group_include() -> Result<()> {
{ name = "typing-extensions" },
]
[package.dev-dependencies]
[package.dependency-groups]
bar = [
{ name = "trio" },
]
@ -16422,7 +16565,7 @@ fn lock_group_include() -> Result<()> {
[package.metadata]
requires-dist = [{ name = "typing-extensions" }]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
bar = [{ name = "trio" }]
foo = [
{ name = "anyio" },

View File

@ -116,7 +116,7 @@ dependencies = [
{ name = "yarl" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "httpx" },
{ name = "pytest" },
@ -135,7 +135,7 @@ requires-dist = [
{ name = "yarl", specifier = ">=1.9,<2" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "httpx", specifier = ">=0.27.0,<0.28" },
{ name = "pytest", specifier = ">=8.0.0,<9" },

View File

@ -332,7 +332,7 @@ serve = [
{ name = "watchfiles" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "psutil" },
{ name = "pytest" },
@ -352,7 +352,7 @@ requires-dist = [
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },

View File

@ -3889,7 +3889,7 @@ deploy = [
{ name = "gunicorn" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "asyncudp" },
{ name = "black" },
@ -4033,7 +4033,7 @@ requires-dist = [
{ name = "zxcvbn" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "asyncudp", specifier = ">=0.7" },
{ name = "black", specifier = "==24.4.2" },

View File

@ -328,7 +328,7 @@ serve = [
{ name = "watchfiles" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "psutil" },
{ name = "pytest" },
@ -348,7 +348,7 @@ requires-dist = [
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },

View File

@ -328,7 +328,7 @@ serve = [
{ name = "watchfiles" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "psutil" },
{ name = "pytest" },
@ -348,7 +348,7 @@ requires-dist = [
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },

View File

@ -328,7 +328,7 @@ serve = [
{ name = "watchfiles" },
]
[package.dev-dependencies]
[package.dependency-groups]
dev = [
{ name = "psutil" },
{ name = "pytest" },
@ -348,7 +348,7 @@ requires-dist = [
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },

View File

@ -72,7 +72,7 @@ fn packse_add_remove_one_package() {
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },
@ -160,7 +160,7 @@ fn packse_add_remove_one_package() {
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },
@ -315,7 +315,7 @@ fn packse_promote_transitive_to_direct_then_remove() {
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },
@ -373,7 +373,7 @@ fn packse_promote_transitive_to_direct_then_remove() {
{ name = "watchfiles", marker = "extra == 'serve'", specifier = ">=0.21.0" },
]
[package.metadata.requires-dev]
[package.metadata.dependency-groups]
dev = [
{ name = "psutil", specifier = ">=5.9.7" },
{ name = "pytest", specifier = ">=7.4.3" },