Skip to content

Typing & Errors

Python gives you two complementary tools for writing code that breaks loudly instead of silently:

  1. Type hints — annotations that describe what types a variable, parameter, or return value should hold. They are checked statically by tools like mypy or pyright, not at runtime.
  2. Exceptions — a signal mechanism that interrupts normal execution when something unexpected happens, letting you catch and recover or propagate errors up the call stack.

Together, type hints and exceptions let you communicate intent precisely and handle failures gracefully.

def greet(name: str, count: int = 1) -> str:
return (name + "! ") * count

name: str, count: int, and -> str are type hints. Python ignores them at runtime — they only exist for static checkers and human readers. They do not make greet("Alice") slower or faster.

try:
result = int("abc")
except ValueError as e:
print(f"Caught: {e}")
finally:
print("Always runs")

try wraps code that might fail. except catches a specific exception type. finally runs regardless of whether an exception occurred.

Type hints and exceptions are not mutually exclusive — they serve different phases:

PhaseTool
Static analysis (before running)Type hints + mypy/pyright
Runtime failures (while running)Exceptions

A function signature tells callers what types are expected; exceptions tell callers what can go wrong at runtime.

LessonWhat you will learn
Type HintsAnnotating variables, params, returns; Optional, Union, aliases
Exceptionstry/except/else/finally, raise, chaining
Context Managerswith, __enter__/__exit__, contextlib
Custom ErrorsSubclassing Exception, attributes, hierarchies
from typing import Optional
def find_item(items: list[str], target: str) -> Optional[int]:
"""Return the index of target in items, or None if not found."""
for i, item in enumerate(items):
if item == target:
return i
return None
fruits = ["apple", "banana", "cherry"]
# type hints describe intent — no runtime enforcement
index = find_item(fruits, "banana")
print(f"Found at index: {index}")
missing = find_item(fruits, "mango")
print(f"Not found: {missing}")
# exceptions signal runtime failures
try:
value = fruits[10]
except IndexError as e:
print(f"IndexError: {e}")
# the else clause runs only when no exception was raised
try:
value = fruits[1]
except IndexError:
print("Out of range")
else:
print(f"Got: {value}")
What does Python do with type hints at runtime?
Which block in a try statement runs regardless of whether an exception was raised?
When does the `else` block of a try statement execute?
Which tool checks Python type hints statically?