mirror of https://github.com/astral-sh/uv
Refresh `BuildDispatch` when running pip install with `--reinstall` (#933)
## Summary
This fixes an extremely subtle bug in `pip install --reinstall`, whereby
if you depend on `setuptools` at the top level, we end up uninstalling
it after resolving, which breaks some cached state. If we have
`--reinstall`, we need to reset that cached state between resolving and
installing.
## Test Plan
Running `pip install --reinstall` with:
```txt
setuptools
devpi @ e334eb4dc9bb023329e4b610e4515b/devpi-2.2.0.tar.gz
```
Fails on `main`, but passes.
This commit is contained in:
parent
116da6b7de
commit
e71e3e8dd1
|
|
@ -149,7 +149,7 @@ pub(crate) async fn pip_install(
|
|||
|
||||
let options = ResolutionOptions::new(resolution_mode, prerelease_mode, exclude_newer);
|
||||
|
||||
let build_dispatch = BuildDispatch::new(
|
||||
let resolve_dispatch = BuildDispatch::new(
|
||||
&client,
|
||||
&cache,
|
||||
&interpreter,
|
||||
|
|
@ -176,7 +176,7 @@ pub(crate) async fn pip_install(
|
|||
&cache,
|
||||
tags,
|
||||
&client,
|
||||
&build_dispatch,
|
||||
&resolve_dispatch,
|
||||
printer,
|
||||
)
|
||||
.await?
|
||||
|
|
@ -196,7 +196,7 @@ pub(crate) async fn pip_install(
|
|||
markers,
|
||||
&client,
|
||||
&flat_index,
|
||||
&build_dispatch,
|
||||
&resolve_dispatch,
|
||||
options,
|
||||
printer,
|
||||
)
|
||||
|
|
@ -215,6 +215,27 @@ pub(crate) async fn pip_install(
|
|||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
|
||||
// Re-initialize the in-flight map.
|
||||
let in_flight = InFlight::default();
|
||||
|
||||
// If we're running with `--reinstall`, initialize a separate `BuildDispatch`, since we may
|
||||
// end up removing some distributions from the environment.
|
||||
let install_dispatch = if reinstall.is_none() {
|
||||
resolve_dispatch
|
||||
} else {
|
||||
BuildDispatch::new(
|
||||
&client,
|
||||
&cache,
|
||||
&interpreter,
|
||||
&index_locations,
|
||||
&flat_index,
|
||||
&in_flight,
|
||||
venv.python_executable(),
|
||||
setup_py,
|
||||
no_build,
|
||||
)
|
||||
};
|
||||
|
||||
// Sync the environment.
|
||||
install(
|
||||
&resolution,
|
||||
|
|
@ -226,7 +247,7 @@ pub(crate) async fn pip_install(
|
|||
tags,
|
||||
&client,
|
||||
&in_flight,
|
||||
&build_dispatch,
|
||||
&install_dispatch,
|
||||
&cache,
|
||||
&venv,
|
||||
printer,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use anyhow::Result;
|
|||
use assert_cmd::assert::Assert;
|
||||
use assert_cmd::prelude::*;
|
||||
use assert_fs::prelude::*;
|
||||
use indoc::indoc;
|
||||
use insta_cmd::_macro_support::insta;
|
||||
use insta_cmd::{assert_cmd_snapshot, get_cargo_bin};
|
||||
|
||||
|
|
@ -687,3 +688,58 @@ fn install_editable_and_registry() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Install a source distribution that uses the `flit` build system, along with `flit`
|
||||
/// at the top-level, along with `--reinstall` to force a re-download after resolution, to ensure
|
||||
/// that the `flit` install and the source distribution build don't conflict.
|
||||
#[test]
|
||||
fn reinstall_build_system() -> Result<()> {
|
||||
let temp_dir = assert_fs::TempDir::new()?;
|
||||
let cache_dir = assert_fs::TempDir::new()?;
|
||||
let venv = create_venv_py312(&temp_dir, &cache_dir);
|
||||
|
||||
// Install devpi.
|
||||
let requirements_txt = temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(indoc! {r"
|
||||
flit_core<4.0.0
|
||||
flask @ https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz
|
||||
"
|
||||
})?;
|
||||
|
||||
insta::with_settings!({
|
||||
filters => INSTA_FILTERS.to_vec()
|
||||
}, {
|
||||
assert_cmd_snapshot!(Command::new(get_cargo_bin(BIN_NAME))
|
||||
.arg("pip")
|
||||
.arg("install")
|
||||
.arg("--reinstall")
|
||||
.arg("-r")
|
||||
.arg("requirements.txt")
|
||||
.arg("--strict")
|
||||
.arg("--cache-dir")
|
||||
.arg(cache_dir.path())
|
||||
.arg("--exclude-newer")
|
||||
.arg(EXCLUDE_NEWER)
|
||||
.env("VIRTUAL_ENV", venv.as_os_str())
|
||||
.current_dir(&temp_dir), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 8 packages in [TIME]
|
||||
Downloaded 8 packages in [TIME]
|
||||
Installed 8 packages in [TIME]
|
||||
+ blinker==1.7.0
|
||||
+ click==8.1.7
|
||||
+ flask==3.0.0 (from https://files.pythonhosted.org/packages/d8/09/c1a7354d3925a3c6c8cfdebf4245bae67d633ffda1ba415add06ffc839c5/flask-3.0.0.tar.gz)
|
||||
+ flit-core==3.9.0
|
||||
+ itsdangerous==2.1.2
|
||||
+ jinja2==3.1.2
|
||||
+ markupsafe==2.1.3
|
||||
+ werkzeug==3.0.1
|
||||
"###);
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,5 @@ license = {text = "MIT"}
|
|||
requires = ["pdm-backend"]
|
||||
build-backend = "pdm.backend"
|
||||
|
||||
|
||||
[tool.pdm]
|
||||
package-type = "library"
|
||||
|
|
|
|||
Loading…
Reference in New Issue