A talk about Type hints in python 3 and the type checker mypy.
It talks about typing module, gradual typing, type checkers and how mypy can be used for type checking.
Overview of Structural Subtyping, brief explanation of Python Protocols and example.
2. Contents
Introduction to Type Checking and Type hints
Why Type Hints? What it is and what it isn’t?
How to type hint in python?
Typing examples
Structural Subtyping (PEP544)
Protocol example
References
4. Type Checking
Type checking is the process of verifying the type safety of a program.
Type checker - Tool to check if the right type and number of arguments are passed.
Type checking may happen at compile time or at run time.
In Python,
5. Type Hints
Formalized in PEP484(introduce a gradual type system) and other PEPs
Supported by the typing module of python(3.5 and later).
PEP484 aims to provide a standard syntax for type annotations,
Opens Python code to easier static analysis
def hello(name='nobody’):
''' Say hello to a person
:param: string value
:return: string value
'’’
return 'Hello' + name
def hello(name: str = 'nobody’) -> str:
''' Say hello to a person
'''
return 'Hello' + name
6. Why?
Type hints catches (certain) bugs earlier
Refactoring and update with confidence
Improve code readability (Code as documentation)
Type checkers can be easily integrated with CI tools.
Make IDEs work better (if you use one!) - code generation
utilizing type information.
7. What it is not…
It’s not going to fix all code issues
It does not about do runtime type checking,
hence no performance overhead at runtime.
It’s not going to make Python a static-typed language
Type hints are optional, python follows gradual typing.
It does not enhance performance.
(type annotations can in theory be used to optimize
generated code, but these aren’t done in python
as of today)
8. Type Checkers
Popular Static Type Checkers in Python: Mypy(Python Community), Pyright(Microsoft),
Pyre(Facebook), Pytype(Google)
Annotations are added to python code to annotate type hints.
Python interpreter does not automatically conduct any type checking whatsoever. That means
those annotations have no effects during runtime, even if you are trying to pass a wrong type for
an object to a function.
Mypy is an optional static type checker for Python that aims to combine the benefits of dynamic
(or 'duck') typing and static typing.
9. mypy
Work on mypy began in 2012, a static type checker for python.
It combines the benefits of dynamic (or 'duck') typing and static typing
that is, it support gradual typing.
Install mypy type checker:
Usage:
To avoid individual lines from being flagged add the comment:
pip install mypy
mypy [--strict|--disallow-untyped-defs] <python_script>
# type: ignore
11. The old way - Using type comments.. (python 2)
Using type annotations (using typing) –
For that install “typing”,
In Python 3.5 and higher:
>>> import typing
In Python 3.2–3.4, you need to install it before importing:
$ pip install typing
How to type hint?
def add(a, b): # type: (float, float) -> float
return a + b
def add(a: float, b: float) -> float:
return a + b
12. Annotations
Function argument/return type annotations
Variable Annotations
>>> x: int = …
Special Forms - can be used as types in annotations using []
Tuple type (E.g.: Tuple[X, Y])
Union type (E.g.: Union[X, Y]) - means either X or Y
Optional type – equivalent to Union[X, None]
Callable type (E.g.: Callable[[int], str] is a function of (int) -> str)
Many more – Literal, Final, Annotated, etc.
Functions and decorators – cast, overload, final, no_type_check, type_check_only, etc.
Constant - TYPE_CHECKING
13. Python will remain a dynamically
typed language, and the authors have
no desire to ever make type hints
mandatory, even by convention.
-
Guido van Rossum, Jukka Lehtosalo,
and Łukasz Langa,
PEP 484—Type Hints
17. PEP544
PEP 544 introduced Structural subtyping (static duck typing)
Protocols - types supporting structural subtyping.
Nominal subtyping is strictly based on the class hierarchy. This is the default in mypy and it
matches how the native isinstance check works.
Structural subtyping can be implemented with protocol. Class D is a structural subtype of
class C if the former has all attributes and methods of the latter, and with compatible types.
Structural subtyping can be seen as a static equivalent of duck typing.
18. Predefined Protocols
PEP484 and typing module defines abstract base classes for several common Python protocols
such as Iterable and Sized.
ABCs in typing module already provide structural behavior at
runtime, isinstance(Bucket(), Iterable) returns True.
19. Cons of this..
They must be explicitly subclassed or registered.
This is particularly difficult to do with library types as the type objects may be hidden deep in the
implementation of the library.
Also, extensive use of ABCs might impose additional runtime costs.
PEP544 solves these problems by allowing users to write the code without explicit base classes in
the class definition.
21. Structural SubTyping
Structural subtyping is natural for Python programmers since it matches the runtime semantics of
duck typing
PEP544 says - Protocol classes are specified to complement Normal classes and users are free to
choose where to apply a particular solution.
22. Examples
A parameterized generic is a generic type, written as list[T], where T is a type variable
that will be bound to a specific type with each usage.
from collections.abc import Sequence
from typing import TypeVar
T = TypeVar(‘T’)
def sample(population: Sequence[T], size: int) -> list[T]:
…
“bound” in TypeVar is used to set the upper bound
for acceptable types.
23. References
typing module docs
PEP 484, PEP 544 and others.
Why is Python a dynamic language and also a strongly typed language?
Slide decks by Luciano Ramalho and Guido van Rossum.
David’s tweet
25. Type hints are the biggest change in the history of Python since the unification of types and classes in
Python 2.2, released in 2001. However, type hints do not benefit all Python users equally. That’s why
they should always be optional.
- Luciano Ramalho
Author of Fluent Python