fix(lint): remove __future__ annotations from new tools, fix 4 failing tests

- Remove `from __future__ import annotations` from array.py, live.py,
  oidc.py, plugins.py to match existing tool pattern and resolve TC002
  ruff errors (fastmcp imports only needed in annotations under PEP 563)
- Add `# noqa: ASYNC109` to live.py timeout parameter (asyncio.timeout
  already used internally)
- Fix test_network_sends_correct_query: query name is GetNetworkInfo
- Fix test_delete_requires_confirm: match "not confirmed" not "destructive"
- Fix test_destructive_set_matches_audit[settings]: add setup_remote_access
  and enable_dynamic_remote_access to KNOWN_DESTRUCTIVE
- Fix test_logs: update mock to dict format {lines: [{timestamp, message}]}

742 tests passing, ruff clean
This commit is contained in:
Jacob Magar
2026-03-15 19:57:46 -04:00
parent 1f35c20cdf
commit 252ec520d1
13 changed files with 1673 additions and 18 deletions

View File

@@ -8,8 +8,11 @@ them to ~/.unraid-mcp/.env with restricted permissions.
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
from fastmcp import Context
if TYPE_CHECKING:
from fastmcp import Context
from ..config.logging import logger
from ..config.settings import (

View File

@@ -29,7 +29,7 @@ from .utils import build_ws_ssl_context, build_ws_url
async def subscribe_once(
query: str,
variables: dict[str, Any] | None = None,
timeout: float = 10.0,
timeout: float = 10.0, # noqa: ASYNC109
) -> dict[str, Any]:
"""Open a WebSocket subscription, receive the first data event, close, return it.
@@ -94,7 +94,7 @@ async def subscribe_once(
elif msg.get("type") == "error" and msg.get("id") == sub_id:
raise ToolError(f"Subscription error: {msg.get('payload')}")
except TimeoutError:
raise ToolError(f"Subscription timed out after {timeout:.0f}s")
raise ToolError(f"Subscription timed out after {timeout:.0f}s") from None
raise ToolError("WebSocket closed before receiving subscription data")
@@ -103,7 +103,7 @@ async def subscribe_collect(
query: str,
variables: dict[str, Any] | None = None,
collect_for: float = 5.0,
timeout: float = 10.0,
timeout: float = 10.0, # noqa: ASYNC109
) -> list[dict[str, Any]]:
"""Open a subscription, collect events for `collect_for` seconds, close, return list.

View File

@@ -4,8 +4,6 @@ Provides the `unraid_array` tool with 13 actions covering parity check
management, array start/stop, and disk add/remove/mount operations.
"""
from __future__ import annotations
from typing import Any, Literal, get_args
from fastmcp import Context, FastMCP

View File

@@ -8,8 +8,6 @@ Use `subscribe_once` actions for current-state reads (cpu, memory, array_state).
Use `subscribe_collect` actions for event streams (notification_feed, log_tail).
"""
from __future__ import annotations
import os
from typing import Any, Literal, get_args
@@ -94,7 +92,7 @@ def register_live_tool(mcp: FastMCP) -> None:
action: LIVE_ACTIONS,
path: str | None = None,
collect_for: float = 5.0,
timeout: float = 10.0,
timeout: float = 10.0, # noqa: ASYNC109
) -> dict[str, Any]:
"""Get real-time data from Unraid via WebSocket subscriptions.

View File

@@ -4,8 +4,6 @@ Provides the `unraid_oidc` tool with 5 read-only actions for querying
OIDC provider configuration and validating sessions.
"""
from __future__ import annotations
from typing import Any, Literal, get_args
from fastmcp import FastMCP

View File

@@ -3,8 +3,6 @@
Provides the `unraid_plugins` tool with 3 actions: list, add, remove.
"""
from __future__ import annotations
from typing import Any, Literal, get_args
from fastmcp import Context, FastMCP