mirror of https://github.com/astral-sh/uv
Avoid installing transitive dev dependencies (#7318)
## Summary This is arguably breaking, arguably a bug... Today, if project A depends on project B, and you install A with dev dependencies enabled, you also get B's dev dependencies. I think this is incorrect. Just like you shouldn't be importing B's dependencies from A, you shouldn't be using B's dev dependencies when developing on A. Closes #7310.
This commit is contained in:
parent
f22e5ef69a
commit
d52af0ccdd
|
|
@ -575,6 +575,23 @@ impl Lock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add any dev dependencies.
|
||||||
|
for group in dev {
|
||||||
|
for dep in root.dev_dependencies.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)) {
|
||||||
|
queue.push_back((dep_dist, None));
|
||||||
|
}
|
||||||
|
for extra in &dep.extra {
|
||||||
|
if seen.insert((&dep.package_id, Some(extra))) {
|
||||||
|
queue.push_back((dep_dist, Some(extra)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any dependency groups that are exclusive to the workspace root (e.g., dev
|
// Add any dependency groups that are exclusive to the workspace root (e.g., dev
|
||||||
|
|
@ -606,16 +623,11 @@ impl Lock {
|
||||||
let mut map = BTreeMap::default();
|
let mut map = BTreeMap::default();
|
||||||
let mut hashes = BTreeMap::default();
|
let mut hashes = BTreeMap::default();
|
||||||
while let Some((dist, extra)) = queue.pop_front() {
|
while let Some((dist, extra)) = queue.pop_front() {
|
||||||
let deps =
|
let deps = if let Some(extra) = extra {
|
||||||
if let Some(extra) = extra {
|
Either::Left(dist.optional_dependencies.get(extra).into_iter().flatten())
|
||||||
Either::Left(dist.optional_dependencies.get(extra).into_iter().flatten())
|
} else {
|
||||||
} else {
|
Either::Right(dist.dependencies.iter())
|
||||||
Either::Right(dist.dependencies.iter().chain(
|
};
|
||||||
dev.iter().flat_map(|group| {
|
|
||||||
dist.dev_dependencies.get(group).into_iter().flatten()
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
};
|
|
||||||
for dep in deps {
|
for dep in deps {
|
||||||
if dep.complexified_marker.evaluate(marker_env, &[]) {
|
if dep.complexified_marker.evaluate(marker_env, &[]) {
|
||||||
let dep_dist = self.find_by_id(&dep.package_id);
|
let dep_dist = self.find_by_id(&dep.package_id);
|
||||||
|
|
|
||||||
|
|
@ -2248,3 +2248,83 @@ fn sync_wheel_path_source_error() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Avoid installing dev dependencies of transitive dependencies.
|
||||||
|
#[test]
|
||||||
|
fn transitive_dev() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "root"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["child"]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
dev-dependencies = ["anyio>3"]
|
||||||
|
|
||||||
|
[tool.uv.sources]
|
||||||
|
child = { workspace = true }
|
||||||
|
|
||||||
|
[tool.uv.workspace]
|
||||||
|
members = ["child"]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let src = context.temp_dir.child("src").child("albatross");
|
||||||
|
src.create_dir_all()?;
|
||||||
|
|
||||||
|
let init = src.child("__init__.py");
|
||||||
|
init.touch()?;
|
||||||
|
|
||||||
|
let child = context.temp_dir.child("child");
|
||||||
|
fs_err::create_dir_all(&child)?;
|
||||||
|
|
||||||
|
let pyproject_toml = child.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "child"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
dev-dependencies = ["iniconfig>1"]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let src = child.child("src").child("albatross");
|
||||||
|
src.create_dir_all()?;
|
||||||
|
|
||||||
|
let init = src.child("__init__.py");
|
||||||
|
init.touch()?;
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.sync().arg("--dev"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 6 packages in [TIME]
|
||||||
|
Prepared 5 packages in [TIME]
|
||||||
|
Installed 5 packages in [TIME]
|
||||||
|
+ anyio==4.3.0
|
||||||
|
+ child==0.1.0 (from file://[TEMP_DIR]/child)
|
||||||
|
+ idna==3.6
|
||||||
|
+ root==0.1.0 (from file://[TEMP_DIR]/)
|
||||||
|
+ sniffio==1.3.1
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue