Guide: Adding Type Hints and Docstrings

Related issues: #18, #19, #20

Context

The FEAST codebase has inconsistent type hints. Some files use modern syntax, some use older typing imports, and some have no hints at all. Adding type hints improves readability, catches bugs via static analysis, and helps the next developer understand each function’s contract.

Before You Start

Steps

1. Read the function. Understand it before annotating it.

Don’t just look at the signature. Read the body. Read who calls it. What types actually flow through?

2. Add parameter and return type hints

Use modern Python syntax (3.10+):

# Before
def has_resources(self):
    if self.income < 10000:
        return False

# After
def has_resources(self) -> bool:
    if self.income < 10000:
        return False

3. Use modern syntax consistently

Old Style Modern Style
Optional[str] str \| None
List[Dict] list[dict]
Tuple[int, str] tuple[int, str]
Dict[str, Any] dict[str, Any]

Remove from typing import List, Dict, Optional, Tuple imports when no longer needed. Keep Any, TypedDict, Callable if used.

4. Use TypedDict for known dict structures

If a dict always has the same keys, define a TypedDict:

from typing import TypedDict

class HouseholdData(TypedDict):
    id: int
    Geometry: str
    Income: float
    Household_Size: int
    Vehicles: int

5. Add docstrings only when the function name isn’t self-explanatory

Skip docstrings for obvious functions like getters. Add one-line docstrings for functions with non-obvious behavior:

def stores_with_1_miles(self) -> int:
    """Count stores within 1 mile using pre-computed distances_map."""

Don’t write multi-paragraph docstrings. One line is almost always enough.

LLM Usage

Definition of Done

While You’re In There

Look for these and file issues:

Stretch Goals