Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
3 changes: 2 additions & 1 deletion doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ Deprecations

Bug fixes
~~~~~~~~~

- Added support for `numpy.bool_` attributes in roundtrips using `h5netcdf` engine with `invalid_netcdf=True` [which casts `bool`s to `numpy.bool_`] (:issue:`4981`, :pull:`4986`).
By `Victor Negîrneac <https://github.com/caenrigen>`_.

Documentation
~~~~~~~~~~~~~
Expand Down
8 changes: 5 additions & 3 deletions xarray/backends/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def check_name(name):

def _validate_attrs(dataset):
"""`attrs` must have a string key and a value which is either: a number,
a string, an ndarray or a list/tuple of numbers/strings.
a string, an ndarray, a bool/numpy.bool_, or a list/tuple of numbers/strings.
"""

def check_attr(name, value):
Expand All @@ -218,10 +218,12 @@ def check_attr(name, value):
"serialization to netCDF files"
)

if not isinstance(value, (str, Number, np.ndarray, np.number, list, tuple)):
if not isinstance(
value, (str, Number, np.ndarray, np.number, np.bool_, list, tuple)
):
raise TypeError(
f"Invalid value for attr {name!r}: {value!r} must be a number, "
"a string, an ndarray or a list/tuple of "
"a string, an ndarray, a bool/numpy.bool_, or a list/tuple of "
"numbers/strings for serialization to netCDF "
"files"
)
Expand Down
8 changes: 8 additions & 0 deletions xarray/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2541,6 +2541,14 @@ def test_complex(self, invalid_netcdf, warntype, num_warns):

assert recorded_num_warns == num_warns

def test_numpy_bool_(self):
# h5netcdf loads booleans as numpy.bool_, this type needs to be supported
# when writing invalid_netcdf datasets in order to support a roundtrip
expected = Dataset({"x": ("y", np.ones(5), {"numpy_bool": np.bool_(True)})})
save_kwargs = {"invalid_netcdf": True}
with self.roundtrip(expected, save_kwargs=save_kwargs) as actual:
assert_identical(expected, actual)

def test_cross_engine_read_write_netcdf4(self):
# Drop dim3, because its labels include strings. These appear to be
# not properly read with python-netCDF4, which converts them into
Expand Down