Avoid environment check optimisation for `uv pip install --exact` (#8219)

## Summary

See https://github.com/astral-sh/uv/issues/8041#issuecomment-2413958550

## Test Plan

`cargo test`
This commit is contained in:
Ahmed Ilyas 2024-10-15 16:37:34 +02:00 committed by GitHub
parent 6d9d147b8c
commit 0943144cf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 77 additions and 7 deletions

View File

@ -204,7 +204,12 @@ pub(crate) async fn pip_install(
// Check if the current environment satisfies the requirements.
// Ideally, the resolver would be fast enough to let us remove this check. But right now, for large environments,
// it's an order of magnitude faster to validate the environment than to resolve the requirements.
if reinstall.is_none() && upgrade.is_none() && source_trees.is_empty() && overrides.is_empty() {
if reinstall.is_none()
&& upgrade.is_none()
&& source_trees.is_empty()
&& overrides.is_empty()
&& matches!(modifications, Modifications::Sufficient)
{
match site_packages.satisfies(&requirements, &constraints, &markers)? {
// If the requirements are already satisfied, we're done.
SatisfiesResult::Fresh {
@ -223,6 +228,7 @@ pub(crate) async fn pip_install(
if dry_run {
writeln!(printer.stderr(), "Would make no changes")?;
}
return Ok(ExitStatus::Success);
}
SatisfiesResult::Unsatisfied(requirement) => {

View File

@ -748,6 +748,27 @@ fn reinstall_incomplete() -> Result<()> {
#[test]
fn exact_install_removes_extraneous_packages() -> Result<()> {
let context = TestContext::new("3.12").with_filtered_counts();
// Install anyio
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("anyio==3.7.0")?;
uv_snapshot!(context.filters(), context.pip_install()
.arg("--exact")
.arg("-r")
.arg("requirements.txt"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved [N] packages in [TIME]
Prepared [N] packages in [TIME]
Installed [N] packages in [TIME]
+ anyio==3.7.0
+ idna==3.6
+ sniffio==1.3.1
"###
);
// Install flask
uv_snapshot!(context.filters(), context.pip_install()
@ -770,10 +791,55 @@ fn exact_install_removes_extraneous_packages() -> Result<()> {
"###
);
// Install anyio with exact flag removes flask and flask dependencies.
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str("anyio==3.7.0")?;
// Install requirements file with exact flag removes flask and flask dependencies.
uv_snapshot!(context.filters(), context.pip_install()
.arg("--exact")
.arg("-r")
.arg("requirements.txt"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved [N] packages in [TIME]
Uninstalled [N] packages in [TIME]
- blinker==1.7.0
- click==8.1.7
- flask==3.0.2
- itsdangerous==2.1.2
- jinja2==3.1.3
- markupsafe==2.1.5
- werkzeug==3.0.1
"###
);
// Install flask again
uv_snapshot!(context.filters(), context.pip_install()
.arg("flask"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved [N] packages in [TIME]
Installed [N] packages in [TIME]
+ blinker==1.7.0
+ click==8.1.7
+ flask==3.0.2
+ itsdangerous==2.1.2
+ jinja2==3.1.3
+ markupsafe==2.1.5
+ werkzeug==3.0.1
"###
);
requirements_txt.write_str(indoc! {r"
anyio==3.7.0
flit_core<4.0.0
"
})?;
// Install requirements file with exact flag installs flit_core and removes flask and flask dependencies.
uv_snapshot!(context.filters(), context.pip_install()
.arg("--exact")
.arg("-r")
@ -787,15 +853,13 @@ fn exact_install_removes_extraneous_packages() -> Result<()> {
Prepared [N] packages in [TIME]
Uninstalled [N] packages in [TIME]
Installed [N] packages in [TIME]
+ anyio==3.7.0
- blinker==1.7.0
- click==8.1.7
- flask==3.0.2
+ idna==3.6
+ flit-core==3.9.0
- itsdangerous==2.1.2
- jinja2==3.1.3
- markupsafe==2.1.5
+ sniffio==1.3.1
- werkzeug==3.0.1
"###
);