h5netcdf 1.6.2__py3-none-any.whl → 1.6.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of h5netcdf might be problematic. Click here for more details.

h5netcdf/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.6.2'
21
- __version_tuple__ = version_tuple = (1, 6, 2)
20
+ __version__ = version = '1.6.4'
21
+ __version_tuple__ = version_tuple = (1, 6, 4)
h5netcdf/core.py CHANGED
@@ -677,7 +677,7 @@ def _unlabeled_dimension_mix(h5py_dataset):
677
677
  if not dimlist:
678
678
  status = "nodim"
679
679
  else:
680
- dimset = set([len(j) for j in dimlist])
680
+ dimset = {len(j) for j in dimlist}
681
681
  # either all dimensions have exactly one scale
682
682
  # or all dimensions have no scale
683
683
  if dimset ^ {0} == set():
@@ -788,7 +788,7 @@ def _check_fillvalue(group, fillvalue, dtype):
788
788
  # 1. we need to warn the user that writing enums with default values
789
789
  # which are defined in the enum dict will mask those values
790
790
  if (h5fillvalue or 0) in dtype.enum_dict.values():
791
- reverse = dict((v, k) for k, v in dtype.enum_dict.items())
791
+ reverse = {v: k for k, v in dtype.enum_dict.items()}
792
792
  msg = (
793
793
  f"Creating variable with default fill_value {h5fillvalue or 0!r}"
794
794
  f" which IS defined in enum type {dtype!r}."
@@ -982,16 +982,16 @@ class Group(Mapping):
982
982
  for k, v in self._all_dimensions.maps[0].items():
983
983
  if k in value:
984
984
  if v != value[k]:
985
- raise ValueError(f"cannot modify existing dimension {k:!r}")
985
+ raise ValueError(f"cannot modify existing dimension {k!r}")
986
986
  else:
987
987
  raise ValueError(
988
- f"new dimensions do not include existing dimension {k:!r}"
988
+ f"new dimensions do not include existing dimension {k!r}"
989
989
  )
990
990
  self._dimensions.update(value)
991
991
 
992
992
  def _create_child_group(self, name):
993
993
  if name in self:
994
- raise ValueError(f"unable to create group {name:!r} (name already exists)")
994
+ raise ValueError(f"unable to create group {name!r} (name already exists)")
995
995
  kwargs = {}
996
996
  kwargs.update(track_order=self._track_order)
997
997
 
@@ -1035,7 +1035,7 @@ class Group(Mapping):
1035
1035
  ):
1036
1036
  if name in self:
1037
1037
  raise ValueError(
1038
- f"unable to create variable {name:!r} (name already exists)"
1038
+ f"unable to create variable {name!r} (name already exists)"
1039
1039
  )
1040
1040
  if data is not None:
1041
1041
  data = np.asarray(data)
@@ -1271,10 +1271,8 @@ class Group(Mapping):
1271
1271
  return item
1272
1272
 
1273
1273
  def __iter__(self):
1274
- for name in self.groups:
1275
- yield name
1276
- for name in self.variables:
1277
- yield name
1274
+ yield from self.groups
1275
+ yield from self.variables
1278
1276
 
1279
1277
  def __len__(self):
1280
1278
  return len(self.variables) + len(self.groups)
@@ -1527,7 +1525,7 @@ class File(Group):
1527
1525
  mode = "r+"
1528
1526
  self._h5py = h5pyd
1529
1527
  try:
