Skip to content

Type Hints

Python is dynamically typed, but type hints (PEP 484+) let you annotate variables and functions for better tooling, readability, and static analysis.

name: str = "Alice"
age: int = 30
price: float = 9.99
active: bool = True
def greet(name: str) -> str:
return f"Hello, {name}!"
def add(a: int, b: int) -> int:
return a + b
def process(data: list) -> None:
for item in data:
print(item)
from typing import List, Dict, Tuple, Set, Optional, Union, Any, Callable
def get_names() -> List[str]:
return ["Alice", "Bob"]
def get_scores() -> Dict[str, int]:
return {"Alice": 90}
def get_point() -> Tuple[int, int]:
return (1, 2)
def find_user(id: int) -> Optional[str]: # str or None
return None
def parse(value: Union[int, str]) -> str:
return str(value)

No need to import from typing for common types:

def get_names() -> list[str]:
return ["Alice", "Bob"]
def get_scores() -> dict[str, int]:
return {"Alice": 90}
def get_point() -> tuple[int, int]:
return (1, 2)
# Old style
from typing import Optional
def find(id: int) -> Optional[str]: ...
# New style (Python 3.10+)
def find(id: int) -> str | None: ...
def parse(value: int | str) -> str: ...
from typing import TypeVar, Generic
T = TypeVar('T')
def first(items: list[T]) -> T:
return items[0]
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()
from typing import Callable
def apply(func: Callable[[int, int], int], a: int, b: int) -> int:
return func(a, b)
apply(lambda x, y: x + y, 3, 4) # 7
from typing import TypedDict
class User(TypedDict):
name: str
age: int
email: str
user: User = {"name": "Alice", "age": 30, "email": "alice@example.com"}
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
label: str = "origin"
p = Point(1.0, 2.0)
print(p) # Point(x=1.0, y=2.0, label='origin')
from typing import Final, Literal
MAX_SIZE: Final = 100 # cannot be reassigned
Direction = Literal["north", "south", "east", "west"]
def move(direction: Direction) -> None:
print(f"Moving {direction}")

Type hints are not enforced at runtime by default. Use libraries like:

  • mypy — static type checker
  • pyright — Microsoft’s type checker (used in Pylance/VS Code)
  • pydantic — runtime validation
Terminal window
pip install mypy
mypy my_script.py