From f2c0a94904633f6450a15b09582f57c93bdb4a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Fri, 28 Mar 2025 08:55:06 +0100 Subject: [PATCH 1/2] fix: adds observable to an observable object accessed via a property When an observable is stored returned by a property, this adds the parent object as an observer to the observable returned by the property. --- src/pydase/observer_pattern/observable/observable.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pydase/observer_pattern/observable/observable.py b/src/pydase/observer_pattern/observable/observable.py index b368179..bffd19c 100644 --- a/src/pydase/observer_pattern/observable/observable.py +++ b/src/pydase/observer_pattern/observable/observable.py @@ -55,6 +55,10 @@ class Observable(ObservableObject): value = super().__getattribute__(name) if is_property_attribute(self, name): + # fixes https://github.com/tiqi-group/pydase/issues/187 and + # https://github.com/tiqi-group/pydase/issues/192 + if isinstance(value, ObservableObject): + value.add_observer(self, name) self._notify_changed(name, value) return value From db43f5dbbb9b482a6035ab6deadd8322a23bb40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Thu, 28 Nov 2024 09:37:15 +0100 Subject: [PATCH 2/2] tests: adds test reproducing the read-only dict bug --- .../test_data_service_observer.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/data_service/test_data_service_observer.py b/tests/data_service/test_data_service_observer.py index fcadc60..e06198a 100644 --- a/tests/data_service/test_data_service_observer.py +++ b/tests/data_service/test_data_service_observer.py @@ -222,3 +222,22 @@ def test_nested_dict_property_changes( # Changing the _voltage attribute should re-evaluate the voltage property, but avoid # recursion service.my_dict["key"].voltage = 1.2 + + +def test_read_only_dict_property(caplog: pytest.LogCaptureFixture) -> None: + class MyObservable(pydase.DataService): + def __init__(self) -> None: + super().__init__() + self._dict_attr = {"dotted.key": 1.0} + + @property + def dict_attr(self) -> dict[str, Any]: + return self._dict_attr + + service_instance = MyObservable() + state_manager = StateManager(service=service_instance) + DataServiceObserver(state_manager) + + service_instance._dict_attr["dotted.key"] = 2.0 + + assert "'dict_attr[\"dotted.key\"]' changed to '2.0'" in caplog.text