From d6e34dc6d9bca2c6292a09fb623f9e0184ba0a6c Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Fri, 13 Mar 2026 14:52:15 +0100 Subject: [PATCH 1/3] Add coverage for scalar validation on empty coord manager --- dascore/core/attrs.py | 5 ++++- dascore/core/coordmanager.py | 2 ++ tests/test_core/test_coordmanager.py | 6 ++++++ tests/test_proc/test_proc_coords.py | 8 ++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/dascore/core/attrs.py b/dascore/core/attrs.py index 93b5c9c1..50b54c61 100644 --- a/dascore/core/attrs.py +++ b/dascore/core/attrs.py @@ -239,8 +239,11 @@ def update(self, **kwargs) -> Self: new_coords = dict(out.get("coords", {})) if isinstance(passed_in_coords, dc.CoordManager): new_coords = passed_in_coords.model_dump(exclude_unset=True) + out["dims"] = passed_in_coords.dims - coord_info, attr_info = separate_coord_info(kwargs, dims=self.dim_tuple) + coord_info, attr_info = separate_coord_info( + kwargs, dims=tuple(out.get("dims", self.dim_tuple)) + ) out.update(attr_info) # Iterate the coordinate information and update. for name, coord_dict in coord_info.items(): diff --git a/dascore/core/coordmanager.py b/dascore/core/coordmanager.py index 8b518625..1b2ba945 100644 --- a/dascore/core/coordmanager.py +++ b/dascore/core/coordmanager.py @@ -819,6 +819,8 @@ def ndim(self): def validate_data(self, data): """Ensure data conforms to coordinates.""" data = np.asarray([]) if data is None else data + if not self.dims and data.shape == (): + return data if self.shape != data.shape: msg = ( f"Data array has a shape of {data.shape} which doesnt match " diff --git a/tests/test_core/test_coordmanager.py b/tests/test_core/test_coordmanager.py index 93e47c66..31f4bc0c 100644 --- a/tests/test_core/test_coordmanager.py +++ b/tests/test_core/test_coordmanager.py @@ -169,6 +169,12 @@ def test_init_list_range(self): out = get_coord_manager(input_dict, dims=list(input_dict)) assert set(out.dims) == set(input_dict) + def test_scalar_data_ok_for_no_dims(self): + """Ensure scalar data validates for coordinate managers with no dims.""" + cm = get_coord_manager() + out = cm.validate_data(np.array(1.0)) + assert out.shape == () + def test_bad_datashape_raises(self, cm_basic): """Ensure a bad datashape raises.""" match = "match the coordinate manager shape" diff --git a/tests/test_proc/test_proc_coords.py b/tests/test_proc/test_proc_coords.py index 9704b3e6..0f2b08a5 100644 --- a/tests/test_proc/test_proc_coords.py +++ b/tests/test_proc/test_proc_coords.py @@ -673,6 +673,14 @@ def test_coord_summary(self, flat_patch): if coords: assert set(coords) == set(patch.coords.coord_map) + def test_squeeze_all_dims_len_one(self, random_patch): + """Squeezing a (1, 1) patch should produce scalar patch with no dims.""" + patch = random_patch.aggregate(dim=None, method="mean", dim_reduce="empty") + out = patch.squeeze() + assert out.data.shape == () + assert out.dims == () + assert out.attrs.dim_tuple == () + class TestGetCoord: """Tests for the get_coord convenience function.""" From 12366bad43e4c45775aad405cf60281be5f14208 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Fri, 13 Mar 2026 16:37:48 +0100 Subject: [PATCH 2/3] Fix PatchAttrs.update dims parsing regression --- dascore/core/attrs.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dascore/core/attrs.py b/dascore/core/attrs.py index 50b54c61..7c56e09a 100644 --- a/dascore/core/attrs.py +++ b/dascore/core/attrs.py @@ -241,9 +241,10 @@ def update(self, **kwargs) -> Self: new_coords = passed_in_coords.model_dump(exclude_unset=True) out["dims"] = passed_in_coords.dims - coord_info, attr_info = separate_coord_info( - kwargs, dims=tuple(out.get("dims", self.dim_tuple)) - ) + dims = out.get("dims", self.dim_tuple) + if isinstance(dims, str): + dims = tuple(dims.split(",")) if dims else tuple() + coord_info, attr_info = separate_coord_info(kwargs, dims=tuple(dims)) out.update(attr_info) # Iterate the coordinate information and update. for name, coord_dict in coord_info.items(): From f26352165433946e545585c8b04fe21d83e8a5d0 Mon Sep 17 00:00:00 2001 From: Derrick Chambers Date: Sat, 14 Mar 2026 13:03:31 +0100 Subject: [PATCH 3/3] Address review on zero-dim scalar validation --- dascore/core/coordmanager.py | 2 +- tests/test_core/test_coordmanager.py | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dascore/core/coordmanager.py b/dascore/core/coordmanager.py index 1b2ba945..e748f495 100644 --- a/dascore/core/coordmanager.py +++ b/dascore/core/coordmanager.py @@ -818,7 +818,7 @@ def ndim(self): def validate_data(self, data): """Ensure data conforms to coordinates.""" - data = np.asarray([]) if data is None else data + data = np.asarray([]) if data is None else np.asarray(data) if not self.dims and data.shape == (): return data if self.shape != data.shape: diff --git a/tests/test_core/test_coordmanager.py b/tests/test_core/test_coordmanager.py index 31f4bc0c..94b31126 100644 --- a/tests/test_core/test_coordmanager.py +++ b/tests/test_core/test_coordmanager.py @@ -175,6 +175,13 @@ def test_scalar_data_ok_for_no_dims(self): out = cm.validate_data(np.array(1.0)) assert out.shape == () + def test_python_scalar_data_ok_for_no_dims(self): + """Ensure python scalars are converted and validate with no dims.""" + cm = get_coord_manager() + out = cm.validate_data(1.0) + assert isinstance(out, np.ndarray) + assert out.shape == () + def test_bad_datashape_raises(self, cm_basic): """Ensure a bad datashape raises.""" match = "match the coordinate manager shape"