Python 3 introduced a powerful feature called function annotations, which allows developers to add metadata to their functions in a concise and standardized way.

The most common use case for function annotations is type hinting. Type hints provide a way to specify the expected types of function parameters and return values. This can help improve code readability, catch errors early, and facilitate better integration with development tools like linters and autocompletion.

While type hinting is undoubtedly useful, function annotations can do much more. This article aims to explore some of these lesser-known use cases, such as data validation, providing metadata for APIs, and more. By the end, you'll have a better understanding of the full potential of function annotations and how to leverage them in your Python projects.

Understanding Function Annotations

Function annotations are a powerful feature in Python, and understanding their syntax, structure, and behavior is essential to using them effectively.

Function annotations are added to a function's signature, using a colon (:) followed by an expression. The expression can be any valid Python code, but it's typically used to specify a type hint.

Here's the basic structure of a function with annotations:

def function_name(param1: annotation1, param2: annotation2, ...) -> return_annotation:
    # Function body

For example:

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

It's important to note that Python itself does not enforce function annotations. In fact, annotations are stored as metadata in the __annotations__ attribute of the function object.

You can access this attribute to inspect the annotations programmatically. For example:

def greet(name: str, age: int) -> str:
    return f"Hello, {name}! You are {age} years old."


# Output: {'name': <class 'str'>, 'age': <class 'int'>, 'return': <class 'str'>}

Since Python doesn't enforce annotations, you can still call a function with incorrectly typed arguments without raising any errors. However, third-party libraries and tools can use this metadata to provide additional functionality.