From 3c37fac72e2c210571312e32ffea50589cf30035 Mon Sep 17 00:00:00 2001 From: Paul Nechifor Date: Sat, 28 Feb 2026 01:44:24 +0200 Subject: [PATCH] fix(annotations): module annotations are needed at runtime --- dimos/core/_test_future_annotations_helper.py | 2 +- dimos/core/module.py | 20 ++----------------- .../sensors/camera/realsense/camera.py | 3 +-- dimos/hardware/sensors/camera/zed/camera.py | 5 +---- .../manipulation/grasping/graspgen_module.py | 2 +- dimos/manipulation/grasping/grasping.py | 4 ++-- .../detection/type/detection2d/bbox.py | 3 +-- pyproject.toml | 3 +++ 8 files changed, 12 insertions(+), 30 deletions(-) diff --git a/dimos/core/_test_future_annotations_helper.py b/dimos/core/_test_future_annotations_helper.py index 08c5ec0063..a96ce0f587 100644 --- a/dimos/core/_test_future_annotations_helper.py +++ b/dimos/core/_test_future_annotations_helper.py @@ -21,7 +21,7 @@ from __future__ import annotations from dimos.core.module import Module -from dimos.core.stream import In, Out # noqa +from dimos.core.stream import In, Out class FutureData: diff --git a/dimos/core/module.py b/dimos/core/module.py index 8f2dd916c9..f36124116d 100644 --- a/dimos/core/module.py +++ b/dimos/core/module.py @@ -17,7 +17,6 @@ from functools import partial import inspect import json -import sys import threading from typing import ( TYPE_CHECKING, @@ -392,14 +391,8 @@ def __init_subclass__(cls, **kwargs: Any) -> None: """ super().__init_subclass__(**kwargs) - # Get type hints for this class only (not inherited ones). - globalns = {} - for c in cls.__mro__: - if c.__module__ in sys.modules: - globalns.update(sys.modules[c.__module__].__dict__) - try: - hints = get_type_hints(cls, globalns=globalns, include_extras=True) + hints = get_type_hints(cls, include_extras=True) except (NameError, AttributeError, TypeError): hints = {} @@ -413,18 +406,9 @@ def __init_subclass__(cls, **kwargs: Any) -> None: def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def] self.ref = None # type: ignore[assignment] - # Get type hints with proper namespace resolution for subclasses - # Collect namespaces from all classes in the MRO chain - globalns = {} - for cls in self.__class__.__mro__: - if cls.__module__ in sys.modules: - globalns.update(sys.modules[cls.__module__].__dict__) - try: - hints = get_type_hints(self.__class__, globalns=globalns, include_extras=True) + hints = get_type_hints(self.__class__, include_extras=True) except (NameError, AttributeError, TypeError): - # If we still can't resolve hints, skip type hint processing - # This can happen with complex forward references hints = {} for name, ann in hints.items(): diff --git a/dimos/hardware/sensors/camera/realsense/camera.py b/dimos/hardware/sensors/camera/realsense/camera.py index 4ff0ccf6c4..dece14046f 100644 --- a/dimos/hardware/sensors/camera/realsense/camera.py +++ b/dimos/hardware/sensors/camera/realsense/camera.py @@ -28,6 +28,7 @@ from dimos.core.core import rpc from dimos.core.module import Module, ModuleConfig from dimos.core.module_coordinator import ModuleCoordinator +from dimos.core.stream import Out from dimos.core.transport import LCMTransport from dimos.hardware.sensors.camera.spec import ( OPTICAL_ROTATION, @@ -45,8 +46,6 @@ if TYPE_CHECKING: import pyrealsense2 as rs # type: ignore[import-not-found] - from dimos.core.stream import Out - def default_base_transform() -> Transform: """Default identity transform for camera mounting.""" diff --git a/dimos/hardware/sensors/camera/zed/camera.py b/dimos/hardware/sensors/camera/zed/camera.py index 171b706ff9..6ce2fc86b2 100644 --- a/dimos/hardware/sensors/camera/zed/camera.py +++ b/dimos/hardware/sensors/camera/zed/camera.py @@ -18,7 +18,6 @@ from dataclasses import dataclass, field import threading import time -from typing import TYPE_CHECKING import cv2 import pyzed.sl as sl @@ -27,6 +26,7 @@ from dimos.core.core import rpc from dimos.core.module import Module, ModuleConfig from dimos.core.module_coordinator import ModuleCoordinator +from dimos.core.stream import Out from dimos.core.transport import LCMTransport from dimos.hardware.sensors.camera.spec import ( OPTICAL_ROTATION, @@ -41,9 +41,6 @@ from dimos.spec import perception from dimos.utils.reactive import backpressure -if TYPE_CHECKING: - from dimos.core.stream import Out - def default_base_transform() -> Transform: """Default identity transform for camera mounting.""" diff --git a/dimos/manipulation/grasping/graspgen_module.py b/dimos/manipulation/grasping/graspgen_module.py index 47520ea0e5..c988d3df51 100644 --- a/dimos/manipulation/grasping/graspgen_module.py +++ b/dimos/manipulation/grasping/graspgen_module.py @@ -25,13 +25,13 @@ from dimos.core.core import rpc from dimos.core.docker_runner import DockerModuleConfig from dimos.core.module import Module +from dimos.core.stream import Out from dimos.msgs.geometry_msgs import PoseArray from dimos.msgs.std_msgs import Header from dimos.utils.logging_config import setup_logger from dimos.utils.transform_utils import matrix_to_pose if TYPE_CHECKING: - from dimos.core.stream import Out from dimos.msgs.sensor_msgs import PointCloud2 logger = setup_logger() diff --git a/dimos/manipulation/grasping/grasping.py b/dimos/manipulation/grasping/grasping.py index 783f899a83..433a07d846 100644 --- a/dimos/manipulation/grasping/grasping.py +++ b/dimos/manipulation/grasping/grasping.py @@ -24,12 +24,12 @@ from dimos.agents.annotation import skill from dimos.core.core import rpc from dimos.core.module import Module +from dimos.core.stream import Out +from dimos.msgs.geometry_msgs import PoseArray from dimos.utils.logging_config import setup_logger from dimos.utils.transform_utils import quaternion_to_euler if TYPE_CHECKING: - from dimos.core.stream import Out - from dimos.msgs.geometry_msgs import PoseArray from dimos.msgs.sensor_msgs import PointCloud2 logger = setup_logger() diff --git a/dimos/perception/detection/type/detection2d/bbox.py b/dimos/perception/detection/type/detection2d/bbox.py index 32109dffd3..45dc848e9d 100644 --- a/dimos/perception/detection/type/detection2d/bbox.py +++ b/dimos/perception/detection/type/detection2d/bbox.py @@ -18,9 +18,8 @@ import hashlib from typing import TYPE_CHECKING, Any -from typing_extensions import Self - if TYPE_CHECKING: + from typing_extensions import Self from ultralytics.engine.results import Results # type: ignore[import-not-found] from dimos.msgs.sensor_msgs import Image diff --git a/pyproject.toml b/pyproject.toml index 84ba5ea25c..fde9b90c29 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -333,6 +333,9 @@ known-first-party = ["dimos"] combine-as-imports = true force-sort-within-sections = true +[tool.ruff.lint.flake8-type-checking] +runtime-evaluated-base-classes = ["dimos.core.module.Module"] + [tool.mypy] python_version = "3.12" incremental = true