generated from john/python-template
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:
co-authored by
Copilot App
parent
67feeb28af
commit
8a30231adf
@@ -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"
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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)
|
||||
|
||||
+8
-1
@@ -141,7 +141,14 @@ async def test_create_all_declares_hot_path_indexes(tmp_path):
|
||||
await create_all(engine=runtime.engine)
|
||||
async with runtime.engine.connect() as connection:
|
||||
|
||||
def collect(sync_connection) -> tuple[dict[str, list[list[str]]], list[list[str]]]:
|
||||
def collect(
|
||||
sync_connection,
|
||||
) -> tuple[
|
||||
dict[str, list[list[str]]],
|
||||
list[list[str]],
|
||||
list[list[str]],
|
||||
list[list[str]],
|
||||
]:
|
||||
database = inspect(sync_connection)
|
||||
indexes = {
|
||||
table: [index["column_names"] for index in database.get_indexes(table)]
|
||||
|
||||
Reference in New Issue
Block a user