From 713a8e015e3e3f7dfa8eb83354ae43d4be4c93fa Mon Sep 17 00:00:00 2001 From: Cagtay Fabry <43667554+CagtayFabry@users.noreply.github.com> Date: Tue, 22 Jun 2021 10:00:00 +0200 Subject: [PATCH] add dataclass_nested_eq decorator (#378) * add `dataclass_nested_eq` decorator * decorate SpatialData with `dataclass_nested_eq` * update CHANGELOG.md * docstring * formatting --- CHANGELOG.md | 2 ++ weldx/geometry.py | 1 + weldx/util.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 016019273..b143ff898 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - added `WeldxFile` wrapper to handle asdf files with history and schemas more easily. [[#341]](https://github.com/BAMWelDX/weldx/pull/341). - add `"step"` as additional method to `util.xr_interp_like` [[#363]](https://github.com/BAMWelDX/weldx/pull/363) +- add `util.compare_nested_eq` decorator for dataclasses with array-like + fields [[#378]](https://github.com/BAMWelDX/weldx/pull/378) ### changes diff --git a/weldx/geometry.py b/weldx/geometry.py index 7006449a0..275e86bd8 100644 --- a/weldx/geometry.py +++ b/weldx/geometry.py @@ -2294,6 +2294,7 @@ def spatial_data( # SpatialData -------------------------------------------------------------------------- +@ut.dataclass_nested_eq @dataclass class SpatialData: """Represent 3D point cloud data with optional triangulation. diff --git a/weldx/util.py b/weldx/util.py index d303ab3ef..31aa079b7 100644 --- a/weldx/util.py +++ b/weldx/util.py @@ -128,6 +128,48 @@ def inner_decorator( return inner_decorator +def dataclass_nested_eq(original_class): + """Set class :code:`__eq__` using :code:`util.compare_nested` on :code:`__dict__`. + + Useful for implementing :code:`__eq__` on classes + created with :code:`@dataclass` decorator. + + Parameters + ---------- + original_class: + original class to decorate + + Returns + ------- + type + The class with overridden :code:`__eq__` function. + + Examples + -------- + A simple dataclass could look like this:: + + @dataclass_nested_eq + @dataclass + class A: + a: np.ndarray + + a = A(np.arange(3)) + b = A(np.arange(3)) + assert a==b + + """ + + def new_eq(self, other): + if not isinstance(other, type(self)): + return False + + return compare_nested(self.__dict__, other.__dict__) + + # set new eq function + original_class.__eq__ = new_eq # Set the class' __eq__ to the new one + return original_class + + def _clean_notebook(file: Union[str, Path]): # pragma: no cover """Clean ID metadata, output and execution count from jupyter notebook cells.