Skip to content

[aw][code health] _FileChangeHandler should inherit from watchdog FileSystemEventHandler #67

@microsasa

Description

@microsasa

Root Cause

_FileChangeHandler in cli.py (lines 117–128) relies on duck typing instead of inheriting from watchdog.events.FileSystemEventHandler:

class _FileChangeHandler:
    """Watchdog handler that triggers refresh on any session-state change."""

    def __init__(self, change_event: threading.Event) -> None:
        self._change_event = change_event
        self._last_trigger = 0.0

    def dispatch(self, event: object) -> None:  # noqa: ANN001
        ...

Two suppressions result from this:

  1. # noqa: ANN001 on dispatch — the event parameter can't be typed without importing watchdog event types, so the annotation is omitted and the linter warning suppressed.

  2. # type: ignore[arg-type] on observer.schedule(handler, ...) — because handler is not a recognised FileSystemEventHandler subtype from the static analysis perspective.

Observer.schedule expects a FileSystemEventHandler instance. The duck-typing approach works today, but it:

  • Loses the BaseEventHandler / FileSystemEventHandler lifecycle hooks (e.g. on_any_event) that watchdog may start calling in future versions
  • Obscures intent — a reader must know that watchdog uses duck typing to understand why dispatch is defined here
  • Carries two noqa/type: ignore suppressions that mask any future type regressions

Fix

from watchdog.events import FileSystemEventHandler  # type: ignore[import-untyped]

class _FileChangeHandler(FileSystemEventHandler):  # type: ignore[misc]
    """Watchdog handler that triggers refresh on any session-state change."""

    def __init__(self, change_event: threading.Event) -> None:
        super().__init__()
        self._change_event = change_event
        self._last_trigger = 0.0

    def dispatch(self, event: object) -> None:
        now = time.monotonic()
        if now - self._last_trigger > 2.0:
            self._last_trigger = now
            self._change_event.set()
  • Remove # noqa: ANN001 from dispatch
  • Remove # type: ignore[arg-type] from observer.schedule(...)
  • Add super().__init__() call
  • The # type: ignore[misc] on the class line covers FileSystemEventHandler being from an untyped package (same pattern already used for Observer)

Acceptance Criteria

  • _FileChangeHandler inherits from watchdog.events.FileSystemEventHandler
  • super().__init__() called in __init__
  • # noqa: ANN001 removed from dispatch
  • # type: ignore[arg-type] removed from observer.schedule(...)
  • All existing tests pass
  • New test: instantiate _FileChangeHandler, call dispatch(object()), assert change_event is set (covers the inheritance path at runtime, not just the constructor)

Generated by Code Health Analysis ·

Metadata

Metadata

Assignees

No one assigned

    Labels

    awCreated by agentic workflowcode-healthCode cleanup and maintenance

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions