Skip to content

Commit 9126a9a

Browse files
committed
fix(types): close mypy gate on services/ after post-#35 strict enforcement
Two narrow fixes that resolve all 27 mypy errors exposed by master's stricter typecheck gate (newly enforced when #35 removed continue-on-error): * services/workspace_tabs.py:195 — annotate `bubbles: list[dict[str, Any]] = []` so the iteration variables `b` / `m` get treated as `dict[str, Any]` rather than `dict[str, object]`. That single annotation kills 26 of the 27 errors (all the "object has no attribute X" / "Value of type object is not indexable" cluster around the metadata-aggregation loop). * services/workspace_resolver.py:84 — `# type: ignore[call-overload]` on the `row["value"]` access plus a comment pointing at the underlying cause. sqlite3.Row supports string-key access at runtime when `row_factory = sqlite3.Row` is set (which `_open_global_db` does), but mypy's stdlib stub types Row as `tuple[Any, ...]` which only accepts SupportsIndex. Verified: mypy → Success, no issues found in 52 source files; ruff → All checks passed; unittest → 207 / 207 OK.
1 parent cb32fca commit 9126a9a

2 files changed

Lines changed: 10 additions & 3 deletions

File tree

services/workspace_resolver.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ def _infer_workspace_name_from_context(workspace_path: str, workspace_id: str) -
8181
continue
8282
for row in rows:
8383
try:
84-
ctx = json.loads(row["value"])
84+
# sqlite3.Row supports string-key access at runtime when
85+
# row_factory = sqlite3.Row is set on the connection (see
86+
# _open_global_db); mypy's stub types Row as tuple[Any, ...]
87+
# which only accepts SupportsIndex, hence the ignore.
88+
ctx = json.loads(row["value"]) # type: ignore[call-overload]
8589
except Exception:
8690
continue
8791
layouts = ctx.get("projectLayouts")

services/workspace_tabs.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import re
66
import sqlite3
77
from datetime import datetime
8+
from typing import Any
89

910
from utils.path_helpers import (
1011
get_workspace_folder_paths,
@@ -191,8 +192,10 @@ def _safe_fetchall(query: str, params: tuple = ()) -> list:
191192

192193
headers = cd.get("fullConversationHeadersOnly") or []
193194

194-
# Build bubbles
195-
bubbles = []
195+
# Build bubbles. Annotated as list[dict[str, Any]] so mypy
196+
# treats nested .get("metadata") / m["inputTokens"] etc. as
197+
# accessing dict values rather than `object`.
198+
bubbles: list[dict[str, Any]] = []
196199
for header in headers:
197200
if not isinstance(header, dict):
198201
continue

0 commit comments

Comments
 (0)