From b3b75b59cf750f7cc44dc55026db836089a30d61 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Fri, 24 Apr 2026 20:50:50 +0200 Subject: [PATCH] Fix CI: Callable import + ControlTaskLike Protocol Two failures introduced by the previous polish commits caught by CI: - ruff UP035 on lib/galaxy_test/base/sse.py: Callable must be imported from collections.abc, not typing (newer ruff version than the local venv had). - packages mypy on test_sse_dispatch_cache.py:78: the injected control_task_factory's type was Callable[[GalaxyQueueWorker], ControlTask], which rejected NoopControlTask (and would have also rejected FakeControlTask / BoomControlTask) because none of the test classes subclass ControlTask. Introduce a ControlTaskLike Protocol covering the single method the dispatcher calls (``send_task(**kwargs)``) and type the factory against it. Keeps ControlTask itself as the production default and lets the test fakes pass via structural typing. --- lib/galaxy/managers/sse_dispatch.py | 14 +++++++++++++- lib/galaxy_test/base/sse.py | 6 ++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/galaxy/managers/sse_dispatch.py b/lib/galaxy/managers/sse_dispatch.py index c5d0e46a402..41a9370f8af 100644 --- a/lib/galaxy/managers/sse_dispatch.py +++ b/lib/galaxy/managers/sse_dispatch.py @@ -15,6 +15,7 @@ from collections.abc import Callable from typing import ( Any, Optional, + Protocol, ) from cachetools import TTLCache @@ -29,6 +30,17 @@ from galaxy.queues import all_control_queues_for_declare from galaxy.web.statsd_client import VanillaGalaxyStatsdClient from galaxy.web_stack import ApplicationStack + +class ControlTaskLike(Protocol): + """Structural type for the dispatcher's control-task collaborator. + + The dispatcher only calls ``send_task(**kwargs)``. Typed as a Protocol so + tests can pass lightweight fakes (``FakeControlTask``, ``NoopControlTask``) + without subclassing ``ControlTask``. + """ + + def send_task(self, **kwargs: Any) -> Any: ... + log = logging.getLogger(__name__) @@ -56,7 +68,7 @@ class SSEEventDispatcher: application_stack: ApplicationStack, statsd_client: Optional[VanillaGalaxyStatsdClient] = None, clock: Callable[[], float] = time.monotonic, - control_task_factory: Callable[[GalaxyQueueWorker], ControlTask] = ControlTask, + control_task_factory: Callable[[GalaxyQueueWorker], ControlTaskLike] = ControlTask, queues_provider: Optional[Callable[[], list[Queue]]] = None, ) -> None: self._queue_worker = queue_worker diff --git a/lib/galaxy_test/base/sse.py b/lib/galaxy_test/base/sse.py index 73b3c39e2b6..d98ab7c6c52 100644 --- a/lib/galaxy_test/base/sse.py +++ b/lib/galaxy_test/base/sse.py @@ -9,10 +9,8 @@ thread instead of silently swallowing them. import queue import threading -from typing import ( - Callable, - Optional, -) +from collections.abc import Callable +from typing import Optional import requests