mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-22 09:10:01 +02:00
fixed serialization of class deriving from class which derives from DataService
This commit is contained in:
parent
49984b7c2e
commit
88886e3fd6
@ -177,19 +177,21 @@ def parse_list_attr_and_index(attr_string: str) -> tuple[str, int | None]:
|
|||||||
return attr_name, index
|
return attr_name, index
|
||||||
|
|
||||||
|
|
||||||
def get_component_class_names() -> list[str]:
|
def get_component_classes() -> list[type]:
|
||||||
"""
|
"""
|
||||||
Returns the names of the component classes in a list.
|
Returns references to the component classes in a list.
|
||||||
|
|
||||||
It takes the names from the pydase/components/__init__.py file, so this file should
|
|
||||||
always be up-to-date with the currently available components.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[str]: List of component class names
|
|
||||||
"""
|
"""
|
||||||
import pydase.components
|
import pydase.components
|
||||||
|
|
||||||
return pydase.components.__all__
|
return [
|
||||||
|
getattr(pydase.components, cls_name) for cls_name in pydase.components.__all__
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_data_service_class_reference() -> Any:
|
||||||
|
import pydase.data_service.data_service
|
||||||
|
|
||||||
|
return getattr(pydase.data_service.data_service, "DataService")
|
||||||
|
|
||||||
|
|
||||||
def is_property_attribute(target_obj: Any, attr_name: str) -> bool:
|
def is_property_attribute(target_obj: Any, attr_name: str) -> bool:
|
||||||
|
@ -8,7 +8,8 @@ import pydase.units as u
|
|||||||
from pydase.data_service.abstract_data_service import AbstractDataService
|
from pydase.data_service.abstract_data_service import AbstractDataService
|
||||||
from pydase.utils.helpers import (
|
from pydase.utils.helpers import (
|
||||||
get_attribute_doc,
|
get_attribute_doc,
|
||||||
get_component_class_names,
|
get_component_classes,
|
||||||
|
get_data_service_class_reference,
|
||||||
parse_list_attr_and_index,
|
parse_list_attr_and_index,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -157,24 +158,26 @@ class Serializer:
|
|||||||
def _serialize_data_service(obj: AbstractDataService) -> dict[str, Any]:
|
def _serialize_data_service(obj: AbstractDataService) -> dict[str, Any]:
|
||||||
readonly = False
|
readonly = False
|
||||||
doc = get_attribute_doc(obj)
|
doc = get_attribute_doc(obj)
|
||||||
obj_type = type(obj).__name__
|
obj_type = "DataService"
|
||||||
if type(obj).__name__ not in get_component_class_names():
|
|
||||||
obj_type = "DataService"
|
|
||||||
|
|
||||||
# Get the dictionary of the base class
|
# Get component base class if any
|
||||||
base_set = set(type(obj).__base__.__dict__)
|
component_base_cls = next(
|
||||||
# Get the dictionary of the derived class
|
(cls for cls in get_component_classes() if isinstance(obj, cls)), None
|
||||||
derived_set = set(type(obj).__dict__)
|
)
|
||||||
# Get the difference between the two dictionaries
|
if component_base_cls:
|
||||||
derived_only_set = derived_set - base_set
|
obj_type = component_base_cls.__name__
|
||||||
|
|
||||||
|
# Get the set of DataService class attributes
|
||||||
|
data_service_attr_set = set(dir(get_data_service_class_reference()))
|
||||||
|
# Get the set of the object attributes
|
||||||
|
obj_attr_set = set(dir(obj))
|
||||||
|
# Get the difference between the two sets
|
||||||
|
derived_only_attr_set = obj_attr_set - data_service_attr_set
|
||||||
|
|
||||||
instance_dict = set(obj.__dict__)
|
|
||||||
# Merge the class and instance dictionaries
|
|
||||||
merged_set = derived_only_set | instance_dict
|
|
||||||
value = {}
|
value = {}
|
||||||
|
|
||||||
# Iterate over attributes, properties, class attributes, and methods
|
# Iterate over attributes, properties, class attributes, and methods
|
||||||
for key in sorted(merged_set):
|
for key in sorted(derived_only_attr_set):
|
||||||
if key.startswith("_"):
|
if key.startswith("_"):
|
||||||
continue # Skip attributes that start with underscore
|
continue # Skip attributes that start with underscore
|
||||||
|
|
||||||
|
@ -294,6 +294,30 @@ def test_dict_serialization() -> None:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_derived_data_service_serialization() -> None:
|
||||||
|
class BaseService(pydase.DataService):
|
||||||
|
class_attr = 1337
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self._name = "Service"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
|
def name(self, value: str) -> None:
|
||||||
|
self._name = value
|
||||||
|
|
||||||
|
class DerivedService(BaseService):
|
||||||
|
...
|
||||||
|
|
||||||
|
base_instance = BaseService()
|
||||||
|
service_instance = DerivedService()
|
||||||
|
assert service_instance.serialize() == base_instance.serialize()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def setup_dict():
|
def setup_dict():
|
||||||
class MySubclass(pydase.DataService):
|
class MySubclass(pydase.DataService):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user