3.1 KiB
Hover type assertions
You can use the hover assertion to test the inferred type of an expression. This exercises the
same logic as the hover LSP action.
Typically, you will not need to use the hover action to test the behavior of our type inference
code, since you can also use reveal_type to display the inferred type of an expression. Since
reveal_type is part of the standard library, we prefer to use it when possible.
However, there are certain situations where reveal_type and hover will give different results.
In particular, reveal_type is not transparent to bidirectional type checking, as seen in the
"Different results" section below.
Syntax
Basic syntax
The hover assertion operates on a specific location in the source text. We find the "inner-most"
expression at that position, and then query the inferred type of that expression. The row to query
is identified just like any other mdtest assertion. The column to query is identified by a down
arrow (↓) in the assertion. (Note that the down arrow should always appear immediately before the
hover keyword in the assertion.)
def test_basic_types(parameter: int) -> None:
# ↓ hover: int
parameter
# ↓ hover: Literal[10]
number = 10
# ↓ hover: Literal["hello"]
text = "hello"
Multiple hovers on the same line
We can have multiple hover assertions for different positions on the same line:
# ↓ hover: Literal[1]
# ↓ hover: Literal[2]
# ↓ hover: Literal[3]
total = 1 + 2 + 3
# ↓ hover: Literal[5]
# ↓ hover: Literal[3]
result = max(5, 3)
Hovering works on every character in an expression
def _(param: bool) -> None:
# ↓ hover: bool
# ↓ hover: bool
# ↓ hover: bool
# ↓ hover: bool
# ↓ hover: bool
result = param
Hovering with unicode characters
def _(café: str) -> None:
# ↓ hover: str
# ↓ hover: str
# ↓ hover: str
# ↓ hover: str
result = café
Different results for reveal_type and hover
from typing import overload
def f(x: dict[str, int]) -> None: ...
# revealed: dict[Unknown, Unknown]
f(reveal_type({}))
# ↓ hover: dict[str, int]
f({})
Hovering on different expression types
Literals
# ↓ hover: Literal[42]
int_value = 42
# ↓ hover: Literal["test"]
string_value = "test"
# ↓ hover: Literal[True]
bool_value = True
Names and attributes
class MyClass:
value: int
def test_attributes(instance: MyClass) -> None:
# ↓ hover: MyClass
instance
# ↓ hover: int
instance.value
Function definitions
def f(x: int) -> None: ...
# ↓ hover: def f(x: int) -> None
result = f
Binary operations
# ↓ hover: Literal[10]
# ↓ hover: Literal[20]
result = 10 + 20
Comprehensions
# List comprehension
# ↓ hover: list[@Todo(list comprehension element type)]
result = [x for x in range(5)]