fix(tools): name uv as the installer for Python servers when it makes the virtualenv (#936)
CI / Rust (ubuntu-22.04) (push) Failing after 1h0m10s
CI / Remote server (linux musl) (push) Failing after 24m13s
CI / Cargo deny (push) Successful in 48s
CI / Frontend (push) Successful in 24m55s
CI / E2E (push) Failing after 14m16s
CI / Rust (macos-latest) (push) Canceled after 0s
CI / Rust (windows-latest) (push) Canceled after 0s

Tools and the install log named "pip (virtualenv)" for Python language servers (basedpyright, Pyright, ty, Ruff) even when the virtualenv is made with uv, which `install_venv` prefers whenever uv is on `PATH`.

The label now comes from the installer that will actually run: "uv (virtualenv)" when uv is on `PATH`, unchanged otherwise. debugpy's private copy still says pip, since it is always installed with `python -m pip`.

Co-authored-by: pcastro93 <[email protected]>
Цей коміт міститься в:
Piettro authored and GitHub committed 2026-11-03 14:37:26 +08:00
1 джерело 53e76e29c6
коміт 843ff74d5d
3 files changed
+29 -3

No files matched your search

+13 -2
Переглянути файл
@@ -540,6 +540,15 @@ impl Tools {
if managed || self.method_missing(spec.method).is_some() { fallback } else { spec.method }
}
/// [`Method::label`], naming the installer that will actually run: a virtualenv is
/// made with uv when it is on `PATH` (see `install_venv`).
fn method_label(&self, method: Method) -> &'static str {
match method {
Method::PipVenv { .. } if self.which("uv").is_some() => "uv (virtualenv)",
m => m.label(),
}
}
/// Requirement check for installing `spec` right now.
fn unavailable_reason(&self, spec: &ToolSpec) -> Option<String> {
self.method_missing(self.install_method(spec))
@@ -624,7 +633,7 @@ impl Tools {
status,
path: path.map(Into::into),
version,
install_method: Some(self.install_method(spec).label().to_string()),
install_method: Some(self.method_label(self.install_method(spec)).to_string()),
can_install: unavailable_reason.is_none() && !bundled,
unavailable_reason,
can_uninstall,
@@ -796,7 +805,9 @@ impl Tools {
let result = (|| {
std::fs::create_dir_all(&self.root)?;
let method = self.install_method(spec);
emit(InstallEvent::Line { text: format!("Installing {} via {}…", spec.display, method.label()) });
emit(InstallEvent::Line {
text: format!("Installing {} via {}…", spec.display, self.method_label(method)),
});
match method {
Method::Bundled { .. } => {
bundled::install(&self.root, spec)?;
+15
Переглянути файл
@@ -161,6 +161,21 @@ fn interchangeable_servers_list_their_alternatives() {
assert!(find(&list, "rust-analyzer").alternatives.is_empty());
}
#[cfg(unix)]
#[test]
fn python_servers_name_uv_when_it_makes_the_virtualenv() {
let env = Env::new();
env.script(&env.sys, "uv", "exit 0");
let list = env.tools().list(&langs());
for name in ["basedpyright", "ty", "ruff"] {
let tool = find(&list, name);
assert_eq!(tool.install_method.as_deref(), Some("uv (virtualenv)"), "{name}");
assert!(tool.can_install, "{name}: uv alone is enough");
}
// debugpy's private copy is always made by `python -m pip`.
assert_eq!(find(&list, "debugpy").install_method.as_deref(), Some("pip (private copy)"));
}
#[cfg(unix)]
#[test]
fn detects_tools_on_path_with_versions() {
+1 -1
Переглянути файл
@@ -99,7 +99,7 @@ export function sampleTools(): ToolInfo[] {
name,
displayName: name === "pyright" ? "Pyright" : name === "ty" ? "ty (Python)" : name,
languages: ["Python"],
installMethod: "pip (virtualenv)",
installMethod: "uv (virtualenv)",
alternatives: ["basedpyright", "pyright", "ty"],
}),
),