Annotated arguments and returns types stored in __annotations__
At runtime, the annotated arguments and return types are accessible through
__annotations__.
The following script prints {'t': <class 'str'>, 'n': <class 'int'>, 'return': None}
def f(t: str, n: int = 4):
"""Function that prints value of its first argument n times (the second argument)"""
for _ in range(n): print(t)
# f('hello world')
print(f.__annotations__)
No runtime checking
Although the annotations are stored in __annotations__, no actual type checking takes place at runtime!
In fact, the PEP explicitely states that
Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.
Challenges
A challenge with fully-annotated code is that it increases the number of required
import statements which has been recognized by
- PEP 563 (Postponed Evaluation of Annotations) and later also by
- PEP 649 (Deferred Evaluation Of Annotations Using Descriptors)
It seems that typing.TYPE_CHECKING was a result of these PEPs, but see also PEP 781 (Make TYPE_CHECKING a built-in constant)