1530
- self._h5file = self._h5py.File(
1528
+ self.__h5file = self._h5py.File(
1531
1529
  path, mode, track_order=track_order, **kwargs
1532
1530
  )
1533
1531
  self._preexisting_file = mode != "w"
@@ -1535,7 +1533,7 @@ class File(Group):
1535
1533
  # if file does not exist, create it
1536
1534
  if _mode == "a":
1537
1535
  mode = "w"
1538
- self._h5file = self._h5py.File(
1536
+ self.__h5file = self._h5py.File(
1539
1537
  path, mode, track_order=track_order, **kwargs
1540
1538
  )
1541
1539
  self._preexisting_file = False
@@ -1551,19 +1549,19 @@ class File(Group):
1551
1549
  else:
1552
1550
  self._preexisting_file = os.path.exists(path) and mode != "w"
1553
1551
  self._h5py = h5py
1554
- self._h5file = self._h5py.File(
1552
+ self.__h5file = self._h5py.File(
1555
1553
  path, mode, track_order=track_order, **kwargs
1556
1554
  )
1557
1555
  elif isinstance(path, h5py.File):
1558
1556
  self._preexisting_file = mode in {"r", "r+", "a"}
1559
1557
  self._h5py = h5py
1560
- self._h5file = path
1558
+ self.__h5file = path
1561
1559
  # h5py File passed in: let the caller decide when to close it
1562
1560
  self._close_h5file = False
1563
1561
  else: # file-like object
1564
1562
  self._preexisting_file = mode in {"r", "r+", "a"}
1565
1563
  self._h5py = h5py
1566
- self._h5file = self._h5py.File(
1564
+ self.__h5file = self._h5py.File(
1567
1565
  path, mode, track_order=track_order, **kwargs
1568
1566
  )
1569
1567
  except Exception:
@@ -1572,6 +1570,7 @@ class File(Group):
1572
1570
  else:
1573
1571
  self._closed = False
1574
1572
 
1573
+ self._filename = self._h5file.filename
1575
1574
  self._mode = mode
1576
1575
  self._writable = mode != "r"
1577
1576
  self._root_ref = weakref.ref(self)
@@ -1696,12 +1695,18 @@ class File(Group):
1696
1695
 
1697
1696
  sync = flush
1698
1697
 
1698
+ @property
1699
+ def _h5file(self):
1700
+ if self._closed:
1701
+ raise ValueError(f"I/O operation on {self}: {self._filename!r}")
1702
+ return self.__h5file
1703
+
1699
1704
  def close(self):
1700
1705
  if not self._closed:
1701
1706
  self.flush()
1702
1707
  if self._close_h5file:
1703
1708
  self._h5file.close()
1704
- self._h5file = None
1709
+ self.__h5file = None
1705
1710
  self._closed = True
1706
1711
 
1707
1712
  __del__ = close
h5netcdf/dimensions.py CHANGED
@@ -22,7 +22,7 @@ class Dimensions(MutableMapping):
22
22
  if not self._group._root._writable:
23
23
  raise RuntimeError("H5NetCDF: Write to read only")
24
24
  if name in self._objects:
25
- raise ValueError(f"dimension {name:!r} already exists")
25
+ raise ValueError(f"dimension {name!r} already exists")
26
26
 
27
27
  self._objects[name] = Dimension(self._group, name, size, create_h5ds=True)
28
28
 
@@ -13,7 +13,7 @@ import netCDF4
13
13
  import numpy as np
14
14
  import pytest
15
15
  from packaging import version
16
- from pytest import raises
16
+ from pytest import raises, warns
17
17
 
18
18
  import h5netcdf
19
19
  from h5netcdf import legacyapi
@@ -164,7 +164,10 @@ def write_legacy_netcdf(tmp_netcdf, write_module):
164
164
  v = ds.createVariable("foo_unlimited", float, ("x", "unlimited"))
165
165
  v[...] = 1
166
166
 
167
- with raises((h5netcdf.CompatibilityError, TypeError)):
167
+ with raises(
168
+ (h5netcdf.CompatibilityError, TypeError),
169
+ match=r"(?i)(boolean dtypes are not a supported NetCDF feature|illegal primitive data type)",
170
+ ):
168
171
  ds.createVariable("boolean", np.bool_, ("x"))
169
172
 
170
173
  g = ds.createGroup("subgroup")
@@ -257,28 +260,32 @@ def read_legacy_netcdf(tmp_netcdf, read_module, write_module):
257
260
  if write_module is not netCDF4:
258
261
  # skip for now: https://github.com/Unidata/netcdf4-python/issues/388
259
262
  assert ds.other_attr == "yes"
260
- with pytest.raises(AttributeError):
263
+ with raises(AttributeError, match="not found"):
261
264
  ds.does_not_exist
262
- assert set(ds.dimensions) == set(
263
- ["x", "y", "z", "empty", "string3", "mismatched_dim", "unlimited"]
264
- )
265
- assert set(ds.variables) == set(
266
- [
267
- "enum_var",
268
- "foo",
269
- "y",
270
- "z",
271
- "intscalar",
272
- "scalar",
273
- "var_len_str",
274
- "mismatched_dim",
275
- "foo_unlimited",
276
- ]
277
- )
278
-
279
- assert set(ds.enumtypes) == set(["enum_t"])
280
-
281
- assert set(ds.groups) == set(["subgroup"])
265
+ assert set(ds.dimensions) == {
266
+ "x",
267
+ "y",
268
+ "z",
269
+ "empty",
270
+ "string3",
271
+ "mismatched_dim",
272
+ "unlimited",
273
+ }
274
+ assert set(ds.variables) == {
275
+ "enum_var",
276
+ "foo",
277
+ "y",
278
+ "z",
279
+ "intscalar",
280
+ "scalar",
281
+ "var_len_str",
282
+ "mismatched_dim",
283
+ "foo_unlimited",
284
+ }
285
+
286
+ assert set(ds.enumtypes) == {"enum_t"}
287
+
288
+ assert set(ds.groups) == {"subgroup"}
282
289
  assert ds.parent is None
283
290
  v = ds.variables["foo"]
284
291
  assert array_equal(v, np.ones((4, 5)))
@@ -379,27 +386,31 @@ def read_h5netcdf(tmp_netcdf, write_module, decode_vlen_strings):
379
386
  if write_module is not netCDF4:
380
387
  # skip for now: https://github.com/Unidata/netcdf4-python/issues/388
381
388
  assert ds.attrs["other_attr"] == "yes"
382
- assert set(ds.dimensions) == set(
383
- ["x", "y", "z", "empty", "string3", "mismatched_dim", "unlimited"]
384
- )
385
- variables = set(
386
- [
387
- "enum_var",
388
- "foo",
389
- "z",
390
- "intscalar",
391
- "scalar",
392
- "var_len_str",
393
- "mismatched_dim",
394
- "foo_unlimited",
395
- ]
396
- )
389
+ assert set(ds.dimensions) == {
390
+ "x",
391
+ "y",
392
+ "z",
393
+ "empty",
394
+ "string3",
395
+ "mismatched_dim",
396
+ "unlimited",
397
+ }
398
+ variables = {
399
+ "enum_var",
400
+ "foo",
401
+ "z",
402
+ "intscalar",
403
+ "scalar",
404
+ "var_len_str",
405
+ "mismatched_dim",
406
+ "foo_unlimited",
407
+ }
397
408
  # fix current failure of hsds/h5pyd
398
409
  if not remote_file:
399
- variables |= set(["y"])
410
+ variables |= {"y"}
400
411
  assert set(ds.variables) == variables
401
412
 
402
- assert set(ds.groups) == set(["subgroup"])
413
+ assert set(ds.groups) == {"subgroup"}
403
414
  assert ds.parent is None
404
415
 
405
416
  v = ds["foo"]
@@ -653,25 +664,27 @@ def test_optional_netcdf4_attrs(tmp_local_or_remote_netcdf):
653
664
  def test_error_handling(tmp_local_or_remote_netcdf):
654
665
  with h5netcdf.File(tmp_local_or_remote_netcdf, "w") as ds:
655
666
  ds.dimensions["x"] = 1
656
- with raises(ValueError):
667
+ with raises(ValueError, match="already exists"):
657
668
  ds.dimensions["x"] = 2
658
- with raises(ValueError):
669
+ with raises(ValueError, match="cannot modify existing dimension"):
659
670
  ds.dimensions = {"x": 2}
660
- with raises(ValueError):
671
+ with raises(
672
+ ValueError, match="new dimensions do not include existing dimension"
673
+ ):
661
674
  ds.dimensions = {"y": 3}
662
675
  ds.create_variable("x", ("x",), dtype=float)
663
- with raises(ValueError):
676
+ with raises(ValueError, match="unable to create variable"):
664
677
  ds.create_variable("x", ("x",), dtype=float)
665
- with raises(ValueError):
678
+ with raises(ValueError, match="name parameter cannot be an empty string"):
666
679
  ds.create_variable("y/", ("x",), dtype=float)
667
680
  ds.create_group("subgroup")
668
- with raises(ValueError):
681
+ with raises(ValueError, match="unable to create group"):
669
682
  ds.create_group("subgroup")
670
683
 
671
684
 
672
685
  def test_decode_string_error(tmp_local_or_remote_netcdf):
673
686
  write_h5netcdf(tmp_local_or_remote_netcdf)
674
- with pytest.raises(TypeError):
687
+ with raises(TypeError, match="keyword argument is not allowed"):
675
688
  with h5netcdf.legacyapi.Dataset(
676
689
  tmp_local_or_remote_netcdf, "r", decode_vlen_strings=True
677
690
  ) as ds:
@@ -738,10 +751,10 @@ def test_invalid_netcdf4(tmp_local_or_remote_netcdf):
738
751
  check_invalid_netcdf4(var, i)
739
752
 
740
753
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r") as ds:
741
- with raises(ValueError):
754
+ with raises(ValueError, match="has no dimension scale associated"):
742
755
  ds["bar"].variables["foo1"].dimensions
743
756
 
744
- with raises(ValueError):
757
+ with raises(ValueError, match="unknown value"):
745
758
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r", phony_dims="srt") as ds:
746
759
  pass
747
760
 
@@ -806,7 +819,7 @@ def test_invalid_netcdf4_mixed(tmp_local_or_remote_netcdf):
806
819
  check_invalid_netcdf4_mixed(var, 3)
807
820
 
808
821
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r") as ds:
809
- with raises(ValueError):
822
+ with raises(ValueError, match="has no dimension scale associated with"):
810
823
  ds.variables["foo1"].dimensions
811
824
 
812
825
 
@@ -824,12 +837,12 @@ def test_invalid_netcdf_malformed_dimension_scales(tmp_local_or_remote_netcdf):
824
837
  f["z"].make_scale()
825
838
  f["foo1"].dims[0].attach_scale(f["x"])
826
839
 
827
- with raises(ValueError):
840
+ with raises(ValueError, match="has mixing of labeled and unlabeled dimensions"):
828
841
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r") as ds:
829
842
  assert ds
830
843
  print(ds)
831
844
 
832
- with raises(ValueError):
845
+ with raises(ValueError, match="has mixing of labeled and unlabeled dimensions"):
833
846
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r", phony_dims="sort") as ds:
834
847
  assert ds
835
848
  print(ds)
@@ -840,13 +853,13 @@ def test_hierarchical_access_auto_create(tmp_local_or_remote_netcdf):
840
853
  ds.create_variable("/foo/bar", data=1)
841
854
  g = ds.create_group("foo/baz")
842
855
  g.create_variable("/foo/hello", data=2)
843
- assert set(ds) == set(["foo"])
844
- assert set(ds["foo"]) == set(["bar", "baz", "hello"])
856
+ assert set(ds) == {"foo"}
857
+ assert set(ds["foo"]) == {"bar", "baz", "hello"}
845
858
  ds.close()
846
859
 
847
860
  ds = h5netcdf.File(tmp_local_or_remote_netcdf, "r")
848
- assert set(ds) == set(["foo"])
849
- assert set(ds["foo"]) == set(["bar", "baz", "hello"])
861
+ assert set(ds) == {"foo"}
862
+ assert set(ds["foo"]) == {"bar", "baz", "hello"}
850
863
  ds.close()
851
864
 
852
865
 
@@ -943,14 +956,17 @@ def test_invalid_netcdf_error(tmp_local_or_remote_netcdf):
943
956
  f.create_variable(
944
957
  "lzf_compressed", data=[1], dimensions=("x"), compression="lzf"
945
958
  )
946
- with pytest.raises(h5netcdf.CompatibilityError):
959
+ with raises(
960
+ h5netcdf.CompatibilityError,
961
+ match="scale-offset filters are not a supported NetCDF feature",
962
+ ):
947
963
  f.create_variable("scaleoffset", data=[1], dimensions=("x",), scaleoffset=0)
948
964
 
949
965
 
950
966
  def test_invalid_netcdf_okay(tmp_local_or_remote_netcdf):
951
967
  if tmp_local_or_remote_netcdf.startswith(remote_h5):
952
968
  pytest.skip("h5pyd does not support NumPy complex dtype yet")
953
- with pytest.warns(UserWarning, match="invalid netcdf features"):
969
+ with warns(UserWarning, match="invalid netcdf features"):
954
970
  with h5netcdf.File(tmp_local_or_remote_netcdf, "w", invalid_netcdf=True) as f:
955
971
  f.create_variable(
956
972
  "lzf_compressed", data=[1], dimensions=("x"), compression="lzf"
@@ -972,7 +988,7 @@ def test_invalid_netcdf_overwrite_valid(tmp_local_netcdf):
972
988
  # https://github.com/h5netcdf/h5netcdf/issues/165
973
989
  with netCDF4.Dataset(tmp_local_netcdf, mode="w"):
974
990
  pass
975
- with pytest.warns(UserWarning):
991
+ with warns(UserWarning, match="You are writing invalid netcdf features"):
976
992
  with h5netcdf.File(tmp_local_netcdf, "a", invalid_netcdf=True) as f:
977
993
  f.create_variable(
978
994
  "lzf_compressed", data=[1], dimensions=("x"), compression="lzf"
@@ -1001,7 +1017,7 @@ def test_reopen_file_different_dimension_sizes(tmp_local_netcdf):
1001
1017
 
1002
1018
 
1003
1019
  def test_invalid_then_valid_no_ncproperties(tmp_local_or_remote_netcdf):
1004
- with pytest.warns(UserWarning, match="invalid netcdf features"):
1020
+ with warns(UserWarning, match="invalid netcdf features"):
1005
1021
  with h5netcdf.File(tmp_local_or_remote_netcdf, "w", invalid_netcdf=True):
1006
1022
  pass
1007
1023
  with h5netcdf.File(tmp_local_or_remote_netcdf, "a"):
@@ -1019,11 +1035,8 @@ def test_creating_and_resizing_unlimited_dimensions(tmp_local_or_remote_netcdf):
1019
1035
  f.dimensions["z"] = None
1020
1036
  f.resize_dimension("z", 20)
1021
1037
 
1022
- with pytest.raises(ValueError) as e:
1038
+ with raises(ValueError, match="is not unlimited and thus cannot be resized"):
1023
1039
  f.resize_dimension("y", 20)
1024
- assert e.value.args[0] == (
1025
- "Dimension 'y' is not unlimited and thus cannot be resized."
1026
- )
1027
1040
 
1028
1041
  h5 = get_hdf5_module(tmp_local_or_remote_netcdf)
1029
1042
  # Assert some behavior observed by using the C netCDF bindings.
@@ -1049,11 +1062,10 @@ def test_creating_variables_with_unlimited_dimensions(tmp_local_or_remote_netcdf
1049
1062
 
1050
1063
  # Trying to create a variable while the current size of the dimension
1051
1064
  # is still zero will fail.
1052
- with pytest.raises(ValueError) as e:
1065
+ with raises(ValueError, match="Shape tuple is incompatible with data"):
1053
1066
  f.create_variable(
1054
1067
  "dummy2", data=np.array([[1, 2], [3, 4]]), dimensions=("x", "y")
1055
1068
  )
1056
- assert e.value.args[0] == "Shape tuple is incompatible with data"
1057
1069
 
1058
1070
  # Creating a coordinate variable
1059
1071
  f.create_variable("x", dimensions=("x",), dtype=np.int64)
@@ -1078,7 +1090,7 @@ def test_creating_variables_with_unlimited_dimensions(tmp_local_or_remote_netcdf
1078
1090
  # We don't expect any errors. This is effectively a void context manager
1079
1091
  expected_errors = memoryview(b"")
1080
1092
  else:
1081
- expected_errors = pytest.raises(TypeError)
1093
+ expected_errors = raises(TypeError, match="Can't broadcast")
1082
1094
  with expected_errors as e:
1083
1095
  f.variables["dummy3"][:] = np.ones((5, 2))
1084
1096
  if not tmp_local_or_remote_netcdf.startswith(remote_h5):
@@ -1115,11 +1127,10 @@ def test_writing_to_an_unlimited_dimension(tmp_local_or_remote_netcdf):
1115
1127
  f.dimensions["z"] = None
1116
1128
 
1117
1129
  # Cannot create it without first resizing it.
1118
- with pytest.raises(ValueError) as e:
1130
+ with raises(ValueError, match="Shape tuple is incompatible with data"):
1119
1131
  f.create_variable(
1120
1132
  "dummy1", data=np.array([[1, 2, 3]]), dimensions=("x", "y")
1121
1133
  )
1122
- assert e.value.args[0] == "Shape tuple is incompatible with data"
1123
1134
 
1124
1135
  # Without data.
1125
1136
  f.create_variable("dummy1", dimensions=("x", "y"), dtype=np.int64)
@@ -1148,7 +1159,9 @@ def test_writing_to_an_unlimited_dimension(tmp_local_or_remote_netcdf):
1148
1159
 
1149
1160
  # broadcast writing
1150
1161
  if tmp_local_or_remote_netcdf.startswith(remote_h5):
1151
- expected_errors = pytest.raises(OSError)
1162
+ expected_errors = raises(
1163
+ OSError, match="Got asyncio.IncompleteReadError during binary read"
1164
+ )
1152
1165
  else:
1153
1166
  # We don't expect any errors. This is effectively a void context manager
1154
1167
  expected_errors = memoryview(b"")
@@ -1761,10 +1774,10 @@ def test_track_order_specification(tmp_local_netcdf):
1761
1774
  # This should always work with the default file opening settings
1762
1775
  # https://github.com/h5netcdf/h5netcdf/issues/136#issuecomment-1017457067
1763
1776
  def test_more_than_7_attr_creation(tmp_local_netcdf):
1764
- with h5netcdf.File(tmp_local_netcdf, "w") as h5file:
1777
+ with h5netcdf.File(tmp_local_netcdf, "w") as _h5file:
1765
1778
  for i in range(100):
1766
- h5file.attrs[f"key{i}"] = i
1767
- h5file.attrs[f"key{i}"] = 0
1779
+ _h5file.attrs[f"key{i}"] = i
1780
+ _h5file.attrs[f"key{i}"] = 0
1768
1781
 
1769
1782
 
1770
1783
  # Add a test that is supposed to fail in relation to issue #136
@@ -1773,18 +1786,10 @@ def test_more_than_7_attr_creation(tmp_local_netcdf):
1773
1786
  # https://github.com/h5netcdf/h5netcdf/issues/136#issuecomment-1017457067
1774
1787
  @pytest.mark.parametrize("track_order", [False, True])
1775
1788
  def test_more_than_7_attr_creation_track_order(tmp_local_netcdf, track_order):
1776
- h5py_version = version.parse(h5py.__version__)
1777
- if track_order and h5py_version < version.parse("3.7.0"):
1778
- expected_errors = pytest.raises(KeyError)
1779
- else:
1780
- # We don't expect any errors. This is effectively a void context manager
1781
- expected_errors = memoryview(b"")
1782
-
1783
- with h5netcdf.File(tmp_local_netcdf, "w", track_order=track_order) as h5file:
1784
- with expected_errors:
1785
- for i in range(100):
1786
- h5file.attrs[f"key{i}"] = i
1787
- h5file.attrs[f"key{i}"] = 0
1789
+ with h5netcdf.File(tmp_local_netcdf, "w", track_order=track_order) as _h5file:
1790
+ for i in range(100):
1791
+ _h5file.attrs[f"key{i}"] = i
1792
+ _h5file.attrs[f"key{i}"] = 0
1788
1793
 
1789
1794
 
1790
1795
  def test_group_names(tmp_local_netcdf):
@@ -1871,18 +1876,11 @@ def test_bool_slicing_length_one_dim(tmp_local_netcdf):
1871
1876
  data = ds["hello"][bool_slice, :]
1872
1877
  np.testing.assert_equal(data, np.zeros((1, 2)))
1873
1878
 
1874
- # should raise for h5py >= 3.0.0 and h5py < 3.7.0
1879
+ # regression test
1875
1880
  # https://github.com/h5py/h5py/pull/2079
1876
1881
  # https://github.com/h5netcdf/h5netcdf/pull/125/
1877
1882
  with h5netcdf.File(tmp_local_netcdf, "r") as ds:
1878
- h5py_version = version.parse(h5py.__version__)
1879
- if version.parse("3.0.0") <= h5py_version < version.parse("3.7.0"):
1880
- error = "Indexing arrays must have integer dtypes"
1881
- with pytest.raises(TypeError) as e:
1882
- ds["hello"][bool_slice, :]
1883
- assert error == str(e.value)
1884
- else:
1885
- ds["hello"][bool_slice, :]
1883
+ ds["hello"][bool_slice, :]
1886
1884
 
1887
1885
 
1888
1886
  def test_fancy_indexing(tmp_local_or_remote_netcdf):
@@ -2303,38 +2301,36 @@ def test_user_type_errors_new_api(tmp_local_or_remote_netcdf):
2303
2301
  enum_type = ds.create_enumtype(np.uint8, "enum_t", enum_dict1)
2304
2302
 
2305
2303
  if tmp_local_or_remote_netcdf.startswith(remote_h5):
2306
- testcontext = pytest.raises(RuntimeError, match="Conflict")
2304
+ testcontext = raises(RuntimeError, match="Conflict")
2307
2305
  else:
2308
- testcontext = pytest.raises(
2309
- (KeyError, TypeError), match="name already exists"
2310
- )
2306
+ testcontext = raises((KeyError, TypeError), match="name already exists")
2311
2307
  with testcontext:
2312
2308
  ds.create_enumtype(np.uint8, "enum_t", enum_dict2)
2313
2309
 
2314
2310
  enum_type2 = g.create_enumtype(np.uint8, "enum_t2", enum_dict2)
2315
2311
  g.create_enumtype(np.uint8, "enum_t", enum_dict2)
2316
- with pytest.raises(TypeError, match="Please provide h5netcdf user type"):
2312
+ with raises(TypeError, match="Please provide h5netcdf user type"):
2317
2313
  ds.create_variable(
2318
2314
  "enum_var1",
2319
2315
  ("enum_dim",),
2320
2316
  dtype=enum_type._h5ds,
2321
2317
  fillvalue=enum_dict1["missing"],
2322
2318
  )
2323
- with pytest.raises(TypeError, match="is not committed into current file"):
2319
+ with raises(TypeError, match="is not committed into current file"):
2324
2320
  ds.create_variable(
2325
2321
  "enum_var2",
2326
2322
  ("enum_dim",),
2327
2323
  dtype=enum_type_ext,
2328
2324
  fillvalue=enum_dict1["missing"],
2329
2325
  )
2330
- with pytest.raises(TypeError, match="is not accessible in current group"):
2326
+ with raises(TypeError, match="is not accessible in current group"):
2331
2327
  ds.create_variable(
2332
2328
  "enum_var3",
2333
2329
  ("enum_dim",),
2334
2330
  dtype=enum_type2,
2335
2331
  fillvalue=enum_dict2["missing"],
2336
2332
  )
2337
- with pytest.raises(TypeError, match="Another dtype with same name"):
2333
+ with raises(TypeError, match="Another dtype with same name"):
2338
2334
  g.create_variable(
2339
2335
  "enum_var4",
2340
2336
  ("enum_dim",),
@@ -2353,38 +2349,36 @@ def test_user_type_errors_legacyapi(tmp_local_or_remote_netcdf):
2353
2349
  g = ds.createGroup("subgroup")
2354
2350
  enum_type = ds.createEnumType(np.uint8, "enum_t", enum_dict1)
2355
2351
  if tmp_local_or_remote_netcdf.startswith(remote_h5):
2356
- testcontext = pytest.raises(RuntimeError, match="Conflict")
2352
+ testcontext = raises(RuntimeError, match="Conflict")
2357
2353
  else:
2358
- testcontext = pytest.raises(
2359
- (KeyError, TypeError), match="name already exists"
2360
- )
2354
+ testcontext = raises((KeyError, TypeError), match="name already exists")
2361
2355
  with testcontext:
2362
2356
  ds.createEnumType(np.uint8, "enum_t", enum_dict1)
2363
2357
 
2364
2358
  enum_type2 = g.createEnumType(np.uint8, "enum_t2", enum_dict2)
2365
2359
  g.create_enumtype(np.uint8, "enum_t", enum_dict2)
2366
- with pytest.raises(TypeError, match="Please provide h5netcdf user type"):
2360
+ with raises(TypeError, match="Please provide h5netcdf user type"):
2367
2361
  ds.createVariable(
2368
2362
  "enum_var1",
2369
2363
  enum_type._h5ds,
2370
2364
  ("enum_dim",),
2371
2365
  fill_value=enum_dict1["missing"],
2372
2366
  )
2373
- with pytest.raises(TypeError, match="is not committed into current file"):
2367
+ with raises(TypeError, match="is not committed into current file"):
2374
2368
  ds.createVariable(
2375
2369
  "enum_var2",
2376
2370
  enum_type_ext,
2377
2371
  ("enum_dim",),
2378
2372
  fill_value=enum_dict1["missing"],
2379
2373
  )
2380
- with pytest.raises(TypeError, match="is not accessible in current group"):
2374
+ with raises(TypeError, match="is not accessible in current group"):
2381
2375
  ds.createVariable(
2382
2376
  "enum_var3",
2383
2377
  enum_type2,
2384
2378
  ("enum_dim",),
2385
2379
  fill_value=enum_dict2["missing"],
2386
2380
  )
2387
- with pytest.raises(TypeError, match="Another dtype with same name"):
2381
+ with raises(TypeError, match="Another dtype with same name"):
2388
2382
  g.createVariable(
2389
2383
  "enum_var4",
2390
2384
  enum_type,
@@ -2402,7 +2396,7 @@ def test_enum_type_errors_new_api(tmp_local_or_remote_netcdf):
2402
2396
  enum_type2 = ds.create_enumtype(np.uint8, "enum_t2", enum_dict2)
2403
2397
 
2404
2398
  # 1.
2405
- with pytest.warns(UserWarning, match="default fill_value 0 which IS defined"):
2399
+ with warns(UserWarning, match="default fill_value 0 which IS defined"):
2406
2400
  ds.create_variable(
2407
2401
  "enum_var1",
2408
2402
  ("enum_dim",),
@@ -2410,18 +2404,14 @@ def test_enum_type_errors_new_api(tmp_local_or_remote_netcdf):
2410
2404
  )
2411
2405
  # 2. is for legacyapi only
2412
2406
  # 3.
2413
- with pytest.warns(
2414
- UserWarning, match="default fill_value 0 which IS NOT defined"
2415
- ):
2407
+ with warns(UserWarning, match="default fill_value 0 which IS NOT defined"):
2416
2408
  ds.create_variable(
2417
2409
  "enum_var2",
2418
2410
  ("enum_dim",),
2419
2411
  dtype=enum_type,
2420
2412
  )
2421
2413
  # 4.
2422
- with pytest.warns(
2423
- UserWarning, match="with specified fill_value 0 which IS NOT"
2424
- ):
2414
+ with warns(UserWarning, match="with specified fill_value 0 which IS NOT"):
2425
2415
  ds.create_variable(
2426
2416
  "enum_var3",
2427
2417
  ("enum_dim",),
@@ -2429,9 +2419,7 @@ def test_enum_type_errors_new_api(tmp_local_or_remote_netcdf):
2429
2419
  fillvalue=0,
2430
2420
  )
2431
2421
  # 5.
2432
- with pytest.raises(
2433
- ValueError, match="with specified fill_value 100 which IS NOT"
2434
- ):
2422
+ with raises(ValueError, match="with specified fill_value 100 which IS NOT"):
2435
2423
  ds.create_variable(
2436
2424
  "enum_var4",
2437
2425
  ("enum_dim",),
@@ -2449,14 +2437,14 @@ def test_enum_type_errors_legacyapi(tmp_local_or_remote_netcdf):
2449
2437
  enum_type2 = ds.createEnumType(np.uint8, "enum_t2", enum_dict2)
2450
2438
 
2451
2439
  # 1.
2452
- with pytest.warns(UserWarning, match="default fill_value 255 which IS defined"):
2440
+ with warns(UserWarning, match="default fill_value 255 which IS defined"):
2453
2441
  ds.createVariable(
2454
2442
  "enum_var1",
2455
2443
  enum_type2,
2456
2444
  ("enum_dim",),
2457
2445
  )
2458
2446
  # 2.
2459
- with pytest.raises(ValueError, match="default fill_value 255 which IS NOT"):
2447
+ with raises(ValueError, match="default fill_value 255 which IS NOT"):
2460
2448
  ds.createVariable(
2461
2449
  "enum_var2",
2462
2450
  enum_type,
@@ -2464,9 +2452,7 @@ def test_enum_type_errors_legacyapi(tmp_local_or_remote_netcdf):
2464
2452
  )
2465
2453
  # 3. is only for new api
2466
2454
  # 4.
2467
- with pytest.warns(
2468
- UserWarning, match="interpreted as '_UNDEFINED' by netcdf-c."
2469
- ):
2455
+ with warns(UserWarning, match="interpreted as '_UNDEFINED' by netcdf-c."):
2470
2456
  ds.createVariable(
2471
2457
  "enum_var3",
2472
2458
  enum_type,
@@ -2474,9 +2460,7 @@ def test_enum_type_errors_legacyapi(tmp_local_or_remote_netcdf):
2474
2460
  fill_value=0,
2475
2461
  )
2476
2462
  # 5.
2477
- with pytest.raises(
2478
- ValueError, match="with specified fill_value 100 which IS NOT"
2479
- ):
2463
+ with raises(ValueError, match="with specified fill_value 100 which IS NOT"):
2480
2464
  ds.createVariable("enum_var4", enum_type, ("enum_dim",), fill_value=100)
2481
2465
 
2482
2466
 
@@ -2494,9 +2478,8 @@ def test_enum_type(tmp_local_or_remote_netcdf):
2494
2478
  "enum_var", ("enum_dim",), dtype=enum_type, fillvalue=enum_dict["missing"]
2495
2479
  )
2496
2480
  v[0:3] = [1, 2, 3]
2497
- with pytest.raises(ValueError) as e:
2481
+ with raises(ValueError, match="assign illegal value"):
2498
2482
  v[3] = 5
2499
- assert "assign illegal value(s)" in e.value.args[0]
2500
2483
 
2501
2484
  # check, if new API can read them
2502
2485
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r") as ds:
@@ -2537,9 +2520,8 @@ def test_enum_type(tmp_local_or_remote_netcdf):
2537
2520
  "enum_var", enum_type, ("enum_dim",), fill_value=enum_dict["missing"]
2538
2521
  )
2539
2522
  v[0:3] = [1, 2, 3]
2540
- with pytest.raises(ValueError) as e:
2523
+ with raises(ValueError, match="assign illegal value"):
2541
2524
  v[3] = 5
2542
- assert "assign illegal value(s)" in e.value.args[0]
2543
2525
 
2544
2526
  # check, if new API can read them
2545
2527
  with h5netcdf.File(tmp_local_or_remote_netcdf, "r") as ds:
@@ -2581,9 +2563,7 @@ def test_enum_type(tmp_local_or_remote_netcdf):
2581
2563
  "enum_var", enum_type, ("enum_dim",), fill_value=enum_dict["missing"]
2582
2564
  )
2583
2565
  v[0:3] = [1, 2, 3]
2584
- with pytest.raises(
2585
- ValueError, match="assign illegal value to Enum variable"
2586
- ):
2566
+ with raises(ValueError, match="assign illegal value to Enum variable"):
2587
2567
  v[3] = 5
2588
2568
 
2589
2569
  # check, if new API can read them
@@ -2770,14 +2750,14 @@ def test_complex_type_creation_errors(tmp_local_netcdf):
2770
2750
 
2771
2751
  with legacyapi.Dataset(tmp_local_netcdf, "w") as ds:
2772
2752
  ds.createDimension("x", size=len(complex_array))
2773
- with pytest.raises(TypeError, match="data type 'c4' not understood"):
2753
+ with raises(TypeError, match="data type 'c4' not understood"):
2774
2754
  ds.createVariable("data", "c4", ("x",))
2775
2755
 
2776
2756
  if "complex256" not in np.sctypeDict:
2777
2757
  pytest.skip("numpy 'complex256' dtype not available")
2778
2758
  with legacyapi.Dataset(tmp_local_netcdf, "w") as ds:
2779
2759
  ds.createDimension("x", size=len(complex_array))
2780
- with pytest.raises(
2760
+ with raises(
2781
2761
  TypeError,
2782
2762
  match="Currently only 'complex64' and 'complex128' dtypes are allowed.",
2783
2763
  ):
@@ -2839,9 +2819,22 @@ def test_h5pyd_append(hsds_up):
2839
2819
  rnd = "".join(random.choice(string.ascii_uppercase) for _ in range(5))
2840
2820
  fname = f"hdf5://testfile{rnd}.nc"
2841
2821
 
2842
- with pytest.warns(UserWarning, match="Append mode for h5pyd"):
2822
+ with warns(UserWarning, match="Append mode for h5pyd"):
2843
2823
  with h5netcdf.File(fname, "a", driver="h5pyd") as ds:
2844
2824
  assert not ds._preexisting_file
2845
2825
 
2846
2826
  with h5netcdf.File(fname, "a", driver="h5pyd") as ds:
2847
2827
  assert ds._preexisting_file
2828
+
2829
+
2830
+ def test_raise_on_closed_file(tmp_local_netcdf):
2831
+ f = h5netcdf.File(tmp_local_netcdf, "w")
2832
+ f.dimensions = {"x": 5}
2833
+ v = f.create_variable("hello", ("x",), float)
2834
+ v[:] = np.ones(5)
2835
+ f.close()
2836
+ with pytest.raises(
2837
+ ValueError,
2838
+ match=f"I/O operation on <Closed h5netcdf.File>: '{tmp_local_netcdf}'",
2839
+ ):
2840
+ print(v[:])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: h5netcdf
3
- Version: 1.6.2
3
+ Version: 1.6.4
4
4
  Summary: netCDF4 via h5py
5
5
  Author-email: Stephan Hoyer <shoyer@gmail.com>, Kai Mühlbauer <kmuehlbauer@wradlib.org>
6
6
  Maintainer-email: h5netcdf developers <devteam@h5netcdf.org>
@@ -0,0 +1,16 @@
1
+ h5netcdf/__init__.py,sha256=Y0EBCcmlJctwl1kCmj7yLijTVy9AioBTr2091vInAtw,456
2
+ h5netcdf/_version.py,sha256=eKLk8tnaa9UngtBI-cdJk3waeUMaUqzicpfaPStcUCU,511
3
+ h5netcdf/attrs.py,sha256=4IvV4ULLWkz4igFsvu9S2LB745wgUKrIdIuSeO5kpX8,3581
4
+ h5netcdf/core.py,sha256=aF04z6vzIapupHp-YM4C4ka67sFUcksuRsib4X7d33A,64311
5
+ h5netcdf/dimensions.py,sha256=ln6n3J-BE2PlJDPlr9YiqPYHhXRUHVH3j_7_1O0VGS0,7802
6
+ h5netcdf/legacyapi.py,sha256=MIZlht5Ad4hDFF1Slz2vXmKkgbv7Fhhf2YwNIe16Lfk,7682
7
+ h5netcdf/utils.py,sha256=6E-HAIE0ONMyL4SxI3oUyQvrDgDWifR5EPde91V9rT0,674
8
+ h5netcdf/tests/conftest.py,sha256=4fLa2qoB8br2UpokaOn1-mjHgqVUgVV0G3QLIUzfbZo,2133
9
+ h5netcdf/tests/pytest.ini,sha256=ruJxrLdCIA4bCPVuPQjxsLSlvVxuIsIakK6iQOmz-ak,107
10
+ h5netcdf/tests/test_h5netcdf.py,sha256=x-htYHyk2T9VO8-kdhZa2l6R4PsvL0G-Q222A9MmHVc,110576
11
+ h5netcdf-1.6.4.dist-info/licenses/AUTHORS.txt,sha256=LTKzUh9o4Wc_oT3aFC48cyDCCP6tdm6VEV_6RrNy4uo,272
12
+ h5netcdf-1.6.4.dist-info/licenses/LICENSE,sha256=Xer1Jg8iL_n9Da0xt0S99blk6tsg9tee_JdgH1rWTjs,1505
13
+ h5netcdf-1.6.4.dist-info/METADATA,sha256=LH_Lqa0YZTwiIn-5uKy8fZsB8jgBIBt5v4nmOHRX1vg,13387
14
+ h5netcdf-1.6.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
+ h5netcdf-1.6.4.dist-info/top_level.txt,sha256=Fb_KIpOE6MBqjSvxV1Ay7oYce1mdmQ1pO9JQJPDeGqg,9
16
+ h5netcdf-1.6.4.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- h5netcdf/__init__.py,sha256=Y0EBCcmlJctwl1kCmj7yLijTVy9AioBTr2091vInAtw,456
2
- h5netcdf/_version.py,sha256=0l_x32-zDcY9aQqQSs0LtsRx42EjkEfyXdUn9HtFgXU,511
3
- h5netcdf/attrs.py,sha256=4IvV4ULLWkz4igFsvu9S2LB745wgUKrIdIuSeO5kpX8,3581
4
- h5netcdf/core.py,sha256=AnPeV5XE_04QZWPSM7WjrddaKfkkdPtvbIMEKf3cSIs,64154
5
- h5netcdf/dimensions.py,sha256=2g0p9DOAC0hhQ94spIAjWeKC1qyhzzO0s15xCFYSscM,7803
6
- h5netcdf/legacyapi.py,sha256=MIZlht5Ad4hDFF1Slz2vXmKkgbv7Fhhf2YwNIe16Lfk,7682
7
- h5netcdf/utils.py,sha256=6E-HAIE0ONMyL4SxI3oUyQvrDgDWifR5EPde91V9rT0,674
8
- h5netcdf/tests/conftest.py,sha256=4fLa2qoB8br2UpokaOn1-mjHgqVUgVV0G3QLIUzfbZo,2133
9
- h5netcdf/tests/pytest.ini,sha256=ruJxrLdCIA4bCPVuPQjxsLSlvVxuIsIakK6iQOmz-ak,107
10
- h5netcdf/tests/test_h5netcdf.py,sha256=Pap1X7YQNRGyU5wH17ZDmHZaPLdRkQwB7BrKQeUjImE,110737
11
- h5netcdf-1.6.2.dist-info/licenses/AUTHORS.txt,sha256=LTKzUh9o4Wc_oT3aFC48cyDCCP6tdm6VEV_6RrNy4uo,272
12
- h5netcdf-1.6.2.dist-info/licenses/LICENSE,sha256=Xer1Jg8iL_n9Da0xt0S99blk6tsg9tee_JdgH1rWTjs,1505
13
- h5netcdf-1.6.2.dist-info/METADATA,sha256=-FuPQxJcnu21jRLDgd6Dqx1Gu39smy8UrAoDImCGAn4,13387
14
- h5netcdf-1.6.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
15
- h5netcdf-1.6.2.dist-info/top_level.txt,sha256=Fb_KIpOE6MBqjSvxV1Ay7oYce1mdmQ1pO9JQJPDeGqg,9
16
- h5netcdf-1.6.2.dist-info/RECORD,,