PythonFunctionsIntermediate

Type hints (annotations)

Annotates parameter and return types for readability and tooling.

Review the syntaxStudy the examplesOpen the coding app
def add(a: int, b: int) -> int:
    return a + b

This static page keeps the syntax and examples indexed for search, while the coding app handles interactive exploration and saved references.

What it does

Overview

Annotates parameter and return types for readability and tooling.

Python type hints (PEP 484) provide a formal syntax for declaring the expected data types of function parameters, return values, and variables. Although Python remains a dynamically typed language and the interpreter does not enforce these hints at runtime (a concept known as type erasure), they are critical for static analysis. Tools like mypy, pyright, and advanced IDEs use these annotations to identify type-related bugs before the code is executed. Performance-wise, hints have a negligible impact on execution speed, as they are stored in the function's '__annotations__' attribute. However, evaluating complex annotations in large modules can slightly increase startup time; this is often mitigated using 'from __future__ import annotations' (PEP 563), which treats hints as strings. A key edge case is the 'forward reference,' where a class is used as a hint before its definition is completed, necessitating string-literal hints or the future-annotations import. Modern Python (3.10+) has simplified this further with the '|' operator for Unions and generic support for built-in collections like list and dict.

Quick reference

Syntax

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

See it in practice

Examples

1

Basic Function Annotations

def calculate_total(price: float, tax_rate: float) -> float:
    return price + (price * tax_rate)

print(calculate_total(100.0, 0.05))
Output:
105.0

Annotates parameters and the return value with primitive float types.

2

Generic Collections and Optional Types

from typing import Optional

def find_index(items: list[str], target: str) -> Optional[int]:
    try:
        return items.index(target)
    except ValueError:
        return None

frameworks = ['Django', 'Flask', 'FastAPI']
print(find_index(frameworks, 'Flask'))
print(find_index(frameworks, 'Tornado'))
Output:
1 None

Uses list[str] to define a list of strings and Optional[int] for a return value that could be an integer or None.

3

Modern Union Types with the Pipe Operator

def process_data(payload: str | bytes) -> str:
    if isinstance(payload, bytes):
        return payload.decode('utf-8')
    return payload

print(process_data('Hello'))
print(process_data(b'World'))
Output:
Hello World

Utilizes the Python 3.10+ pipe operator (|) to allow multiple acceptable types for a single argument.

Debug faster

Common Errors

1

LogicError

Cause: Assuming type hints provide automatic runtime type validation or enforcement.

Fix: Use runtime validation with isinstance() checks or leverage a data validation library like Pydantic.

def add_one(x: int) -> int:
    return x + 1

print(add_one('5'))
2

TypeError

Cause: Using built-in types as generics (e.g., list[int]) in Python versions prior to 3.9.

Fix: Import uppercase equivalents (List, Dict) from the typing module or upgrade the Python interpreter to 3.9+.

def get_names(data: list[str]):
    return [name for name in data]

Runtime support

Compatibility

Python 3.8+

Best with type checkers (mypy/pyright) and IDE support

Source: MDN Web Docs

Common questions

Frequently Asked Questions

Annotates parameter and return types for readability and tooling.

LogicError: Use runtime validation with isinstance() checks or leverage a data validation library like Pydantic. TypeError: Import uppercase equivalents (List, Dict) from the typing module or upgrade the Python interpreter to 3.9+.