From a531637db4f0cae18d56442e3852032e5b6e0403 Mon Sep 17 00:00:00 2001 From: lda Date: Sat, 29 Aug 2026 18:02:58 +0700 Subject: [PATCH] type: accept typed API mappings in CLI renderers --- src/wf_cli/commands/caps.py | 7 ++++--- src/wf_cli/commands/sources.py | 3 ++- src/wf_cli/commands/status.py | 3 ++- src/wf_cli/formats.py | 9 +++++---- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/wf_cli/commands/caps.py b/src/wf_cli/commands/caps.py index ff9c5baf..e140def8 100644 --- a/src/wf_cli/commands/caps.py +++ b/src/wf_cli/commands/caps.py @@ -1,6 +1,7 @@ from __future__ import annotations import json +from collections.abc import Mapping from enum import StrEnum from pathlib import Path from typing import Annotated, Any @@ -167,7 +168,7 @@ def call_capability( def render_cap_call_output( - result: dict[str, Any], + result: Mapping[str, Any], *, output_format: CapCallOutputFormat, unwrap_text: bool, @@ -198,7 +199,7 @@ def _resolve_cap_call_output_format( return output_format -def _compact_cap_call_summary(result: dict[str, Any]) -> str: +def _compact_cap_call_summary(result: Mapping[str, Any]) -> str: output = result.get("output") output_summary = _summarize_output(output) return "\t".join( @@ -225,7 +226,7 @@ def _summarize_output(output: object) -> str: return type(output).__name__ -def _unwrap_single_mcp_text_block(result: dict[str, Any]) -> str: +def _unwrap_single_mcp_text_block(result: Mapping[str, Any]) -> str: output = result.get("output") if not isinstance(output, dict): raise ValueError("--unwrap-text requires exactly one MCP text content block") diff --git a/src/wf_cli/commands/sources.py b/src/wf_cli/commands/sources.py index ec4343fa..ec1eeec8 100644 --- a/src/wf_cli/commands/sources.py +++ b/src/wf_cli/commands/sources.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections.abc import Mapping from enum import StrEnum from typing import Annotated @@ -139,7 +140,7 @@ def _list_source_inventory_names( def _source_capability_names( - payload: dict[str, object], + payload: Mapping[str, object], *, capability_key: str, ) -> list[str]: diff --git a/src/wf_cli/commands/status.py b/src/wf_cli/commands/status.py index 94d73ba2..97d0c257 100644 --- a/src/wf_cli/commands/status.py +++ b/src/wf_cli/commands/status.py @@ -1,5 +1,6 @@ from __future__ import annotations +from collections.abc import Mapping from typing import Any import typer @@ -153,7 +154,7 @@ async def _fetch_registry(context: CliContext) -> dict[str, Any]: } -def _payload_count(payload: dict[str, Any], items_key: str) -> int: +def _payload_count(payload: Mapping[str, Any], items_key: str) -> int: """Prefer a paged API's total count, falling back to the current page size.""" total = payload.get("total") if isinstance(total, int): diff --git a/src/wf_cli/formats.py b/src/wf_cli/formats.py index e51c0f85..a8b0a2fc 100644 --- a/src/wf_cli/formats.py +++ b/src/wf_cli/formats.py @@ -1,6 +1,7 @@ from __future__ import annotations import json +from collections.abc import Mapping from enum import StrEnum from typing import Any @@ -14,7 +15,7 @@ class ListOutputFormat(StrEnum): def render_list_payload( - payload: dict[str, Any], + payload: Mapping[str, Any], *, collection_key: str, output_format: ListOutputFormat, @@ -44,7 +45,7 @@ def render_list_payload( def emit_list_payload( - payload: dict[str, Any], + payload: Mapping[str, Any], *, collection_key: str, output_format: ListOutputFormat, @@ -64,7 +65,7 @@ def emit_list_payload( def _item_id(item: object, *, id_field: str) -> str: - if not isinstance(item, dict): + if not isinstance(item, Mapping): return str(item) value = item.get(id_field) return "" if value is None else str(value) @@ -76,7 +77,7 @@ def _compact_line( id_field: str, summary_fields: tuple[str, ...], ) -> str: - if not isinstance(item, dict): + if not isinstance(item, Mapping): return str(item) parts = [_item_id(item, id_field=id_field)] for field in summary_fields: