From b97db395aefd2df297e20f60f5816f2264e93bc4 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 13:28:57 -0500 Subject: [PATCH 1/8] Add uuid property to DiffractionObject --- src/diffpy/utils/diffraction_objects.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index ab39e53b..abfd44b0 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -1,4 +1,5 @@ import datetime +import uuid import warnings from copy import deepcopy @@ -29,7 +30,7 @@ def _xtype_wmsg(xtype): def _setter_wmsg(attribute): return ( f"Direct modification of attribute '{attribute}' is not allowed. " - f"Please use 'insert_scattering_quantity' to modify '{attribute}'.", + f"Please use 'input_data' to modify '{attribute}'.", ) @@ -53,7 +54,8 @@ def __init__( if yarray is None: yarray = np.empty(0) - self.insert_scattering_quantity(xarray, yarray, xtype) + self._id = uuid.uuid4() + self.input_data(xarray, yarray, xtype) def __eq__(self, other): if not isinstance(other, DiffractionObject): @@ -205,6 +207,14 @@ def input_xtype(self): def input_xtype(self, _): raise AttributeError(_setter_wmsg("input_xtype")) + @property + def id(self): + return self._id + + @id.setter + def id(self, _): + raise AttributeError(_setter_wmsg("id")) + def set_angles_from_list(self, angles_list): self.angles = angles_list self.n_steps = len(angles_list) - 1.0 @@ -317,7 +327,7 @@ def _set_xarrays(self, xarray, xtype): self.dmin = np.nanmin(self._all_arrays[:, 3], initial=np.inf) self.dmax = np.nanmax(self._all_arrays[:, 3], initial=0.0) - def insert_scattering_quantity( + def input_data( self, xarray, yarray, @@ -351,7 +361,7 @@ def insert_scattering_quantity( if len(xarray) != len(yarray): raise ValueError( "'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'insert_scattering_quantity' " + "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " "with 'xarray' and 'yarray' of identical length." ) From 5d87cdcaef215d783cbc05042f6c717e134f17c1 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 13:29:12 -0500 Subject: [PATCH 2/8] Modify tests functions to test gettable id property --- tests/test_diffraction_objects.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index f93190ae..ef758b9d 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -1,5 +1,7 @@ import re +import uuid from pathlib import Path +from uuid import UUID import numpy as np import pytest @@ -335,8 +337,8 @@ def test_dump(tmp_path, mocker): @pytest.mark.parametrize("inputs, expected", tc_params) def test_constructor(inputs, expected): - actual_do = DiffractionObject(**inputs) - diff = DeepDiff(actual_do.__dict__, expected, ignore_order=True, significant_digits=13) + actual = DiffractionObject(**inputs).__dict__ + diff = DeepDiff(actual, expected, ignore_order=True, significant_digits=13, exclude_paths="root['_id']") assert diff == {} @@ -364,16 +366,33 @@ def test_all_array_setter(): with pytest.raises( AttributeError, match="Direct modification of attribute 'all_arrays' is not allowed. " - "Please use 'insert_scattering_quantity' to modify 'all_arrays'.", + "Please use 'input_data' to modify 'all_arrays'.", ): actual_do.all_arrays = np.empty((4, 4)) +def test_id_getter(): + do = DiffractionObject() + assert hasattr(do, "id") + assert isinstance(do.id, UUID) + assert len(str(do.id)) == 36 + + +def test_id_setter(): + do = DiffractionObject() + # Attempt to directly modify the property + with pytest.raises( + AttributeError, + match="Direct modification of attribute 'id' is not allowed. Please use 'input_data' to modify 'id'.", + ): + do.id = uuid.uuid4() + + def test_xarray_yarray_length_mismatch(): with pytest.raises( ValueError, match="'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'insert_scattering_quantity' " + "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " "with 'xarray' and 'yarray' of identical length", ): DiffractionObject(xarray=np.array([1.0, 2.0]), yarray=np.array([0.0, 0.0, 0.0])) @@ -391,7 +410,7 @@ def test_input_xtype_setter(): with pytest.raises( AttributeError, match="Direct modification of attribute 'input_xtype' is not allowed. " - "Please use 'insert_scattering_quantity' to modify 'input_xtype'.", + "Please use 'input_data' to modify 'input_xtype'.", ): do.input_xtype = "q" From cd535869827ddc77441597ad3fbc91b854e572b0 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 13:29:17 -0500 Subject: [PATCH 3/8] Add news --- news/uuid.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/uuid.rst diff --git a/news/uuid.rst b/news/uuid.rst new file mode 100644 index 00000000..474793f4 --- /dev/null +++ b/news/uuid.rst @@ -0,0 +1,23 @@ +**Added:** + +* Gettable `id` property to `DiffractionObject` + +**Changed:** + +* + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 6169620dce28ab3f599b16c371ff29fe26a4133e Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 13:31:36 -0500 Subject: [PATCH 4/8] Use insert_scattering_quantity for now before PR merged --- src/diffpy/utils/diffraction_objects.py | 8 ++++---- tests/test_diffraction_objects.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/diffpy/utils/diffraction_objects.py b/src/diffpy/utils/diffraction_objects.py index abfd44b0..0ec305bc 100644 --- a/src/diffpy/utils/diffraction_objects.py +++ b/src/diffpy/utils/diffraction_objects.py @@ -30,7 +30,7 @@ def _xtype_wmsg(xtype): def _setter_wmsg(attribute): return ( f"Direct modification of attribute '{attribute}' is not allowed. " - f"Please use 'input_data' to modify '{attribute}'.", + f"Please use 'insert_scattering_quantity' to modify '{attribute}'.", ) @@ -55,7 +55,7 @@ def __init__( yarray = np.empty(0) self._id = uuid.uuid4() - self.input_data(xarray, yarray, xtype) + self.insert_scattering_quantity(xarray, yarray, xtype) def __eq__(self, other): if not isinstance(other, DiffractionObject): @@ -327,7 +327,7 @@ def _set_xarrays(self, xarray, xtype): self.dmin = np.nanmin(self._all_arrays[:, 3], initial=np.inf) self.dmax = np.nanmax(self._all_arrays[:, 3], initial=0.0) - def input_data( + def insert_scattering_quantity( self, xarray, yarray, @@ -361,7 +361,7 @@ def input_data( if len(xarray) != len(yarray): raise ValueError( "'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " + "Please re-initialize 'DiffractionObject' or re-run the method 'insert_scattering_quantity' " "with 'xarray' and 'yarray' of identical length." ) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index ef758b9d..b54d7a02 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -366,7 +366,7 @@ def test_all_array_setter(): with pytest.raises( AttributeError, match="Direct modification of attribute 'all_arrays' is not allowed. " - "Please use 'input_data' to modify 'all_arrays'.", + "Please use 'insert_scattering_quantity' to modify 'all_arrays'.", ): actual_do.all_arrays = np.empty((4, 4)) @@ -383,7 +383,7 @@ def test_id_setter(): # Attempt to directly modify the property with pytest.raises( AttributeError, - match="Direct modification of attribute 'id' is not allowed. Please use 'input_data' to modify 'id'.", + match="Direct modification of attribute 'id' is not allowed. Please use 'insert_scattering_quantity' to modify 'id'.", ): do.id = uuid.uuid4() @@ -392,7 +392,7 @@ def test_xarray_yarray_length_mismatch(): with pytest.raises( ValueError, match="'xarray' and 'yarray' must have the same length. " - "Please re-initialize 'DiffractionObject' or re-run the method 'input_data' " + "Please re-initialize 'DiffractionObject' or re-run the method 'insert_scattering_quantity' " "with 'xarray' and 'yarray' of identical length", ): DiffractionObject(xarray=np.array([1.0, 2.0]), yarray=np.array([0.0, 0.0, 0.0])) @@ -410,7 +410,7 @@ def test_input_xtype_setter(): with pytest.raises( AttributeError, match="Direct modification of attribute 'input_xtype' is not allowed. " - "Please use 'input_data' to modify 'input_xtype'.", + "Please use 'insert_scattering_quantity' to modify 'input_xtype'.", ): do.input_xtype = "q" From 0dd95e898b3b7b964117ac1c6d900287216eefe7 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 14:35:34 -0500 Subject: [PATCH 5/8] Use input_data across all tests file instead of input_scattering_data --- tests/test_diffraction_objects.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index c01c203b..3a7ae366 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -378,12 +378,12 @@ def test_id_getter(): assert len(str(do.id)) == 36 -def test_id_setter(): +def test_id_setter_error(): do = DiffractionObject() # Attempt to directly modify the property with pytest.raises( AttributeError, - match="Direct modification of attribute 'id' is not allowed. Please use 'insert_scattering_quantity' to modify 'id'.", + match="Direct modification of attribute 'id' is not allowed. Please use 'input_data' to modify 'id'.", ): do.id = uuid.uuid4() @@ -403,7 +403,7 @@ def test_input_xtype_getter(): assert do.input_xtype == "tth" -def test_input_xtype_setter(): +def test_input_xtype_setter_error(): do = DiffractionObject(xtype="tth") # Attempt to directly modify the property From 4bd441fa39fc8fee9090097858ea729321de812a Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 17:13:49 -0500 Subject: [PATCH 6/8] Add mocker for testing id property --- tests/test_diffraction_objects.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 3a7ae366..5b366846 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -378,12 +378,18 @@ def test_id_getter(): assert len(str(do.id)) == 36 +def test_id_getter_with_mock(mocker): + mocker.patch.object(DiffractionObject, "id", new_callable=lambda: UUID("d67b19c6-3016-439f-81f7-cf20a04bee87")) + do = DiffractionObject() + assert do.id == UUID("d67b19c6-3016-439f-81f7-cf20a04bee87") + + def test_id_setter_error(): do = DiffractionObject() - # Attempt to directly modify the property + with pytest.raises( AttributeError, - match="Direct modification of attribute 'id' is not allowed. Please use 'input_data' to modify 'id'.", + match="Direct modification of attribute 'id' is not allowed. " "Please use 'input_data' to modify 'id'.", ): do.id = uuid.uuid4() From 3a52b2f82893a307a32dbc28638eb43fbf6b35a7 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 17:24:39 -0500 Subject: [PATCH 7/8] Fix spacing in error msg --- tests/test_diffraction_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_diffraction_objects.py b/tests/test_diffraction_objects.py index 5b366846..50080550 100644 --- a/tests/test_diffraction_objects.py +++ b/tests/test_diffraction_objects.py @@ -389,7 +389,7 @@ def test_id_setter_error(): with pytest.raises( AttributeError, - match="Direct modification of attribute 'id' is not allowed. " "Please use 'input_data' to modify 'id'.", + match="Direct modification of attribute 'id' is not allowed. Please use 'input_data' to modify 'id'.", ): do.id = uuid.uuid4() From 6e51eb79e66a78c7dbafe4797174ffe19ad7be75 Mon Sep 17 00:00:00 2001 From: Sangjoon Bob Lee Date: Thu, 12 Dec 2024 17:30:57 -0500 Subject: [PATCH 8/8] Re-run CI for codecov fail