Type Checking in Python

by Jarrett Retz December 19th, 2020
python programming typing type checking

What is Typing?

Typing is a bug deterrent. It acts as a strong code linter that allows your code to check itself.

What does it mean to check itself? When we type a function in Python or Javascript, we explicitly define the data type and data structures that are allowed to be passed as an argument.

If the function detects that it may receive (or receives) an argument other than the declared type it can warn the developer or error out during compilation.

Why Type Check?

I have already been mentioned that typing helps us prevent the introduction of bugs into our software by being verbose about what is allowed.

This can catch mistakes before they occur. Furthermore, typing allows us to create documentation for our code as we go. It helps us describe the functions' inputs and outputs.

Some other (more advanced?) programming languages have typing built into them. This includes (but don't quote me on this):

  • C and C++
  • Java
  • Typescript

Python and Javascript are criticized for lacking type checks. That's why things like Typescript and the typing module were created.

typing module

Support for type hints (Python Docs)

This module does not strictly enforce typing with Python. However, it can provide helpful hints or warnings through IDEs.

We can type our functions that use built-in types like str, list, and it has support for more exotic types that are used in asynchronous applications. You can dive deep into type checking and the time is typically well spent.

A few more things we can do with the module:

  • create type aliases
  • build new types
  • check our type definitions (get_type_hints())

Providing docstrings is often enough for other developers (or you) to properly use a function. However, type checks may be more your style, or they can add an extra layer of structure to your scripts.

Example of Type Checking in Python

In this section, we'll quickly lay out a few examples of using the typing module with Python.

Starting with a very basic example, let's create a function with one typed argument and print the type hints to the console.

from typing import get_type_hints

def add_2(number: int) -> int:
    return number + 2

print(add_2(4))
# 6

print(get_type_hints(add_2))
# {'number': <class 'int'>, 'return': <class 'int'>}

The following example works in Python ^3.9.1. We are saying the items takes in a list of strings.

from typing import get_type_hints

def print_rows(items: list[str]) -> None:
    for i in range(len(items)):
        print(items[i])
        print("\n")

print(print_rows(["potatoes", "carrots", "onions"]))
##potatoes
##
##
##carrots
##
##
##onions
##
##
##None

print(get_type_hints(print_rows, include_extras=True))
##{'items': list[str], 'return': <class 'NoneType'>}

What if our list accepts strings or integers? We have to import Union from typing.

from typing import get_type_hints, Union

def print_rows(items: list[Union[str, int]]) -> None:
    for i in range(len(items)):
        print(items[i])
        print("\n")

print(print_rows(["potatoes", "carrots", "onions"]))
##potatoes
##
##
##carrots
##
##
##onions
##
##
##None

print(get_type_hints(print_rows, include_extras=True))
##{'items': list[typing.Union[str, int]], 'return': <class 'NoneType'>}

This is starting to get messy. Thankfully, Python has an answer for that. We can create a type alias and pass that into the function instead!

from typing import get_type_hints, Union

GroceryItems = list[Union[str, int]]

def print_rows(items: GroceryItems) -> None:
    for i in range(len(items)):
        print(items[i])
        print("\n")

print(print_rows(["potatoes", "carrots", "onions"]))
##potatoes
##
##
##carrots
##
##
##onions
##
##
##None

print(get_type_hints(print_rows))
##{'items': list[typing.Union[str, int]], 'return': <class 'NoneType'>}

We get the exact same output.

Conclusion

Typing is cool, but it's overlooked. For reasons that are beyond developers' understanding, unless we are required to type check, we usually don't.

It's comparable to working out. We don't notice the benefits until later (sometimes too late!).

Thanks for reading!


Have a thought about the article?

Send JRTS a message!

We'll use this email to respond to your message.

Contact