h5netcdf 1.6.3__tar.gz → 1.6.4__tar.gz

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.

Files changed (33) hide show
  1. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/CHANGELOG.rst +7 -0
  2. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/PKG-INFO +1 -1
  3. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/_version.py +2 -2
  4. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/core.py +17 -12
  5. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/tests/test_h5netcdf.py +68 -47
  6. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf.egg-info/PKG-INFO +1 -1
  7. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/.pre-commit-config.yaml +0 -0
  8. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/AUTHORS.txt +0 -0
  9. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/LICENSE +0 -0
  10. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/README.rst +0 -0
  11. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/Makefile +0 -0
  12. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/api.rst +0 -0
  13. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/changelog.rst +0 -0
  14. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/conf.py +0 -0
  15. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/devguide.rst +0 -0
  16. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/feature.rst +0 -0
  17. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/index.rst +0 -0
  18. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/doc/legacyapi.rst +0 -0
  19. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/__init__.py +0 -0
  20. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/attrs.py +0 -0
  21. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/dimensions.py +0 -0
  22. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/legacyapi.py +0 -0
  23. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/tests/conftest.py +0 -0
  24. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/tests/pytest.ini +0 -0
  25. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf/utils.py +0 -0
  26. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf.egg-info/SOURCES.txt +0 -0
  27. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf.egg-info/dependency_links.txt +0 -0
  28. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf.egg-info/requires.txt +0 -0
  29. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/h5netcdf.egg-info/top_level.txt +0 -0
  30. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/licenses/H5PY_LICENSE.txt +0 -0
  31. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/licenses/PSF_LICENSE.txt +0 -0
  32. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/pyproject.toml +0 -0
  33. {h5netcdf-1.6.3 → h5netcdf-1.6.4}/setup.cfg +0 -0
@@ -1,6 +1,13 @@
1
1
  Change Log
2
2
  ----------
3
3
 
4
+ Version 1.6.4 (August 5th, 2025):
5
+
6
+ - Cleanup: pyupgrade --py39-plus
7
+ By `Kurt Schwehr <https://github.com/schwehr>`_
8
+ - Add better error messages when operating on a closed file (:issue:`274`, :pull:`275`).
9
+ By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_
10
+
4
11
  Version 1.6.3 (June 30th, 2025):
5
12
 
6
13
  - fix invalid string format specifier, match raises/warns with messages in test suite,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: h5netcdf
3
- Version: 1.6.3
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>
@@ -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.3'
21
- __version_tuple__ = version_tuple = (1, 6, 3)
20
+ __version__ = version = '1.6.4'
21
+ __version_tuple__ = version_tuple = (1, 6, 4)
@@ -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}."
@@ -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
@@ -262,26 +262,30 @@ def read_legacy_netcdf(tmp_netcdf, read_module, write_module):
262
262
  assert ds.other_attr == "yes"
263
263
  with raises(AttributeError, match="not found"):
264
264
  ds.does_not_exist
265
- assert set(ds.dimensions) == set(
266
- ["x", "y", "z", "empty", "string3", "mismatched_dim", "unlimited"]
267
- )
268
- assert set(ds.variables) == set(
269
- [
270
- "enum_var",
271
- "foo",
272
- "y",
273
- "z",
274
- "intscalar",
275
- "scalar",
276
- "var_len_str",
277
- "mismatched_dim",
278
- "foo_unlimited",
279
- ]
280
- )
281
-
282
- assert set(ds.enumtypes) == set(["enum_t"])
283
-
284
- 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"}
285
289
  assert ds.parent is None
286
290
  v = ds.variables["foo"]
287
291
  assert array_equal(v, np.ones((4, 5)))
@@ -382,27 +386,31 @@ def read_h5netcdf(tmp_netcdf, write_module, decode_vlen_strings):
382
386
  if write_module is not netCDF4:
383
387
  # skip for now: https://github.com/Unidata/netcdf4-python/issues/388
384
388
  assert ds.attrs["other_attr"] == "yes"
