From 01d531ef4f23874f808b40ad1d2ec3186bead557 Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 31 Oct 2024 15:44:23 +0000 Subject: [PATCH 1/4] Extend call to __query_wi__ wit open_{upper, lower} --- cf/query.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cf/query.py b/cf/query.py index 87ff0c1c5b..56e2365ca1 100644 --- a/cf/query.py +++ b/cf/query.py @@ -972,7 +972,7 @@ def _evaluate(self, x, parent_attr): if operator == "wi": _wi = getattr(x, "__query_wi__", None) if _wi is not None: - return _wi(value) + return _wi(value, self.open_lower, self.open_upper) if self.open_lower: lower_bound = x > value[0] From c9aedd4c60229bc09c862d8e4a7ed52df098f45c Mon Sep 17 00:00:00 2001 From: "Sadie L. Bartholomew" Date: Thu, 31 Oct 2024 15:52:56 +0000 Subject: [PATCH 2/4] Add clarification about __query_wi__ to docstring --- cf/query.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cf/query.py b/cf/query.py index 56e2365ca1..268ca7b6d0 100644 --- a/cf/query.py +++ b/cf/query.py @@ -166,10 +166,11 @@ class Query: evaluated. ====================== ============================================== - In general, each method must have the query value as it's only - parameter. The only exception is for `__query_isclose__`, which + In general, each method must have the query value as its only + parameter. The only exceptions are for `__query_isclose__`, which also requires the absolute and relative numerical tolerances to be - provided. + provided, and for `__query_wi__`, which also requires upper and + lower interval openness Booleans to be provided. When the condition is on an attribute, or nested attributes, of the operand, the query interface method is looked for on the From 45763fc919aded91b03f223f4de3a9f0fe4e8875 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 4 Nov 2024 12:03:46 +0000 Subject: [PATCH 3/4] Fix changelog --- Changelog.rst | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/Changelog.rst b/Changelog.rst index d1ed7a8d2f..14723cf7a4 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -1,22 +1,3 @@ -version NEXTVERSION + 1 ------------------------ - -**2024-??-??** - -* Allow access to netCDF-4 files in S3 object stores - (https://github.com/NCAS-CMS/cf-python/issues/712) -* New class `cf.H5netcdfArray` -* New class `cf.NetCDF4Array` -* New class `cf.CFAH5netcdfArray` -* New class `cf.CFANetCDF4Array` -* New dependency: ``h5netcdf>=1.3.0`` -* New dependency: ``h5py>=3.10.0`` -* New dependency: ``s3fs>=2024.2.0`` -* Changed dependency: ``1.11.2.0<=cfdm<1.11.3.0`` -* Changed dependency: ``cfunits>=3.3.7`` - ----- - version NEXTVERSION ------------------- @@ -33,6 +14,12 @@ version NEXTVERSION * New keyword parameter to `cf.Field.derivative`: ``ignore_coordinate_units`` (https://github.com/NCAS-CMS/cf-python/issues/807) +* Allow access to netCDF-4 files in S3 object stores + (https://github.com/NCAS-CMS/cf-python/issues/712) +* New class `cf.H5netcdfArray` +* New class `cf.NetCDF4Array` +* New class `cf.CFAH5netcdfArray` +* New class `cf.CFANetCDF4Array` * Fix bug that sometimes puts an incorrect ``radian-1`` or ``radian-2`` in the returned units of the differential operator methods and functions @@ -46,6 +33,12 @@ version NEXTVERSION * Fix bug where `cf.normalize_slice` doesn't correctly handle certain cyclic slices (https://github.com/NCAS-CMS/cf-python/issues/774) +* New dependency: ``h5netcdf>=1.3.0`` +* New dependency: ``h5py>=3.10.0`` +* New dependency: ``s3fs>=2024.2.0`` +* Changed dependency: ``1.11.2.0<=cfdm<1.11.3.0`` +* Changed dependency: ``cfunits>=3.3.7`` + ---- From 1cde9f41e86bc2c9e0c291410e293542b8d89781 Mon Sep 17 00:00:00 2001 From: David Hassell Date: Mon, 4 Nov 2024 12:05:58 +0000 Subject: [PATCH 4/4] remove REVIEW comments --- cf/test/test_Data.py | 4 ---- cf/test/test_Field.py | 2 -- cf/test/test_FullArray.py | 1 - cf/test/test_NetCDF4Array.py | 8 -------- cf/test/test_active_storage.py | 1 - cf/test/test_functions.py | 1 - cf/test/test_read_write.py | 2 -- 7 files changed, 19 deletions(-) diff --git a/cf/test/test_Data.py b/cf/test/test_Data.py index a62b49b76e..e29c192062 100644 --- a/cf/test/test_Data.py +++ b/cf/test/test_Data.py @@ -1479,7 +1479,6 @@ def test_Data__getitem__(self): f = cf.Data([-999, 35], mask=[True, False]).reshape(2, 1) self.assertTrue(e.equals(f)) - # REVIEW: getitem: `test_Data__getitem__`: Chained subspaces reading from disk # Chained subspaces reading from disk f = cf.read(self.filename)[0] d = f.data @@ -3290,7 +3289,6 @@ def test_Data_rechunk(self): self.assertEqual(e.chunks, ((4,), (5,))) self.assertTrue(e.equals(d)) - # REVIEW: getitem: `test_Data_rechunk`: rechunking after a __getitem__ # Test rechunking after a __getitem__ e = d[:2].rechunk((2, 5)) self.assertTrue(e.equals(d[:2])) @@ -4520,7 +4518,6 @@ def test_Data__str__(self): for element in elements0: self.assertNotIn(element, d._get_cached_elements()) - # REVIEW: getitem: `test_Data_cull_graph`: prevent new asanyarray layer def test_Data_cull_graph(self): """Test `Data.cull`""" # Note: The number of layers in the culled graphs include a @@ -4779,7 +4776,6 @@ def test_Data_pad_missing(self): with self.assertRaises(ValueError): d.pad_missing(99, to_size=99) - # REVIEW: getitem: `test_Data_is_masked`: test `Data.is_masked` def test_Data_is_masked(self): """Test Data.is_masked.""" d = cf.Data(np.arange(6).reshape(2, 3)) diff --git a/cf/test/test_Field.py b/cf/test/test_Field.py index 04517ed4f2..92392b29f5 100644 --- a/cf/test/test_Field.py +++ b/cf/test/test_Field.py @@ -1466,7 +1466,6 @@ def test_Field_indices(self): shape = (1, 1, 1) self.assertEqual(g.shape, shape) - # REVIEW: getitem: `test_Field_indices`: make sure works when 'g.array' is not masked self.assertEqual(np.ma.compressed(g.array), 29) if mode != "full": self.assertEqual(g.construct("longitude").array, 83) @@ -1485,7 +1484,6 @@ def test_Field_indices(self): shape = (1, 2, 2) self.assertEqual(g.shape, shape) - # REVIEW: getitem: `test_Field_indices`: make sure works when 'g.array' is not masked self.assertTrue((np.ma.compressed(g.array) == [4, 29]).all()) # Add 2-d auxiliary coordinates with bounds, so we can diff --git a/cf/test/test_FullArray.py b/cf/test/test_FullArray.py index 8b25642686..63dcb84f34 100644 --- a/cf/test/test_FullArray.py +++ b/cf/test/test_FullArray.py @@ -1,4 +1,3 @@ -# REVIEW: getitem: `test_FullArray`: new test module import datetime import faulthandler import unittest diff --git a/cf/test/test_NetCDF4Array.py b/cf/test/test_NetCDF4Array.py index 35d76581be..0d049ff497 100644 --- a/cf/test/test_NetCDF4Array.py +++ b/cf/test/test_NetCDF4Array.py @@ -12,7 +12,6 @@ import cf -# REVIEW: h5: `test_NetCDF4Array.py`: renamed 'NetCDFArray' to 'NetCDF4Array' n_tmpfiles = 1 tmpfiles = [ tempfile.mkstemp("_test_NetCDF4Array.nc", dir=os.getcwd())[1] @@ -41,7 +40,6 @@ class NetCDF4ArrayTest(unittest.TestCase): dtype=np.dtype(float), ) - # REVIEW: h5: `test_NetCDF4Array`: renamed 'NetCDFArray' to 'NetCDF4Array' def test_NetCDF4Array_del_file_location(self): a = cf.NetCDF4Array(("/data1/file1", "/data2/file2"), ("tas1", "tas2")) b = a.del_file_location("/data1") @@ -62,7 +60,6 @@ def test_NetCDF4Array_del_file_location(self): with self.assertRaises(ValueError): b.del_file_location("/data1/") - # REVIEW: h5: `test_NetCDF4Array`: renamed 'NetCDFArray' to 'NetCDF4Array' def test_NetCDF4Array_file_locations(self): a = cf.NetCDF4Array("/data1/file1") self.assertEqual(a.file_locations(), ("/data1",)) @@ -73,7 +70,6 @@ def test_NetCDF4Array_file_locations(self): a = cf.NetCDF4Array(("/data1/file1", "/data2/file2", "/data1/file2")) self.assertEqual(a.file_locations(), ("/data1", "/data2", "/data1")) - # REVIEW: h5: `test_NetCDF4Array`: renamed 'NetCDFArray' to 'NetCDF4Array' def test_NetCDF4Array_add_file_location(self): a = cf.NetCDF4Array("/data1/file1", "tas") b = a.add_file_location("/home/user") @@ -109,7 +105,6 @@ def test_NetCDF4Array_add_file_location(self): self.assertEqual(b.get_filenames(), a.get_filenames()) self.assertEqual(b.get_addresses(), a.get_addresses()) - # REVIEW: h5: `test_NetCDF4Array`: renamed 'NetCDFArray' to 'NetCDF4Array' def test_NetCDF4Array__dask_tokenize__(self): a = cf.NetCDF4Array("/data1/file1", "tas", shape=(12, 2), mask=False) self.assertEqual(tokenize(a), tokenize(a.copy())) @@ -117,7 +112,6 @@ def test_NetCDF4Array__dask_tokenize__(self): b = cf.NetCDF4Array("/home/file2", "tas", shape=(12, 2)) self.assertNotEqual(tokenize(a), tokenize(b)) - # REVIEW: h5: `test_NetCDF4Array`: renamed 'NetCDFArray' to 'NetCDF4Array' def test_NetCDF4Array_multiple_files(self): f = cf.example_field(0) cf.write(f, tmpfile1) @@ -135,7 +129,6 @@ def test_NetCDF4Array_multiple_files(self): self.assertEqual(len(n.get_filenames()), 2) self.assertTrue((n[...] == f.array).all()) - # REVIEW: getitem: `test_NetCDF4Array`: test `NetCDF4Array.shape` def test_NetCDF4Array_shape(self): shape = (12, 73, 96) a = cf.NetCDF4Array("/home/file2", "tas", shape=shape) @@ -145,7 +138,6 @@ def test_NetCDF4Array_shape(self): self.assertEqual(a.shape, (shape[0] // 2,) + shape[1:]) self.assertEqual(a.original_shape, shape) - # REVIEW: getitem: `test_NetCDF4Array`: test `NetCDF4Array.index` def test_NetCDF4Array_index(self): shape = (12, 73, 96) a = cf.NetCDF4Array("/home/file2", "tas", shape=shape) diff --git a/cf/test/test_active_storage.py b/cf/test/test_active_storage.py index 8c7af64bdc..f14e063849 100644 --- a/cf/test/test_active_storage.py +++ b/cf/test/test_active_storage.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `test_active_storage.py`: new test module import atexit import datetime import faulthandler diff --git a/cf/test/test_functions.py b/cf/test/test_functions.py index 32bc3c4bd1..f6cce13ae0 100644 --- a/cf/test/test_functions.py +++ b/cf/test/test_functions.py @@ -47,7 +47,6 @@ def test_aliases(self): self.assertEqual(cf.tempdir(), cf.TEMPDIR()) self.assertEqual(cf.chunksize(), cf.CHUNKSIZE()) - # REVIEW: active: `test_configuration`: test `cf.active_storage`, cf.active_storage_url`, cf.active_storage_max_requests` def test_configuration(self): # This test assumes 'total_memory' remains constant throughout # the test run, which should be true generally in any diff --git a/cf/test/test_read_write.py b/cf/test/test_read_write.py index fb0b88055f..f0bf697fac 100644 --- a/cf/test/test_read_write.py +++ b/cf/test/test_read_write.py @@ -79,7 +79,6 @@ def test_write_filename(self): self.assertTrue((a == g[0].array).all()) - # REVIEW: h5: `test_read_mask`: rename numpy to np def test_read_mask(self): f = self.f0.copy() @@ -561,7 +560,6 @@ def test_read_write_netCDF4_compress_shuffle(self): f"Bad read/write with lossless compression: {fmt}", ) - # REVIEW: h5: `test_write_datatype`: rename numpy to np def test_write_datatype(self): f = cf.read(self.filename)[0] self.assertEqual(f.dtype, np.dtype(float))