mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-21 16:50:02 +02:00
feat: only updating the class attributes with the values from the JSON if the types are the same
This commit is contained in:
parent
3e72e25f9f
commit
2e683df6ef
@ -16,7 +16,7 @@ from pyDataInterface.utils.helpers import (
|
||||
get_nested_value_by_path_and_key,
|
||||
get_object_attr_from_path,
|
||||
parse_list_attr_and_index,
|
||||
set_if_differs,
|
||||
update_value_if_changed,
|
||||
)
|
||||
from pyDataInterface.utils.warnings import (
|
||||
warn_if_instance_class_does_not_inherit_from_DataService,
|
||||
@ -110,17 +110,26 @@ class DataService(rpyc.Service, TaskManager):
|
||||
|
||||
def load_DataService_from_JSON(self, json_dict: dict[str, Any]) -> None:
|
||||
# Traverse the serialized representation and set the attributes of the class
|
||||
serialized_class = self.serialize()
|
||||
for path in generate_paths_from_DataService_dict(json_dict):
|
||||
value = get_nested_value_by_path_and_key(json_dict, path=path)
|
||||
value_type = get_nested_value_by_path_and_key(
|
||||
json_dict, path=path, key="type"
|
||||
)
|
||||
class_value_type = get_nested_value_by_path_and_key(
|
||||
serialized_class, path=path, key="type"
|
||||
)
|
||||
if class_value_type == value_type:
|
||||
# Split the path into parts
|
||||
parts = path.split(".")
|
||||
attr_name = parts[-1]
|
||||
|
||||
# Split the path into parts
|
||||
parts = path.split(".")
|
||||
attr_name = parts[-1]
|
||||
|
||||
self.update_DataService_attribute(parts[:-1], attr_name, value, value_type)
|
||||
self.update_DataService_attribute(parts[:-1], attr_name, value)
|
||||
else:
|
||||
logger.info(
|
||||
f'Attribute type of "{path}" changed from "{value_type}" to '
|
||||
f'"{class_value_type}". Ignoring value from JSON file...'
|
||||
)
|
||||
|
||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||
current_value = getattr(self, __name, None)
|
||||
@ -607,7 +616,6 @@ class DataService(rpyc.Service, TaskManager):
|
||||
path_list: list[str],
|
||||
attr_name: str,
|
||||
value: Any,
|
||||
attr_type: Optional[str] = None,
|
||||
) -> None:
|
||||
# If attr_name corresponds to a list entry, extract the attr_name and the index
|
||||
attr_name, index = parse_list_attr_and_index(attr_name)
|
||||
@ -622,13 +630,13 @@ class DataService(rpyc.Service, TaskManager):
|
||||
|
||||
# Set the attribute at the terminal point of the path
|
||||
if isinstance(attr, Enum):
|
||||
set_if_differs(target_obj, attr_name, attr.__class__[value])
|
||||
update_value_if_changed(target_obj, attr_name, attr.__class__[value])
|
||||
elif isinstance(attr, list) and index is not None:
|
||||
set_if_differs(attr, index, value)
|
||||
update_value_if_changed(attr, index, value)
|
||||
elif isinstance(attr, DataService) and isinstance(value, dict):
|
||||
for key, v in value.items():
|
||||
self.update_DataService_attribute([*path_list, attr_name], key, v)
|
||||
elif callable(attr):
|
||||
return process_callable_attribute(attr, value["args"])
|
||||
else:
|
||||
set_if_differs(target_obj, attr_name, value)
|
||||
update_value_if_changed(target_obj, attr_name, value)
|
||||
|
@ -236,24 +236,39 @@ def convert_arguments_to_hinted_types(
|
||||
return args
|
||||
|
||||
|
||||
def set_if_differs(target: Any, attr_name: str | int, new_value: Any) -> None:
|
||||
def update_value_if_changed(target: Any, attr_name: str | int, new_value: Any) -> None:
|
||||
"""
|
||||
Set the value of an attribute or a list element on a target object to a new value,
|
||||
but only if the current value of the attribute or the list element differs from the
|
||||
new value.
|
||||
Updates the value of an attribute or a list element on a target object if the new
|
||||
value differs from the current one.
|
||||
|
||||
This function supports updating both attributes of an object and elements of a list.
|
||||
|
||||
- For objects, the function first checks the current value of the attribute. If the
|
||||
current value differs from the new value, the function updates the attribute.
|
||||
|
||||
- For lists, the function checks the current value at the specified index. If the
|
||||
current value differs from the new value, the function updates the list element
|
||||
at the given index.
|
||||
|
||||
Args:
|
||||
target: The object that has the attribute or the list.
|
||||
attr_name: The name of the attribute or the index of the list element.
|
||||
new_value: The new value for the attribute or the list element.
|
||||
target (Any):
|
||||
The target object that has the attribute or the list.
|
||||
attr_name (str | int):
|
||||
The name of the attribute or the index of the list element.
|
||||
new_value (Any):
|
||||
The new value for the attribute or the list element.
|
||||
"""
|
||||
|
||||
if isinstance(target, list) and isinstance(attr_name, int):
|
||||
# Case for a list
|
||||
if target[attr_name] != new_value:
|
||||
target[attr_name] = new_value
|
||||
elif isinstance(attr_name, str):
|
||||
# Case for an attribute
|
||||
if getattr(target, attr_name) != new_value:
|
||||
# Get the current value of the attribute
|
||||
attr_value = getattr(target, attr_name)
|
||||
|
||||
# If the type matches and the current value is different from the new value,
|
||||
# update the attribute.
|
||||
if attr_value != new_value:
|
||||
setattr(target, attr_name, new_value)
|
||||
else:
|
||||
logger.error(f"Incompatible arguments: {target}, {attr_name}.")
|
||||
|
Loading…
x
Reference in New Issue
Block a user