x ai python type hint
x ai python type hint
ai generated
Python Type Hints Tutorial
Type hints (also called type annotations) were introduced in Python 3.5 via PEP 484. They allow you to declare the expected types of variables, function parameters, and return values.
Important points:
- Type hints are not enforced at runtime (Python remains dynamically typed).
- They are used by static type checkers (mypy, pyright, pylance), IDEs (VS Code, PyCharm), and documentation tools.
- They improve code readability, catch bugs early, and enable better autocompletion/refactoring.
1. Basic Syntax
# Variable annotations (Python 3.6+) age: int = 25 name: str = "Alice" is_active: bool = True score: float = 95.5 data: list[int] = [1, 2, 3] # Python 3.9+ built-in generics coords: tuple[float, float] = (10.5, 20.3)
For older Python versions (before 3.9), use typing module:
from typing import List, Tuple data: List[int] = [1, 2, 3] coords: Tuple[float, float] = (10.5, 20.3)
2. Function Annotations
def greet(name: str) -> str: return f"Hello, {name}!" def add(a: int, b: int) -> int: return a + b # Optional parameters from typing import Optional def find_user(user_id: int) -> Optional[str]: # returns str or None ...
None as return type:
def log(message: str) -> None: print(message) # no return value
3. Common Types from typing Module
| Type | Description | Example |
|---|---|---|
List[T] |
List of type T | List[int] |
Dict[K, V] |
Dictionary with key K, value V | Dict[str, int] |
Set[T] |
Set of type T | Set[str] |
Tuple[T, ...] |
Tuple (fixed or variable length) | Tuple[int, str] |
Optional[T] |
T or None (equivalent to `T | None`) |
Union[T1, T2] |
T1 or T2 (new syntax: T1 | T2) |
int | str |
Any |
Any type (disables checking) | Any |
NoReturn |
Function never returns (e.g. sys.exit) |
NoReturn |
Modern union syntax (Python 3.10+):
def process(value: int | str) -> None: ...
4. Collections with Generics (Python 3.9+)
def process_items(items: list[str]) -> dict[str, int]: return {item: len(item) for item in items}
5. Classes and Self
from typing import Self # Python 3.11+ class User: name: str age: int def __init__(self, name: str, age: int) -> None: self.name = name self.age = age def copy(self) -> Self: # returns instance of same class return User(self.name, self.age)
6. Advanced Features
TypedDict (structured dictionaries)
from typing import TypedDict class UserDict(TypedDict): name: str age: int active: bool def create_user(data: UserDict) -> None: ...
Literal types (exact values)
from typing import Literal def set_status(status: Literal["active", "inactive", "banned"]) -> None: ...
Protocols (structural subtyping - "duck typing" for types)
from typing import Protocol class SupportsClose(Protocol): def close(self) -> None: ... def close_resource(res: SupportsClose) -> None: res.close()
Generics (custom generic classes/functions)
from typing import TypeVar, Generic T = TypeVar("T") class Box(Generic[T]): def __init__(self, value: T): self.value = value def get(self) -> T: return self.value string_box: Box[str] = Box("hello")
Callable (functions as types)
from collections.abc import Callable def apply(func: Callable[[int, int], int], a: int, b: int) -> int: return func(a, b)
7. Type Aliases and NewType
from typing import TypeAlias, NewType # Simple alias UserId: TypeAlias = int # Distinct type for type checkers (runtime same as int) UserIdStrict = NewType("UserIdStrict", int) def get_user(uid: UserIdStrict) -> str: ...
8. Type Checking in Practice
Install a type checker:
pip install mypy mypy my_script.py # or mypy .
Configuration (pyproject.toml or mypy.ini):
[tool.mypy] python_version = "3.12" strict = true disallow_untyped_defs = true
Popular IDE support:
- VS Code + Pylance (Microsoft) — best experience
- PyCharm — excellent built-in support
9. Common Patterns & Tips
# 1. Forward references (when class not yet defined) class Node: children: list["Node"] # string quotes in older Python # 2. Ignoring type errors (when necessary) x: int = 5 y = x + "hello" # type: ignore # 3. Revealing type during development from typing import reveal_type reveal_type(some_variable) # mypy will print inferred type
10. Complete Example
from typing import TypedDict, Literal from collections.abc import Sequence class Point(TypedDict): x: float y: float def move(point: Point, direction: Literal["up", "down", "left", "right"]) -> Point: if direction == "up": point["y"] += 1 # ... other directions return point def process_points(points: Sequence[Point]) -> list[Point]: return [move(p.copy(), "up") for p in points] # .copy() for TypedDict in 3.11+
Resources
- Official docs: https://docs.python.org/3/library/typing.html
- mypy docs: https://mypy.readthedocs.io/
- PEP 484, 526, 544, 585, 604, etc.
typeshed— type stubs for third-party libraries
Best Practice Recommendation:
Start adding type hints gradually. Use strict = true in mypy once your codebase is mostly annotated. Tools like pyright or VS Code can help you incrementally improve type coverage.
Type hints make large Python codebases significantly more maintainable. Happy typing!