diff --git a/src/pydase/utils/serializer.py b/src/pydase/utils/serializer.py index e91ea77..c54504c 100644 --- a/src/pydase/utils/serializer.py +++ b/src/pydase/utils/serializer.py @@ -267,18 +267,24 @@ def set_nested_value_by_path( logger.error(e) return - # setting the new value serialized_value = dump(value) - serialized_value.pop("readonly", None) - value_type = serialized_value.pop("type") - if "readonly" in current_dict and current_dict["type"] != "method": - current_dict["type"] = value_type + keys_to_keep = set(serialized_value.keys()) + + if current_dict == {}: # adding an attribute / element to a list or dict + pass + elif current_dict["type"] == "method": # state change of task + keys_to_keep = set(current_dict.keys()) + + serialized_value = current_dict + serialized_value["value"] = value.name if isinstance(value, Enum) else None + else: + # attribute-specific information should not be overwritten by new value + serialized_value.pop("readonly") + serialized_value.pop("doc") current_dict.update(serialized_value) # removes keys that are not present in the serialized new value - keys_to_keep = set(serialized_value.keys()) | {"type", "readonly"} - for key in list(current_dict.keys()): if key not in keys_to_keep: current_dict.pop(key, None) diff --git a/tests/utils/test_serializer.py b/tests/utils/test_serializer.py index 096dec3..cc47707 100644 --- a/tests/utils/test_serializer.py +++ b/tests/utils/test_serializer.py @@ -405,6 +405,9 @@ def setup_dict() -> dict[str, Any]: enum_attr = MyEnum.RUNNING attr_list = [0, 1, MySubclass()] + def my_task(self) -> None: + pass + return ServiceClass().serialize()["value"] @@ -439,6 +442,28 @@ def test_update_enum_attribute_to_float(setup_dict: dict[str, Any]) -> None: } +def test_update_task_state(setup_dict: dict[str, Any]) -> None: + assert setup_dict["my_task"] == { + "async": False, + "doc": None, + "frontend_render": False, + "readonly": True, + "signature": {"parameters": {}, "return_annotation": {}}, + "type": "method", + "value": None, + } + set_nested_value_by_path(setup_dict, "my_task", TaskStatus.RUNNING) + assert setup_dict["my_task"] == { + "async": False, + "doc": None, + "frontend_render": False, + "readonly": True, + "signature": {"parameters": {}, "return_annotation": {}}, + "type": "method", + "value": "RUNNING", + } + + def test_update_list_entry(setup_dict: dict[str, Any]) -> None: set_nested_value_by_path(setup_dict, "attr_list[1]", 20) assert setup_dict["attr_list"]["value"][1]["value"] == 20