fix(api/v2): move FrameSourceFactory alias under TYPE_CHECKING

As a module-level runtime value, FrameSourceFactory = Callable[..., Any] is a
GenericAlias that passes isinstance(obj, type) but makes issubclass(obj, Service)
raise on Python 3.10/3.14. The service factory scans this module for Service
subclasses (services/factory.py:90), so the runtime alias crashed service
initialization on those interpreters with 'issubclass() arg 1 must be a class'
-> 'Could not initialize services', erroring out dozens of unrelated tests at
setup (3.13 was unaffected, which is why local runs passed).

The alias is only referenced in a lazy annotation (from __future__ import
annotations), so moving it + the Callable import under TYPE_CHECKING removes it
from the runtime namespace with no behavior change.

Verified: alias absent from runtime module namespace, factory scan finds
BackgroundExecutionService cleanly, durable service tests 26/26 pass.
This commit is contained in:
ogabrielluiz
2026-06-15 19:38:48 -03:00
parent e0176f9c04
commit e5a9e36527

View File

@ -20,7 +20,6 @@ import contextlib
import json
import os
import tempfile
from collections.abc import Callable
from pathlib import Path
from typing import TYPE_CHECKING, Any
from uuid import uuid4
@ -37,7 +36,7 @@ from langflow.services.deps import get_job_service
from langflow.services.jobs.exceptions import DuplicateJobError
if TYPE_CHECKING:
from collections.abc import AsyncIterator
from collections.abc import AsyncIterator, Callable
from uuid import UUID
from lfx.services.settings.service import SettingsService
@ -45,10 +44,16 @@ if TYPE_CHECKING:
from langflow.services.database.models.jobs.model import Job, JobEvent
from langflow.services.database.models.user.model import UserRead
# A frame-source factory returns the async-generator callable the runner drives.
# Default wiring (Task 2.7) returns ``_stream_event_frames`` bound to the run's
# adapter + flow; tests inject a scripted generator.
FrameSourceFactory = Callable[..., Any]
# A frame-source factory returns the async-generator callable the runner drives.
# Default wiring (Task 2.7) returns ``_stream_event_frames`` bound to the run's
# adapter + flow; tests inject a scripted generator.
#
# Defined under TYPE_CHECKING on purpose: as a module-level runtime value,
# ``Callable[..., Any]`` is a GenericAlias that passes ``isinstance(obj, type)``
# but makes ``issubclass(obj, Service)`` raise on Python 3.10/3.14. The service
# factory scans this module for ``Service`` subclasses (services/factory.py), so a
# runtime alias here crashes service initialization on those interpreters.
FrameSourceFactory = Callable[..., Any]
# Durable statuses that mean the run is over. ``events()`` keys off these (not the
# process-local live bus) so a reattach to a finished job replays and returns