How To Type Check In Python

Python is a dynamically typed language, which means you don’t need to specify the type of a variable when you declare it. However, in some cases, it can be useful to enforce type checking to prevent bugs and improve code safety. In this blog post, we will explore how to perform type checking in Python using annotations and the mypy library.

Type Annotations

Python 3.5 introduced type annotations, which allow you to specify the expected types of function arguments and return values. To add a type annotation, simply add a colon followed by the type immediately after the variable name.

For example, here’s a function that takes two integers and returns their sum, with type annotations:

    def add(a: int, b: int) -> int:
        return a + b
    

Note that type annotations are not enforced by the Python interpreter. They are mainly used for documentation purposes and can be checked by third-party tools like mypy.

Using the Mypy Library

Mypy is a popular static type checker for Python. It helps you catch type errors before runtime, making your code more reliable and easier to maintain.

To install mypy, simply run:

    pip install mypy
    

Once mypy is installed, you can use it to check your Python files. For example, let’s say you have a file called example.py with the following code:

    def add(a: int, b: int) -> int:
        return a + b

    result = add(1, "2")
    print(result)
    

Running mypy example.py will produce the following output:

    example.py:6: error: Argument 2 to "add" has incompatible type "str"; expected "int"
    

Mypy has detected that we’re trying to pass a string as the second argument to the add function, which expects an integer. This helps us catch the error before running the code.

Using Union and Optional Types

Sometimes, a function can accept multiple types for a given argument or return an optional value. In these cases, you can use the Union and Optional types from the typing module.

For example, here’s a function that takes an integer or a float and returns their square:

    from typing import Union

    def square(x: Union[int, float]) -> Union[int, float]:
        return x * x
    

And here’s a function that takes a list and an index, and returns the element at the specified index if it exists, or None otherwise:

    from typing import Optional, List

    def get_element(lst: List[int], index: int) -> Optional[int]:
        return lst[index] if 0 <= index < len(lst) else None
    

Conclusion

Type checking can be a valuable tool in improving the reliability and maintainability of your Python code. By using type annotations and tools like mypy, you can catch type-related bugs early in the development process and ensure your code behaves as expected.