mirror of https://github.com/astral-sh/ruff
[ty] More low-hanging fruit for inlay hint goto-definition (#21548)
This commit is contained in:
parent
eb7c098d6b
commit
06941c1987
|
|
@ -588,6 +588,8 @@ mod tests {
|
||||||
y = x
|
y = x
|
||||||
z = i(1)
|
z = i(1)
|
||||||
w = z
|
w = z
|
||||||
|
aa = b'foo'
|
||||||
|
bb = aa
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -599,6 +601,8 @@ mod tests {
|
||||||
y[: Literal[1]] = x
|
y[: Literal[1]] = x
|
||||||
z[: int] = i(1)
|
z[: int] = i(1)
|
||||||
w[: int] = z
|
w[: int] = z
|
||||||
|
aa = b'foo'
|
||||||
|
bb[: Literal[b"foo"]] = aa
|
||||||
|
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
|
@ -630,12 +634,12 @@ mod tests {
|
||||||
350 | int(x, base=10) -> integer
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
|
||||||
info: Source
|
info: Source
|
||||||
--> main2.py:7:5
|
--> main2.py:6:13
|
||||||
|
|
|
|
||||||
5 | x = 1
|
5 | x = 1
|
||||||
6 | y[: Literal[1]] = x
|
6 | y[: Literal[1]] = x
|
||||||
|
| ^
|
||||||
7 | z[: int] = i(1)
|
7 | z[: int] = i(1)
|
||||||
| ^^^
|
|
||||||
8 | w[: int] = z
|
8 | w[: int] = z
|
||||||
|
|
|
|
||||||
|
|
||||||
|
|
@ -649,13 +653,71 @@ mod tests {
|
||||||
350 | int(x, base=10) -> integer
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
|
||||||
info: Source
|
info: Source
|
||||||
--> main2.py:8:5
|
--> main2.py:7:5
|
||||||
|
|
|
|
||||||
|
5 | x = 1
|
||||||
6 | y[: Literal[1]] = x
|
6 | y[: Literal[1]] = x
|
||||||
7 | z[: int] = i(1)
|
7 | z[: int] = i(1)
|
||||||
8 | w[: int] = z
|
|
||||||
| ^^^
|
| ^^^
|
||||||
|
8 | w[: int] = z
|
||||||
|
9 | aa = b'foo'
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:5
|
||||||
|
|
|
||||||
|
6 | y[: Literal[1]] = x
|
||||||
|
7 | z[: int] = i(1)
|
||||||
|
8 | w[: int] = z
|
||||||
|
| ^^^
|
||||||
|
9 | aa = b'foo'
|
||||||
|
10 | bb[: Literal[b"foo"]] = aa
|
||||||
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/typing.pyi:351:1
|
||||||
|
|
|
||||||
|
349 | Final: _SpecialForm
|
||||||
|
350 |
|
||||||
|
351 | Literal: _SpecialForm
|
||||||
|
| ^^^^^^^
|
||||||
|
352 | TypedDict: _SpecialForm
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:10:6
|
||||||
|
|
|
||||||
|
8 | w[: int] = z
|
||||||
|
9 | aa = b'foo'
|
||||||
|
10 | bb[: Literal[b"foo"]] = aa
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:1448:7
|
||||||
|
|
|
||||||
|
1447 | @disjoint_base
|
||||||
|
1448 | class bytes(Sequence[int]):
|
||||||
|
| ^^^^^
|
||||||
|
1449 | """bytes(iterable_of_ints) -> bytes
|
||||||
|
1450 | bytes(string, encoding[, errors]) -> bytes
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:10:14
|
||||||
|
|
|
||||||
|
8 | w[: int] = z
|
||||||
|
9 | aa = b'foo'
|
||||||
|
10 | bb[: Literal[b"foo"]] = aa
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
"#);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -706,6 +768,25 @@ mod tests {
|
||||||
10 | x4[: int], y4[: str] = (x3, y3)
|
10 | x4[: int], y4[: str] = (x3, y3)
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:14
|
||||||
|
|
|
||||||
|
7 | x1, y1 = (1, 'abc')
|
||||||
|
8 | x2[: Literal[1]], y2[: Literal["abc"]] = (x1, y1)
|
||||||
|
| ^
|
||||||
|
9 | x3[: int], y3[: str] = (i(1), s('abc'))
|
||||||
|
10 | x4[: int], y4[: str] = (x3, y3)
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/typing.pyi:351:1
|
--> stdlib/typing.pyi:351:1
|
||||||
|
|
|
|
||||||
|
|
@ -725,6 +806,25 @@ mod tests {
|
||||||
10 | x4[: int], y4[: str] = (x3, y3)
|
10 | x4[: int], y4[: str] = (x3, y3)
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:915:7
|
||||||
|
|
|
||||||
|
914 | @disjoint_base
|
||||||
|
915 | class str(Sequence[str]):
|
||||||
|
| ^^^
|
||||||
|
916 | """str(object='') -> str
|
||||||
|
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:32
|
||||||
|
|
|
||||||
|
7 | x1, y1 = (1, 'abc')
|
||||||
|
8 | x2[: Literal[1]], y2[: Literal["abc"]] = (x1, y1)
|
||||||
|
| ^^^^^
|
||||||
|
9 | x3[: int], y3[: str] = (i(1), s('abc'))
|
||||||
|
10 | x4[: int], y4[: str] = (x3, y3)
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/builtins.pyi:348:7
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
|
||||||
|
|
@ -848,6 +948,25 @@ mod tests {
|
||||||
10 | x4[: int], y4[: str] = x3, y3
|
10 | x4[: int], y4[: str] = x3, y3
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:14
|
||||||
|
|
|
||||||
|
7 | x1, y1 = 1, 'abc'
|
||||||
|
8 | x2[: Literal[1]], y2[: Literal["abc"]] = x1, y1
|
||||||
|
| ^
|
||||||
|
9 | x3[: int], y3[: str] = i(1), s('abc')
|
||||||
|
10 | x4[: int], y4[: str] = x3, y3
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/typing.pyi:351:1
|
--> stdlib/typing.pyi:351:1
|
||||||
|
|
|
|
||||||
|
|
@ -867,6 +986,25 @@ mod tests {
|
||||||
10 | x4[: int], y4[: str] = x3, y3
|
10 | x4[: int], y4[: str] = x3, y3
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:915:7
|
||||||
|
|
|
||||||
|
914 | @disjoint_base
|
||||||
|
915 | class str(Sequence[str]):
|
||||||
|
| ^^^
|
||||||
|
916 | """str(object='') -> str
|
||||||
|
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:32
|
||||||
|
|
|
||||||
|
7 | x1, y1 = 1, 'abc'
|
||||||
|
8 | x2[: Literal[1]], y2[: Literal["abc"]] = x1, y1
|
||||||
|
| ^^^^^
|
||||||
|
9 | x3[: int], y3[: str] = i(1), s('abc')
|
||||||
|
10 | x4[: int], y4[: str] = x3, y3
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/builtins.pyi:348:7
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
|
||||||
|
|
@ -1008,6 +1146,25 @@ mod tests {
|
||||||
10 | w[: tuple[int, str]] = z
|
10 | w[: tuple[int, str]] = z
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:19
|
||||||
|
|
|
||||||
|
7 | x = (1, 'abc')
|
||||||
|
8 | y[: tuple[Literal[1], Literal["abc"]]] = x
|
||||||
|
| ^
|
||||||
|
9 | z[: tuple[int, str]] = (i(1), s('abc'))
|
||||||
|
10 | w[: tuple[int, str]] = z
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/typing.pyi:351:1
|
--> stdlib/typing.pyi:351:1
|
||||||
|
|
|
|
||||||
|
|
@ -1027,6 +1184,25 @@ mod tests {
|
||||||
10 | w[: tuple[int, str]] = z
|
10 | w[: tuple[int, str]] = z
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:915:7
|
||||||
|
|
|
||||||
|
914 | @disjoint_base
|
||||||
|
915 | class str(Sequence[str]):
|
||||||
|
| ^^^
|
||||||
|
916 | """str(object='') -> str
|
||||||
|
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:31
|
||||||
|
|
|
||||||
|
7 | x = (1, 'abc')
|
||||||
|
8 | y[: tuple[Literal[1], Literal["abc"]]] = x
|
||||||
|
| ^^^^^
|
||||||
|
9 | z[: tuple[int, str]] = (i(1), s('abc'))
|
||||||
|
10 | w[: tuple[int, str]] = z
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/builtins.pyi:2695:7
|
--> stdlib/builtins.pyi:2695:7
|
||||||
|
|
|
|
||||||
|
|
@ -1183,6 +1359,25 @@ mod tests {
|
||||||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:14
|
||||||
|
|
|
||||||
|
7 | x1, (y1, z1) = (1, ('abc', 2))
|
||||||
|
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
|
||||||
|
| ^
|
||||||
|
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
|
||||||
|
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/typing.pyi:351:1
|
--> stdlib/typing.pyi:351:1
|
||||||
|
|
|
|
||||||
|
|
@ -1202,6 +1397,25 @@ mod tests {
|
||||||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:915:7
|
||||||
|
|
|
||||||
|
914 | @disjoint_base
|
||||||
|
915 | class str(Sequence[str]):
|
||||||
|
| ^^^
|
||||||
|
916 | """str(object='') -> str
|
||||||
|
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:33
|
||||||
|
|
|
||||||
|
7 | x1, (y1, z1) = (1, ('abc', 2))
|
||||||
|
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
|
||||||
|
| ^^^^^
|
||||||
|
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
|
||||||
|
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/typing.pyi:351:1
|
--> stdlib/typing.pyi:351:1
|
||||||
|
|
|
|
||||||
|
|
@ -1221,6 +1435,25 @@ mod tests {
|
||||||
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:8:55
|
||||||
|
|
|
||||||
|
7 | x1, (y1, z1) = (1, ('abc', 2))
|
||||||
|
8 | x2[: Literal[1]], (y2[: Literal["abc"]], z2[: Literal[2]]) = (x1, (y1, z1))
|
||||||
|
| ^
|
||||||
|
9 | x3[: int], (y3[: str], z3[: int]) = (i(1), (s('abc'), i(2)))
|
||||||
|
10 | x4[: int], (y4[: str], z4[: int]) = (x3, (y3, z3))
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/builtins.pyi:348:7
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
|
||||||
|
|
@ -1375,6 +1608,25 @@ mod tests {
|
||||||
8 | w[: int] = z
|
8 | w[: int] = z
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:6:13
|
||||||
|
|
|
||||||
|
5 | x: int = 1
|
||||||
|
6 | y[: Literal[1]] = x
|
||||||
|
| ^
|
||||||
|
7 | z: int = i(1)
|
||||||
|
8 | w[: int] = z
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/builtins.pyi:348:7
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
|
||||||
|
|
@ -4988,6 +5240,78 @@ mod tests {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:13:17
|
||||||
|
|
|
||||||
|
11 | else:
|
||||||
|
12 | x = None
|
||||||
|
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:13:20
|
||||||
|
|
|
||||||
|
11 | else:
|
||||||
|
12 | x = None
|
||||||
|
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:348:7
|
||||||
|
|
|
||||||
|
347 | @disjoint_base
|
||||||
|
348 | class int:
|
||||||
|
| ^^^
|
||||||
|
349 | """int([x]) -> integer
|
||||||
|
350 | int(x, base=10) -> integer
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:13:23
|
||||||
|
|
|
||||||
|
11 | else:
|
||||||
|
12 | x = None
|
||||||
|
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> stdlib/builtins.pyi:915:7
|
||||||
|
|
|
||||||
|
914 | @disjoint_base
|
||||||
|
915 | class str(Sequence[str]):
|
||||||
|
| ^^^
|
||||||
|
916 | """str(object='') -> str
|
||||||
|
917 | str(bytes_or_buffer[, encoding[, errors]]) -> str
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:13:26
|
||||||
|
|
|
||||||
|
11 | else:
|
||||||
|
12 | x = None
|
||||||
|
13 | y[: Literal[1, 2, 3, "hello"] | None] = x
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
|
||||||
info[inlay-hint-location]: Inlay Hint Target
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
--> stdlib/types.pyi:950:11
|
--> stdlib/types.pyi:950:11
|
||||||
|
|
|
|
||||||
|
|
@ -5123,6 +5447,45 @@ mod tests {
|
||||||
"#);
|
"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_property_literal_type() {
|
||||||
|
let mut test = inlay_hint_test(
|
||||||
|
r"
|
||||||
|
class F:
|
||||||
|
@property
|
||||||
|
def whatever(self): ...
|
||||||
|
|
||||||
|
ab = F.whatever",
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot!(test.inlay_hints(), @r"
|
||||||
|
class F:
|
||||||
|
@property
|
||||||
|
def whatever(self): ...
|
||||||
|
|
||||||
|
ab[: property] = F.whatever
|
||||||
|
---------------------------------------------
|
||||||
|
info[inlay-hint-location]: Inlay Hint Target
|
||||||
|
--> main.py:4:9
|
||||||
|
|
|
||||||
|
2 | class F:
|
||||||
|
3 | @property
|
||||||
|
4 | def whatever(self): ...
|
||||||
|
| ^^^^^^^^
|
||||||
|
5 |
|
||||||
|
6 | ab = F.whatever
|
||||||
|
|
|
||||||
|
info: Source
|
||||||
|
--> main2.py:6:6
|
||||||
|
|
|
||||||
|
4 | def whatever(self): ...
|
||||||
|
5 |
|
||||||
|
6 | ab[: property] = F.whatever
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_complex_parameter_combinations() {
|
fn test_complex_parameter_combinations() {
|
||||||
let mut test = inlay_hint_test(
|
let mut test = inlay_hint_test(
|
||||||
|
|
|
||||||
|
|
@ -7601,6 +7601,11 @@ impl<'db> Type<'db> {
|
||||||
Self::TypeAlias(alias) => alias.value_type(db).definition(db),
|
Self::TypeAlias(alias) => alias.value_type(db).definition(db),
|
||||||
Self::NewTypeInstance(newtype) => Some(TypeDefinition::NewType(newtype.definition(db))),
|
Self::NewTypeInstance(newtype) => Some(TypeDefinition::NewType(newtype.definition(db))),
|
||||||
|
|
||||||
|
Self::PropertyInstance(property) => property
|
||||||
|
.getter(db)
|
||||||
|
.and_then(|getter|getter.definition(db))
|
||||||
|
.or_else(||property.setter(db).and_then(|setter|setter.definition(db))),
|
||||||
|
|
||||||
Self::StringLiteral(_)
|
Self::StringLiteral(_)
|
||||||
| Self::BooleanLiteral(_)
|
| Self::BooleanLiteral(_)
|
||||||
| Self::LiteralString
|
| Self::LiteralString
|
||||||
|
|
@ -7612,7 +7617,6 @@ impl<'db> Type<'db> {
|
||||||
| Self::WrapperDescriptor(_)
|
| Self::WrapperDescriptor(_)
|
||||||
| Self::DataclassDecorator(_)
|
| Self::DataclassDecorator(_)
|
||||||
| Self::DataclassTransformer(_)
|
| Self::DataclassTransformer(_)
|
||||||
| Self::PropertyInstance(_)
|
|
||||||
| Self::BoundSuper(_) => self.to_meta_type(db).definition(db),
|
| Self::BoundSuper(_) => self.to_meta_type(db).definition(db),
|
||||||
|
|
||||||
Self::TypeVar(bound_typevar) => Some(TypeDefinition::TypeVar(bound_typevar.typevar(db).definition(db)?)),
|
Self::TypeVar(bound_typevar) => Some(TypeDefinition::TypeVar(bound_typevar.typevar(db).definition(db)?)),
|
||||||
|
|
@ -7622,20 +7626,22 @@ impl<'db> Type<'db> {
|
||||||
Protocol::Synthesized(_) => None,
|
Protocol::Synthesized(_) => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
Type::TypedDict(typed_dict) => {
|
Self::TypedDict(typed_dict) => {
|
||||||
Some(TypeDefinition::Class(typed_dict.defining_class().definition(db)))
|
Some(TypeDefinition::Class(typed_dict.defining_class().definition(db)))
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::Union(_) | Self::Intersection(_) => None,
|
Self::Union(_) | Self::Intersection(_) => None,
|
||||||
|
|
||||||
Self::SpecialForm(special_form) => special_form.definition(db),
|
Self::SpecialForm(special_form) => special_form.definition(db),
|
||||||
|
Self::Never => Type::SpecialForm(SpecialFormType::Never).definition(db),
|
||||||
|
Self::Dynamic(DynamicType::Any) => Type::SpecialForm(SpecialFormType::Any).definition(db),
|
||||||
|
Self::Dynamic(DynamicType::Unknown) => Type::SpecialForm(SpecialFormType::Unknown).definition(db),
|
||||||
|
Self::AlwaysTruthy => Type::SpecialForm(SpecialFormType::AlwaysTruthy).definition(db),
|
||||||
|
Self::AlwaysFalsy => Type::SpecialForm(SpecialFormType::AlwaysFalsy).definition(db),
|
||||||
|
|
||||||
// These types have no definition
|
// These types have no definition
|
||||||
Self::Dynamic(_)
|
Self::Dynamic(DynamicType::Divergent(_) | DynamicType::Todo(_) | DynamicType::TodoTypeAlias | DynamicType::TodoUnpack)
|
||||||
| Self::Never
|
|
||||||
| Self::Callable(_)
|
| Self::Callable(_)
|
||||||
| Self::AlwaysTruthy
|
|
||||||
| Self::AlwaysFalsy
|
|
||||||
| Self::TypeIs(_) => None,
|
| Self::TypeIs(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ use crate::types::signatures::{CallableSignature, Parameter, Parameters, Signatu
|
||||||
use crate::types::tuple::TupleSpec;
|
use crate::types::tuple::TupleSpec;
|
||||||
use crate::types::visitor::TypeVisitor;
|
use crate::types::visitor::TypeVisitor;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
BoundTypeVarIdentity, CallableType, DynamicType, IntersectionType, KnownBoundMethodType,
|
BoundTypeVarIdentity, CallableType, IntersectionType, KnownBoundMethodType, KnownClass,
|
||||||
KnownClass, MaterializationKind, Protocol, ProtocolInstanceType, SpecialFormType,
|
MaterializationKind, Protocol, ProtocolInstanceType, SpecialFormType, StringLiteralType,
|
||||||
StringLiteralType, SubclassOfInner, Type, UnionType, WrapperDescriptorKind, visitor,
|
SubclassOfInner, Type, UnionType, WrapperDescriptorKind, visitor,
|
||||||
};
|
};
|
||||||
use ruff_db::parsed::parsed_module;
|
use ruff_db::parsed::parsed_module;
|
||||||
|
|
||||||
|
|
@ -611,9 +611,7 @@ impl Display for DisplayRepresentation<'_> {
|
||||||
impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
||||||
match self.ty {
|
match self.ty {
|
||||||
Type::Dynamic(dynamic) => dynamic
|
Type::Dynamic(dynamic) => write!(f.with_detail(TypeDetail::Type(self.ty)), "{dynamic}"),
|
||||||
.display_with(self.db, self.settings.clone())
|
|
||||||
.fmt_detailed(f),
|
|
||||||
Type::Never => f.with_detail(TypeDetail::Type(self.ty)).write_str("Never"),
|
Type::Never => f.with_detail(TypeDetail::Type(self.ty)).write_str("Never"),
|
||||||
Type::NominalInstance(instance) => {
|
Type::NominalInstance(instance) => {
|
||||||
let class = instance.class(self.db);
|
let class = instance.class(self.db);
|
||||||
|
|
@ -662,7 +660,9 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.write_char('>')
|
f.write_char('>')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Type::PropertyInstance(_) => f.write_str("property"),
|
Type::PropertyInstance(_) => f
|
||||||
|
.with_detail(TypeDetail::Type(self.ty))
|
||||||
|
.write_str("property"),
|
||||||
Type::ModuleLiteral(module) => {
|
Type::ModuleLiteral(module) => {
|
||||||
write!(
|
write!(
|
||||||
f.with_detail(TypeDetail::Type(self.ty)),
|
f.with_detail(TypeDetail::Type(self.ty)),
|
||||||
|
|
@ -709,9 +709,10 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
f.with_detail(TypeDetail::Type(KnownClass::Type.to_class_literal(self.db)))
|
f.with_detail(TypeDetail::Type(KnownClass::Type.to_class_literal(self.db)))
|
||||||
.write_str("type")?;
|
.write_str("type")?;
|
||||||
f.write_char('[')?;
|
f.write_char('[')?;
|
||||||
dynamic
|
write!(
|
||||||
.display_with(self.db, self.settings.clone())
|
f.with_detail(TypeDetail::Type(Type::Dynamic(dynamic))),
|
||||||
.fmt_detailed(f)?;
|
"{dynamic}"
|
||||||
|
)?;
|
||||||
f.write_char(']')
|
f.write_char(']')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -847,18 +848,33 @@ impl<'db> FmtDetailed<'db> for DisplayRepresentation<'db> {
|
||||||
Type::Intersection(intersection) => intersection
|
Type::Intersection(intersection) => intersection
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt_detailed(f),
|
.fmt_detailed(f),
|
||||||
Type::IntLiteral(n) => write!(f, "{n}"),
|
Type::IntLiteral(n) => write!(f.with_detail(TypeDetail::Type(self.ty)), "{n}"),
|
||||||
Type::BooleanLiteral(boolean) => f.write_str(if boolean { "True" } else { "False" }),
|
Type::BooleanLiteral(boolean) => f
|
||||||
|
.with_detail(TypeDetail::Type(self.ty))
|
||||||
|
.write_str(if boolean { "True" } else { "False" }),
|
||||||
Type::StringLiteral(string) => {
|
Type::StringLiteral(string) => {
|
||||||
write!(f, "{}", string.display_with(self.db, self.settings.clone()))
|
write!(
|
||||||
|
f.with_detail(TypeDetail::Type(self.ty)),
|
||||||
|
"{}",
|
||||||
|
string.display_with(self.db, self.settings.clone())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
// an alternative would be to use `Type::SpecialForm(SpecialFormType::LiteralString)` here,
|
||||||
|
// which would mean users would be able to jump to the definition of `LiteralString` from the
|
||||||
|
// inlay hint, but that seems less useful than the definition of `str` for a variable that is
|
||||||
|
// inferred as an *inhabitant* of `LiteralString` (since that variable will just be a string
|
||||||
|
// at runtime)
|
||||||
Type::LiteralString => f
|
Type::LiteralString => f
|
||||||
.with_detail(TypeDetail::Type(self.ty))
|
.with_detail(TypeDetail::Type(self.ty))
|
||||||
.write_str("LiteralString"),
|
.write_str("LiteralString"),
|
||||||
Type::BytesLiteral(bytes) => {
|
Type::BytesLiteral(bytes) => {
|
||||||
let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db), Quote::Double);
|
let escape = AsciiEscape::with_preferred_quote(bytes.value(self.db), Quote::Double);
|
||||||
|
|
||||||
escape.bytes_repr(TripleQuotes::No).write(f)
|
write!(
|
||||||
|
f.with_detail(TypeDetail::Type(self.ty)),
|
||||||
|
"{}",
|
||||||
|
escape.bytes_repr(TripleQuotes::No)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Type::EnumLiteral(enum_literal) => {
|
Type::EnumLiteral(enum_literal) => {
|
||||||
enum_literal
|
enum_literal
|
||||||
|
|
@ -1162,48 +1178,6 @@ impl Display for DisplayFunctionType<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> DynamicType<'db> {
|
|
||||||
fn display_with<'a>(
|
|
||||||
&'a self,
|
|
||||||
db: &'db dyn Db,
|
|
||||||
settings: DisplaySettings<'db>,
|
|
||||||
) -> DisplayDynamicType<'a, 'db> {
|
|
||||||
DisplayDynamicType {
|
|
||||||
dynamic_type: self,
|
|
||||||
db,
|
|
||||||
settings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DisplayDynamicType<'a, 'db> {
|
|
||||||
dynamic_type: &'a DynamicType<'db>,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
db: &'db dyn Db,
|
|
||||||
#[allow(dead_code)]
|
|
||||||
settings: DisplaySettings<'db>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'db> FmtDetailed<'db> for DisplayDynamicType<'_, 'db> {
|
|
||||||
fn fmt_detailed(&self, f: &mut TypeWriter<'_, '_, 'db>) -> fmt::Result {
|
|
||||||
match self.dynamic_type {
|
|
||||||
DynamicType::Any => write!(
|
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(SpecialFormType::Any))),
|
|
||||||
"{}",
|
|
||||||
self.dynamic_type,
|
|
||||||
),
|
|
||||||
DynamicType::Unknown => write!(
|
|
||||||
f.with_detail(TypeDetail::Type(Type::SpecialForm(
|
|
||||||
SpecialFormType::Unknown
|
|
||||||
))),
|
|
||||||
"{}",
|
|
||||||
self.dynamic_type,
|
|
||||||
),
|
|
||||||
_ => write!(f, "{}", self.dynamic_type),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'db> GenericAlias<'db> {
|
impl<'db> GenericAlias<'db> {
|
||||||
pub(crate) fn display(self, db: &'db dyn Db) -> DisplayGenericAlias<'db> {
|
pub(crate) fn display(self, db: &'db dyn Db) -> DisplayGenericAlias<'db> {
|
||||||
self.display_with(db, DisplaySettings::default())
|
self.display_with(db, DisplaySettings::default())
|
||||||
|
|
@ -1237,16 +1211,20 @@ impl<'db> FmtDetailed<'db> for DisplayGenericAlias<'db> {
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt_detailed(f)
|
.fmt_detailed(f)
|
||||||
} else {
|
} else {
|
||||||
let prefix = match self.specialization.materialization_kind(self.db) {
|
let prefix_details = match self.specialization.materialization_kind(self.db) {
|
||||||
None => "",
|
None => None,
|
||||||
Some(MaterializationKind::Top) => "Top[",
|
Some(MaterializationKind::Top) => Some(("Top", SpecialFormType::Top)),
|
||||||
Some(MaterializationKind::Bottom) => "Bottom[",
|
Some(MaterializationKind::Bottom) => Some(("Bottom", SpecialFormType::Bottom)),
|
||||||
};
|
};
|
||||||
let suffix = match self.specialization.materialization_kind(self.db) {
|
let suffix = match self.specialization.materialization_kind(self.db) {
|
||||||
None => "",
|
None => "",
|
||||||
Some(_) => "]",
|
Some(_) => "]",
|
||||||
};
|
};
|
||||||
f.write_str(prefix)?;
|
if let Some((name, form)) = prefix_details {
|
||||||
|
f.with_detail(TypeDetail::Type(Type::SpecialForm(form)))
|
||||||
|
.write_str(name)?;
|
||||||
|
f.write_char('[')?;
|
||||||
|
}
|
||||||
self.origin
|
self.origin
|
||||||
.display_with(self.db, self.settings.clone())
|
.display_with(self.db, self.settings.clone())
|
||||||
.fmt_detailed(f)?;
|
.fmt_detailed(f)?;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue