SerializerComponent.encode() and nested encoding go straight to SerializerBase._convert_to_dict.
They never call the object's as_dict() or to_dict().
As a result:
Descriptors: DescriptorNumber.as_dict adds value, unit, variance and __serializer_id, and Parameter.as_dict adds _dependency_string, _dependency_map_serializer_ids and _independent.
None of these overrides runs when a descriptor is encoded directly or as part of a model, so a dependent Parameter may lose its dependency information.
NewBase: when the model itself has no display_name, NewBase.to_dict adds display_name to skip. skip is passed down to the children, so they lose their explicit labels: Model(display_name=None).to_dict()['width'] has no display_name even though the child was given 'Width (m)'.
We should move these overrides to _REDIRECT for single attributes, or an object hook in _convert_to_dict for added fields.
#308 already does this for the descriptors' display_name.
To reproduce:
from easyscience.base_classes import ModelBase
from easyscience.variable import Parameter
# 1. encode() skips Parameter.as_dict(), so the dependency is lost
a = Parameter(2, unit='m')
b = Parameter.from_dependency(dependency_expression='2 * a', dependency_map={'a': a})
print('_dependency_string' in b.as_dict()) # True
print('_dependency_string' in b.encode()) # False
print(Parameter.from_dict(b.encode(skip=['unique_name'])).independent) # True: no longer depends on `a`
# 2. An unlabeled NewBase model drops its children's explicit labels
class Model(ModelBase):
def __init__(self, width=None, display_name=None):
super().__init__(display_name=display_name)
self._width = Parameter(2, display_name='my_width')
@property
def width(self):
return self._width
print(Model(display_name='My model').to_dict()['width'].get('display_name')) # my_width
print(Model().to_dict()['width'].get('display_name')) # None: label lost
SerializerComponent.encode()and nested encoding go straight toSerializerBase._convert_to_dict.They never call the object's as_dict() or to_dict().
As a result:
Descriptors:
DescriptorNumber.as_dictaddsvalue,unit,varianceand__serializer_id, andParameter.as_dictadds_dependency_string,_dependency_map_serializer_idsand_independent.None of these overrides runs when a descriptor is encoded directly or as part of a model, so a dependent Parameter may lose its dependency information.
NewBase: when the model itself has no display_name,NewBase.to_dictadds display_name toskip.skipis passed down to the children, so they lose their explicit labels:Model(display_name=None).to_dict()['width']has nodisplay_nameeven though the child was given 'Width (m)'.We should move these overrides to
_REDIRECTfor single attributes, or an object hook in_convert_to_dictfor added fields.#308 already does this for the descriptors' display_name.
To reproduce: