0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-13 19:21:50 +02:00

fix: plugin widget import machinery

- lazy import client so plugin widgets can import BECWidgets which use
  it indirectly
- exclude classes originating from bec_widgets core from plugin
  discovery
- better errors
This commit is contained in:
2025-06-20 18:14:50 +02:00
parent c4e921a49d
commit 60b2a95521
2 changed files with 12 additions and 6 deletions

View File

@ -14,18 +14,21 @@ from typing import TYPE_CHECKING, Literal, TypeAlias, cast
from bec_lib.endpoints import MessageEndpoints from bec_lib.endpoints import MessageEndpoints
from bec_lib.logger import bec_logger from bec_lib.logger import bec_logger
from bec_lib.utils.import_utils import lazy_import_from from bec_lib.utils.import_utils import lazy_import, lazy_import_from
from rich.console import Console from rich.console import Console
from rich.table import Table from rich.table import Table
import bec_widgets.cli.client as client
from bec_widgets.cli.rpc.rpc_base import RPCBase, RPCReference from bec_widgets.cli.rpc.rpc_base import RPCBase, RPCReference
from bec_widgets.utils.serialization import register_serializer_extension from bec_widgets.utils.serialization import register_serializer_extension
if TYPE_CHECKING: # pragma: no cover if TYPE_CHECKING: # pragma: no cover
from bec_lib.messages import GUIRegistryStateMessage from bec_lib.messages import GUIRegistryStateMessage
import bec_widgets.cli.client as client
else: else:
GUIRegistryStateMessage = lazy_import_from("bec_lib.messages", "GUIRegistryStateMessage") GUIRegistryStateMessage = lazy_import_from("bec_lib.messages", "GUIRegistryStateMessage")
client = lazy_import("bec_widgets.cli.client")
logger = bec_logger.logger logger = bec_logger.logger

View File

@ -38,9 +38,11 @@ def _loaded_submodules_from_specs(
try: try:
submodule.__loader__.exec_module(submodule) submodule.__loader__.exec_module(submodule)
except Exception as e: except Exception as e:
logger.error( exception_text = "".join(traceback.format_exception(e))
f"Error loading plugin {submodule}: \n{''.join(traceback.format_exception(e))}" if "(most likely due to a circular import)" in exception_text:
) logger.warning(f"Circular import encountered while loading {submodule}")
else:
logger.error(f"Error loading plugin {submodule}: \n{exception_text}")
yield submodule yield submodule
@ -59,7 +61,8 @@ def _get_widgets_from_module(module: ModuleType) -> BECClassContainer:
module, module,
predicate=lambda item: inspect.isclass(item) predicate=lambda item: inspect.isclass(item)
and issubclass(item, BECWidget) and issubclass(item, BECWidget)
and item is not BECWidget, and item is not BECWidget
and not item.__module__.startswith("bec_widgets"),
) )
return BECClassContainer( return BECClassContainer(
BECClassInfo(name=k, module=module.__name__, file=module.__loader__.get_filename(), obj=v) BECClassInfo(name=k, module=module.__name__, file=module.__loader__.get_filename(), obj=v)