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`` + ---- diff --git a/cf/cfimplementation.py b/cf/cfimplementation.py index b15a3929d9..118e73ce7a 100644 --- a/cf/cfimplementation.py +++ b/cf/cfimplementation.py @@ -26,8 +26,6 @@ TiePointIndex, ) from .data import Data - -# REVIEW: h5: `cfimplementation.py`: import `CFAH5netcdfArray`, `CFANetCDF4Array`, `H5netcdfArray`,`NetCDF4Array` from .data.array import ( BoundsFromNodesArray, CellConnectivityArray, @@ -116,7 +114,6 @@ def set_construct(self, parent, construct, axes=None, copy=True, **kwargs): parent, construct, axes=axes, copy=copy, **kwargs ) - # REVIEW: h5: `initialise_CFANetCDF4Array`: new method to initialise `CFANetCDF4Array` def initialise_CFANetCDF4Array(self, **kwargs): """Return a `CFANetCDF4Array` instance. @@ -133,7 +130,6 @@ def initialise_CFANetCDF4Array(self, **kwargs): cls = self.get_class("CFANetCDF4Array") return cls(**kwargs) - # REVIEW: h5: `initialise_CFAH5netcdfArray`: new method to initialise `CFAH5netcdfArray` def initialise_CFAH5netcdfArray(self, **kwargs): """Return a `CFAH5netcdfArray` instance. diff --git a/cf/constants.py b/cf/constants.py index 3275a834f4..1472bd83d2 100644 --- a/cf/constants.py +++ b/cf/constants.py @@ -63,7 +63,6 @@ "LOG_LEVEL": logging.getLevelName(logging.getLogger().level), "BOUNDS_COMBINATION_MODE": "AND", "CHUNKSIZE": parse_bytes(_CHUNKSIZE), - # REVIEW: active: `CONSTANTS`: new constants 'active_storage', 'active_storage_url', 'active_storage_max_requests' "active_storage": False, "active_storage_url": None, "active_storage_max_requests": 100, diff --git a/cf/data/array/__init__.py b/cf/data/array/__init__.py index c57a72081a..cd2c53766b 100644 --- a/cf/data/array/__init__.py +++ b/cf/data/array/__init__.py @@ -1,19 +1,11 @@ from .boundsfromnodesarray import BoundsFromNodesArray from .cellconnectivityarray import CellConnectivityArray - -# REVIEW: h5: `__init__.py`: import `CFAH5netcdfArray` from .cfah5netcdfarray import CFAH5netcdfArray - -# REVIEW: h5: `__init__.py`: import `CFAH5netcdfArray` from .cfanetcdf4array import CFANetCDF4Array from .fullarray import FullArray from .gatheredarray import GatheredArray - -# REVIEW: h5: `__init__.py`: import `H5netcdfArray` from .h5netcdfarray import H5netcdfArray from .netcdfarray import NetCDFArray - -# REVIEW: h5: `__init__.py`: import `NetCDF4Array` from .netcdf4array import NetCDF4Array from .pointtopologyarray import PointTopologyArray from .raggedcontiguousarray import RaggedContiguousArray diff --git a/cf/data/array/cfah5netcdfarray.py b/cf/data/array/cfah5netcdfarray.py index edcdfceeda..47c58bff06 100644 --- a/cf/data/array/cfah5netcdfarray.py +++ b/cf/data/array/cfah5netcdfarray.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `CFAH5netcdfArray`: New class for accessing CFA with `h5netcdf` from .h5netcdfarray import H5netcdfArray from .mixin import CFAMixin diff --git a/cf/data/array/cfanetcdf4array.py b/cf/data/array/cfanetcdf4array.py index 73d926b44b..b3b6b69d7a 100644 --- a/cf/data/array/cfanetcdf4array.py +++ b/cf/data/array/cfanetcdf4array.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `CFAnetCDF4Array`: New class for accessing CFA with `netCDF4` from .mixin import CFAMixin from .netcdf4array import NetCDF4Array diff --git a/cf/data/array/fullarray.py b/cf/data/array/fullarray.py index 11f9a26aa1..81278c3407 100644 --- a/cf/data/array/fullarray.py +++ b/cf/data/array/fullarray.py @@ -16,7 +16,6 @@ class FullArray(IndexMixin, Array): """ - # REVIEW: h5: `__init__`: replace units/calendar API with attributes def __init__( self, fill_value=None, @@ -121,7 +120,6 @@ def __str__(self): return f"Filled with {fill_value!r}" - # REVIEW: getitem: `_get_array`: new method to convert subspace to numpy array def _get_array(self, index=None): """Returns the full array. @@ -156,7 +154,6 @@ def _get_array(self, index=None): return array - # REVIEW: getitem: `array`: New property to convert subspace to numpy array @property def array(self): """Return an independent numpy array containing the data. diff --git a/cf/data/array/h5netcdfarray.py b/cf/data/array/h5netcdfarray.py index a8f78f94d9..465a9ebf81 100644 --- a/cf/data/array/h5netcdfarray.py +++ b/cf/data/array/h5netcdfarray.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `H5netcdfArray`: New class to access netCDF with `h5netcdf` import cfdm from ...mixin_container import Container diff --git a/cf/data/array/locks.py b/cf/data/array/locks.py index efa0114699..5a7b2bd333 100644 --- a/cf/data/array/locks.py +++ b/cf/data/array/locks.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `locks.py`: New module to provide file locks from dask.utils import SerializableLock # Global lock for netCDF file access diff --git a/cf/data/array/mixin/__init__.py b/cf/data/array/mixin/__init__.py index 7db2cd73e8..8e5dd7690d 100644 --- a/cf/data/array/mixin/__init__.py +++ b/cf/data/array/mixin/__init__.py @@ -1,9 +1,6 @@ -# REVIEW: active: `__init__.py`: import `ActiveStorageMixin` from .activestoragemixin import ActiveStorageMixin from .arraymixin import ArrayMixin from .cfamixin import CFAMixin from .compressedarraymixin import CompressedArrayMixin from .filearraymixin import FileArrayMixin - -# REVIEW: getitem: `__init__.py`: import `IndexMixin` from .indexmixin import IndexMixin diff --git a/cf/data/array/mixin/activestoragemixin.py b/cf/data/array/mixin/activestoragemixin.py index 9843d09858..024bb05d04 100644 --- a/cf/data/array/mixin/activestoragemixin.py +++ b/cf/data/array/mixin/activestoragemixin.py @@ -1,6 +1,3 @@ -# REVIEW: active: `ActiveStorageMixin`: new mixin class `ActiveStorageMixin` - - class ActiveStorageMixin: """Mixin class for enabling active storage operations. diff --git a/cf/data/array/mixin/arraymixin.py b/cf/data/array/mixin/arraymixin.py index 41ad6b5d6b..3468253b36 100644 --- a/cf/data/array/mixin/arraymixin.py +++ b/cf/data/array/mixin/arraymixin.py @@ -18,7 +18,6 @@ def __array_function__(self, func, types, args, kwargs): """ return NotImplemented - # REVIEW: active: `_meta`: Moved to here from `FileArrayMixin` @property def _meta(self): """Normalise the array to an appropriate Dask meta object. diff --git a/cf/data/array/mixin/cfamixin.py b/cf/data/array/mixin/cfamixin.py index 8af0840465..56682cd94f 100644 --- a/cf/data/array/mixin/cfamixin.py +++ b/cf/data/array/mixin/cfamixin.py @@ -35,7 +35,6 @@ def __new__(cls, *args, **kwargs): } return instance - # REVIEW: h5: `__init__`: replace units/calendar API with attributes def __init__( self, filename=None, @@ -224,7 +223,6 @@ def __init__( "substitutions", substitutions.copy(), copy=False ) - # REVIEW: h5: `_parse_cfa`: Refactoring of code that used to be in `__init__` def _parse_cfa(self, x, term, substitutions): """Parse the CFA aggregation instructions. @@ -465,7 +463,6 @@ def get_fragment_shape(self): """ return self._get_component("fragment_shape") - # REVIEW: h5: `get_storage_options`: new method to get file access options def get_storage_options(self): """Return `s3fs.S3FileSystem` options for accessing S3 fragment files. diff --git a/cf/data/array/mixin/indexmixin.py b/cf/data/array/mixin/indexmixin.py index 4cf2ad18b1..d105ba943a 100644 --- a/cf/data/array/mixin/indexmixin.py +++ b/cf/data/array/mixin/indexmixin.py @@ -7,7 +7,6 @@ from ....functions import indices_shape, parse_indices -# REVIEW: getitem: `IndexMixin`: new mixin class `IndexMixin` class IndexMixin: """Mixin class for lazy indexing of a data array. diff --git a/cf/data/array/netcdf4array.py b/cf/data/array/netcdf4array.py index 6a5eb80b71..796925542a 100644 --- a/cf/data/array/netcdf4array.py +++ b/cf/data/array/netcdf4array.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `NetCDF4Array`: New class to access netCDF with `netCDF4`, replaces `NetCDFArray` import cfdm from ...mixin_container import Container diff --git a/cf/data/array/netcdfarray.py b/cf/data/array/netcdfarray.py index fab088f6f3..4642dff910 100644 --- a/cf/data/array/netcdfarray.py +++ b/cf/data/array/netcdfarray.py @@ -1,4 +1,3 @@ -# REVIEW: h5: `NetCDFArray`: Replaced by `NetCDF4Array` class NetCDFArray: """A netCDF array accessed with `netCDF4`. diff --git a/cf/data/dask_regrid.py b/cf/data/dask_regrid.py index 6c3cab5fc6..f825fe1488 100644 --- a/cf/data/dask_regrid.py +++ b/cf/data/dask_regrid.py @@ -2,7 +2,6 @@ import numpy as np -# REVIEW: getitem: `regrid.py`: import `cf_asanyarray` from .dask_utils import cf_asanyarray @@ -177,7 +176,6 @@ def regrid( """ weights, dst_mask = weights_dst_mask - # REVIEW: getitem: `regrid`: convert a to a usable array a = cf_asanyarray(a) if dst_mask is not None: dst_mask = cf_asanyarray(dst_mask) diff --git a/cf/data/dask_utils.py b/cf/data/dask_utils.py index a958702883..b088d97bb8 100644 --- a/cf/data/dask_utils.py +++ b/cf/data/dask_utils.py @@ -398,6 +398,7 @@ def cf_rt2dt(a, units): """ a = cfdm_asanyarray(a) + if not units.iscalendartime: return rt2dt(a, units_in=units) diff --git a/cf/data/fragment/__init__.py b/cf/data/fragment/__init__.py index fd82cfa9cf..b7315107d4 100644 --- a/cf/data/fragment/__init__.py +++ b/cf/data/fragment/__init__.py @@ -1,9 +1,5 @@ from .fullfragmentarray import FullFragmentArray - -# REVIEW: h5: `__init__.py`: import `H5netcdfFragmentArray` from .h5netcdffragmentarray import H5netcdfFragmentArray from .netcdffragmentarray import NetCDFFragmentArray - -# REVIEW: h5: `__init__.py`: import `NetCDF4FragmentArray` from .netcdf4fragmentarray import NetCDF4FragmentArray from .umfragmentarray import UMFragmentArray diff --git a/cf/data/fragment/fullfragmentarray.py b/cf/data/fragment/fullfragmentarray.py index 652c7806cf..e2855b3003 100644 --- a/cf/data/fragment/fullfragmentarray.py +++ b/cf/data/fragment/fullfragmentarray.py @@ -9,7 +9,6 @@ class FullFragmentArray(FragmentArrayMixin, FullArray): """ - # REVIEW: h5: `__init__`: replace units/calendar API with attributes def __init__( self, fill_value=None, diff --git a/cf/data/fragment/h5netcdffragmentarray.py b/cf/data/fragment/h5netcdffragmentarray.py index 6ae379c984..0b70976c7f 100644 --- a/cf/data/fragment/h5netcdffragmentarray.py +++ b/cf/data/fragment/h5netcdffragmentarray.py @@ -2,7 +2,6 @@ from .mixin import FragmentArrayMixin -# REVIEW: h5: `H5netcdfFragmentArray`: New class to access netCDF fragment with `h5netcdf` class H5netcdfFragmentArray(FragmentArrayMixin, H5netcdfArray): """A netCDF fragment array accessed with `h5netcdf`. diff --git a/cf/data/fragment/mixin/fragmentarraymixin.py b/cf/data/fragment/mixin/fragmentarraymixin.py index 85e844201e..f02c779002 100644 --- a/cf/data/fragment/mixin/fragmentarraymixin.py +++ b/cf/data/fragment/mixin/fragmentarraymixin.py @@ -12,7 +12,6 @@ class FragmentArrayMixin: """ - # REVIEW: getitem: `_get_array`: new method to convert subspace to numpy array def _get_array(self, index=None): """Returns a subspace of the dataset variable. @@ -166,7 +165,6 @@ def _size_1_axis(self, indices): None """ - # REVIEW: getitem: `_size_1_axis`: refactor to use `original_shape` original_shape = self.original_shape if original_shape.count(1): return original_shape.index(1) diff --git a/cf/data/fragment/netcdf4fragmentarray.py b/cf/data/fragment/netcdf4fragmentarray.py index 869c083676..91f87dc2e8 100644 --- a/cf/data/fragment/netcdf4fragmentarray.py +++ b/cf/data/fragment/netcdf4fragmentarray.py @@ -2,7 +2,6 @@ from .mixin import FragmentArrayMixin -# REVIEW: h5: `NetCDF4FragmentArray`: New class to access netCDF fragment with `netCDF4` class NetCDF4FragmentArray(FragmentArrayMixin, NetCDF4Array): """A netCDF fragment array accessed with `netCDF4`. diff --git a/cf/data/fragment/netcdffragmentarray.py b/cf/data/fragment/netcdffragmentarray.py index c5365098c9..ee34501e94 100644 --- a/cf/data/fragment/netcdffragmentarray.py +++ b/cf/data/fragment/netcdffragmentarray.py @@ -7,7 +7,6 @@ from .netcdf4fragmentarray import NetCDF4FragmentArray -# REVIEW: getitem: `NetCDFFragmentArray`: new inheritance to allow for different netCDF backends class NetCDFFragmentArray( FragmentArrayMixin, IndexMixin, @@ -24,7 +23,6 @@ class NetCDFFragmentArray( """ - # REVIEW: h5: `__init__`: replace units/calendar API with attributes def __init__( self, filename=None, @@ -176,7 +174,6 @@ def __init__( # By default, close the file after data array access self._set_component("close", True, copy=False) - # REVIEW: getitem: `_get_array`: new method to convert subspace to numpy array def _get_array(self, index=None): """Returns a subspace of the dataset variable. diff --git a/cf/data/fragment/umfragmentarray.py b/cf/data/fragment/umfragmentarray.py index b45bf44bf9..9168225945 100644 --- a/cf/data/fragment/umfragmentarray.py +++ b/cf/data/fragment/umfragmentarray.py @@ -9,8 +9,6 @@ class UMFragmentArray(FragmentArrayMixin, UMArray): """ - # REVIEW: h5: `__init__`: replace units/calendar API with attributes - # REVIEW: h5: `__init__`: new keyword 'storage_options' def __init__( self, filename=None, diff --git a/cf/data/utils.py b/cf/data/utils.py index 8888178133..481cf81623 100644 --- a/cf/data/utils.py +++ b/cf/data/utils.py @@ -542,7 +542,6 @@ def parse_weights(d, weights, axis=None): w = [] shape = d.shape axes = d._axes - Data = type(d) for key, value in weights.items(): value = Data.asdata(value) diff --git a/cf/field.py b/cf/field.py index 4d735a11c7..d73e2b7b49 100644 --- a/cf/field.py +++ b/cf/field.py @@ -5220,7 +5220,6 @@ def histogram(self, digitized): """ raise RuntimeError("Use cf.histogram instead.") - # REVIEW: active: active storage docstring @_deprecated_kwarg_check("i", version="3.0.0", removed_at="4.0.0") @_manage_log_level_via_verbosity def collapse( @@ -7101,7 +7100,6 @@ def collapse( "collapse" ) - # REVIEW: active: `collapse`: include size 1 axes in collapse # Note: It is important that size 1 axes are also passed # on to the Data collapse, because active storage # collapses get confused if they're not there. diff --git a/cf/functions.py b/cf/functions.py index da04b18f58..22820bc3db 100644 --- a/cf/functions.py +++ b/cf/functions.py @@ -163,7 +163,6 @@ def _free_memory(): return float(virtual_memory().available) -# REVIEW: active: `configuration`: new keywords 'active_storage', 'active_storage_url', 'active_storage_max_requests' def configuration( atol=None, rtol=None, @@ -425,7 +424,6 @@ def configuration( ) -# REVIEW: active: `_configuration`: new keywords 'active_storage', 'active_storage_url', 'active_storage_max_requests' def _configuration(_Configuration, **kwargs): """Internal helper function to provide the logic for `cf.configuration`. @@ -584,7 +582,6 @@ class log_level(ConstantAccess, cfdm.log_level): _reset_log_emergence_level = _reset_log_emergence_level -# REVIEW: active: `regrid_logging`: new examples class regrid_logging(ConstantAccess): """Whether or not to enable `esmpy` regridding logging. @@ -716,7 +713,6 @@ def _parse(cls, arg): ) # pragma: no cover -# REVIEW: active: `relaxed_identities`: new examples class relaxed_identities(ConstantAccess): """Use 'relaxed' mode when getting a construct identity. @@ -850,7 +846,6 @@ def _parse(cls, arg): return parse_bytes(arg) -# REVIEW: active: `tempdir`: new examples class tempdir(ConstantAccess): """The directory for internally generated temporary files. @@ -1202,7 +1197,6 @@ def _parse(cls, arg): return arg -# REVIEW: active: `active_storage`: new function class active_storage(ConstantAccess): """Whether or not to attempt active storage reductions. @@ -1272,7 +1266,6 @@ def _parse(cls, arg): return bool(arg) -# REVIEW: active: `active_storage_url`: new function class active_storage_url(ConstantAccess): """The URL location of the active storage reducer. @@ -1337,7 +1330,6 @@ def _parse(cls, arg): return str(arg) -# REVIEW: active: `active_storage_max_requests`: new function class active_storage_max_requests(ConstantAccess): """Concurrent active storage server requests per `dask` chunk. @@ -2446,9 +2438,6 @@ def normalize_slice(index, size, cyclic=False): return slice(start, stop, step) -# REVIEW: getitem: `get_subspace`: remove deprecated function - - _equals = cfdm.Data()._equals @@ -2897,7 +2886,6 @@ def relpath(filename, start=None): 'http://data/archive/file.nc' """ - # REVIEW: h5: `relpath`: minor refactor u = urlparse(filename) if u.scheme != "": return filename @@ -2936,7 +2924,6 @@ def dirname(filename): 'http://data/archive' """ - # REVIEW: h5: `relpath`: minor refactor u = urlparse(filename) if u.scheme != "": return filename.rpartition("/")[0] @@ -2976,7 +2963,6 @@ def pathjoin(path1, path2): 'http://data/archive/file.nc' """ - # REVIEW: h5: `relpath`: minor refactor u = urlparse(path1) if u.scheme != "": return urljoin(path1, path2) @@ -3347,7 +3333,6 @@ def _get_module_info(module, alternative_name=False, try_except=False): ) -# REVIEW: h5: `environment`: new dependencies def environment(display=True, paths=True): """Return the names and versions of the cf package and its dependencies. diff --git a/cf/query.py b/cf/query.py index 87ff0c1c5b..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 @@ -972,7 +973,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] diff --git a/cf/read_write/netcdf/netcdfread.py b/cf/read_write/netcdf/netcdfread.py index dedd3e6ead..1392e0c7a5 100644 --- a/cf/read_write/netcdf/netcdfread.py +++ b/cf/read_write/netcdf/netcdfread.py @@ -209,7 +209,6 @@ def _create_data( if data.npartitions == 1: data._cfa_set_write(True) - # # REVIEW: h5: `_create_data`: control caching # if ( # not compression_index # and self.read_vars.get("cache") diff --git a/cf/read_write/um/umread.py b/cf/read_write/um/umread.py index 9efbb5644e..e73166eba1 100644 --- a/cf/read_write/um/umread.py +++ b/cf/read_write/um/umread.py @@ -1973,7 +1973,6 @@ def create_data(self): recs = self.recs um_Units = self.um_Units - # REVIEW: h5: `create_data`: replace units/calendar API with attributes attributes = { "units": getattr(um_Units, "units", None), "calendar": getattr(um_Units, "calendar", None), diff --git a/cf/read_write/write.py b/cf/read_write/write.py index a2b7ed114b..23a8dda3cd 100644 --- a/cf/read_write/write.py +++ b/cf/read_write/write.py @@ -13,7 +13,6 @@ netcdf = NetCDFWrite(implementation()) -# REVIEW: h5: `write`: docstring improvements @_manage_log_level_via_verbosity def write( fields, diff --git a/cf/regrid/regrid.py b/cf/regrid/regrid.py index fd39bed21f..eb7ee6656a 100644 --- a/cf/regrid/regrid.py +++ b/cf/regrid/regrid.py @@ -2465,8 +2465,6 @@ def create_esmpy_weights( from netCDF4 import Dataset from .. import __version__ - - # REVIEW: h5: new name and location of file lock from ..data.array.locks import netcdf_lock if ( diff --git a/cf/regrid/regridoperator.py b/cf/regrid/regridoperator.py index 3272aaf835..10a77bc641 100644 --- a/cf/regrid/regridoperator.py +++ b/cf/regrid/regridoperator.py @@ -727,7 +727,6 @@ def tosparse(self): # Read the weights from the weights file from netCDF4 import Dataset - # REVIEW: h5: new name and location of file lock from ..data.array.locks import netcdf_lock netcdf_lock.acquire() 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))