Python typing.Annotated examples

Updated: February 14, 2024 By: Guest Contributor Post a comment

Introduction

Type checking in Python serves as a syntax for declaring types of variables, function parameters, and return values. It helps in early detection of potential errors, makes code more understandable, and facilitates better auto-completion and type inference in IDEs. With the advent of Annotated in the typing module, developers can go a step further by providing custom metadata to their type hints.

With the growing complexity of Python applications, ensuring code clarity and reducing the chances for bugs have become paramount. The typing module, introduced in Python 3.5, brought static type checking to the language, enhancing predictability and readability. This guide explores how to use the typing module, focusing on the Annotated class, which allows for more detailed type definitions. Through annotated examples, we aim to simplify your understanding of Python’s type annotations and their practical applications.

Basic Usage of Annotated

Annotated can be used to add extra information about the type hint. This is especially useful for scenarios where simple type hints are not enough. The first example shows how to use Annotated to add a simple description to a type hint.

from typing import Annotated

def display(message: Annotated[str, "This is a string message"]):
    print(message)

# Example usage:
display("Hello, world!")

This shows how Annotated could be used to add a descriptive comment to a type hint, making the code more readable and providing documentation inline.

Using Annotated for Validation

In more advanced scenarios, Annotated can also incorporate validation or conversion logic. This example illustrates annotating a parameter to indicate it should be validated as a positive integer.

from typing import Annotated

def is_positive(n: int) -> bool:
    return n > 0

def process_number(number: Annotated[int, is_positive]):
    if is_positive(number):
        print(f"{number} is positive.")
    else:
        print("This shouldn't happen due to type annotation.")

# Example usage:
process_number(10)  # This will print: 10 is positive.
process_number(-5) # Type checkers may warn before running.

Here, Annotated serves both as a documentation tool and a rudimentary form of input validation, though actual runtime checks depend on external libraries or custom implementations.

Combining Annotated with Other Type Hints

The real power of Annotated is unleashed when it is used in combination with other types from the typing module, like Generics. The following example demonstrates its application with a generic list.

from typing import Annotated, List

def get_first_positive(numbers: Annotated[List[int], "Contains only positive numbers"]):
    for number in numbers:
        if number > 0:
            return number
    return None  # If no positive number is found.

# Example usage:
print(get_first_positive([1, -2, 3, -4]))  # Output: 1

This example highlights how Annotated can be used to provide comprehensive type hints that include both the type of the container and requirements for the elements it contains, enhancing understandability and maintainability.

Conclusion

Given its adaptable and informative nature, Annotated in Python’s typing module is an invaluable tool for enhancing code readability and robustness. By embedding additional information directly within type hints, developers can create more expressive and self-documented code bases. While the static checking tools’ support for Annotated is still evolving, its utility in documenting and designing clearer APIs is undeniable. As the Python ecosystem continues to mature, embracing advanced typing features like Annotated becomes not just advantageous but necessary for high-quality software development.