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:

  1. typing module
  2. 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:

  1. Name of the function
  2. Parameters of the function
  3. 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)
  1. For instance methods, omit type for self
  2. Use return type as None, if the method doesn’t return anything
  3. User defined classes are valid annotations as types assigned to variables

Change the return type of the multiply(self) -> int from int to str, and run the code against mypy. You should see mypy throw the following error:

error: Incompatible return value type (got "int", expected "str")

Pros and cons of Type hints

Pros:

  1. Type hints make code more readable, which also helps to improve documentation
  2. Type hints help to improve IDEs, to predict errors more precisely, and in-code completion

Cons:

  1. Type hints consume the developer’s time
  2. Type hints increase the startup time of the script by a few milliseconds

Free Resources