From dbbd11a7a3ab019508bc3a2a3bb0e31c36e603b6 Mon Sep 17 00:00:00 2001 From: Asuka Minato Date: Fri, 27 Mar 2026 06:24:05 +0900 Subject: [PATCH] fix --- pyrefly/lib/lsp/wasm/hover.rs | 3 +++ pyrefly/lib/test/lsp/hover.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/pyrefly/lib/lsp/wasm/hover.rs b/pyrefly/lib/lsp/wasm/hover.rs index 01e1f57ae0..abdb567985 100644 --- a/pyrefly/lib/lsp/wasm/hover.rs +++ b/pyrefly/lib/lsp/wasm/hover.rs @@ -542,6 +542,7 @@ pub fn get_hover( .get_callables_from_call(handle, position) .map(|info| info.callee_range) .or_else(find_callee_range_at_position); + let hovering_over_callee = callee_range_opt.is_some_and(|range| range.contains(position)); if let Some(callee_range) = callee_range_opt { let is_constructor = transaction @@ -550,6 +551,8 @@ pub fn get_hover( .is_some_and(is_constructor_call); if is_constructor && let Some(new_type) = override_constructor_return_type(type_.clone()) { type_ = new_type; + } else if hovering_over_callee { + type_ = transaction.coerce_type_to_callable(handle, type_); } } diff --git a/pyrefly/lib/test/lsp/hover.rs b/pyrefly/lib/test/lsp/hover.rs index 813c78f85d..0b3ff8cd84 100644 --- a/pyrefly/lib/test/lsp/hover.rs +++ b/pyrefly/lib/test/lsp/hover.rs @@ -177,6 +177,36 @@ greeter("hi") ); } +#[test] +fn hover_on_callable_protocol_attribute_uses_dunder_call_signature() { + let code = r#" +from typing import Protocol, cast + +class Parametrize(Protocol): + def __call__(self, argnames: str, *, ids: list[str] | None = None) -> int: ... + +class Mark: + parametrize: Parametrize + +mark = cast(Mark, ...) +mark.parametrize("role", ids=["owner"]) +# ^^^^^^^^^^^ +"#; + let report = get_batched_lsp_operations_report(&[("main", code)], get_test_report); + assert!( + report.contains("__call__"), + "Expected hover to refer to __call__, got: {report}" + ); + assert!( + report.contains("argnames: str"), + "Expected hover to show the positional parameter, got: {report}" + ); + assert!( + report.contains("ids: list[str] | None = None"), + "Expected hover to show the keyword-only parameter, got: {report}" + ); +} + #[test] fn hover_over_inline_ignore_comment() { let code = r#"