Do not re-resolve with a new Python version in `uv tool` if it is incompatible with `--python` (#14606)

Closes https://github.com/astral-sh/uv/issues/14604
This commit is contained in:
Zanie Blue 2025-07-14 09:07:30 -05:00 committed by GitHub
parent 0af025eafb
commit 4890f3ef2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 11 deletions

View File

@ -98,14 +98,6 @@ pub(crate) async fn refine_interpreter(
return Ok(None);
}
// If the user passed a `--python` request, and the refined interpreter is incompatible, we
// can't use it.
if let Some(python_request) = python_request {
if !python_request.satisfied(interpreter, cache) {
return Ok(None);
}
}
// We want an interpreter that's as close to the required version as possible. If we choose the
// "latest" Python, we risk choosing a version that lacks wheels for the tool's requirements
// (assuming those requirements don't publish source distributions).
@ -135,15 +127,15 @@ pub(crate) async fn refine_interpreter(
Bound::Unbounded => unreachable!("`requires-python` should never be unbounded"),
};
let python_request = PythonRequest::Version(VersionRequest::Range(
let requires_python_request = PythonRequest::Version(VersionRequest::Range(
VersionSpecifiers::from_iter([lower_bound, upper_bound]),
PythonVariant::default(),
));
debug!("Refining interpreter with: {python_request}");
debug!("Refining interpreter with: {requires_python_request}");
let interpreter = PythonInstallation::find_or_download(
Some(&python_request),
Some(&requires_python_request),
EnvironmentPreference::OnlySystem,
python_preference,
python_downloads,
@ -158,6 +150,14 @@ pub(crate) async fn refine_interpreter(
.await?
.into_interpreter();
// If the user passed a `--python` request, and the refined interpreter is incompatible, we
// can't use it.
if let Some(python_request) = python_request {
if !python_request.satisfied(&interpreter, cache) {
return Ok(None);
}
}
Ok(Some(interpreter))
}

View File

@ -3026,6 +3026,7 @@ fn tool_run_reresolve_python() -> anyhow::Result<()> {
+ foo==1.0.0 (from file://[TEMP_DIR]/foo)
");
// When an incompatible Python version is explicitly requested, we should not re-resolve
uv_snapshot!(context.filters(), context.tool_run()
.arg("--from")
.arg("./foo")
@ -3034,6 +3035,25 @@ fn tool_run_reresolve_python() -> anyhow::Result<()> {
.arg("foo")
.env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str())
.env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()), @r"
success: false
exit_code: 1
----- stdout -----
----- stderr -----
× No solution found when resolving tool dependencies:
Because the current Python version (3.11.[X]) does not satisfy Python>=3.12 and foo==1.0.0 depends on Python>=3.12, we can conclude that foo==1.0.0 cannot be used.
And because only foo==1.0.0 is available and you require foo, we can conclude that your requirements are unsatisfiable.
");
// Unless the discovered interpreter is compatible with the request
uv_snapshot!(context.filters(), context.tool_run()
.arg("--from")
.arg("./foo")
.arg("--python")
.arg(">=3.11")
.arg("foo")
.env(EnvVars::UV_TOOL_DIR, tool_dir.as_os_str())
.env(EnvVars::XDG_BIN_HOME, bin_dir.as_os_str()), @r"
success: true
exit_code: 0
----- stdout -----