uv lock to use overrides from tool.uv (#4108) (#4369)

## Summary

This will make `uv lock` read `override-dependencies` from the
`[tool.uv]` section of `pyproject.toml`.
Resolves #4108

This [other](https://github.com/astral-sh/uv/pull/4446) implementation
touches more code but seems more consistent.

## Test Plan

Unit test
This commit is contained in:
Sandu
2024-06-24 12:44:54 -04:00
committed by GitHub
parent bfc342da94
commit 03cfdc2275
3 changed files with 83 additions and 1 deletions
+8
View File
@@ -83,6 +83,14 @@ pub struct ToolUv {
)
)]
pub dev_dependencies: Option<Vec<pep508_rs::Requirement<VerbatimParsedUrl>>>,
#[cfg_attr(
feature = "schemars",
schemars(
with = "Option<Vec<String>>",
description = "PEP 508 style requirements, e.g. `flask==3.0.0`, or `black @ https://...`."
)
)]
pub override_dependencies: Option<Vec<pep508_rs::Requirement<VerbatimParsedUrl>>>,
}
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq)]
+25 -1
View File
@@ -4,6 +4,7 @@ use anstream::eprint;
use distribution_types::{IndexLocations, UnresolvedRequirementSpecification};
use install_wheel_rs::linker::LinkMode;
use pep508_rs::RequirementOrigin;
use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
@@ -124,7 +125,30 @@ pub(super) async fn do_lock(
.map(UnresolvedRequirementSpecification::from)
.collect();
let constraints = vec![];
let overrides = vec![];
let mut overrides: Vec<UnresolvedRequirementSpecification> = vec![];
for workspace_package in workspace.packages().values() {
if workspace_package.root() == workspace.root() {
if let Some(override_dependencies) = workspace_package
.pyproject_toml()
.tool
.as_ref()
.and_then(|tool| tool.uv.as_ref())
.and_then(|uv| uv.override_dependencies.as_ref())
{
for override_dependency in override_dependencies {
let req = pypi_types::Requirement::from(
override_dependency
.clone()
.with_origin(RequirementOrigin::Workspace),
);
overrides.push(UnresolvedRequirementSpecification::from(req));
}
}
break;
}
}
let dev = vec![DEV_DEPENDENCIES.clone()];
let source_trees = vec![];
+50
View File
@@ -583,6 +583,56 @@ fn lock_project_extra() -> Result<()> {
Ok(())
}
#[test]
fn lock_project_with_overrides() -> 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 = ["flask==3.0.0"]
[tool.uv]
override-dependencies = ["werkzeug==2.3.8"]
"#,
)?;
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: `uv lock` is experimental and may change without warning.
Resolved 9 packages in [TIME]
"###);
// Install the base dependencies from the lockfile.
uv_snapshot!(context.filters(), context.sync(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
warning: `uv sync` is experimental and may change without warning.
Prepared 8 packages in [TIME]
Installed 8 packages in [TIME]
+ blinker==1.7.0
+ click==8.1.7
+ flask==3.0.0
+ itsdangerous==2.1.2
+ jinja2==3.1.3
+ markupsafe==2.1.5
+ project==0.1.0 (from file://[TEMP_DIR]/)
+ werkzeug==2.3.8
"###);
Ok(())
}
/// Lock a project with a dependency that has an extra.
#[test]
fn lock_dependency_extra() -> Result<()> {