mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-21 00:40:01 +02:00
feat: removing superfluous property accesses
This commit is contained in:
parent
6eafe07ac7
commit
c12bb87b2b
@ -19,6 +19,7 @@ from pydase.utils.helpers import (
|
|||||||
get_component_class_names,
|
get_component_class_names,
|
||||||
get_nested_value_from_DataService_by_path_and_key,
|
get_nested_value_from_DataService_by_path_and_key,
|
||||||
get_object_attr_from_path,
|
get_object_attr_from_path,
|
||||||
|
is_property_attribute,
|
||||||
parse_list_attr_and_index,
|
parse_list_attr_and_index,
|
||||||
update_value_if_changed,
|
update_value_if_changed,
|
||||||
)
|
)
|
||||||
@ -58,6 +59,8 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
self._load_values_from_json()
|
self._load_values_from_json()
|
||||||
|
|
||||||
def __setattr__(self, __name: str, __value: Any) -> None:
|
def __setattr__(self, __name: str, __value: Any) -> None:
|
||||||
|
# converting attributes that are not properties
|
||||||
|
if not isinstance(getattr(type(self), __name, None), property):
|
||||||
current_value = getattr(self, __name, None)
|
current_value = getattr(self, __name, None)
|
||||||
# parse ints into floats if current value is a float
|
# parse ints into floats if current value is a float
|
||||||
if isinstance(current_value, float) and isinstance(__value, int):
|
if isinstance(current_value, float) and isinstance(__value, int):
|
||||||
@ -84,6 +87,27 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
if not attr_name.startswith("_DataService__"):
|
if not attr_name.startswith("_DataService__"):
|
||||||
warn_if_instance_class_does_not_inherit_from_DataService(attr_value)
|
warn_if_instance_class_does_not_inherit_from_DataService(attr_value)
|
||||||
|
|
||||||
|
def __set_attribute_based_on_type(
|
||||||
|
self,
|
||||||
|
target_obj: Any,
|
||||||
|
attr_name: str,
|
||||||
|
attr: Any,
|
||||||
|
value: Any,
|
||||||
|
index: Optional[int],
|
||||||
|
path_list: list[str],
|
||||||
|
) -> None:
|
||||||
|
if isinstance(attr, Enum):
|
||||||
|
update_value_if_changed(target_obj, attr_name, attr.__class__[value])
|
||||||
|
elif isinstance(attr, list) and index is not None:
|
||||||
|
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):
|
||||||
|
process_callable_attribute(attr, value["args"])
|
||||||
|
else:
|
||||||
|
update_value_if_changed(target_obj, attr_name, value)
|
||||||
|
|
||||||
def _rpyc_getattr(self, name: str) -> Any:
|
def _rpyc_getattr(self, name: str) -> Any:
|
||||||
if name.startswith("_"):
|
if name.startswith("_"):
|
||||||
# disallow special and private attributes
|
# disallow special and private attributes
|
||||||
@ -338,24 +362,19 @@ class DataService(rpyc.Service, AbstractDataService):
|
|||||||
) -> 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)
|
||||||
|
|
||||||
# Traverse the object according to the path parts
|
# Traverse the object according to the path parts
|
||||||
target_obj = get_object_attr_from_path(self, path_list)
|
target_obj = get_object_attr_from_path(self, path_list)
|
||||||
|
|
||||||
attr = get_object_attr_from_path(target_obj, [attr_name])
|
# If the attribute is a property, change it using the setter without getting the
|
||||||
|
# property value (would otherwise be bad for expensive getter methods)
|
||||||
|
if is_property_attribute(target_obj, attr_name):
|
||||||
|
setattr(target_obj, attr_name, value)
|
||||||
|
return
|
||||||
|
|
||||||
|
attr = get_object_attr_from_path(target_obj, [attr_name])
|
||||||
if attr is None:
|
if attr is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Set the attribute at the terminal point of the path
|
self.__set_attribute_based_on_type(
|
||||||
if isinstance(attr, Enum):
|
target_obj, attr_name, attr, value, index, path_list
|
||||||
update_value_if_changed(target_obj, attr_name, attr.__class__[value])
|
)
|
||||||
elif isinstance(attr, list) and index is not None:
|
|
||||||
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:
|
|
||||||
update_value_if_changed(target_obj, attr_name, value)
|
|
||||||
|
@ -394,3 +394,7 @@ def get_component_class_names() -> list[str]:
|
|||||||
import pydase.components
|
import pydase.components
|
||||||
|
|
||||||
return pydase.components.__all__
|
return pydase.components.__all__
|
||||||
|
|
||||||
|
|
||||||
|
def is_property_attribute(target_obj: Any, attr_name: str) -> bool:
|
||||||
|
return isinstance(getattr(type(target_obj), attr_name, None), property)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user