adds load_state decorator

This commit is contained in:
Mose Müller 2023-11-09 15:29:39 +01:00
parent 2208e5f66e
commit aa9f1ba35a

View File

@ -1,6 +1,7 @@
import json import json
import logging import logging
import os import os
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional, cast from typing import TYPE_CHECKING, Any, Optional, cast
@ -8,7 +9,6 @@ import pydase.units as u
from pydase.data_service.data_service_cache import DataServiceCache from pydase.data_service.data_service_cache import DataServiceCache
from pydase.utils.helpers import ( from pydase.utils.helpers import (
get_object_attr_from_path_list, get_object_attr_from_path_list,
is_property_attribute,
parse_list_attr_and_index, parse_list_attr_and_index,
) )
from pydase.utils.serializer import ( from pydase.utils.serializer import (
@ -23,6 +23,36 @@ if TYPE_CHECKING:
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def load_state(func: Callable[..., Any]) -> Callable[..., Any]:
"""This function should be used as a decorator on property setters to indicate that
the value should be loaded from the JSON file.
Example:
>>> class Service(pydase.DataService):
... _name = "Service"
...
... @property
... def name(self) -> str:
... return self._name
...
... @name.setter
... @load_state
... def name(self, value: str) -> None:
... self._name = value
"""
func._load_state = True
return func
def has_load_state_decorator(prop: property):
if prop and isinstance(prop, property):
# Check if the setter function has the attribute set by the @load_state
# decorator
return getattr(prop.fset, "_load_state", False)
return False
class StateManager: class StateManager:
""" """
Manages the state of a DataService instance, serving as both a cache and a Manages the state of a DataService instance, serving as both a cache and a
@ -211,6 +241,8 @@ class StateManager:
def __attr_value_should_change(self, parent_object: Any, attr_name: str) -> bool: def __attr_value_should_change(self, parent_object: Any, attr_name: str) -> bool:
# If the attribute is a property, change it using the setter without getting # If the attribute is a property, change it using the setter without getting
# the property value (would otherwise be bad for expensive getter methods) # the property value (would otherwise be bad for expensive getter methods)
if is_property_attribute(parent_object, attr_name): prop = getattr(type(parent_object), attr_name, None)
return True
if isinstance(prop, property):
return has_load_state_decorator(prop)
return True return True