Skip to content

Python Type Hints

How to use Python type hints (PEP 484) to improve code clarity, catch errors early, and enable better IDE support for variables, functions, and objects.

Type Hinting in Python

Type hinting is a formal solution for statically indicating the type of a value in Python code.

It was specified in PEP 484 and introduced in Python 3.5.

With type hinting, developers can check the consistency of variables and their types throughout the code base. All this is done in ahead of time, i.e., before the code is executed.

Syntax of Type Hints in Python

Type hints in Python involve a colon and a type declaration after the first invocation of a name in a namespace. For example:

name: str
age: int

name = input("Your name?")
age = int(input("Your age?"))

Python type checking systems will attempt to infer types whenever possible.

In the following example, the type checker can infer that name is a string (because input() returns nothing else) and that age is a int (because int() returns nothing else).

name = input("Your name?") 
age =  int(input("Your age?"))

Type Hints in Python functions

In Python, it is also possible to type hint functions to describe in advance the values they accept and return.

Consider the following example in which a

greeting = "Hi, {}, you are {} years old"

def greet(user, age):
    return greeting.format(user, age)

name = input("Your name?")
age = int(input("Your age?"))

print(greet(name, age))

It is possible to disambiguate the code above with type hints in the following way:

greeting = "Hi, {}, you are {} years old"

def greet(user:str, age:int) -> str:
    return greeting.format(user, age)

name = input("Your name?")
age = int(input("Your age?"))

print(greet(name, age))

Type Hints in Python Objects

Since objects like lists, dictionaries, and tuples can contain other objects, we will sometimes want to type hint them to indicate what kinds of objects they contain.

For this we need to turn to Python's typing module, which supplies tools for describing the types such things will hold.

For example, dictionaries are composed of keys and values among several types: you may describe the types for a dictionary by passing them to typing.Dict as a list. Similarly, you may specify the object type of a list by passing it to typing.List.

from typing import Dict, List

dict_of_users: Dict[int,str] = {
    1: "Tom",
    2: "Ryan"
}

list_of_users: List[str] = [
    "Tom", "Ryan"
]

Type Hints in Python classes

To provide type hints for classes, simply refer to their names as you would any other type. For example:

from typing import Dict

class User:
    def __init__(self, name):
        self.name = name

users: Dict[int, User] = {
    1: User("Serdar"),
    2: User("Davis")
}

def inspect_user(user:User) -> None:
    print (user.name)

user1 = users[1]
inspect_user(user1)

When using type hints for custom objects, we will sometimes need to provide a type hint for an object that has not been defined yet. In that case, you can use a string to provide the object name:

class User:
    def __init__(self, name:str, address:"Address"):
        self.name = name
        self.address = address

class Address:
    def __init__(self, owner:User, address_line:str):        
        self.owner = owner
        self.address_line = address_line

Multiple Type Hints in Python Objects

Some objects may contain one of a couple of different types of objects. For this, you can use Union or Optional.

  • Use Union to indicate that an object can be one of several types.
  • Use Optional to indicate that an object is either one given type or None.

For example, consider a dictionary that takes integers (int) as keys but either integers (int) or strings (str) as values.

Union examplepython
from typing import Dict, Optional, Union

dict_of_users: Dict[int, Union[int,str]] = {
    1: "Tom",
    2: "Ryan",
    3: 23
}

Then, consider a variable user defined as below: it can be an int or None (but not a str!)

Option examplepython
user_id: Optional[int]
user_id = None 		# valid
user_id = 3 		# valid
user_id = "Hello" 	# not valid

Type Aliases

Python allows you to give a type an alias and use the alias for type hinting.

A type alias is defined by assigning the type to the alias.

For example, we can assign the Union[int, float] type an alias Number and use the Number alias in the sum() function.

from typing import Union

number = Union[int, float]

def sum(x: number, y: number) -> number:
    return x + y

Type Hints for list, dictionary and set

There are built-in types to set type hints for list, dictionary and set.

To specify the types of values in the list, dictionary, and sets, you can use type aliases from the typing module:

Type Alias Built-in Type
List list
Tuple tuple
Dict dict
Set set
Frozenset frozenset
Sequence For list, tuple, and any other sequence data type.
Mapping For dictionary (dict), set, frozenset, and any other mapping data type
ByteString bytes, bytearray, and memoryview types.

Style recommendations

The PEP 8 recommends the following style guidelines for type hinting:

  • Use the normal rules for colon, that is, no space before and one space after the colon (text: str).
  • Use spaces around the = sign when combining the annotation of an argument with a default value (align: bool = True).
  • Use spaces around the arrow -> (def headline(...) -> str).
Navigation