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_nested_value_by_path_and_key,
|
||||||
get_object_attr_from_path,
|
get_object_attr_from_path,
|
||||||
parse_list_attr_and_index,
|
parse_list_attr_and_index,
|
||||||
set_if_differs,
|
update_value_if_changed,
|
||||||
)
|
)
|
||||||
from pyDataInterface.utils.warnings import (
|
from pyDataInterface.utils.warnings import (
|
||||||
warn_if_instance_class_does_not_inherit_from_DataService,
|
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:
|
def load_DataService_from_JSON(self, json_dict: dict[str, Any]) -> None:
|
||||||
# Traverse the serialized representation and set the attributes of the class
|
# 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):
|
for path in generate_paths_from_DataService_dict(json_dict):
|
||||||
value = get_nested_value_by_path_and_key(json_dict, path=path)
|
value = get_nested_value_by_path_and_key(json_dict, path=path)
|
||||||
value_type = get_nested_value_by_path_and_key(
|
value_type = get_nested_value_by_path_and_key(
|
||||||
json_dict, path=path, key="type"
|
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
|
self.update_DataService_attribute(parts[:-1], attr_name, value)
|
||||||
parts = path.split(".")
|
else:
|
||||||
attr_name = parts[-1]
|
logger.info(
|
||||||
|
f'Attribute type of "{path}" changed from "{value_type}" to '
|
||||||
self.update_DataService_attribute(parts[:-1], attr_name, value, value_type)
|
f'"{class_value_type}". Ignoring value from JSON file...'
|
||||||
|
)
|
||||||
|
|
||||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||||
current_value = getattr(self, __name, None)
|
current_value = getattr(self, __name, None)
|
||||||
@ -607,7 +616,6 @@ class DataService(rpyc.Service, TaskManager):
|
|||||||
path_list: list[str],
|
path_list: list[str],
|
||||||
attr_name: str,
|
attr_name: str,
|
||||||
value: Any,
|
value: Any,
|
||||||
attr_type: Optional[str] = None,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
# If attr_name corresponds to a list entry, extract the attr_name and the index
|
# 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)
|
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
|
# Set the attribute at the terminal point of the path
|
||||||
if isinstance(attr, Enum):
|
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:
|
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):
|
elif isinstance(attr, DataService) and isinstance(value, dict):
|
||||||
for key, v in value.items():
|
for key, v in value.items():
|
||||||
self.update_DataService_attribute([*path_list, attr_name], key, v)
|
self.update_DataService_attribute([*path_list, attr_name], key, v)
|
||||||
elif callable(attr):
|
elif callable(attr):
|
||||||
return process_callable_attribute(attr, value["args"])
|
return process_callable_attribute(attr, value["args"])
|
||||||
else:
|
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
|
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,
|
Updates the value of an attribute or a list element on a target object if the new
|
||||||
but only if the current value of the attribute or the list element differs from the
|
value differs from the current one.
|
||||||
new value.
|
|
||||||
|
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:
|
Args:
|
||||||
target: The object that has the attribute or the list.
|
target (Any):
|
||||||
attr_name: The name of the attribute or the index of the list element.
|
The target object that has the attribute or the list.
|
||||||
new_value: The new value for the attribute or the list element.
|
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):
|
if isinstance(target, list) and isinstance(attr_name, int):
|
||||||
# Case for a list
|
|
||||||
if target[attr_name] != new_value:
|
if target[attr_name] != new_value:
|
||||||
target[attr_name] = new_value
|
target[attr_name] = new_value
|
||||||
elif isinstance(attr_name, str):
|
elif isinstance(attr_name, str):
|
||||||
# Case for an attribute
|
# Get the current value of the attribute
|
||||||
if getattr(target, attr_name) != new_value:
|
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)
|
setattr(target, attr_name, new_value)
|
||||||
else:
|
else:
|
||||||
logger.error(f"Incompatible arguments: {target}, {attr_name}.")
|
logger.error(f"Incompatible arguments: {target}, {attr_name}.")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user