What are Type hints in Python?
Python is a dynamically typed language, meaning that there is no static type checking involved unless the code is executed. This can lead to runtime bugs that are difficult to debug and fix. Hence, type hints, also called type annotations, were introduced in Python 3.5 via the typing module to support the external static type checkers and linters to correctly recognize errors.
There are 2 parts to Type hinting:
- typing module
- static type checker
There are various static type checkers. One of the most widely used static type checkers is mypy. Hence, we will be using mypy as the static type checker.
mypy Module
Use pip to install mypy:
pip install mypy
In order to use mypy against your script, run:
mypy path/to/script.py
Type hints for built-in types
| Built type | Type hint |
|---|---|
| int | int_var: int = 3 |
| float | float_var: float = 3.4 |
| boolean | bool_var: bool = True |
| string | str_var: str = “edpresso” |
| bytes | bytes_var: bytes = b"educative.io" |
The typehints for collections in python are to be imported from the typing module.
from typing import List, Set, Dict, Tuple
| Collection | Type hint |
|---|---|
| list | list_int: List[int] = [3] |
| list | list_string: List[str] = [“edcoffee”] |
| set | set_int: Set[int] = {9,1,3} |
| tuple (finite number of elements) | tuple_float: Tuple[float, str, int] = (3.5, “educative”, 9) |
| tuple (infinite number of elements) | tuple_float: Tuple[float, …] = (3.5, 2.3, 45.6) |
| dict | dict_kv: Dict[str, int] = {“key”: 4} |
Note: In Python 3.9+, in the declarations for type hints for collections, the collection type is not capitalized:
list_int: list[int] = [3]
Type hints for functions
A function signature has the following:
- Name of the function
- Parameters of the function
- Return type of the function
Type hints are applicable to the parameters and the return type of a function. Type hints are applied to a function by annotations. For example:
def multiply(num1: int, num2: int) -> int:
return num1 * num2
Type hints for Classes
class Multiply:
def __init__(self, num1: int, num2: int) -> None:
self.num1 = num1
self.num2 = num2
def multiply(self) -> int:
return self.num1 * self.num2
product: Multiply = Multiply(1, 2)
- For instance methods, omit type for
self - Use return type as
None, if the method doesn’t return anything - User defined classes are valid annotations as types assigned to variables
Change the return type of the
multiply(self) -> intfrominttostr, and run the code againstmypy. You should see mypy throw the following error:
error: Incompatible return value type (got "int", expected "str")
Pros and cons of Type hints
Pros:
- Type hints make code more readable, which also helps to improve documentation
- Type hints help to improve IDEs, to predict errors more precisely, and in-code completion
Cons:
- Type hints consume the developer’s time
- Type hints increase the startup time of the script by a few milliseconds