refactor: phase 3 - API efficiency improvements

Add typed dataclasses for tuple returns:
- types.py: HeadlineItem, FetchResult, Block dataclasses with legacy tuple converters
- fetch.py: Add type hints and HeadlineTuple type alias

Add pyright for static type checking:
- Add pyright to dependencies
- Verify type coverage with pyright (0 errors in core modules)

This enables:
- Named types instead of raw tuples (better IDE support, self-documenting)
- Type-safe APIs across modules
- Backward compatibility via to_tuple/from_tuple methods

Note: Lazy imports skipped for render.py - startup impact is minimal.
This commit is contained in:
2026-03-15 16:05:41 -07:00
parent cdc8094de2
commit 35e5c8d38b
4 changed files with 166 additions and 4 deletions

60
engine/types.py Normal file
View File

@@ -0,0 +1,60 @@
"""
Shared dataclasses for the mainline application.
Provides named types for tuple returns across modules.
"""
from dataclasses import dataclass
@dataclass
class HeadlineItem:
"""A single headline item: title, source, and timestamp."""
title: str
source: str
timestamp: str
def to_tuple(self) -> tuple[str, str, str]:
"""Convert to tuple for backward compatibility."""
return (self.title, self.source, self.timestamp)
@classmethod
def from_tuple(cls, t: tuple[str, str, str]) -> "HeadlineItem":
"""Create from tuple for backward compatibility."""
return cls(title=t[0], source=t[1], timestamp=t[2])
def items_to_tuples(items: list[HeadlineItem]) -> list[tuple[str, str, str]]:
"""Convert list of HeadlineItem to list of tuples."""
return [item.to_tuple() for item in items]
def tuples_to_items(tuples: list[tuple[str, str, str]]) -> list[HeadlineItem]:
"""Convert list of tuples to list of HeadlineItem."""
return [HeadlineItem.from_tuple(t) for t in tuples]
@dataclass
class FetchResult:
"""Result from fetch_all() or fetch_poetry()."""
items: list[HeadlineItem]
linked: int
failed: int
def to_legacy_tuple(self) -> tuple[list[tuple], int, int]:
"""Convert to legacy tuple format for backward compatibility."""
return ([item.to_tuple() for item in self.items], self.linked, self.failed)
@dataclass
class Block:
"""Rendered headline block from make_block()."""
content: list[str]
color: str
meta_row_index: int
def to_legacy_tuple(self) -> tuple[list[str], str, int]:
"""Convert to legacy tuple format for backward compatibility."""
return (self.content, self.color, self.meta_row_index)