mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Annotate locals assigned from cross-module calls in the historic-EPC stack 🟪
Review ask (dancafc): resolver/repository locals now carry explicit types (matches: list[ScoredHistoricEpc], records: list[HistoricEpc], df: pd.DataFrame, ...) so the flow reads without chasing callee signatures. CLAUDE.md's Type Safety section gains the rule so future sessions enforce it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
246834fac0
commit
cbffae07b8
3 changed files with 12 additions and 6 deletions
|
|
@ -34,4 +34,7 @@ All new code must pass `pyright` with zero errors under `typeCheckingMode = stri
|
|||
Use Optional over | None
|
||||
Annotate all function return types. Use `dict[str, Any]` for untyped external API
|
||||
payloads — never bare `dict`. Add `pandas-stubs` when introducing pandas to a module.
|
||||
Annotate locals assigned from cross-module calls (e.g. `matches: list[ScoredHistoricEpc]
|
||||
= rank_historic_epc(...)`) — the reader shouldn't need the callee's signature to follow
|
||||
the flow; inference-only locals are fine within a module's own helpers.
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ from __future__ import annotations
|
|||
|
||||
from typing import Optional
|
||||
|
||||
from datatypes.epc.domain.historic_epc import HistoricEpc
|
||||
from datatypes.epc.domain.historic_epc_matching import (
|
||||
HistoricEpcMatches,
|
||||
ScoredHistoricEpc,
|
||||
rank_historic_epc,
|
||||
)
|
||||
from domain.postcode import Postcode
|
||||
|
|
@ -24,8 +26,8 @@ class HistoricEpcResolver:
|
|||
if not user_address:
|
||||
raise ValueError("user_address must be non-empty")
|
||||
pc = Postcode(postcode)
|
||||
records = self._repo.get_for_postcode(pc)
|
||||
matches = rank_historic_epc(records, user_address)
|
||||
records: list[HistoricEpc] = self._repo.get_for_postcode(pc)
|
||||
matches: list[ScoredHistoricEpc] = rank_historic_epc(records, user_address)
|
||||
return HistoricEpcMatches(
|
||||
user_address=user_address,
|
||||
postcode=str(pc),
|
||||
|
|
@ -37,11 +39,11 @@ class HistoricEpcResolver:
|
|||
) -> Optional[tuple[str, str, float]]:
|
||||
"""``(uprn, matched_address, lexiscore)`` for an unambiguous rank-1
|
||||
match, else None (no data / ambiguous tie / zero score)."""
|
||||
matches = self.match(user_address, postcode)
|
||||
uprn = matches.unambiguous_uprn()
|
||||
matches: HistoricEpcMatches = self.match(user_address, postcode)
|
||||
uprn: Optional[str] = matches.unambiguous_uprn()
|
||||
if not uprn or uprn == "nan":
|
||||
return None
|
||||
top = matches.top()
|
||||
top: Optional[ScoredHistoricEpc] = matches.top()
|
||||
if top is None:
|
||||
return None
|
||||
return uprn, top.record.address, top.lexiscore
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
from collections.abc import Hashable
|
||||
from typing import Any
|
||||
|
||||
import pandas as pd
|
||||
from botocore.exceptions import ClientError
|
||||
|
||||
from datatypes.epc.domain.historic_epc import HistoricEpc
|
||||
|
|
@ -59,7 +60,7 @@ class HistoricEpcS3Repository(HistoricEpcRepository):
|
|||
raise PostcodeNotFound(f"{postcode.value!r} is not a valid UK postcode")
|
||||
key = f"{self._root_prefix.rstrip('/')}/{postcode}/data.csv.gz"
|
||||
try:
|
||||
df = self._client.read_csv_gz(key)
|
||||
df: pd.DataFrame = self._client.read_csv_gz(key)
|
||||
except ClientError as e:
|
||||
if e.response.get("Error", {}).get("Code") in ("NoSuchKey", "404"):
|
||||
return []
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue