diff --git a/docs/docs/api-reference/index.md b/docs/docs/api-reference/index.md index 4bd6f561..1a035c29 100644 --- a/docs/docs/api-reference/index.md +++ b/docs/docs/api-reference/index.md @@ -8,8 +8,8 @@ This section contains the reference detailing the functions and modules available in EasyScience. - [base_classes](base_classes.md) – Core abstract and helper base - classes used to build EasyScience objects (e.g. `ObjBase`, - `ModelBase`). + classes used to build EasyScience objects (e.g. `NewBase`, + `ModelBase`, `EasyList`). - [fitting](fitting.md) – Fitting utilities and interfaces, including `Fitter` and available minimizers. - [global_object](global_object.md) – Global singleton providing shared @@ -23,4 +23,5 @@ available in EasyScience. - [utils](utils.md) – Miscellaneous utility functions and helpers (class tools, decorators, type helpers). - [variable](variable.md) – Descriptor types and variable abstractions - (e.g. `DescriptorNumber`, `Parameter`, `DescriptorArray`). + (e.g. `DescriptorNumber`, `Parameter`, `DescriptorArray`). All of them + are `NewBase` objects, serialized with `to_dict`/`from_dict`. diff --git a/src/easyscience/base_classes/based_base.py b/src/easyscience/base_classes/based_base.py index 4044fb7b..7070f93a 100644 --- a/src/easyscience/base_classes/based_base.py +++ b/src/easyscience/base_classes/based_base.py @@ -239,11 +239,11 @@ def __dir__(self) -> Iterable[str]: def __copy__(self) -> BasedBase: """Return a copy of the object.""" - temp = self.as_dict(skip=['unique_name']) + temp = self.to_dict(skip=['unique_name']) new_obj = self.__class__.from_dict(temp) return new_obj - def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: + def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: """ Convert an object into a full dictionary using ``SerializerDict``. This is a shortcut for @@ -266,4 +266,4 @@ def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: skip = [] if 'unique_name' not in skip: skip.append('unique_name') - return super().as_dict(skip=skip) + return super().to_dict(skip=skip) diff --git a/src/easyscience/base_classes/easy_list.py b/src/easyscience/base_classes/easy_list.py index 23ac673d..f1f60acd 100644 --- a/src/easyscience/base_classes/easy_list.py +++ b/src/easyscience/base_classes/easy_list.py @@ -45,7 +45,10 @@ def __init__( Initial items to add to the list. protected_types : list[Type[NewBase]] | Type[NewBase] | None, default=None Types that are allowed in the list. Can be a single NewBase - subclass or a list of them. If None,. By default, None. + subclass or a list of them. If None, any ``NewBase`` object + is accepted, including descriptors and parameters. Note that + only ``ModelBase`` items contribute to ``get_all_variables`` + and hence to fitting. By default, None. unique_name : Optional[str], default=None Optional unique name for the list. By default, None. display_name : Optional[str], default=None diff --git a/src/easyscience/base_classes/new_base.py b/src/easyscience/base_classes/new_base.py index 115677f1..106e6f3c 100644 --- a/src/easyscience/base_classes/new_base.py +++ b/src/easyscience/base_classes/new_base.py @@ -137,6 +137,14 @@ def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: Dict[str, Any] Encoded object containing all information to reform an EasyScience object. + + Notes + ----- + A ``unique_name`` that was generated automatically is not + written; only an explicitly supplied one is, so that a + deserialized object gets a fresh name instead of clashing with + the original. Likewise ``display_name`` is omitted when it is + ``None``. Pass ``skip`` to drop further fields. """ serializer = SerializerBase() if skip is None: diff --git a/src/easyscience/fitting/multi_fitter.py b/src/easyscience/fitting/multi_fitter.py index dbafa3b6..55933d4e 100644 --- a/src/easyscience/fitting/multi_fitter.py +++ b/src/easyscience/fitting/multi_fitter.py @@ -6,6 +6,7 @@ import numpy as np from ..base_classes import EasyList +from ..base_classes import ModelBase from .fitter import Fitter from .minimizers import FitResults @@ -38,7 +39,7 @@ def __init__( # Aggregate the fit objects so a single object can be sent to Fitter. # *-unpacking keeps any sequence (list, tuple, etc) working, as the # old CollectionBase container did. - self._fit_objects = EasyList(*fit_objects) + self._fit_objects = EasyList(*fit_objects, protected_types=ModelBase) self._fit_functions = list(fit_functions) # Initialize with the first of the fit_functions, without this it is # not possible to change the fitting engine. With no functions given diff --git a/src/easyscience/io/serializer_base.py b/src/easyscience/io/serializer_base.py index 5d9b0e51..26b1ad72 100644 --- a/src/easyscience/io/serializer_base.py +++ b/src/easyscience/io/serializer_base.py @@ -215,13 +215,13 @@ def runner(o): err = False if err: raise NotImplementedError( - 'Unable to automatically determine as_dict ' + 'Unable to automatically determine to_dict ' 'format from class. MSONAble requires all ' 'args to be present as either self.argname or ' 'self._argname, and kwargs to be present under' 'a self.kwargs variable to automatically ' 'determine the dict format. Alternatively, ' - 'you can implement both as_dict and from_dict.' + 'you can implement both to_dict and from_dict.' ) d[c] = self._recursive_encoder( a, skip=skip, encoder=self, full_encode=full_encode, **kwargs diff --git a/src/easyscience/io/serializer_component.py b/src/easyscience/io/serializer_component.py index 10c5f7aa..9ef079ab 100644 --- a/src/easyscience/io/serializer_component.py +++ b/src/easyscience/io/serializer_component.py @@ -26,7 +26,7 @@ class SerializerComponent: """ def __deepcopy__(self, memo): - return self.from_dict(self.as_dict()) + return self.from_dict(self.to_dict()) def encode( self, skip: Optional[List[str]] = None, encoder: Optional[SerializerBase] = None, **kwargs @@ -82,7 +82,7 @@ def decode(cls, obj: Any, decoder: Optional[SerializerBase] = None) -> Any: decoder = SerializerDict return decoder.decode(obj) - def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: + def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: """ Convert an EasyScience object into a full dictionary using ``SerializerDict``. This is a shortcut for diff --git a/src/easyscience/job/theoreticalmodel.py b/src/easyscience/job/theoreticalmodel.py index 3fa87e50..3cddec7e 100644 --- a/src/easyscience/job/theoreticalmodel.py +++ b/src/easyscience/job/theoreticalmodel.py @@ -18,6 +18,6 @@ def __init__(self, name: str, *args, **kwargs): def __str__(self): raise NotImplementedError('Copy not implemented') - def as_dict(self, skip: list = []) -> dict: - this_dict = super().as_dict(skip=skip) + def to_dict(self, skip: list = []) -> dict: + this_dict = super().to_dict(skip=skip) return this_dict diff --git a/src/easyscience/variable/descriptor_any_type.py b/src/easyscience/variable/descriptor_any_type.py index 157117d8..06f52dbf 100644 --- a/src/easyscience/variable/descriptor_any_type.py +++ b/src/easyscience/variable/descriptor_any_type.py @@ -34,7 +34,6 @@ def __init__( description: Optional[str] = None, url: Optional[str] = None, display_name: Optional[str] = None, - parent: Optional[Any] = None, ): """ Constructor for the DescriptorAnyType class. @@ -42,9 +41,9 @@ def __init__( param name: Name of the descriptor param value: Value of the descriptor param description: Description of the descriptor param url: URL of the descriptor param display_name: Display - name of the descriptor param parent: Parent of the descriptor .. - note:: Undo/Redo functionality is implemented for the attributes - ``variance``, ``error``, ``unit`` and ``value``. + name of the descriptor .. note:: Undo/Redo functionality is + implemented for the attributes ``variance``, ``error``, + ``unit`` and ``value``. """ self._value = value @@ -55,7 +54,6 @@ def __init__( description=description, url=url, display_name=display_name, - parent=parent, ) @property @@ -99,7 +97,7 @@ def __repr__(self) -> str: return f"<{self.__class__.__name__} '{self._name}': {value_repr}>" - def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - raw_dict = super().as_dict(skip=skip) + def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: + raw_dict = super().to_dict(skip=skip) raw_dict['value'] = self._value return raw_dict diff --git a/src/easyscience/variable/descriptor_array.py b/src/easyscience/variable/descriptor_array.py index 35f1c022..de6c0dac 100644 --- a/src/easyscience/variable/descriptor_array.py +++ b/src/easyscience/variable/descriptor_array.py @@ -42,7 +42,6 @@ def __init__( description: Optional[str] = None, url: Optional[str] = None, display_name: Optional[str] = None, - parent: Optional[Any] = None, dimensions: Optional[list] = None, ): """ @@ -52,11 +51,11 @@ def __init__( the values of the descriptor param unit: Unit of the descriptor param variance: Variances of the descriptor param description: Description of the descriptor param url: URL of the descriptor - param display_name: Display name of the descriptor param parent: - Parent of the descriptor param dimensions: List of dimensions to - pass to scipp. Will be autogenerated if not supplied. .. note:: - Undo/Redo functionality is implemented for the attributes - ``variance``, ``error``, ``unit`` and ``value``. + param display_name: Display name of the descriptor param + dimensions: List of dimensions to pass to scipp. Will be + autogenerated if not supplied. .. note:: Undo/Redo functionality + is implemented for the attributes ``variance``, ``error``, + ``unit`` and ``value``. """ if not isinstance(value, (list, np.ndarray)): @@ -104,7 +103,6 @@ def __init__( description=description, url=url, display_name=display_name, - parent=parent, ) # Call convert_unit during initialization to ensure that the unit has no numbers in it, and to ensure unit consistency. @@ -472,14 +470,14 @@ def __repr__(self) -> str: string = string.replace('\n', ',') return string - def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: + def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: """ Dict representation of the current DescriptorArray. The dict contains the value, unit and variances, in addition to the properties of DescriptorBase. """ - raw_dict = super().as_dict(skip=skip) + raw_dict = super().to_dict(skip=skip) raw_dict['value'] = self._array.values raw_dict['unit'] = str(self._array.unit) raw_dict['variance'] = self._array.variances diff --git a/src/easyscience/variable/descriptor_base.py b/src/easyscience/variable/descriptor_base.py index ba7198bc..e2214d3a 100644 --- a/src/easyscience/variable/descriptor_base.py +++ b/src/easyscience/variable/descriptor_base.py @@ -5,14 +5,16 @@ import abc from typing import Any +from typing import Dict +from typing import List from typing import Optional from easyscience import global_object +from easyscience.base_classes.new_base import NewBase from easyscience.global_object.undo_redo import property_stack -from easyscience.io import SerializerComponent -class DescriptorBase(SerializerComponent, metaclass=abc.ABCMeta): +class DescriptorBase(NewBase, metaclass=abc.ABCMeta): """ This is the base of all variable descriptions for models. @@ -29,7 +31,7 @@ class DescriptorBase(SerializerComponent, metaclass=abc.ABCMeta): _global_object = global_object # Used by serializer - _REDIRECT = {'parent': None} + _REDIRECT = {} def __init__( self, @@ -38,7 +40,6 @@ def __init__( description: Optional[str] = None, url: Optional[str] = None, display_name: Optional[str] = None, - parent: Optional[Any] = None, ): """ This is the base of variables for models. @@ -63,9 +64,6 @@ def __init__( Lookup url for documentation/information. By default, None. display_name : Optional[str], default=None A pretty name for the object. By default, None. - parent : Optional[Any], default=None - The object which this descriptor is attached to. By default, - None. Raises ------ @@ -74,17 +72,12 @@ def __init__( has an invalid type. """ - if unique_name is None: - unique_name = global_object.generate_unique_name(self.__class__.__name__) - self._unique_name = unique_name - if not isinstance(name, str): raise TypeError('Name must be a string') - self._name: str = name - if display_name is not None and not isinstance(display_name, str): - raise TypeError('Display name must be a string or None') - self._display_name: str = display_name + super().__init__(unique_name=unique_name, display_name=display_name) + + self._name: str = name if description is not None and not isinstance(description, str): raise TypeError('Description must be a string or None') @@ -98,13 +91,6 @@ def __init__( url = '' self._url: str = url - # Let the collective know we've been assimilated - self._parent = parent - global_object.map.add_vertex(self, obj_type='created') - # Make the connection between self and parent - if parent is not None: - global_object.map.add_edge(parent, self) - @property def name(self) -> str: """ @@ -142,6 +128,9 @@ def display_name(self) -> str: """ Get a pretty display name. + Unlike ``NewBase`` the fallback is the ``name`` of the + descriptor rather than its ``unique_name``. + Returns ------- str @@ -234,40 +223,6 @@ def url(self, url: Optional[str]) -> None: raise TypeError('url must be a string') self._url = url - @property - def unique_name(self) -> str: - """ - Get the unique name of this object. - - Returns - ------- - str - Unique name of this object. - """ - return self._unique_name - - @unique_name.setter - def unique_name(self, new_unique_name: str): - """ - Set a new unique name for the object. - - The old name is still kept in the map. - - Parameters - ---------- - new_unique_name : str - New unique name for the object. - - Raises - ------ - TypeError - If ``new_unique_name`` is not a string. - """ - if not isinstance(new_unique_name, str): - raise TypeError('Unique name has to be a string.') - self._unique_name = new_unique_name - global_object.map.add_vertex(self) - @property @abc.abstractmethod def value(self) -> Any: @@ -281,9 +236,3 @@ def value(self, value: Any) -> None: @abc.abstractmethod def __repr__(self) -> str: """Return printable representation of the object.""" - - def __copy__(self) -> DescriptorBase: - """Return a copy of the object.""" - temp = self.as_dict(skip=['unique_name']) - new_obj = self.__class__.from_dict(temp) - return new_obj diff --git a/src/easyscience/variable/descriptor_bool.py b/src/easyscience/variable/descriptor_bool.py index 05a09d9d..874509fc 100644 --- a/src/easyscience/variable/descriptor_bool.py +++ b/src/easyscience/variable/descriptor_bool.py @@ -3,7 +3,6 @@ from __future__ import annotations -from typing import Any from typing import Optional from easyscience.global_object.undo_redo import property_stack @@ -22,7 +21,6 @@ def __init__( description: Optional[str] = None, url: Optional[str] = None, display_name: Optional[str] = None, - parent: Optional[Any] = None, ): if not isinstance(value, bool): raise ValueError(f'{value=} must be type bool') @@ -32,7 +30,6 @@ def __init__( description=description, url=url, display_name=display_name, - parent=parent, ) if not isinstance(value, bool): raise TypeError(f'{value=} must be type bool') diff --git a/src/easyscience/variable/descriptor_number.py b/src/easyscience/variable/descriptor_number.py index 5bcbcb0d..c2a97262 100644 --- a/src/easyscience/variable/descriptor_number.py +++ b/src/easyscience/variable/descriptor_number.py @@ -65,7 +65,6 @@ def __init__( description: Optional[str] = None, url: Optional[str] = None, display_name: Optional[str] = None, - parent: Optional[Any] = None, **kwargs: Any, # Additional keyword arguments (used for (de)serialization) ): """ @@ -75,9 +74,9 @@ def __init__( descriptor param unit: Unit of the descriptor param variance: Variance of the descriptor param description: Description of the descriptor param url: URL of the descriptor param display_name: - Display name of the descriptor param parent: Parent of the - descriptor .. note:: Undo/Redo functionality is implemented for - the attributes ``variance``, ``error``, ``unit`` and ``value``. + Display name of the descriptor .. note:: Undo/Redo functionality + is implemented for the attributes ``variance``, ``error``, + ``unit`` and ``value``. """ self._observers: List[DescriptorNumber] = [] @@ -107,7 +106,6 @@ def __init__( description=description, url=url, display_name=display_name, - parent=parent, ) # Call convert_unit during initialization to ensure that the unit has no numbers in it, and to ensure unit consistency. @@ -444,8 +442,8 @@ def __repr__(self) -> str: return string # return f"<{class_name} '{obj_name}': {obj_value:0.04f}{obj_unit}>" - def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: - raw_dict = super().as_dict(skip=skip) + def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: + raw_dict = super().to_dict(skip=skip) raw_dict['value'] = self._scalar.value raw_dict['unit'] = str(self._scalar.unit) raw_dict['variance'] = self._scalar.variance diff --git a/src/easyscience/variable/descriptor_str.py b/src/easyscience/variable/descriptor_str.py index 5e74e786..e4b28823 100644 --- a/src/easyscience/variable/descriptor_str.py +++ b/src/easyscience/variable/descriptor_str.py @@ -3,7 +3,6 @@ from __future__ import annotations -from typing import Any from typing import Optional from easyscience.global_object.undo_redo import property_stack @@ -22,7 +21,6 @@ def __init__( description: Optional[str] = None, url: Optional[str] = None, display_name: Optional[str] = None, - parent: Optional[Any] = None, ): super().__init__( name=name, @@ -30,7 +28,6 @@ def __init__( description=description, url=url, display_name=display_name, - parent=parent, ) if not isinstance(value, str): raise ValueError(f'{value=} must be type str') diff --git a/src/easyscience/variable/parameter.py b/src/easyscience/variable/parameter.py index 3ec654f7..35654ed5 100644 --- a/src/easyscience/variable/parameter.py +++ b/src/easyscience/variable/parameter.py @@ -52,7 +52,6 @@ def __init__( url: Optional[str] = None, display_name: Optional[str] = None, callback: property = property(), - parent: Optional[Any] = None, **kwargs: Any, # Additional keyword arguments (used for (de)serialization) ): """ @@ -92,9 +91,6 @@ def __init__( callback : property, default=property() Callback used to synchronize the parameter with an external model. - parent : Optional[Any], default=None - The object which is the parent to this one. By default, - None. **kwargs : Any Additional keyword arguments used during serialization. @@ -147,7 +143,6 @@ def __init__( description=description, url=url, display_name=display_name, - parent=parent, **kwargs, # Additional keyword arguments (used for (de)serialization) ) @@ -903,11 +898,11 @@ def free(self) -> bool: def free(self, value: bool) -> None: self.fixed = not value - def as_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: + def to_dict(self, skip: Optional[List[str]] = None) -> Dict[str, Any]: """ - Overwrite the as_dict method to handle dependency information. + Overwrite the to_dict method to handle dependency information. """ - raw_dict = super().as_dict(skip=skip) + raw_dict = super().to_dict(skip=skip) # Add dependency information for dependent parameters if not self._independent: diff --git a/tests/unit/base_classes/test_collection_base.py b/tests/unit/base_classes/test_collection_base.py index 732c3acf..8886a474 100644 --- a/tests/unit/base_classes/test_collection_base.py +++ b/tests/unit/base_classes/test_collection_base.py @@ -305,7 +305,7 @@ def test_CollectionBase_dir(cls): 'append', 'unique_name', 'index', - 'as_dict', + 'to_dict', 'clear', 'extend', 'encode', @@ -327,11 +327,11 @@ def test_CollectionBase_dir(cls): @pytest.mark.parametrize('cls', class_constructors) -def test_CollectionBase_as_dict(cls): +def test_CollectionBase_to_dict(cls): name = 'testing' kwargs = {'p1': DescriptorNumber('par1', 1)} obj = cls(name, **kwargs) - d = obj.as_dict() + d = obj.to_dict() def check_dict(dict_1: dict, dict_2: dict): keys_1 = list(dict_1.keys()) @@ -423,7 +423,7 @@ def test_CollectionBase_iterator_dict(cls): l_object = [p1, p2, p3, p4] obj = cls(name, *l_object) - d = obj.as_dict() + d = obj.to_dict() global_object.map._clear() obj2 = cls.from_dict(d) diff --git a/tests/unit/base_classes/test_obj_base.py b/tests/unit/base_classes/test_obj_base.py index 5eb1b2ea..723d617f 100644 --- a/tests/unit/base_classes/test_obj_base.py +++ b/tests/unit/base_classes/test_obj_base.py @@ -141,11 +141,11 @@ def test_ObjBase_fit_objects(setup_pars: dict): pass -def test_ObjBase_as_dict(clear, setup_pars: dict): +def test_ObjBase_to_dict(clear, setup_pars: dict): name = setup_pars['name'] del setup_pars['name'] obj = ObjBase(name, **setup_pars) - obtained = obj.as_dict() + obtained = obj.to_dict() assert isinstance(obtained, dict) expected = { '@module': 'easyscience.legacy.obj_base', @@ -238,7 +238,7 @@ def test_ObjBase_dict_roundtrip(clear, setup_pars: dict): name = setup_pars['name'] del setup_pars['name'] obj = ObjBase(name, **setup_pars, unique_name='special_name') - obj_dict = obj.as_dict() + obj_dict = obj.to_dict() global_object.map._clear() @@ -246,7 +246,7 @@ def test_ObjBase_dict_roundtrip(clear, setup_pars: dict): new_obj = ObjBase.from_dict(obj_dict) # Expect - new_obj_dict = new_obj.as_dict() + new_obj_dict = new_obj.to_dict() assert obj_dict == new_obj_dict @@ -257,7 +257,7 @@ def test_ObjBase_dir(setup_pars): expected = [ 'encode', 'decode', - 'as_dict', + 'to_dict', 'des1', 'des2', 'from_dict', diff --git a/tests/unit/fitting/test_multi_fitter.py b/tests/unit/fitting/test_multi_fitter.py index 1960affe..3af44358 100644 --- a/tests/unit/fitting/test_multi_fitter.py +++ b/tests/unit/fitting/test_multi_fitter.py @@ -259,7 +259,9 @@ def test_rejects_foreign_object(self): MultiFitter([Line(1.0, 0.5), 'not a model'], [None, None]) def test_rejects_bare_parameter(self): - """CollectionBase accepted bare parameters; EasyList does not.""" + """CollectionBase accepted bare parameters; the ModelBase-gated + EasyList does not (a Parameter is a NewBase, but EasyList only + harvests parameters from ModelBase members).""" model = Line(1.0, 0.5) with pytest.raises(TypeError, match='Items must be one of'): MultiFitter([model, Parameter('p', 1.0)], [model, None]) diff --git a/tests/unit/global_object/test_integration_comprehensive.py b/tests/unit/global_object/test_integration_comprehensive.py index 61268954..541c9e46 100644 --- a/tests/unit/global_object/test_integration_comprehensive.py +++ b/tests/unit/global_object/test_integration_comprehensive.py @@ -361,8 +361,8 @@ def test_serialization_integration_with_global_state(self, clear_all): original_vertex_count = len(global_obj.map.vertices()) # When - Serialize objects - param_dict = param.as_dict() - obj_dict = obj.as_dict() + param_dict = param.to_dict() + obj_dict = obj.to_dict() # Clear global state global_obj.map._clear() diff --git a/tests/unit/io/test_serializer_base.py b/tests/unit/io/test_serializer_base.py index c3c8dd21..550c4d75 100644 --- a/tests/unit/io/test_serializer_base.py +++ b/tests/unit/io/test_serializer_base.py @@ -471,7 +471,7 @@ def __init__(self, name: str, missing_param: str = 'default'): obj = MockObjMissingAttrs('test') - with pytest.raises(NotImplementedError, match='Unable to automatically determine as_dict'): + with pytest.raises(NotImplementedError, match='Unable to automatically determine to_dict'): serializer._convert_to_dict(obj) def test_convert_to_dict_with_kwargs_attribute(self, serializer, clear): diff --git a/tests/unit/io/test_serializer_component.py b/tests/unit/io/test_serializer_component.py index c4e21f49..a90e364c 100644 --- a/tests/unit/io/test_serializer_component.py +++ b/tests/unit/io/test_serializer_component.py @@ -71,7 +71,7 @@ def check_dict(check, item): @pytest.mark.parametrize(**skip_dict) @pytest.mark.parametrize(**dp_param_dict) -def test_variable_as_dict_methods(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): +def test_variable_to_dict_methods(dp_kwargs: dict, dp_cls: Type[DescriptorNumber], skip): data_dict = {k: v for k, v in dp_kwargs.items() if k[0] != '@'} obj = dp_cls(**data_dict) @@ -84,7 +84,7 @@ def test_variable_as_dict_methods(dp_kwargs: dict, dp_cls: Type[DescriptorNumber if not isinstance(skip, list): skip = [skip] - enc = obj.as_dict(skip=skip) + enc = obj.to_dict(skip=skip) expected_keys = set(dp_kwargs.keys()) obtained_keys = set(enc.keys()) diff --git a/tests/unit/io/test_serializer_dict.py b/tests/unit/io/test_serializer_dict.py index 1ddf21ef..1b37fae9 100644 --- a/tests/unit/io/test_serializer_dict.py +++ b/tests/unit/io/test_serializer_dict.py @@ -50,7 +50,7 @@ def test_variable_SerializerDict(dp_kwargs: dict, dp_cls: Type[DescriptorNumber] if not isinstance(skip, list): skip = [skip] - enc = obj.encode(skip=skip, encoder=SerializerDict) + enc = SerializerDict().encode(obj, skip=skip) expected_keys = set(dp_kwargs.keys()) obtained_keys = set(enc.keys()) @@ -71,9 +71,9 @@ def test_variable_SerializerDict_decode(dp_kwargs: dict, dp_cls: Type[Descriptor obj = dp_cls(**data_dict) - enc = obj.encode(encoder=SerializerDict) + enc = SerializerDict().encode(obj) global_object.map._clear() - dec = dp_cls.decode(enc, decoder=SerializerDict) + dec = SerializerDict.decode(enc) for k in data_dict.keys(): if hasattr(obj, k) and hasattr(dec, k): @@ -88,7 +88,7 @@ def test_variable_SerializerDict_from_dict(dp_kwargs: dict, dp_cls: Type[Descrip obj = dp_cls(**data_dict) - enc = obj.encode(encoder=SerializerDict) + enc = SerializerDict().encode(obj) global_object.map._clear() dec = dp_cls.from_dict(enc) @@ -106,7 +106,7 @@ def test_group_encode(): from easyscience.base_classes import CollectionBase b = CollectionBase('test', d0, d1) - d = b.as_dict() + d = b.to_dict() assert isinstance(d['data'], list) @@ -117,5 +117,5 @@ def test_group_encode2(): from easyscience.base_classes import CollectionBase b = ObjBase('outer', b=CollectionBase('test', d0, d1)) - d = b.as_dict() + d = b.to_dict() assert isinstance(d['b'], dict) diff --git a/tests/unit/variable/test_descriptor_any_type.py b/tests/unit/variable/test_descriptor_any_type.py index 5dc28b58..12db376a 100644 --- a/tests/unit/variable/test_descriptor_any_type.py +++ b/tests/unit/variable/test_descriptor_any_type.py @@ -17,7 +17,6 @@ def descriptor(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor diff --git a/tests/unit/variable/test_descriptor_array.py b/tests/unit/variable/test_descriptor_array.py index 73bb0857..36ede2e3 100644 --- a/tests/unit/variable/test_descriptor_array.py +++ b/tests/unit/variable/test_descriptor_array.py @@ -23,7 +23,6 @@ def descriptor(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor @@ -37,7 +36,6 @@ def descriptor_dimensionless(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor @@ -67,7 +65,6 @@ def test_init_sc_unit(self): description='description', url='url', display_name='display_name', - parent=None, ) # Expect @@ -86,7 +83,6 @@ def test_init_sc_unit_unknown(self): description='description', url='url', display_name='display_name', - parent=None, ) @pytest.mark.parametrize('value', [True, 'string']) @@ -103,7 +99,6 @@ def test_init_value_type_exception(self, value): description='description', url='url', display_name='display_name', - parent=None, ) def test_init_variance_exception(self): @@ -119,7 +114,6 @@ def test_init_variance_exception(self): description='description', url='url', display_name='display_name', - parent=None, ) # test from_scipp @@ -1481,7 +1475,6 @@ def test_negation(self, descriptor): description='description', url='url', display_name='display_name', - parent=None, ) assert type(result) == DescriptorArray assert result.name == result.unique_name @@ -1500,7 +1493,6 @@ def test_abs(self, descriptor): description='description', url='url', display_name='display_name', - parent=None, ) # Then diff --git a/tests/unit/variable/test_descriptor_base.py b/tests/unit/variable/test_descriptor_base.py index 24c342dc..9661afa3 100644 --- a/tests/unit/variable/test_descriptor_base.py +++ b/tests/unit/variable/test_descriptor_base.py @@ -4,6 +4,10 @@ import pytest from easyscience import global_object +from easyscience.base_classes import EasyList +from easyscience.base_classes import NewBase +from easyscience.io import SerializerComponent +from easyscience.variable import DescriptorNumber from easyscience.variable.descriptor_base import DescriptorBase @@ -19,7 +23,6 @@ def descriptor(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor @@ -40,7 +43,6 @@ def test_init_name_type_error(self, name): description='description', url='url', display_name='display_name', - parent=None, ) @pytest.mark.parametrize( @@ -56,7 +58,6 @@ def test_init_display_name_type_error(self, display_name): description='description', url='url', display_name=display_name, - parent=None, ) @pytest.mark.parametrize( @@ -72,7 +73,6 @@ def test_init_description_type_error(self, description): description=description, url='url', display_name='display_name', - parent=None, ) @pytest.mark.parametrize( @@ -88,7 +88,6 @@ def test_init_url_type_error(self, url): description='description', url=url, display_name='display_name', - parent=None, ) def test_init(self, descriptor: DescriptorBase): diff --git a/tests/unit/variable/test_descriptor_bool.py b/tests/unit/variable/test_descriptor_bool.py index 3c181f0e..48372485 100644 --- a/tests/unit/variable/test_descriptor_bool.py +++ b/tests/unit/variable/test_descriptor_bool.py @@ -16,7 +16,6 @@ def descriptor(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor @@ -45,7 +44,6 @@ def test_init_bool_value_type_exception(self, bool_value): description='description', url='url', display_name='display_name', - parent=None, ) def test_value(self, descriptor: DescriptorBool): diff --git a/tests/unit/variable/test_descriptor_number.py b/tests/unit/variable/test_descriptor_number.py index 6abd3029..3d3f7331 100644 --- a/tests/unit/variable/test_descriptor_number.py +++ b/tests/unit/variable/test_descriptor_number.py @@ -20,7 +20,6 @@ def descriptor(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor @@ -51,7 +50,6 @@ def test_init_sc_unit(self): description='description', url='url', display_name='display_name', - parent=None, ) # Expect @@ -70,7 +68,6 @@ def test_init_sc_unit_unknown(self): description='description', url='url', display_name='display_name', - parent=None, ) @pytest.mark.parametrize('value', [True, 'string']) @@ -87,7 +84,6 @@ def test_init_value_type_exception(self, value): description='description', url='url', display_name='display_name', - parent=None, ) def test_init_variance_exception(self): @@ -104,7 +100,6 @@ def test_init_variance_exception(self): description='description', url='url', display_name='display_name', - parent=None, ) # test from_scipp diff --git a/tests/unit/variable/test_descriptor_str.py b/tests/unit/variable/test_descriptor_str.py index 46acc847..36b721c1 100644 --- a/tests/unit/variable/test_descriptor_str.py +++ b/tests/unit/variable/test_descriptor_str.py @@ -16,7 +16,6 @@ def descriptor(self): description='description', url='url', display_name='display_name', - parent=None, ) return descriptor @@ -44,7 +43,6 @@ def test_init_string_type_exception(self, string): description='description', url='url', display_name='display_name', - parent=None, ) def test_value(self, descriptor: DescriptorStr): diff --git a/tests/unit/variable/test_parameter.py b/tests/unit/variable/test_parameter.py index 1ac05b45..5376edf3 100644 --- a/tests/unit/variable/test_parameter.py +++ b/tests/unit/variable/test_parameter.py @@ -29,7 +29,6 @@ def parameter(self) -> Parameter: url='url', display_name='display_name', callback=self.mock_callback, - parent=None, ) return parameter @@ -96,7 +95,6 @@ def test_init_value_min_exception(self): url='url', display_name='display_name', callback=mock_callback, - parent=None, ) def test_init_value_max_exception(self): @@ -117,7 +115,6 @@ def test_init_value_max_exception(self): url='url', display_name='display_name', callback=mock_callback, - parent=None, ) def test_make_dependent_on(self, normal_parameter: Parameter): diff --git a/tests/unit/variable/test_parameter_dependency_serialization.py b/tests/unit/variable/test_parameter_dependency_serialization.py index 62feb5f3..98daed45 100644 --- a/tests/unit/variable/test_parameter_dependency_serialization.py +++ b/tests/unit/variable/test_parameter_dependency_serialization.py @@ -40,7 +40,7 @@ def test_independent_parameter_serialization(self, clear_global_map): param = Parameter(name='test', value=5.0, unit='m', min=0, max=10) # Serialize - serialized = param.as_dict() + serialized = param.to_dict() # Should not contain dependency fields assert '_dependency_string' not in serialized @@ -68,7 +68,7 @@ def test_dependent_parameter_serialization(self, clear_global_map): ) # Serialize dependent parameter - serialized = b.as_dict() + serialized = b.to_dict() # Should contain dependency information assert serialized['_dependency_string'] == '2 * a' @@ -106,7 +106,7 @@ def test_dependency_resolution_after_deserialization(self, clear_global_map): assert c.value == 5.0 # 2 + 3 # Serialize all parameters - params_data = {'a': a.as_dict(), 'b': b.as_dict(), 'c': c.as_dict()} + params_data = {'a': a.to_dict(), 'b': b.to_dict(), 'c': c.to_dict()} # Clear and deserialize (manual approach) global_object.map._clear() @@ -151,7 +151,7 @@ def test_dependency_resolution_after_deserialization_desired_unit(self, clear_gl assert c.unit == 'cm' # Serialize all parameters - params_data = {'a': a.as_dict(), 'b': b.as_dict(), 'c': c.as_dict()} + params_data = {'a': a.to_dict(), 'b': b.to_dict(), 'c': c.to_dict()} # Clear and deserialize (manual approach) global_object.map._clear() @@ -192,8 +192,8 @@ def test_unique_name_dependency_serialization(self, clear_global_map): ) # Serialize both parameters - a_serialized = a.as_dict() - b_serialized = b.as_dict() + a_serialized = a.to_dict() + b_serialized = b.to_dict() # Should contain unique name mapping assert b_serialized['_dependency_string'] == '2 * __Parameter_0__' @@ -237,9 +237,9 @@ def test_json_serialization_roundtrip(self, clear_global_map): # Serialize to JSON params_data = { - 'length': length.as_dict(), - 'width': width.as_dict(), - 'area': area.as_dict(), + 'length': length.to_dict(), + 'width': width.to_dict(), + 'area': area.to_dict(), } json_str = json.dumps(params_data, default=str) @@ -281,7 +281,7 @@ def test_multiple_dependent_parameters(self, clear_global_map): assert z.value == 6.0 # 4 + 2 # Serialize all - params_data = {'x': x.as_dict(), 'y': y.as_dict(), 'z': z.as_dict()} + params_data = {'x': x.to_dict(), 'y': y.to_dict(), 'z': z.to_dict()} # Deserialize and resolve global_object.map._clear() @@ -319,7 +319,7 @@ def test_dependency_with_descriptor_number(self, clear_global_map): # Then # Serialize all - params_data = {'x': x.as_dict(), 'y': y.as_dict(), 'z': z.as_dict()} + params_data = {'x': x.to_dict(), 'y': y.to_dict(), 'z': z.to_dict()} # Deserialize and resolve global_object.map._clear() new_params = {} @@ -350,7 +350,7 @@ def test_get_parameters_with_pending_dependencies(self, clear_global_map): ) # Serialize and deserialize - params_data = {'a': a.as_dict(), 'b': b.as_dict()} + params_data = {'a': a.to_dict(), 'b': b.to_dict()} global_object.map._clear() new_params = {} for name, data in params_data.items(): @@ -376,7 +376,7 @@ def test_error_handling_missing_dependency(self, clear_global_map): ) # Serialize b but not a - b_data = b.as_dict() + b_data = b.to_dict() # Deserialize without a in the global map global_object.map._clear() @@ -397,7 +397,7 @@ def test_backward_compatibility_base_deserializer(self, clear_global_map): ) # Use base serializer path (SerializerDict.decode) - serialized = b.encode(encoder=SerializerDict) + serialized = SerializerDict().encode(b) global_object.map._clear() # This should not raise the "_independent" error anymore @@ -440,7 +440,7 @@ def test_serializer_id_system_order_independence(self, clear_global_map, order): y_dep_id = y._DescriptorNumber__serializer_id # Serialize all parameters - params_data = {'x': x.as_dict(), 'y': y.as_dict(), 'z': z.as_dict()} + params_data = {'x': x.to_dict(), 'y': y.to_dict(), 'z': z.to_dict()} # Verify dependency IDs are in serialized data assert params_data['x']['__serializer_id'] == x_dep_id @@ -492,7 +492,7 @@ def test_deserialize_and_resolve_parameters_helper(self, clear_global_map): assert c.value == 5.0 # 2 + 3 # Serialize all parameters - params_data = {'a': a.as_dict(), 'b': b.as_dict(), 'c': c.as_dict()} + params_data = {'a': a.to_dict(), 'b': b.to_dict(), 'c': c.to_dict()} # Clear global map global_object.map._clear()