replaces lambda functions with functions in callback manager

This commit is contained in:
Mose Müller 2023-11-16 09:08:40 +01:00
parent 0ea997384c
commit f5116607b9

View File

@ -3,7 +3,7 @@ from __future__ import annotations
import inspect import inspect
import logging import logging
from collections.abc import Callable from collections.abc import Callable
from typing import TYPE_CHECKING, Any, cast from typing import TYPE_CHECKING, Any
from pydase.data_service.abstract_data_service import AbstractDataService from pydase.data_service.abstract_data_service import AbstractDataService
from pydase.utils.helpers import get_class_and_instance_attributes from pydase.utils.helpers import get_class_and_instance_attributes
@ -96,17 +96,20 @@ class CallbackManager:
# Default arguments solve the late binding problem by capturing the # Default arguments solve the late binding problem by capturing the
# value at the time the lambda is defined, not when it is called. This # value at the time the lambda is defined, not when it is called. This
# prevents attr_name from being overwritten in the next loop iteration. # prevents attr_name from being overwritten in the next loop iteration.
callback = ( def callback(
lambda index, value, attr_name=attr_name: self.service._callback_manager.emit_notification( index: int, value: Any, attr_name: str = attr_name
parent_path=parent_path, ) -> None:
name=f"{attr_name}[{index}]", """Emits a notification through the service's callback manager."""
value=value,
)
if self.service == self.service.__root__
# Skip private and protected lists # Skip private and protected lists
and not cast(str, attr_name).startswith("_") if (
else None self.service == self.service.__root__
) and not attr_name.startswith("_")
):
self.service._callback_manager.emit_notification(
parent_path=parent_path,
name=f"{attr_name}[{index}]",
value=value,
)
# Check if attr_value is already a DataServiceList or in the mapping # Check if attr_value is already a DataServiceList or in the mapping
if isinstance(attr_value, DataServiceList): if isinstance(attr_value, DataServiceList):
@ -164,17 +167,20 @@ class CallbackManager:
# Create and register a callback for the object # Create and register a callback for the object
# only emit the notification when the call was registered by the root object # only emit the notification when the call was registered by the root object
callback: Callable[[str, Any], None] = ( def callback(attr_name: str, value: Any) -> None:
lambda name, value: obj._callback_manager.emit_notification( """Emits a notification through the service's callback manager."""
parent_path=parent_path, name=name, value=value # Skip private and protected attrs
) # exlude proerty notifications -> those are handled in separate callbacks
if self.service == obj.__root__ if (
and not name.startswith("_") # we are only interested in public attributes self.service == self.service.__root__
and not isinstance( and not attr_name.startswith("_")
getattr(type(obj), name, None), property and not isinstance(getattr(type(obj), attr_name, None), property)
) # exlude proerty notifications -> those are handled in separate callbacks ):
else None self.service._callback_manager.emit_notification(
) parent_path=parent_path,
name=attr_name,
value=value,
)
obj._callback_manager.callbacks.add(callback) obj._callback_manager.callbacks.add(callback)
@ -300,34 +306,46 @@ class CallbackManager:
if isinstance( if isinstance(
dependency_value, (DataServiceList, AbstractDataService) dependency_value, (DataServiceList, AbstractDataService)
): ):
callback = (
lambda name, value, dependent_attr=attr_name: obj._callback_manager.emit_notification( def list_or_data_service_callback(
parent_path=parent_path, name: Any, value: Any, dependent_attr: str = attr_name
name=dependent_attr, ) -> None:
value=getattr(obj, dependent_attr), """Emits a notification through the service's callback
) manager.
if self.service == obj.__root__ """
else None if self.service == obj.__root__:
) obj._callback_manager.emit_notification(
parent_path=parent_path,
name=dependent_attr,
value=getattr(obj, dependent_attr),
)
self.__register_recursive_parameter_callback( self.__register_recursive_parameter_callback(
dependency_value, dependency_value,
callback=callback, callback=list_or_data_service_callback,
) )
else: else:
callback = (
lambda name, _, dep_attr=attr_name, dep=dependency: obj._callback_manager.emit_notification( # type: ignore def callback(
parent_path=parent_path, name: str,
name=dep_attr, value: Any,
value=getattr(obj, dep_attr), dependent_attr: str = attr_name,
) dep: str = dependency,
if name == dep and self.service == obj.__root__ ) -> None:
else None """Emits a notification through the service's callback
) manager.
"""
if name == dep and self.service == obj.__root__:
obj._callback_manager.emit_notification(
parent_path=parent_path,
name=dependent_attr,
value=getattr(obj, dependent_attr),
)
# Add to callbacks # Add to callbacks
obj._callback_manager.callbacks.add(callback) obj._callback_manager.callbacks.add(callback)
def _register_start_stop_task_callbacks( def _register_start_stop_task_callbacks( # noqa
self, obj: "AbstractDataService", parent_path: str self, obj: "AbstractDataService", parent_path: str
) -> None: ) -> None:
""" """
@ -346,16 +364,22 @@ class CallbackManager:
# Create and register a callback for the object # Create and register a callback for the object
# only emit the notification when the call was registered by the root object # only emit the notification when the call was registered by the root object
callback: Callable[[str, dict[str, Any] | None], None] = ( def task_status_change_callback(
lambda name, status: obj._callback_manager.emit_notification( name: str, task_status: dict[str, Any] | None
parent_path=parent_path, name=name, value=status ) -> None:
) """Emits a notification through the service's callback
if self.service == obj.__root__ manager.
and not name.startswith("_") # we are only interested in public attributes """
else None if self.service == obj.__root__ and not name.startswith("_"):
) obj._callback_manager.emit_notification(
parent_path=parent_path,
name=name,
value=task_status,
)
obj._task_manager.task_status_change_callbacks.append(callback) obj._task_manager.task_status_change_callbacks.append(
task_status_change_callback
)
# Recursively register callbacks for all nested attributes of the object # Recursively register callbacks for all nested attributes of the object
attrs: dict[str, Any] = get_class_and_instance_attributes(obj) attrs: dict[str, Any] = get_class_and_instance_attributes(obj)