Triage high-value ty diagnostics
Quality Gate / gate (push) Failing after 47s

Apply the highest-value typing fixes from the ty baseline pass:
- align migration row typing with SQLAlchemy RowMapping sequences
- accept refreshable callback return type in homepage gallery
- guard nullable media URL before ui.image in people photos
- guard nullable source MIME type before startswith checks
- fix tests/test_db collect() return annotation to match 4-tuple

This clears all actionable ty findings from that set and leaves only
known SQLModel/SQLAlchemy descriptor false positives.

Co-authored-by: Copilot App <[email protected]>
This commit is contained in:
Jim Lancaster
2026-08-23 16:54:34 -05:00
co-authored by Copilot App
parent 67feeb28af
commit 8a30231adf
5 changed files with 21 additions and 8 deletions
+7 -4
View File
@@ -3,6 +3,7 @@ from __future__ import annotations
import base64
import json
import shutil
from collections.abc import Sequence
from dataclasses import dataclass
from datetime import UTC
from datetime import date
@@ -18,6 +19,7 @@ from sqlalchemy import Table
from sqlalchemy import create_engine
from sqlalchemy import inspect as sqlalchemy_inspect
from sqlalchemy import select
from sqlalchemy.engine import RowMapping
from sqlalchemy.engine import make_url
from sqlmodel import SQLModel
@@ -69,7 +71,7 @@ def export_bundle(*, source_db_url: str, source_upload_dir: Path, bundle_dir: Pa
}
engine = create_engine(source_db_url)
legacy_portrait_rows: list[dict[str, Any]] = []
legacy_portrait_rows: Sequence[RowMapping] = ()
try: # noqa: PLR1702
inspector = sqlalchemy_inspect(engine)
source_tables = set(inspector.get_table_names())
@@ -195,9 +197,10 @@ def default_sync_db_url(settings: Settings | None = None) -> str:
return get_database_url(runtime_settings).replace("+aiosqlite", "").replace("+asyncpg", "").replace("+psycopg", "")
def _serialize_row(row: dict[str, Any], *, table_name: str, source_upload_dir: Path) -> dict[str, Any]:
def _serialize_row(row: RowMapping, *, table_name: str, source_upload_dir: Path) -> dict[str, Any]:
serialized: dict[str, Any] = {}
for key, value in row.items():
for raw_key, value in row.items():
key = str(raw_key)
serialized_value = _serialize_value(value)
if table_name == "source" and key == "file_path" and isinstance(serialized_value, str):
serialized[key] = _canonical_media_relative_path(
@@ -315,7 +318,7 @@ def _prepare_photo_payload_and_uploads( # noqa: PLR0915
*,
payload: dict[str, Any],
uploads_bundle_dir: Path,
legacy_portrait_rows: list[dict[str, Any]],
legacy_portrait_rows: Sequence[RowMapping],
) -> None:
photo_rows = payload.setdefault("tables", {}).setdefault("photo", [])
photos_dir = uploads_bundle_dir / "photos"
+1 -1
View File
@@ -43,7 +43,7 @@ def _render_homepage_gallery(
base_url: str,
enable_rotation: bool = False,
rotate_enabled: list[bool] | None = None,
on_change: Callable[[], None] | None = None,
on_change: Callable[[], object] | None = None,
) -> None:
if not photos:
render_empty_state("No homepage image uploaded yet.")
+4 -1
View File
@@ -283,7 +283,10 @@ def register_page() -> None: # noqa: PLR0915
base_url=str(request.base_url),
)
with ui.element("div").classes("relative w-full"):
ui.image(photo_url).classes("w-full rounded-md")
if photo_url is None:
ui.label("Image unavailable").classes("w-full text-sm ui-text-muted p-2")
else:
ui.image(photo_url).classes("w-full rounded-md")
description_text = photo.description or "No description"
ui.label(description_text).classes(
"absolute inset-x-0 bottom-0 text-center text-white text-xs font-semibold "
+1 -1
View File
@@ -407,7 +407,7 @@ def _render_source_metadata_column(
def _resolve_source_detail_layout(*, source: Source, settings: Settings) -> str:
media_type = lookup_source_mime_type(source.file_path)
if not media_type.startswith("image/"):
if media_type is None or not media_type.startswith("image/"):
return "standard"
absolute = (settings.upload_dir / Path(source.file_path)).resolve()
dimensions = _read_image_dimensions(absolute)