Python Type Hinting

Beginner’s Cheat Sheet

Debanga Raj Neog, Ph.D
Depurr
3 min readMay 18, 2020

--

Python is a dynamic programming language, i.e., the environment can be changed at run-time and isn’t explicitly coded in the source code. Variables have no types, functions, and objects that can be altered on run-time. Therefore, to run a python script we don’t need to specify the types of the variables unlike strongly typed languages such as C++. It makes Python an easy language to learn and code. But at the same type, for debugging, documenting, improve IDEs and Linters, build and maintain a cleaner architecture, and integrating with scripts written in another language, it is often useful to know the types of the variables. Python lacks it.

To solve this issue, optional static type hinting was specified in the Python Enhancement Proposal (PEP) 484 and introduced for the first time in Python 3.5.

In this blog, I will show some basic usage of type hinting that can be used in your python project right away!

Basic Syntax

The basic syntax of type hinting is as follows:

def add_two_integers(x: int = 1, y: int = 2) -> int:
return x + y

Here, we use colon : to specify the type of input arguments, and arrow -> to specify the type of the return variable of a function. We can use equal = to specify the default value of the input parameters.

Style Suggestions

  • Colon usage: Use normal rules for colons, that is, no space before and one space after a colon (x: int) .
  • Default assignment usage: Use spaces around the = sign when combining an argument annotation with a default value (align: x: int = 1).
  • Return arrow usage: Use spaces around the ->arrow.

Usage

Basic Variables

All the following declarations are valid. Any simple basic types not mentioned below can be used.

length: int # no value at runtime until assigned
length: int = 10
is_square: bool # no value at runtime until assigned
is_square: bool = False

width: float # no value at runtime until assigned
width: float = 100

name: str # no value at runtime until assigned
name: str = "rectangle"

Built-in Data Structures

To statically type built-in data structure we can use typing package as follows.

from typing import List, Set, Dict, Tuple, Optional

List

x: List[int] = [1, 2]

Set

x: Set[str] = {'rect', 'square'}

Dictionary

x: Dict[str, float] = {'length': 10.0, 'width': 100.0}

Tuples

x: Tuple[str, float, float] = ("rect", 10.0, 100.0)

x: Tuple[int, ...] = (1, 2, 3) # Variable size tuple

Optional

Optional is used as Optional[A] to indicate that the object is either of type A or None.

def compare_numbers(x: int) -> int:
if x<10:
return 1
elif x>10:
return 0
else:
return None
x: Optional[int] = compare_numbers(10)

Functions

from typing import Callable, Iterator, Union

Callable function

It follows the format Callable[[arg1, arg2], return_type], where arg1, arg2 and input types and return_type is the type of the return variable.

x: Callable[[int, int], int] = add_two_integers

Iterators

For generator functions that use yield can use Iterators to specify the return type.

def generator(n: int) -> Iterator[int]:
i = 0
while i < n:
yield i
i += 1

Union

A union can be used as Union[A, B] to indicate that the object can have type A or B.

def add_two_integers_or_floats(x: Union[int, float], y: Union[int, float]) -> Union[int, float]:
return x + y

Type aliases

You can also use type aliases for the convenience of coding.

F = List[float] # Aliasing list of floatsa: F = [1.0, 4.6, 9.1]

Generics

Defining a fixed type may be sometimes restrictive. We can use TypeVar for generic definitions. Here is an example from [4]

from typing import TypeVar, Iterable, DefaultDictRelation = Tuple[T, T]
def create_tree(tuples: Iterable[Relation]) -> DefaultDict[T, List[T]]:
tree: DefaultDict[T, List[T]] = defaultdict(list)
for idx, child in enumerate(tuples):
tree[idx].append(child)
return treeprint(create_tree([(2.0,1.0), (3.0,1.0), (4.0,3.0), (1.0,6.0)]))

Using Mypy

You can use mypy python static type checker package (http://mypy-lang.org/) to check whether a script has some type of static typing errors.

You can install it by running:

pip install mypy

Then you can test your script (say, my_script.py) by running:

mypy my_script.py

Further Reading

--

--

Debanga Raj Neog, Ph.D
Depurr
Editor for

Entrepreneur. Computer Vision Expert. Machine Learning Nerd. Buy me a Chimay Blue.