Python Type Hints - How to Debug Types With reveal_type()

When working with type hints, it’s often useful to debug the types of variables. Type checkers allow you to do this with reveal_type()
and reveal_locals()
.
For example, take this code:
items = [1, None]
We don’t need to add a hint to items
since our type checker can infer its type. But we might not be sure what type has been inferred—is it list[int | None]
, the less useful list[object]
, or worst list[Any]
? We can check by adding a call to reveal_type()
:
items = [1, None]
reveal_type(items)
Then when we run our type checker, in this case Mypy, it will log the type of items
:
$ mypy example.py
example.py:2: note: Revealed type is 'builtins.list[Union[builtins.int, None]]'
Here Mypy wrote its “long-form spelling” of list[int | None]
(in a future version it may use a shorter form).
Note that reveal_type()
does not exist at runtime, so if we run our code with the call in place, Python crashes with a NameError
:
$ python example.py
Traceback (most recent call last):
File "/.../example.py", line 2, in <module>
reveal_type(items)
NameError: name 'reveal_type' is not defined
So, we need to remove all calls to reveal_type()
before running our code.
A good way to make sure you never accidentally commit a call to reveal_type()
is to use flake8, perhaps under pre-commit. It will flag calls with the error F821 undefined name 'reveal_type'
.
Also, reveal_locals()
Mypy also supports reveal_locals()
, which does a reveal_type()
for each local variable. This can save time when debugging several variables.
For example, if we take this code:
CONSTANT = 1
def example() -> None:
first_item = 1
items = [first_item, None]
reveal_locals()
We can run Mypy and see:
$ mypy example.py
example.py:7: note: Revealed local types are:
example.py:7: note: first_item: builtins.int
example.py:7: note: items: builtins.list[Union[builtins.int, None]]
The local variables first_item
and items
have their types revealed, but the global variable CONSTANT
does not.
Make your development more pleasant with Boost Your Django DX.
One summary email a week, no spam, I pinky promise.
Related posts: