Skip to content

Commit 17c9e8f

Browse files
kmuehlbauerjhammandcherianpre-commit-ci[bot]
authored
ensure no forward slashes in names for HDF5-based backends (#7953)
* ensure no forward slashes in names for HDF5-based backends * fix mypy * Update xarray/backends/netCDF4_.py Co-authored-by: Joe Hamman <jhamman1@gmail.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Joe Hamman <jhamman1@gmail.com> Co-authored-by: Deepak Cherian <dcherian@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 58096a6 commit 17c9e8f

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ Deprecations
3434
Bug fixes
3535
~~~~~~~~~
3636

37+
- Ensure no forward slashes in variable and dimension names for HDF5-based engines.
38+
(:issue:`7943`, :pull:`7953`) By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
39+
3740

3841
Documentation
3942
~~~~~~~~~~~~~

xarray/backends/h5netcdf_.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from xarray.backends.netCDF4_ import (
2121
BaseNetCDF4Array,
2222
_encode_nc4_variable,
23+
_ensure_no_forward_slash_in_name,
2324
_extract_nc4_variable_encoding,
2425
_get_datatype,
2526
_nc4_require_group,
@@ -256,6 +257,7 @@ def get_encoding(self):
256257
}
257258

258259
def set_dimension(self, name, length, is_unlimited=False):
260+
_ensure_no_forward_slash_in_name(name)
259261
if is_unlimited:
260262
self.ds.dimensions[name] = None
261263
self.ds.resize_dimension(name, length)
@@ -273,6 +275,7 @@ def prepare_variable(
273275
):
274276
import h5py
275277

278+
_ensure_no_forward_slash_in_name(name)
276279
attrs = variable.attrs.copy()
277280
dtype = _get_datatype(variable, raise_on_invalid_encoding=check_encoding)
278281

xarray/backends/netCDF4_.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ def _nc4_require_group(ds, group, mode, create_group=_netcdf4_create_group):
194194
return ds
195195

196196

197+
def _ensure_no_forward_slash_in_name(name):
198+
if "/" in name:
199+
raise ValueError(
200+
f"Forward slashes '/' are not allowed in variable and dimension names (got {name!r}). "
201+
"Forward slashes are used as hierarchy-separators for "
202+
"HDF5-based files ('netcdf4'/'h5netcdf')."
203+
)
204+
205+
197206
def _ensure_fill_value_valid(data, attributes):
198207
# work around for netCDF4/scipy issue where _FillValue has the wrong type:
199208
# https://github.com/Unidata/netcdf4-python/issues/271
@@ -447,6 +456,7 @@ def get_encoding(self):
447456
}
448457

449458
def set_dimension(self, name, length, is_unlimited=False):
459+
_ensure_no_forward_slash_in_name(name)
450460
dim_length = length if not is_unlimited else None
451461
self.ds.createDimension(name, size=dim_length)
452462

@@ -470,6 +480,8 @@ def encode_variable(self, variable):
470480
def prepare_variable(
471481
self, name, variable, check_encoding=False, unlimited_dims=None
472482
):
483+
_ensure_no_forward_slash_in_name(name)
484+
473485
datatype = _get_datatype(
474486
variable, self.format, raise_on_invalid_encoding=check_encoding
475487
)

xarray/tests/test_backends.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,20 @@ def test_encoding_unlimited_dims(self) -> None:
16111611
assert actual.encoding["unlimited_dims"] == set("y")
16121612
assert_equal(ds, actual)
16131613

1614+
def test_raise_on_forward_slashes_in_names(self) -> None:
1615+
# test for forward slash in variable names and dimensions
1616+
# see GH 7943
1617+
data_vars: list[dict[str, Any]] = [
1618+
{"PASS/FAIL": (["PASSFAIL"], np.array([0]))},
1619+
{"PASS/FAIL": np.array([0])},
1620+
{"PASSFAIL": (["PASS/FAIL"], np.array([0]))},
1621+
]
1622+
for dv in data_vars:
1623+
ds = Dataset(data_vars=dv)
1624+
with pytest.raises(ValueError, match="Forward slashes '/' are not allowed"):
1625+
with self.roundtrip(ds):
1626+
pass
1627+
16141628

16151629
@requires_netCDF4
16161630
class TestNetCDF4Data(NetCDF4Base):

0 commit comments

Comments
 (0)