CodeNebula
Python🔧Core Languagebeginner

Type Hints (PEP 484)

Python · Core Language · Run with python3

Explanation

Python 3.5 introduced type hints via PEP 484. They are not enforced at runtime — they're metadata for static type checkers (`mypy`, `pyright`, `ruff`). The `typing` module provides `List`, `Dict`, `Optional`, `Union`, `Callable`, `TypeVar`, `Generic`, `Protocol`. Python 3.10+ replaced `Optional[X]` with `X | None` and `Union[X, Y]` with `X | Y`. Python 3.12 added `type` statement for type aliases.

Real-World Scenario

A large API client library adding type hints catches errors like passing a `str` where an `int` is expected before code reaches production. IDE autocomplete becomes precise — you get attribute suggestions specific to the return type of each function. ```python from typing import TypeVar, Generic, Callable from collections.abc import Iterable T = TypeVar("T") U = TypeVar("U") def first(items: Iterable[T]) -> T | None: return next(iter(items), None) def transform(items: list[T], fn: Callable[[T], U]) -> list[U]: return [fn(item) for item in items] class Stack(Generic[T]): def __init__(self) -> None: self._items: list[T] = [] def push(self, item: T) -> None: self._items.append(item) def pop(self) -> T: return self._items.pop() stack: Stack[int] = Stack() stack.push(1) stack.push(2) print(stack.pop()) # 2 print(first([10, 20, 30])) # 10 print(transform(["a", "bb", "ccc"], len)) # [1, 2, 3] ```

Quick Snippet

snippet.py
from typing import TypeVar, Generic, Callable
from collections.abc import Iterable

T = TypeVar("T")
U = TypeVar("U")

def first(items: Iterable[T]) -> T | None:
    return next(iter(items), None)

def transform(items: list[T], fn: Callable[[T], U]) -> list[U]:
    return [fn(item) for item in items]

class Stack(Generic[T]):
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

stack: Stack[int] = Stack()
stack.push(1)
stack.push(2)
print(stack.pop())  # 2
print(first([10, 20, 30]))  # 10
print(transform(["a", "bb", "ccc"], len))  # [1, 2, 3]

Full Example

type_hints.py
# Compile: python3 type_hints.py
# Output:
# 2
# 10
# [1, 2, 3]

from typing import TypeVar, Generic, Callable
from collections.abc import Iterable

T = TypeVar("T")
U = TypeVar("U")

def first(items: Iterable[T]) -> T | None:
    return next(iter(items), None)

def transform(items: list[T], fn: Callable[[T], U]) -> list[U]:
    return [fn(item) for item in items]

class Stack(Generic[T]):
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

    def __len__(self) -> int:
        return len(self._items)

stack: Stack[int] = Stack()
stack.push(1)
stack.push(2)
print(stack.pop())
print(first([10, 20, 30]))
print(transform(["a", "bb", "ccc"], len))

# Union types (Python 3.10+)
def process(value: int | str) -> str:
    return str(value).upper()

print(process(42))    # 42
print(process("hi"))  # HI
Run command
python3 type_hints.py