385
- assert set(ds.dimensions) == set(
386
- ["x", "y", "z", "empty", "string3", "mismatched_dim", "unlimited"]
387
- )
388
- variables = set(
389
- [
390
- "enum_var",
391
- "foo",
392
- "z",
393
- "intscalar",
394
- "scalar",
395
- "var_len_str",
396
- "mismatched_dim",
397
- "foo_unlimited",
398
- ]
399
- )
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
+ }
400
408
  # fix current failure of hsds/h5pyd
401
409
  if not remote_file:
402
- variables |= set(["y"])
410
+ variables |= {"y"}
403
411
  assert set(ds.variables) == variables
404
412
 
405
- assert set(ds.groups) == set(["subgroup"])
413
+ assert set(ds.groups) == {"subgroup"}
406
414
  assert ds.parent is None
407
415
 
408
416
  v = ds["foo"]
@@ -845,13 +853,13 @@ def test_hierarchical_access_auto_create(tmp_local_or_remote_netcdf):
845
853
  ds.create_variable("/foo/bar", data=1)
846
854
  g = ds.create_group("foo/baz")
847
855
  g.create_variable("/foo/hello", data=2)
848
- assert set(ds) == set(["foo"])
849
- assert set(ds["foo"]) == set(["bar", "baz", "hello"])
856
+ assert set(ds) == {"foo"}
857
+ assert set(ds["foo"]) == {"bar", "baz", "hello"}
850
858
  ds.close()
851
859
 
852
860
  ds = h5netcdf.File(tmp_local_or_remote_netcdf, "r")
853
- assert set(ds) == set(["foo"])
854
- assert set(ds["foo"]) == set(["bar", "baz", "hello"])
861
+ assert set(ds) == {"foo"}
862
+ assert set(ds["foo"]) == {"bar", "baz", "hello"}
855
863
  ds.close()
856
864
 
857
865
 
@@ -1766,10 +1774,10 @@ def test_track_order_specification(tmp_local_netcdf):
1766
1774
  # This should always work with the default file opening settings
1767
1775
  # https://github.com/h5netcdf/h5netcdf/issues/136#issuecomment-1017457067
1768
1776
  def test_more_than_7_attr_creation(tmp_local_netcdf):
1769
- with h5netcdf.File(tmp_local_netcdf, "w") as h5file:
1777
+ with h5netcdf.File(tmp_local_netcdf, "w") as _h5file:
1770
1778
  for i in range(100):
1771
- h5file.attrs[f"key{i}"] = i
1772
- h5file.attrs[f"key{i}"] = 0
1779
+ _h5file.attrs[f"key{i}"] = i
1780
+ _h5file.attrs[f"key{i}"] = 0
1773
1781
 
1774
1782
 
1775
1783
  # Add a test that is supposed to fail in relation to issue #136
@@ -1778,10 +1786,10 @@ def test_more_than_7_attr_creation(tmp_local_netcdf):
1778
1786
  # https://github.com/h5netcdf/h5netcdf/issues/136#issuecomment-1017457067
1779
1787
  @pytest.mark.parametrize("track_order", [False, True])
1780
1788
  def test_more_than_7_attr_creation_track_order(tmp_local_netcdf, track_order):
1781
- with h5netcdf.File(tmp_local_netcdf, "w", track_order=track_order) as h5file:
1789
+ with h5netcdf.File(tmp_local_netcdf, "w", track_order=track_order) as _h5file:
1782
1790
  for i in range(100):
1783
- h5file.attrs[f"key{i}"] = i
1784
- h5file.attrs[f"key{i}"] = 0
1791
+ _h5file.attrs[f"key{i}"] = i
1792
+ _h5file.attrs[f"key{i}"] = 0
1785
1793
 
1786
1794
 
1787
1795
  def test_group_names(tmp_local_netcdf):
@@ -2817,3 +2825,16 @@ def test_h5pyd_append(hsds_up):
2817
2825
 
2818
2826
  with h5netcdf.File(fname, "a", driver="h5pyd") as ds:
2819
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.3
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>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes