Skip to content

Commit c4767f5

Browse files
authored
[ty] Add type definitions for Type::SpecialForms (#21544)
1 parent 6e84f4f commit c4767f5

File tree

10 files changed

+479
-61
lines changed

10 files changed

+479
-61
lines changed

crates/ty_ide/src/goto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ impl<'db> DefinitionsOrTargets<'db> {
213213
| ty_python_semantic::types::TypeDefinition::Function(definition)
214214
| ty_python_semantic::types::TypeDefinition::TypeVar(definition)
215215
| ty_python_semantic::types::TypeDefinition::TypeAlias(definition)
216+
| ty_python_semantic::types::TypeDefinition::SpecialForm(definition)
216217
| ty_python_semantic::types::TypeDefinition::NewType(definition) => {
217218
ResolvedDefinition::Definition(definition)
218219
}

crates/ty_ide/src/goto_type_definition.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,134 @@ mod tests {
6868
");
6969
}
7070

71+
#[test]
72+
fn goto_type_of_typing_dot_literal() {
73+
let test = cursor_test(
74+
r#"
75+
from typing import Literal
76+
77+
a<CURSOR>b = Literal
78+
"#,
79+
);
80+
81+
assert_snapshot!(test.goto_type_definition(), @r"
82+
info[goto-type-definition]: Type definition
83+
--> stdlib/typing.pyi:351:1
84+
|
85+
349 | Final: _SpecialForm
86+
350 |
87+
351 | Literal: _SpecialForm
88+
| ^^^^^^^
89+
352 | TypedDict: _SpecialForm
90+
|
91+
info: Source
92+
--> main.py:4:1
93+
|
94+
2 | from typing import Literal
95+
3 |
96+
4 | ab = Literal
97+
| ^^
98+
|
99+
");
100+
}
101+
102+
// this is a slightly different case to the one above,
103+
// since `Any` is a class in typeshed rather than a variable
104+
#[test]
105+
fn goto_type_of_typing_dot_any() {
106+
let test = cursor_test(
107+
r#"
108+
from typing import Any
109+
110+
a<CURSOR>b = Any
111+
"#,
112+
);
113+
114+
assert_snapshot!(test.goto_type_definition(), @r#"
115+
info[goto-type-definition]: Type definition
116+
--> stdlib/typing.pyi:166:7
117+
|
118+
164 | # from _typeshed import AnnotationForm
119+
165 |
120+
166 | class Any:
121+
| ^^^
122+
167 | """Special type indicating an unconstrained type.
123+
|
124+
info: Source
125+
--> main.py:4:1
126+
|
127+
2 | from typing import Any
128+
3 |
129+
4 | ab = Any
130+
| ^^
131+
|
132+
"#);
133+
}
134+
135+
// Similarly, `Generic` is a `type[]` type in typeshed
136+
#[test]
137+
fn goto_type_of_typing_dot_generic() {
138+
let test = cursor_test(
139+
r#"
140+
from typing import Generic
141+
142+
a<CURSOR>b = Generic
143+
"#,
144+
);
145+
146+
assert_snapshot!(test.goto_type_definition(), @r"
147+
info[goto-type-definition]: Type definition
148+
--> stdlib/typing.pyi:770:1
149+
|
150+
768 | def __class_getitem__(cls, args: TypeVar | tuple[TypeVar, ...]) -> _Final: ...
151+
769 |
152+
770 | Generic: type[_Generic]
153+
| ^^^^^^^
154+
771 |
155+
772 | class _ProtocolMeta(ABCMeta):
156+
|
157+
info: Source
158+
--> main.py:4:1
159+
|
160+
2 | from typing import Generic
161+
3 |
162+
4 | ab = Generic
163+
| ^^
164+
|
165+
");
166+
}
167+
168+
#[test]
169+
fn goto_type_of_ty_extensions_special_form() {
170+
let test = cursor_test(
171+
r#"
172+
from ty_extensions import AlwaysTruthy
173+
174+
a<CURSOR>b = AlwaysTruthy
175+
"#,
176+
);
177+
178+
assert_snapshot!(test.goto_type_definition(), @r"
179+
info[goto-type-definition]: Type definition
180+
--> stdlib/ty_extensions.pyi:21:1
181+
|
182+
19 | # Types
183+
20 | Unknown = object()
184+
21 | AlwaysTruthy = object()
185+
| ^^^^^^^^^^^^
186+
22 | AlwaysFalsy = object()
187+
|
188+
info: Source
189+
--> main.py:4:1
190+
|
191+
2 | from ty_extensions import AlwaysTruthy
192+
3 |
193+
4 | ab = AlwaysTruthy
194+
| ^^
195+
|
196+
");
197+
}
198+
71199
#[test]
72200
fn goto_type_of_expression_with_function_type() {
73201
let test = cursor_test(

crates/ty_ide/src/inlay_hints.rs

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,25 @@ mod tests {
601601
w[: int] = z
602602
603603
---------------------------------------------
604+
info[inlay-hint-location]: Inlay Hint Target
605+
--> stdlib/typing.pyi:351:1
606+
|
607+
349 | Final: _SpecialForm
608+
350 |
609+
351 | Literal: _SpecialForm
610+
| ^^^^^^^
611+
352 | TypedDict: _SpecialForm
612+
|
613+
info: Source
614+
--> main2.py:6:5
615+
|
616+
5 | x = 1
617+
6 | y[: Literal[1]] = x
618+
| ^^^^^^^
619+
7 | z[: int] = i(1)
620+
8 | w[: int] = z
621+
|
622+
604623
info[inlay-hint-location]: Inlay Hint Target
605624
--> stdlib/builtins.pyi:348:7
606625
|
@@ -668,6 +687,44 @@ mod tests {
668687
x4[: int], y4[: str] = (x3, y3)
669688
670689
---------------------------------------------
690+
info[inlay-hint-location]: Inlay Hint Target
691+
--> stdlib/typing.pyi:351:1
692+
|
693+
349 | Final: _SpecialForm
694+
350 |
695+
351 | Literal: _SpecialForm
696+
| ^^^^^^^
697+
352 | TypedDict: _SpecialForm
698+
|
699+
info: Source
700+
--> main2.py:8:6
701+
|
702+
7 | x1, y1 = (1, 'abc')
703+
8 | x2[: Literal[1]], y2[: Literal["abc"]] = (x1, y1)
704+
| ^^^^^^^
705+
9 | x3[: int], y3[: str] = (i(1), s('abc'))
706+
10 | x4[: int], y4[: str] = (x3, y3)
707+
|
708+
709+
info[inlay-hint-location]: Inlay Hint Target
710+
--> stdlib/typing.pyi:351:1
711+
|
712+
349 | Final: _SpecialForm
713+
350 |
714+
351 | Literal: _SpecialForm
715+
| ^^^^^^^
716+
352 | TypedDict: _SpecialForm
717+
|
718+
info: Source
719+
--> main2.py:8:24
720+
|
721+
7 | x1, y1 = (1, 'abc')
722+
8 | x2[: Literal[1]], y2[: Literal["abc"]] = (x1, y1)
723+
| ^^^^^^^
724+
9 | x3[: int], y3[: str] = (i(1), s('abc'))
725+
10 | x4[: int], y4[: str] = (x3, y3)
726+
|
727+
671728
info[inlay-hint-location]: Inlay Hint Target
672729
--> stdlib/builtins.pyi:348:7
673730
|
@@ -772,6 +829,44 @@ mod tests {
772829
x4[: int], y4[: str] = x3, y3
773830
774831
---------------------------------------------
832+
info[inlay-hint-location]: Inlay Hint Target
833+
--> stdlib/typing.pyi:351:1
834+
|
835+
349 | Final: _SpecialForm
836+
350 |
837+
351 | Literal: _SpecialForm
838+
| ^^^^^^^
839+
352 | TypedDict: _SpecialForm
840+
|
841+
info: Source
842+
--> main2.py:8:6
843+
|
844+
7 | x1, y1 = 1, 'abc'
845+
8 | x2[: Literal[1]], y2[: Literal["abc"]] = x1, y1
846+
| ^^^^^^^
847+
9 | x3[: int], y3[: str] = i(1), s('abc')
848+
10 | x4[: int], y4[: str] = x3, y3
849+
|
850+
851+
info[inlay-hint-location]: Inlay Hint Target
852+
--> stdlib/typing.pyi:351:1
853+
|
854+
349 | Final: _SpecialForm
855+
350 |
856+
351 | Literal: _SpecialForm
857+
| ^^^^^^^
858+
352 | TypedDict: _SpecialForm
859+
|
860+
info: Source
861+
--> main2.py:8:24
862+
|
863+
7 | x1, y1 = 1, 'abc'
864+
8 | x2[: Literal[1]], y2[: Literal["abc"]] = x1, y1
865+
| ^^^^^^^
866+
9 | x3[: int], y3[: str] = i(1), s('abc')
867+
10 | x4[: int], y4[: str] = x3, y3
868+
|
869+
775870
info[inlay-hint-location]: Inlay Hint Target
776871
--> stdlib/builtins.pyi:348:7
777872
|
@@ -876,6 +971,44 @@ mod tests {
876971
w[: tuple[int, str]] = z
877972
878973
---------------------------------------------
974+
info[inlay-hint-location]: Inlay Hint Target
975+
--> stdlib/typing.pyi:351:1
976+
|
977+
349 | Final: _SpecialForm
978+
350 |
979+
351 | Literal: _SpecialForm
980+
| ^^^^^^^
981+
352 | TypedDict: _SpecialForm
982+
|
983+
info: Source
984+
--> main2.py:8:11
985+
|
986+
7 | x = (1, 'abc')
987+
8 | y[: tuple[Literal[1], Literal["abc"]]] = x
988+
| ^^^^^^^
989+
9 | z[: tuple[int, str]] = (i(1), s('abc'))
990+
10 | w[: tuple[int, str]] = z
991+
|
992+
993+
info[inlay-hint-location]: Inlay Hint Target
994+
--> stdlib/typing.pyi:351:1
995+
|
996+
349 | Final: _SpecialForm
997+
350 |
998+
351 | Literal: _SpecialForm
999+
| ^^^^^^^
1000+
352 | TypedDict: _SpecialForm
1001+
|
1002+
info: Source
1003+
--> main2.py:8:23
1004+
|
1005+
7 | x = (1, 'abc')
1006+
8 | y[: tuple[Literal[1], Literal["abc"]]] = x
1007+
| ^^^^^^^
1008+
9 | z[: tuple[int, str]] = (i(1), s('abc'))
1009+
10 | w[: tuple[int, str]] = z
1010+
|
1011+
8791012
info[inlay-hint-location]: Inlay Hint Target
8801013
--> stdlib/builtins.pyi:348:7
8811014
|
@@ -978,6 +1111,63 @@ mod tests {
9781111
x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
9791112
x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
9801113
---------------------------------------------
1114+
info[inlay-hint-location]: Inlay Hint Target
1115+
--> stdlib/typing.pyi:351:1
1116+
|
1117+
349 | Final: _SpecialForm
1118+
350 |
1119+
351 | Literal: _SpecialForm
1120+
| ^^^^^^^
1121+
352 | TypedDict: _SpecialForm
1122+
|
1123+
info: Source
1124+
--> main2.py:8:6
1125+
|
1126+
7 | x1, (y1, z1) = (1, ('abc', 2))
1127+
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
1128+
| ^^^^^^^
1129+
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
1130+
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
1131+
|
1132+
1133+
info[inlay-hint-location]: Inlay Hint Target
1134+
--> stdlib/typing.pyi:351:1
1135+
|
1136+
349 | Final: _SpecialForm
1137+
350 |
1138+
351 | Literal: _SpecialForm
1139+
| ^^^^^^^
1140+
352 | TypedDict: _SpecialForm
1141+
|
1142+
info: Source
1143+
--> main2.py:8:25
1144+
|
1145+
7 | x1, (y1, z1) = (1, ('abc', 2))
1146+
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
1147+
| ^^^^^^^
1148+
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
1149+
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
1150+
|
1151+
1152+
info[inlay-hint-location]: Inlay Hint Target
1153+
--> stdlib/typing.pyi:351:1
1154+
|
1155+
349 | Final: _SpecialForm
1156+
350 |
1157+
351 | Literal: _SpecialForm
1158+
| ^^^^^^^
1159+
352 | TypedDict: _SpecialForm
1160+
|
1161+
info: Source
1162+
--> main2.py:8:47
1163+
|
1164+
7 | x1, (y1, z1) = (1, ('abc', 2))
1165+
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
1166+
| ^^^^^^^
1167+
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
1168+
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
1169+
|
1170+
9811171
info[inlay-hint-location]: Inlay Hint Target
9821172
--> stdlib/builtins.pyi:348:7
9831173
|
@@ -1113,6 +1303,25 @@ mod tests {
11131303
z: int = i(1)
11141304
w[: int] = z
11151305
---------------------------------------------
1306+
info[inlay-hint-location]: Inlay Hint Target
1307+
--> stdlib/typing.pyi:351:1
1308+
|
1309+
349 | Final: _SpecialForm
1310+
350 |
1311+
351 | Literal: _SpecialForm
1312+
| ^^^^^^^
1313+
352 | TypedDict: _SpecialForm
1314+
|
1315+
info: Source
1316+
--> main2.py:6:5
1317+
|
1318+
5 | x: int = 1
1319+
6 | y[: Literal[1]] = x
1320+
| ^^^^^^^
1321+
7 | z: int = i(1)
1322+
8 | w[: int] = z
1323+
|
1324+
11161325
info[inlay-hint-location]: Inlay Hint Target
11171326
--> stdlib/builtins.pyi:348:7
11181327
|

0 commit comments

Comments
 (0)