From 1858560e972c7f6d914559d976253a034ac8fda7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 23 Aug 2026 10:58:11 +0000 Subject: [PATCH] refactor(cli, runner): replace Any with VisualQARunner/ClaimVerifier in runner-handling signatures cli.py's _new_runner()/_runner_scope() and runner.py's _resolve_default_visualize() were typed Any even though every real call site passes/returns a concrete VisualQARunner or ClaimVerifier instance, continuing the same Any->concrete-type vein as #277/#281/#283/#284/#285/#289. Tightened using a TYPE_CHECKING-guarded import in cli.py (matching runner.py's own existing pattern) to avoid circular import risk. Annotation-only, zero behavior change. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01FAav5x8va7JZ8E1LmLYQKy --- src/frontend_visualqa/cli.py | 9 ++++++--- src/frontend_visualqa/runner.py | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/frontend_visualqa/cli.py b/src/frontend_visualqa/cli.py index 4c6b727..9815da6 100644 --- a/src/frontend_visualqa/cli.py +++ b/src/frontend_visualqa/cli.py @@ -12,7 +12,7 @@ from collections.abc import AsyncIterator, Callable, Coroutine from contextlib import asynccontextmanager from pathlib import Path -from typing import Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from pydantic import ValidationError @@ -33,6 +33,9 @@ ) from frontend_visualqa.text_utils import clip_text +if TYPE_CHECKING: + from frontend_visualqa.runner import VisualQARunner + logger = logging.getLogger(__name__) T = TypeVar("T") @@ -601,7 +604,7 @@ async def _run_status() -> dict[str, Any]: return serialize_result(result) -def _new_runner(*, browser_config: BrowserConfig | None = None, reporters: list[str] | None = None) -> Any: +def _new_runner(*, browser_config: BrowserConfig | None = None, reporters: list[str] | None = None) -> VisualQARunner: from frontend_visualqa.runner import VisualQARunner return VisualQARunner(browser_config=browser_config, reporters=reporters) @@ -610,7 +613,7 @@ def _new_runner(*, browser_config: BrowserConfig | None = None, reporters: list[ @asynccontextmanager async def _runner_scope( *, browser_config: BrowserConfig | None = None, reporters: list[str] | None = None -) -> AsyncIterator[Any]: +) -> AsyncIterator[VisualQARunner]: runner = _new_runner(browser_config=browser_config, reporters=reporters) try: yield runner diff --git a/src/frontend_visualqa/runner.py b/src/frontend_visualqa/runner.py index 2101d12..b4cb58e 100644 --- a/src/frontend_visualqa/runner.py +++ b/src/frontend_visualqa/runner.py @@ -87,7 +87,7 @@ def _load_class(name: str) -> Any: return loaded -def _resolve_default_visualize(claim_verifier: Any, fallback: bool) -> bool: +def _resolve_default_visualize(claim_verifier: ClaimVerifier, fallback: bool) -> bool: """Read *claim_verifier*'s ``_visualize`` flag, falling back to *fallback* if absent. Shared by construction and ``_rebind_claim_verifier`` so the two places that