Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion dascore/core/attrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,12 @@ 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)
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():
Expand Down
4 changes: 3 additions & 1 deletion dascore/core/coordmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,9 @@ 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
Comment on lines +822 to +823
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep shape/size semantics consistent for zero-dim scalars

This early return allows scalar data for empty-dim managers, but CoordManager.shape still reports (0,) when self.dims is empty, so zero-dim patches can now be created with data.shape == () while patch.shape == (0,) and patch.size == 0. That violates the documented Patch shape/size behavior and can mislead downstream code that relies on coords.shape/coords.size after squeeze() or other zero-dim reductions.

Useful? React with 👍 / 👎.

if self.shape != data.shape:
msg = (
f"Data array has a shape of {data.shape} which doesnt match "
Expand Down
13 changes: 13 additions & 0 deletions tests/test_core/test_coordmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,19 @@ 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_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"
Expand Down
8 changes: 8 additions & 0 deletions tests/test_proc/test_proc_coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down
Loading