Type Hints and Dataclasses for Cleaner Pipeline Code
Use type hints and dataclasses to make records explicit, catch bugs before runtime, and keep pipeline functions small and testable.
PythonBeginner2 min readUpdated 11 Oct 2026
Why bother in data code?
Pipelines pass the same records through many functions. Dictionaries with unknown keys make every step guess. A typed record says exactly what a row contains.
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
@dataclass(frozen=True)
class OrderLine:
order_id: str
sku: str
qty: int
unit_price: Decimal
business_date: date
@property
def net(self) -> Decimal:
return self.unit_price * self.qtyfrozen=True makes instances immutable, so a transform cannot silently change its input.
Type hints on functions
from collections.abc import Iterable, Iterator
def only_valid(lines: Iterable[OrderLine]) -> Iterator[OrderLine]:
for line in lines:
if line.qty != 0:
yield lineHints do nothing at runtime. A checker such as mypy or pyright reads them and reports mistakes like passing a str where a date is expected.
Parse at the edge, trust inside
def parse(row: dict[str, str]) -> OrderLine:
return OrderLine(
order_id=row["order_id"],
sku=row["sku"],
qty=int(row["qty"]),
unit_price=Decimal(row["unit_price"]),
business_date=date.fromisoformat(row["business_date"]),
)Convert raw strings into typed records once, where data enters. Every function after that can rely on the types.
Finished this note?
