Background: Type hints were introduced in Python 3.5 (PEP 484) to support static code analysis, autocompletion, refactoring, and auto-documentation. Previously, Python managed without strict typing, but as projects and teams grew, they became necessary to improve code quality.
Problem: Type annotations are merely hints for developers and external tools (mypy, Pyright, etc.), the interpreter ignores them during execution. Errors often occur when:
Solution: Use type annotations for functions and variables for better readability, code analysis by linters, and IDE support. Do not rely solely on annotations — a static type checker is needed. Example:
def greeting(name: str) -> str: return f"Hello, {name}" def sum_nums(nums: list[int]) -> int: return sum(nums)
More complex examples use the typing module:
from typing import List, Dict, Optional def process(data: List[Dict[str, Optional[int]]]) -> None: ...
Key Features:
Does the Python interpreter handle types from annotations at runtime?
No. Annotations are available through __annotations__, but do not control behavior during execution.
Can variables be used without annotations in annotated functions?
Yes. Annotations are not mandatory, but their absence can be confusing.
Can the type of a variable be redefined after annotation?
Yes, but this undermines the essence of static analysis and hinders linters. It's better to avoid this:
x: int = 5 x = 'string' # Linter will complain, but the code will run.
Negative Case: A function is annotated, but a different type is actually returned due to changes in function logic. Pros:
Positive Case: All functions and data are annotated, the project is checked by mypy during CI/CD. Pros: