Merge pull request #232 from tiqi-group/fix/nested-attribute-notification

fix: properly checking is attribute is nested
This commit is contained in:
Mose Müller 2025-05-22 15:37:02 +02:00 committed by GitHub
commit 9ee498eb5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 5 deletions

View File

@ -20,6 +20,19 @@ from pydase.utils.serialization.types import SerializedObject
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def _is_nested_attribute(full_access_path: str, changing_attributes: list[str]) -> bool:
"""Return True if the full_access_path is a nested attribute of any
changing_attribute."""
return any(
(
full_access_path.startswith((f"{attr}.", f"{attr}["))
and full_access_path != attr
)
for attr in changing_attributes
)
class DataServiceObserver(PropertyObserver): class DataServiceObserver(PropertyObserver):
def __init__(self, state_manager: StateManager) -> None: def __init__(self, state_manager: StateManager) -> None:
self.state_manager = state_manager self.state_manager = state_manager
@ -29,11 +42,7 @@ class DataServiceObserver(PropertyObserver):
super().__init__(state_manager.service) super().__init__(state_manager.service)
def on_change(self, full_access_path: str, value: Any) -> None: def on_change(self, full_access_path: str, value: Any) -> None:
if any( if _is_nested_attribute(full_access_path, self.changing_attributes):
full_access_path.startswith(changing_attribute)
and full_access_path != changing_attribute
for changing_attribute in self.changing_attributes
):
return return
cached_value_dict: SerializedObject cached_value_dict: SerializedObject

View File

@ -262,3 +262,22 @@ def test_dependency_as_function_argument(caplog: pytest.LogCaptureFixture) -> No
service_instance.some_int = 1337 service_instance.some_int = 1337
assert "'other_int' changed to '1338'" in caplog.text assert "'other_int' changed to '1338'" in caplog.text
def test_property_starting_with_dependency_name(
caplog: pytest.LogCaptureFixture,
) -> None:
class MyObservable(pydase.DataService):
my_int = 0
@property
def my_int_2(self) -> int:
return self.my_int + 1
service_instance = MyObservable()
state_manager = StateManager(service=service_instance)
DataServiceObserver(state_manager)
service_instance.my_int = 1337
assert "'my_int_2' changed to '1338'" in caplog.text