From 53ac09c920982c71b036992227c91f8fc5526309 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Tue, 16 Dec 2025 09:42:42 -0500 Subject: [PATCH 1/3] improve rendering of signatures in hovers --- crates/ty_ide/src/hover.rs | 52 +++++++++---------- .../ty_python_semantic/src/types/display.rs | 35 +++++++++++-- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/crates/ty_ide/src/hover.rs b/crates/ty_ide/src/hover.rs index c192b87380..40e15ba927 100644 --- a/crates/ty_ide/src/hover.rs +++ b/crates/ty_ide/src/hover.rs @@ -1183,13 +1183,13 @@ def ab(a: str): ... .build(); assert_snapshot!(test.hover(), @r" - (a: int) -> Unknown + def ab(a: int) -> Unknown --------------------------------------------- the int overload --------------------------------------------- ```python - (a: int) -> Unknown + def ab(a: int) -> Unknown ``` --- the int overload @@ -1243,13 +1243,13 @@ def ab(a: str): .build(); assert_snapshot!(test.hover(), @r#" - (a: str) -> Unknown + def ab(a: str) -> Unknown --------------------------------------------- the int overload --------------------------------------------- ```python - (a: str) -> Unknown + def ab(a: str) -> Unknown ``` --- the int overload @@ -1303,7 +1303,7 @@ def ab(a: int): .build(); assert_snapshot!(test.hover(), @r" - ( + def ab( a: int, b: int ) -> Unknown @@ -1312,7 +1312,7 @@ def ab(a: int): --------------------------------------------- ```python - ( + def ab( a: int, b: int ) -> Unknown @@ -1369,13 +1369,13 @@ def ab(a: int): .build(); assert_snapshot!(test.hover(), @r" - (a: int) -> Unknown + def ab(a: int) -> Unknown --------------------------------------------- the two arg overload --------------------------------------------- ```python - (a: int) -> Unknown + def ab(a: int) -> Unknown ``` --- the two arg overload @@ -1433,7 +1433,7 @@ def ab(a: int, *, c: int): .build(); assert_snapshot!(test.hover(), @r" - ( + def ab( a: int, *, b: int @@ -1443,7 +1443,7 @@ def ab(a: int, *, c: int): --------------------------------------------- ```python - ( + def ab( a: int, *, b: int @@ -1505,7 +1505,7 @@ def ab(a: int, *, c: int): .build(); assert_snapshot!(test.hover(), @r" - ( + def ab( a: int, *, c: int @@ -1515,7 +1515,7 @@ def ab(a: int, *, c: int): --------------------------------------------- ```python - ( + def ab( a: int, *, c: int @@ -1564,11 +1564,11 @@ def ab(a: int, *, c: int): ); assert_snapshot!(test.hover(), @r#" - ( + def foo( a: int, b ) -> Unknown - ( + def foo( a: str, b ) -> Unknown @@ -1577,11 +1577,11 @@ def ab(a: int, *, c: int): --------------------------------------------- ```python - ( + def foo( a: int, b ) -> Unknown - ( + def foo( a: str, b ) -> Unknown @@ -1628,15 +1628,15 @@ def ab(a: int, *, c: int): ); assert_snapshot!(test.hover(), @r#" - (a: int) -> Unknown - (a: str) -> Unknown + def foo(a: int) -> Unknown + def foo(a: str) -> Unknown --------------------------------------------- The first overload --------------------------------------------- ```python - (a: int) -> Unknown - (a: str) -> Unknown + def foo(a: int) -> Unknown + def foo(a: str) -> Unknown ``` --- The first overload @@ -2151,10 +2151,10 @@ def function(): // TODO: This should just be `**AB@Alias2 ()` // https://github.com/astral-sh/ty/issues/1581 assert_snapshot!(test.hover(), @r" - (**AB@Alias2) -> tuple[AB@Alias2] + def _(**AB@Alias2) -> tuple[AB@Alias2] --------------------------------------------- ```python - (**AB@Alias2) -> tuple[AB@Alias2] + def _(**AB@Alias2) -> tuple[AB@Alias2] ``` --------------------------------------------- info[hover]: Hovered content is @@ -3233,12 +3233,12 @@ def function(): // TODO: We should only show the matching overload here. // https://github.com/astral-sh/ty/issues/73 assert_snapshot!(test.hover(), @r" - (other: Test, /) -> Test - (other: Other, /) -> Test + def __add__(other: Test, /) -> Test + def __add__(other: Other, /) -> Test --------------------------------------------- ```python - (other: Test, /) -> Test - (other: Other, /) -> Test + def __add__(other: Test, /) -> Test + def __add__(other: Other, /) -> Test ``` --------------------------------------------- info[hover]: Hovered content is diff --git a/crates/ty_python_semantic/src/types/display.rs b/crates/ty_python_semantic/src/types/display.rs index 885c9cb7f0..5dbbd624e4 100644 --- a/crates/ty_python_semantic/src/types/display.rs +++ b/crates/ty_python_semantic/src/types/display.rs @@ -15,6 +15,7 @@ use rustc_hash::{FxHashMap, FxHashSet}; use crate::Db; use crate::place::Place; +use crate::semantic_index::definition::Definition; use crate::types::class::{ClassLiteral, ClassType, GenericAlias}; use crate::types::function::{FunctionType, OverloadLiteral}; use crate::types::generics::{GenericContext, Specialization}; @@ -40,6 +41,9 @@ pub struct DisplaySettings<'db> { pub qualified: Rc>, /// Whether long unions and literals are displayed in full pub preserve_full_unions: bool, + /// Disallow Signature printing to introduce a name + /// (presumably because we rendered one already) + pub disallow_signature_name: bool, } impl<'db> DisplaySettings<'db> { @@ -75,6 +79,14 @@ impl<'db> DisplaySettings<'db> { } } + #[must_use] + pub fn disallow_signature_name(&self) -> Self { + Self { + disallow_signature_name: true, + ..self.clone() + } + } + #[must_use] pub fn from_possibly_ambiguous_types( db: &'db dyn Db, @@ -742,7 +754,7 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> { type_parameters.fmt_detailed(f)?; signature .bind_self(self.db, Some(typing_self_ty)) - .display_with(self.db, self.settings.clone()) + .display_with(self.db, self.settings.disallow_signature_name()) .fmt_detailed(f) } signatures => { @@ -1158,7 +1170,7 @@ impl<'db> FmtDetailed<'db> for DisplayOverloadLiteral<'db> { write!(f, "{}", self.literal.name(self.db))?; type_parameters.fmt_detailed(f)?; signature - .display_with(self.db, self.settings.clone()) + .display_with(self.db, self.settings.disallow_signature_name()) .fmt_detailed(f) } } @@ -1205,7 +1217,7 @@ impl<'db> FmtDetailed<'db> for DisplayFunctionType<'db> { write!(f, "{}", self.ty.name(self.db))?; type_parameters.fmt_detailed(f)?; signature - .display_with(self.db, self.settings.clone()) + .display_with(self.db, self.settings.disallow_signature_name()) .fmt_detailed(f) } signatures => { @@ -1624,6 +1636,7 @@ impl<'db> Signature<'db> { settings: DisplaySettings<'db>, ) -> DisplaySignature<'a, 'db> { DisplaySignature { + definition: self.definition(), parameters: self.parameters(), return_ty: self.return_ty, db, @@ -1633,6 +1646,7 @@ impl<'db> Signature<'db> { } pub(crate) struct DisplaySignature<'a, 'db> { + definition: Option>, parameters: &'a Parameters<'db>, return_ty: Option>, db: &'db dyn Db, @@ -1660,6 +1674,19 @@ impl<'db> FmtDetailed<'db> for DisplaySignature<'_, 'db> { // When we exit this function, write a marker signaling we're ending a signature let mut f = f.with_detail(TypeDetail::SignatureEnd); + // If we're multiline printing and a name hasn't been emitted, try to + // make one up to make things more pretty + if self.settings.multiline && !self.settings.disallow_signature_name { + f.write_str("def ")?; + if let Some(definition) = self.definition + && let Some(name) = definition.name(self.db) + { + f.write_str(&name)?; + } else { + f.write_str("_")?; + } + } + // Parameters self.parameters .display_with(self.db, self.settings.clone()) @@ -2694,7 +2721,7 @@ mod tests { let db = setup_db(); // Empty parameters with no return type. - assert_snapshot!(display_signature_multiline(&db, [], None), @"() -> Unknown"); + assert_snapshot!(display_signature_multiline(&db, [], None), @"def _() -> Unknown"); // Empty parameters with a return type. assert_snapshot!( From 5de62caff685eb0c9884af6f59c32419c55e2185 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Tue, 16 Dec 2025 09:50:26 -0500 Subject: [PATCH 2/3] regen --- crates/ty_python_semantic/src/types/display.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/ty_python_semantic/src/types/display.rs b/crates/ty_python_semantic/src/types/display.rs index 5dbbd624e4..a9f317d6ce 100644 --- a/crates/ty_python_semantic/src/types/display.rs +++ b/crates/ty_python_semantic/src/types/display.rs @@ -2726,7 +2726,7 @@ mod tests { // Empty parameters with a return type. assert_snapshot!( display_signature_multiline(&db, [], Some(Type::none(&db))), - @"() -> None" + @"def _() -> None" ); // Single parameter type (no name) with a return type. @@ -2736,7 +2736,7 @@ mod tests { [Parameter::positional_only(None).with_annotated_type(Type::none(&db))], Some(Type::none(&db)) ), - @"(None, /) -> None" + @"def _(None, /) -> None" ); // Two parameters where one has annotation and the other doesn't. @@ -2753,7 +2753,7 @@ mod tests { Some(Type::none(&db)) ), @r" - ( + def _( x=int, y: str = str ) -> None @@ -2771,7 +2771,7 @@ mod tests { Some(Type::none(&db)) ), @r" - ( + def _( x, y, / @@ -2790,7 +2790,7 @@ mod tests { Some(Type::none(&db)) ), @r" - ( + def _( x, /, y @@ -2809,7 +2809,7 @@ mod tests { Some(Type::none(&db)) ), @r" - ( + def _( *, x, y @@ -2828,7 +2828,7 @@ mod tests { Some(Type::none(&db)) ), @r" - ( + def _( x, *, y @@ -2867,7 +2867,7 @@ mod tests { Some(KnownClass::Bytes.to_instance(&db)) ), @r" - ( + def _( a, b: int, c=Literal[1], From aa03af22afa14549cdd389f882928bd7631357a8 Mon Sep 17 00:00:00 2001 From: Aria Desires Date: Tue, 16 Dec 2025 11:51:36 -0500 Subject: [PATCH 3/3] remove underscore fallback --- crates/ty_ide/src/hover.rs | 4 +-- .../ty_python_semantic/src/types/display.rs | 32 +++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/crates/ty_ide/src/hover.rs b/crates/ty_ide/src/hover.rs index 40e15ba927..8efcf90b8d 100644 --- a/crates/ty_ide/src/hover.rs +++ b/crates/ty_ide/src/hover.rs @@ -2151,10 +2151,10 @@ def function(): // TODO: This should just be `**AB@Alias2 ()` // https://github.com/astral-sh/ty/issues/1581 assert_snapshot!(test.hover(), @r" - def _(**AB@Alias2) -> tuple[AB@Alias2] + (**AB@Alias2) -> tuple[AB@Alias2] --------------------------------------------- ```python - def _(**AB@Alias2) -> tuple[AB@Alias2] + (**AB@Alias2) -> tuple[AB@Alias2] ``` --------------------------------------------- info[hover]: Hovered content is diff --git a/crates/ty_python_semantic/src/types/display.rs b/crates/ty_python_semantic/src/types/display.rs index a9f317d6ce..c500911c48 100644 --- a/crates/ty_python_semantic/src/types/display.rs +++ b/crates/ty_python_semantic/src/types/display.rs @@ -1676,15 +1676,13 @@ impl<'db> FmtDetailed<'db> for DisplaySignature<'_, 'db> { // If we're multiline printing and a name hasn't been emitted, try to // make one up to make things more pretty - if self.settings.multiline && !self.settings.disallow_signature_name { + if self.settings.multiline + && !self.settings.disallow_signature_name + && let Some(definition) = self.definition + && let Some(name) = definition.name(self.db) + { f.write_str("def ")?; - if let Some(definition) = self.definition - && let Some(name) = definition.name(self.db) - { - f.write_str(&name)?; - } else { - f.write_str("_")?; - } + f.write_str(&name)?; } // Parameters @@ -2721,12 +2719,12 @@ mod tests { let db = setup_db(); // Empty parameters with no return type. - assert_snapshot!(display_signature_multiline(&db, [], None), @"def _() -> Unknown"); + assert_snapshot!(display_signature_multiline(&db, [], None), @"() -> Unknown"); // Empty parameters with a return type. assert_snapshot!( display_signature_multiline(&db, [], Some(Type::none(&db))), - @"def _() -> None" + @"() -> None" ); // Single parameter type (no name) with a return type. @@ -2736,7 +2734,7 @@ mod tests { [Parameter::positional_only(None).with_annotated_type(Type::none(&db))], Some(Type::none(&db)) ), - @"def _(None, /) -> None" + @"(None, /) -> None" ); // Two parameters where one has annotation and the other doesn't. @@ -2753,7 +2751,7 @@ mod tests { Some(Type::none(&db)) ), @r" - def _( + ( x=int, y: str = str ) -> None @@ -2771,7 +2769,7 @@ mod tests { Some(Type::none(&db)) ), @r" - def _( + ( x, y, / @@ -2790,7 +2788,7 @@ mod tests { Some(Type::none(&db)) ), @r" - def _( + ( x, /, y @@ -2809,7 +2807,7 @@ mod tests { Some(Type::none(&db)) ), @r" - def _( + ( *, x, y @@ -2828,7 +2826,7 @@ mod tests { Some(Type::none(&db)) ), @r" - def _( + ( x, *, y @@ -2867,7 +2865,7 @@ mod tests { Some(KnownClass::Bytes.to_instance(&db)) ), @r" - def _( + ( a, b: int, c=Literal[1],