diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63dae6e6..528943d9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -82,7 +82,7 @@ repos: rev: 'v1.10.0' hooks: - id: mypy - exclude: 'noxfile\.py|docs/conf\.py' + exclude: 'noxfile\.py|docs/src/conf\.py|^benchmarks' - repo: https://github.com/abravalheri/validate-pyproject # More exhaustive than Ruff RUF200. diff --git a/benchmarks/asv_delegated_conda.py b/benchmarks/asv_delegated_conda.py index 9a45d6ca..37e5b7cd 100644 --- a/benchmarks/asv_delegated_conda.py +++ b/benchmarks/asv_delegated_conda.py @@ -14,8 +14,7 @@ class CondaDelegated(Conda): - """ - Manage a Conda environment using custom user scripts, run at each commit. + """Manage a Conda environment using custom user scripts, run at each commit. Ignores user input variations - ``matrix`` / ``pythons`` / ``conda_environment_file``, since environment is being managed outside ASV. diff --git a/benchmarks/benchmarks/__init__.py b/benchmarks/benchmarks/__init__.py index ce79d0ae..35cce87b 100644 --- a/benchmarks/benchmarks/__init__.py +++ b/benchmarks/benchmarks/__init__.py @@ -4,8 +4,7 @@ def disable_repeat_between_setup(benchmark_object): - """ - Decorate benchmarks where object persistence would be inappropriate. + """Decorate benchmarks where object persistence would be inappropriate. E.g: * Data is realised during testing. @@ -30,8 +29,7 @@ def disable_repeat_between_setup(benchmark_object): def skip_benchmark(benchmark_object): - """ - Decorate benchmarks to be skipped. + """Decorate benchmarks to be skipped. Simply doesn't return the object. @@ -43,12 +41,10 @@ def skip_benchmark(benchmark_object): (e.g. ``def time_something(self):`` ). """ - pass def on_demand_benchmark(benchmark_object): - """ - Decorate benchmark(s) that are disabled unless ON_DEMAND_BENCHARKS env var is set. + """Decorate benchmark(s) that are disabled unless ON_DEMAND_BENCHARKS env var is set. For benchmarks that, for whatever reason, should not be run by default. E.g: diff --git a/benchmarks/benchmarks/esmf_regridder/__init__.py b/benchmarks/benchmarks/esmf_regridder/__init__.py index 4d054375..89afb8df 100644 --- a/benchmarks/benchmarks/esmf_regridder/__init__.py +++ b/benchmarks/benchmarks/esmf_regridder/__init__.py @@ -15,6 +15,7 @@ MeshToGridESMFRegridder, ) from esmf_regrid.schemes import ESMFAreaWeightedRegridder + from ..generate_data import _curvilinear_cube, _grid_cube, _gridlike_mesh_cube diff --git a/benchmarks/benchmarks/esmf_regridder/scalability.py b/benchmarks/benchmarks/esmf_regridder/scalability.py index 80bc3722..1a6d3071 100644 --- a/benchmarks/benchmarks/esmf_regridder/scalability.py +++ b/benchmarks/benchmarks/esmf_regridder/scalability.py @@ -14,6 +14,7 @@ MeshToGridESMFRegridder, ) from esmf_regrid.schemes import ESMFAreaWeightedRegridder + from .. import on_demand_benchmark, skip_benchmark from ..generate_data import _grid_cube, _gridlike_mesh_cube @@ -64,7 +65,7 @@ def time_prepare(self, n): class PrepareScalabilityMeshToGrid(PrepareScalabilityMixin): """Benchmarks for the prepare step of :class:`~esmf_regrid.esmf_regrid.schemes.MeshToGridESMFRegridder`.""" - regridder = MeshToGridESMFRegridder + regridder = MeshToGridESMFRegridder # type: ignore[assignment] def src_cube(self, n): """Cube to regrid from.""" @@ -114,7 +115,7 @@ def time_prepare(self, _, n): class PrepareScalabilityGridToMesh(PrepareScalabilityMixin): """Benchmarks for the prepare step of :class:`~esmf_regrid.esmf_regrid.schemes.GridToMeshESMFRegridder`.""" - regridder = GridToMeshESMFRegridder + regridder = GridToMeshESMFRegridder # type: ignore[assignment] def tgt_cube(self, n): """Cube containing the regridding target grid.""" @@ -257,7 +258,7 @@ def time_lazy_perform(self, cache, height): class PerformScalabilityMeshToGrid(PerformScalabilityMixin): """Benchmarks for the perform step of :class:`~esmf_regrid.esmf_regrid.schemes.MeshToGridESMFRegridder`.""" - regridder = MeshToGridESMFRegridder + regridder = MeshToGridESMFRegridder # type: ignore[assignment] chunk_size = [PerformScalabilityMixin.grid_size ^ 2, 10] file_name = "chunked_cube_1d.nc" @@ -298,7 +299,7 @@ def time_lazy_perform(self, cache, height): class PerformScalabilityGridToMesh(PerformScalabilityMixin): """Benchmarks for the perform step of :class:`~esmf_regrid.esmf_regrid.schemes.GridToMeshESMFRegridder`.""" - regridder = GridToMeshESMFRegridder + regridder = GridToMeshESMFRegridder # type: ignore[assignment] def setup_cache(self): """ASV setup_cache method.""" diff --git a/benchmarks/benchmarks/generate_data.py b/benchmarks/benchmarks/generate_data.py index d829533c..495e9087 100644 --- a/benchmarks/benchmarks/generate_data.py +++ b/benchmarks/benchmarks/generate_data.py @@ -1,5 +1,4 @@ -""" -Scripts for generating supporting data for benchmarking. +"""Scripts for generating supporting data for benchmarking. Data generated using iris-esmf-regrid should use :func:`run_function_elsewhere`, which means that data is generated using a @@ -43,7 +42,7 @@ default_data_dir = (Path(__file__).parent.parent / ".data").resolve() # Optionally override the default data location with environment variable. BENCHMARK_DATA = Path(environ.get("BENCHMARK_DATA", default_data_dir)) -if BENCHMARK_DATA == default_data_dir: +if default_data_dir == BENCHMARK_DATA: BENCHMARK_DATA.mkdir(exist_ok=True) message = ( f"No BENCHMARK_DATA env var, defaulting to {BENCHMARK_DATA}. " @@ -62,8 +61,7 @@ def run_function_elsewhere(func_to_run, *args, **kwargs): - """ - Run a given function using the :const:`DATA_GEN_PYTHON` executable. + """Run a given function using the :const:`DATA_GEN_PYTHON` executable. This structure allows the function to be written natively. @@ -90,7 +88,7 @@ def run_function_elsewhere(func_to_run, *args, **kwargs): func_string = dedent(getsource(func_to_run)) func_string = func_string.replace("@staticmethod\n", "") func_call_term_strings = [repr(arg) for arg in args] - func_call_term_strings += [f"{name}={repr(val)}" for name, val in kwargs.items()] + func_call_term_strings += [f"{name}={val!r}" for name, val in kwargs.items()] func_call_string = ( f"{func_to_run.__name__}(" + ",".join(func_call_term_strings) + ")" ) @@ -115,8 +113,7 @@ def _grid_cube( """Call _grid_cube via :func:`run_function_elsewhere`.""" def external(*args, **kwargs): - """ - Prep and call _grid_cube, saving to a NetCDF file. + """Prep and call _grid_cube, saving to a NetCDF file. Saving to a file allows the original python executable to pick back up. @@ -178,8 +175,7 @@ def _curvilinear_cube( """Call _curvilinear_cube via :func:`run_function_elsewhere`.""" def external(*args, **kwargs): - """ - Prep and call _curvilinear_cube, saving to a NetCDF file. + """Prep and call _curvilinear_cube, saving to a NetCDF file. Saving to a file allows the original python executable to pick back up. @@ -227,8 +223,7 @@ def _gridlike_mesh_cube(n_lons, n_lats): """Call _gridlike_mesh via :func:`run_function_elsewhere`.""" def external(*args, **kwargs): - """ - Prep and call _gridlike_mesh, saving to a NetCDF file. + """Prep and call _gridlike_mesh, saving to a NetCDF file. Saving to a file allows the original python executable to pick back up. diff --git a/benchmarks/bm_runner.py b/benchmarks/bm_runner.py index 8588cd22..16fa3252 100644 --- a/benchmarks/bm_runner.py +++ b/benchmarks/bm_runner.py @@ -11,7 +11,6 @@ import shlex import subprocess from tempfile import NamedTemporaryFile -from typing import Literal # The threshold beyond which shifts are 'notable'. See `asv compare`` docs # for more. @@ -29,7 +28,7 @@ def _echo(echo_string: str): # Use subprocess for printing to reduce chance of printing out of sequence # with the subsequent calls. - subprocess.run(["echo", f"BM_RUNNER DEBUG: {echo_string}"]) + subprocess.run(["echo", f"BM_RUNNER DEBUG: {echo_string}"], check=False) def _subprocess_runner(args, asv=False, **kwargs): @@ -103,10 +102,10 @@ def _setup_common() -> None: def _asv_compare(*commits: str) -> None: """Run through a list of commits comparing each one to the next.""" - commits = [commit[:8] for commit in commits] - for i in range(len(commits) - 1): - before = commits[i] - after = commits[i + 1] + _commits = [commit[:8] for commit in commits] + for i in range(len(_commits) - 1): + before = _commits[i] + after = _commits[i + 1] asv_command = shlex.split( f"compare {before} {after} --factor={COMPARE_FACTOR} --split" ) @@ -124,7 +123,7 @@ class _SubParserGenerator(ABC): description: str = NotImplemented epilog: str = NotImplemented - def __init__(self, subparsers: ArgumentParser.add_subparsers) -> None: + def __init__(self, subparsers: argparse._SubParsersAction) -> None: self.subparser: ArgumentParser = subparsers.add_parser( self.name, description=self.description, @@ -249,9 +248,9 @@ def func(args: argparse.Namespace) -> None: ) # Only do a single round. - asv_command = shlex.split(re.sub(r"rounds=\d", "rounds=1", asv_command)) + _asv_command = shlex.split(re.sub(r"rounds=\d", "rounds=1", asv_command)) try: - _subprocess_runner([*asv_command, *args.asv_args], asv=True) + _subprocess_runner([*_asv_command, *args.asv_args], asv=True) except subprocess.CalledProcessError as err: # C/SPerf benchmarks are much bigger than the CI ones: # Don't fail the whole run if memory blows on 1 benchmark. @@ -259,8 +258,10 @@ def func(args: argparse.Namespace) -> None: if err.returncode != 2: raise - asv_command = shlex.split(f"publish {commit_range} --html-dir={publish_subdir}") - _subprocess_runner(asv_command, asv=True) + _asv_command = shlex.split( + f"publish {commit_range} --html-dir={publish_subdir}" + ) + _subprocess_runner(_asv_command, asv=True) # Print completion message. location = BENCHMARKS_DIR / ".asv" diff --git a/docs/src/conf.py b/docs/src/conf.py index 2534f9b5..fbd4268a 100644 --- a/docs/src/conf.py +++ b/docs/src/conf.py @@ -1,5 +1,4 @@ -""" -Configuration file for the Sphinx documentation builder. +"""Configuration file for the Sphinx documentation builder. Created originally using sphinx-quickstart on 2022-02-21. """ @@ -80,18 +79,18 @@ def _dotv(version): # Automate the discovery of the python versions tested with CI. -python_support = sorted( - [fname.stem for fname in Path(".").glob("../../requirements/py*.yml")] +python_support_list = sorted( + [fname.stem for fname in Path().glob("../../requirements/py*.yml")] ) -if not python_support: +if not python_support_list: python_support = "unknown Python versions" -elif len(python_support) == 1: - python_support = f"Python {_dotv(python_support[0])}" +elif len(python_support_list) == 1: + python_support = f"Python {_dotv(python_support_list[0])}" else: - rest = ", ".join([_dotv(v) for v in python_support[:-1]]) - last = _dotv(python_support[-1]) + rest = ", ".join([_dotv(v) for v in python_support_list[:-1]]) + last = _dotv(python_support_list[-1]) python_support = f"Python {rest} and {last}" rst_epilog = f""" diff --git a/esmf_regrid/__init__.py b/esmf_regrid/__init__.py index 2472b508..5dd1b9e7 100644 --- a/esmf_regrid/__init__.py +++ b/esmf_regrid/__init__.py @@ -26,5 +26,4 @@ from .constants import Constants, check_method, check_norm from .schemes import * - __version__ = "0.12.dev0" diff --git a/esmf_regrid/_esmf_sdo.py b/esmf_regrid/_esmf_sdo.py index 2da3128e..a1eb9375 100644 --- a/esmf_regrid/_esmf_sdo.py +++ b/esmf_regrid/_esmf_sdo.py @@ -10,8 +10,7 @@ class SDO(ABC): - """ - Abstract base class for handling spatial discretisation objects. + """Abstract base class for handling spatial discretisation objects. This contains shared things for representing the three spatial discretisation objects supported by ESMPy, Grids, Meshes, and LocStreams. @@ -74,8 +73,7 @@ def mask(self): return self._mask def _array_to_matrix(self, array): - """ - Reshape data to a form that is compatible with weight matrices. + """Reshape data to a form that is compatible with weight matrices. The data should be presented in the form of a matrix (i.e. 2D) in order to be compatible with the weight matrix. @@ -87,8 +85,7 @@ def _array_to_matrix(self, array): return array.T.reshape((self.size, -1)) def _matrix_to_array(self, array, extra_dims): - """ - Reshape data to restore original dimensions. + """Reshape data to restore original dimensions. This is the inverse operation of `_array_to_matrix`. """ @@ -96,8 +93,7 @@ def _matrix_to_array(self, array, extra_dims): class GridInfo(SDO): - """ - Class for handling structured grids. + """Class for handling structured grids. This class holds information about lat-lon type grids. That is, grids defined by lists of latitude and longitude values for points/bounds @@ -125,8 +121,7 @@ def __init__( mask=None, center=False, ): - """ - Create a :class:`GridInfo` object describing the grid. + """Create a :class:`GridInfo` object describing the grid. Parameters ---------- @@ -327,8 +322,7 @@ def add_get_item(grid, **kwargs): class RefinedGridInfo(GridInfo): - """ - Class for handling structured grids represented in :mod:`esmpy` in higher resolution. + """Class for handling structured grids represented in :mod:`esmpy` in higher resolution. A specialised version of :class:`GridInfo`. Designed to provide higher accuracy conservative regridding for rectilinear grids, especially those with @@ -349,8 +343,7 @@ def __init__( crs=None, mask=None, ): - """ - Create a :class:`RefinedGridInfo` object describing the grid. + """Create a :class:`RefinedGridInfo` object describing the grid. Parameters ---------- @@ -436,8 +429,7 @@ def _refined_mask(self): return new_mask def _collapse_weights(self, is_tgt): - """ - Return a matrix to collapse the weight matrix. + """Return a matrix to collapse the weight matrix. The refined grid may contain more cells than the represented grid. When this is the case, the generated weight matrix will refer to too many points and will have diff --git a/esmf_regrid/constants.py b/esmf_regrid/constants.py index 2335d60e..91ece3e9 100644 --- a/esmf_regrid/constants.py +++ b/esmf_regrid/constants.py @@ -36,7 +36,7 @@ class NormType(Enum): def check_method(method): """Check that method is a member of the `Constants.Method` enum or raise an error.""" - if method in method_dict.keys(): + if method in method_dict: result = method_dict[method] elif method in method_dict.values(): result = method @@ -49,7 +49,7 @@ def check_method(method): def check_norm(norm): """Check that normtype is a member of the `Constants.NormType` enum or raise an error.""" - if norm in norm_dict.keys(): + if norm in norm_dict: result = norm_dict[norm] elif norm in norm_dict.values(): result = norm diff --git a/esmf_regrid/esmf_regridder.py b/esmf_regrid/esmf_regridder.py index 5322c415..b6b61e99 100644 --- a/esmf_regrid/esmf_regridder.py +++ b/esmf_regrid/esmf_regridder.py @@ -5,7 +5,8 @@ import scipy.sparse import esmf_regrid -from esmf_regrid import check_method, check_norm, Constants +from esmf_regrid import Constants, check_method, check_norm + from . import esmpy from ._esmf_sdo import GridInfo, RefinedGridInfo @@ -33,7 +34,7 @@ def _get_regrid_weights_dict(src_field, tgt_field, regrid_method): factors=True, ) # Without specifying deep_copy=true, the information in weights_dict - # would be corrupted when the ESMF regridder is destoyed. + # would be corrupted when the ESMF regridder is destroyed. weights_dict = regridder.get_weights_dict(deep_copy=True) # The weights_dict contains all the information needed for regridding, # the ESMF objects can be safely removed. @@ -61,8 +62,7 @@ class Regridder: def __init__( self, src, tgt, method=Constants.Method.CONSERVATIVE, precomputed_weights=None ): - """ - Create a regridder from descriptions of horizontal grids/meshes. + """Create a regridder from descriptions of horizontal grids/meshes. Weights will be calculated using :mod:`esmpy` and stored as a :class:`scipy.sparse.csr_matrix` @@ -106,14 +106,14 @@ def __init__( ) if isinstance(tgt, RefinedGridInfo): # At this point, the weight matrix represents more target points than - # tgt respresents. In order to collapse these points, we collapse the + # tgt represents. In order to collapse these points, we collapse the # weights matrix by the appropriate matrix multiplication. self.weight_matrix = ( tgt._collapse_weights(is_tgt=True) @ self.weight_matrix ) if isinstance(src, RefinedGridInfo): # At this point, the weight matrix represents more source points than - # src respresents. In order to collapse these points, we collapse the + # src represents. In order to collapse these points, we collapse the # weights matrix by the appropriate matrix multiplication. self.weight_matrix = self.weight_matrix @ src._collapse_weights( is_tgt=False @@ -141,8 +141,7 @@ def _out_dtype(self, in_dtype): return out_dtype def regrid(self, src_array, norm_type=Constants.NormType.FRACAREA, mdtol=1): - """ - Perform regridding on an array of data. + """Perform regridding on an array of data. Parameters ---------- diff --git a/esmf_regrid/experimental/io.py b/esmf_regrid/experimental/io.py index b43a6619..e0dc174b 100644 --- a/esmf_regrid/experimental/io.py +++ b/esmf_regrid/experimental/io.py @@ -9,8 +9,7 @@ import scipy.sparse import esmf_regrid -from esmf_regrid import _load_context -from esmf_regrid import check_method, Constants +from esmf_regrid import Constants, _load_context, check_method from esmf_regrid.experimental.unstructured_scheme import ( GridToMeshESMFRegridder, MeshToGridESMFRegridder, @@ -23,7 +22,6 @@ MeshRecord, ) - SUPPORTED_REGRIDDERS = [ ESMFAreaWeightedRegridder, ESMFBilinearRegridder, @@ -81,9 +79,9 @@ def _managed_var_name(src_cube, tgt_cube): coord.var_name = "_".join([TARGET_NAME, "mesh", coord.name()]) yield None finally: - for coord, var_name in zip(src_mesh_coords, src_coord_names): + for coord, var_name in zip(src_mesh_coords, src_coord_names, strict=False): coord.var_name = var_name - for coord, var_name in zip(tgt_mesh_coords, tgt_coord_names): + for coord, var_name in zip(tgt_mesh_coords, tgt_coord_names, strict=False): coord.var_name = var_name @@ -100,8 +98,7 @@ def _clean_var_names(cube): def save_regridder(rg, filename): - """ - Save a regridder scheme instance. + """Save a regridder scheme instance. Saves any of the regridder classes, i.e. :class:`~esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`, @@ -271,8 +268,7 @@ def _standard_mesh_cube(mesh, location, name): def load_regridder(filename): - """ - Load a regridder scheme instance. + """Load a regridder scheme instance. Loads any of the regridder classes, i.e. :class:`~esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`, @@ -303,7 +299,7 @@ def load_regridder(filename): # Determine the regridder type. regridder_type = weights_cube.attributes[REGRIDDER_TYPE] - assert regridder_type in REGRIDDER_NAME_MAP.keys() + assert regridder_type in REGRIDDER_NAME_MAP scheme = REGRIDDER_NAME_MAP[regridder_type] # Determine the regridding method, allowing for files created when diff --git a/esmf_regrid/experimental/unstructured_regrid.py b/esmf_regrid/experimental/unstructured_regrid.py index cd58dc67..6ebfad8d 100644 --- a/esmf_regrid/experimental/unstructured_regrid.py +++ b/esmf_regrid/experimental/unstructured_regrid.py @@ -7,8 +7,7 @@ class MeshInfo(SDO): - """ - Class for handling unstructured meshes. + """Class for handling unstructured meshes. This class holds information about Meshes in a form similar to UGRID. It contains methods for translating this information into :mod:`esmpy` objects. @@ -30,8 +29,7 @@ def __init__( elem_coords=None, location="face", ): - """ - Create a :class:`MeshInfo` object describing a UGRID-like mesh. + """Create a :class:`MeshInfo` object describing a UGRID-like mesh. Parameters ---------- diff --git a/esmf_regrid/experimental/unstructured_scheme.py b/esmf_regrid/experimental/unstructured_scheme.py index 172bfd4e..9a39193e 100644 --- a/esmf_regrid/experimental/unstructured_scheme.py +++ b/esmf_regrid/experimental/unstructured_scheme.py @@ -8,7 +8,7 @@ from iris.experimental.ugrid import Mesh as MeshXY except ImportError: raise exc -from esmf_regrid import check_method, Constants +from esmf_regrid import Constants, check_method from esmf_regrid.schemes import ( _ESMFRegridder, _get_mask, @@ -30,8 +30,7 @@ def regrid_unstructured_to_rectilinear( use_src_mask=False, use_tgt_mask=False, ): - r""" - Regrid unstructured :class:`~iris.cube.Cube` onto rectilinear grid. + r"""Regrid unstructured :class:`~iris.cube.Cube` onto rectilinear grid. Return a new :class:`~iris.cube.Cube` with :attr:`~iris.cube.Cube.data` values calculated using weights generated by :mod:`esmpy` to give the weighted @@ -120,8 +119,7 @@ def __init__( use_src_mask=False, use_tgt_mask=False, ): - """ - Create regridder for conversions between source mesh and target grid. + """Create regridder for conversions between source mesh and target grid. Parameters ---------- @@ -192,8 +190,7 @@ def regrid_rectilinear_to_unstructured( use_src_mask=False, use_tgt_mask=False, ): - r""" - Regrid rectilinear :class:`~iris.cube.Cube` onto unstructured mesh. + r"""Regrid rectilinear :class:`~iris.cube.Cube` onto unstructured mesh. Return a new :class:`~iris.cube.Cube` with :attr:`~iris.cube.Cube.data` values calculated using weights generated by :mod:`esmpy` to give the weighted @@ -287,8 +284,7 @@ def __init__( use_tgt_mask=False, tgt_location=None, ): - """ - Create regridder for conversions between source grid and target mesh. + """Create regridder for conversions between source grid and target mesh. Parameters ---------- @@ -362,8 +358,7 @@ def regrid_unstructured_to_unstructured( use_src_mask=False, use_tgt_mask=False, ): - r""" - Regrid rectilinear :class:`~iris.cube.Cube` onto unstructured mesh. + r"""Regrid rectilinear :class:`~iris.cube.Cube` onto unstructured mesh. Return a new :class:`~iris.cube.Cube` with :attr:`~iris.cube.Cube.data` values calculated using weights generated by :mod:`esmpy` to give the weighted diff --git a/esmf_regrid/schemes.py b/esmf_regrid/schemes.py index 69ba70e1..d98d37db 100644 --- a/esmf_regrid/schemes.py +++ b/esmf_regrid/schemes.py @@ -19,7 +19,7 @@ except ImportError: raise exc -from esmf_regrid import check_method, Constants +from esmf_regrid import Constants, check_method from esmf_regrid.esmf_regridder import GridInfo, RefinedGridInfo, Regridder from esmf_regrid.experimental.unstructured_regrid import MeshInfo @@ -85,8 +85,7 @@ def _get_mask(cube_or_mesh, use_mask=True): def _contiguous_masked(bounds, mask): - """ - Return the (N+1, M+1) vertices for 2D coordinate bounds of shape (N, M, 4). + """Return the (N+1, M+1) vertices for 2D coordinate bounds of shape (N, M, 4). Assumes the bounds are contiguous outside of the mask. As long as the only discontiguities are associated with masked points, the returned vertices will @@ -256,8 +255,7 @@ def _mesh_to_MeshInfo(mesh, location, mask=None): def _regrid_along_dims(data, regridder, dims, num_out_dims, mdtol): - """ - Perform regridding on data over specific dimensions. + """Perform regridding on data over specific dimensions. Parameters ---------- @@ -295,8 +293,7 @@ def _regrid_along_dims(data, regridder, dims, num_out_dims, mdtol): def _map_complete_blocks( src, func, active_dims, out_sizes, *args, dtype=None, **kwargs ): - """ - Apply a function to complete blocks. + """Apply a function to complete blocks. Based on :func:`iris._lazy_data.map_complete_blocks`. By "complete blocks" we mean that certain dimensions are enforced to be @@ -349,7 +346,7 @@ def _map_complete_blocks( if num_out == 1: out_chunks[sorted_dims[0]] = out_sizes[0] else: - for dim, size in zip(active_dims, out_sizes): + for dim, size in zip(active_dims, out_sizes, strict=False): # Note: when mapping 2D to 2D, this will be the only alteration to # out_chunks, the same as iris._lazy_data.map_complete_blocks out_chunks[dim] = size @@ -402,8 +399,7 @@ def _map_complete_blocks( def _create_cube(data, src_cube, src_dims, tgt_coords, num_tgt_dims): - r""" - Return a new cube for the result of regridding. + r"""Return a new cube for the result of regridding. Returned cube represents the result of regridding the source cube onto the new grid/mesh. @@ -448,7 +444,7 @@ def _create_cube(data, src_cube, src_dims, tgt_coords, num_tgt_dims): ) if num_tgt_dims == 1: grid_y_dim = grid_x_dim = min(src_dims) - for tgt_coord, dim in zip(tgt_coords, (grid_x_dim, grid_y_dim)): + for tgt_coord, dim in zip(tgt_coords, (grid_x_dim, grid_y_dim), strict=False): if len(tgt_coord.shape) == 1: if isinstance(tgt_coord, iris.coords.DimCoord): new_cube.add_dim_coord(tgt_coord, dim) @@ -535,8 +531,7 @@ def _regrid_rectilinear_to_rectilinear__prepare( src_mask=None, tgt_mask=None, ): - """ - First (setup) part of 'regrid_rectilinear_to_rectilinear'. + """First (setup) part of 'regrid_rectilinear_to_rectilinear'. Check inputs and calculate the sparse regrid matrix and related info. The 'regrid info' returned can be re-used over many 2d slices. @@ -570,8 +565,7 @@ def _regrid_rectilinear_to_rectilinear__prepare( def _regrid_rectilinear_to_rectilinear__perform(src_cube, regrid_info, mdtol): - """ - Second (regrid) part of 'regrid_rectilinear_to_rectilinear'. + """Second (regrid) part of 'regrid_rectilinear_to_rectilinear'. Perform the prepared regrid calculation on a single cube. @@ -621,8 +615,7 @@ def _regrid_unstructured_to_rectilinear__prepare( src_mask=None, tgt_mask=None, ): - """ - First (setup) part of 'regrid_unstructured_to_rectilinear'. + """First (setup) part of 'regrid_unstructured_to_rectilinear'. Check inputs and calculate the sparse regrid matrix and related info. The 'regrid info' returned can be re-used over many 2d slices. @@ -652,8 +645,7 @@ def _regrid_unstructured_to_rectilinear__prepare( def _regrid_unstructured_to_rectilinear__perform(src_cube, regrid_info, mdtol): - """ - Second (regrid) part of 'regrid_unstructured_to_rectilinear'. + """Second (regrid) part of 'regrid_unstructured_to_rectilinear'. Perform the prepared regrid calculation on a single cube. @@ -707,8 +699,7 @@ def _regrid_rectilinear_to_unstructured__prepare( tgt_mask=None, tgt_location=None, ): - """ - First (setup) part of 'regrid_rectilinear_to_unstructured'. + """First (setup) part of 'regrid_rectilinear_to_unstructured'. Check inputs and calculate the sparse regrid matrix and related info. The 'regrid info' returned can be re-used over many 2d slices. @@ -748,8 +739,7 @@ def _regrid_rectilinear_to_unstructured__prepare( def _regrid_rectilinear_to_unstructured__perform(src_cube, regrid_info, mdtol): - """ - Second (regrid) part of 'regrid_rectilinear_to_unstructured'. + """Second (regrid) part of 'regrid_rectilinear_to_unstructured'. Perform the prepared regrid calculation on a single cube. @@ -805,8 +795,7 @@ def _regrid_unstructured_to_unstructured__prepare( src_location=None, tgt_location=None, ): - """ - First (setup) part of 'regrid_unstructured_to_unstructured'. + """First (setup) part of 'regrid_unstructured_to_unstructured'. Check inputs and calculate the sparse regrid matrix and related info. The 'regrid info' returned can be re-used over many 2d slices. @@ -845,8 +834,7 @@ def _regrid_unstructured_to_unstructured__prepare( def _regrid_unstructured_to_unstructured__perform(src_cube, regrid_info, mdtol): - """ - Second (regrid) part of 'regrid_unstructured_to_unstructured'. + """Second (regrid) part of 'regrid_unstructured_to_unstructured'. Perform the prepared regrid calculation on a single cube. @@ -896,8 +884,7 @@ def regrid_rectilinear_to_rectilinear( src_resolution=None, tgt_resolution=None, ): - r""" - Regrid rectilinear :class:`~iris.cube.Cube` onto another rectilinear grid. + r"""Regrid rectilinear :class:`~iris.cube.Cube` onto another rectilinear grid. Return a new :class:`~iris.cube.Cube` with :attr:`~iris.cube.Cube.data` values calculated using the area weighted @@ -945,8 +932,7 @@ def regrid_rectilinear_to_rectilinear( class ESMFAreaWeighted: - """ - A scheme which can be recognised by :meth:`iris.cube.Cube.regrid`. + """A scheme which can be recognised by :meth:`iris.cube.Cube.regrid`. This class describes an area-weighted regridding scheme for regridding between horizontal grids/meshes. It uses :mod:`esmpy` to handle @@ -957,8 +943,7 @@ class ESMFAreaWeighted: def __init__( self, mdtol=0, use_src_mask=False, use_tgt_mask=False, tgt_location="face" ): - """ - Area-weighted scheme for regridding between rectilinear grids. + """Area-weighted scheme for regridding between rectilinear grids. Parameters ---------- @@ -995,7 +980,7 @@ def __init__( def __repr__(self): """Return a representation of the class.""" - return "ESMFAreaWeighted(mdtol={})".format(self.mdtol) + return f"ESMFAreaWeighted(mdtol={self.mdtol})" def regridder( self, @@ -1007,8 +992,7 @@ def regridder( use_tgt_mask=None, tgt_location="face", ): - """ - Create regridder to perform regridding from ``src_grid`` to ``tgt_grid``. + """Create regridder to perform regridding from ``src_grid`` to ``tgt_grid``. Parameters ---------- @@ -1072,8 +1056,7 @@ def regridder( class ESMFBilinear: - """ - A scheme which can be recognised by :meth:`iris.cube.Cube.regrid`. + """A scheme which can be recognised by :meth:`iris.cube.Cube.regrid`. This class describes a bilinear regridding scheme for regridding between horizontal grids/meshes. It uses :mod:`esmpy` to handle @@ -1083,8 +1066,7 @@ class ESMFBilinear: def __init__( self, mdtol=0, use_src_mask=False, use_tgt_mask=False, tgt_location=None ): - """ - Area-weighted scheme for regridding between rectilinear grids. + """Area-weighted scheme for regridding between rectilinear grids. Parameters ---------- @@ -1113,7 +1095,7 @@ def __init__( def __repr__(self): """Return a representation of the class.""" - return "ESMFBilinear(mdtol={})".format(self.mdtol) + return f"ESMFBilinear(mdtol={self.mdtol})" def regridder( self, @@ -1123,8 +1105,7 @@ def regridder( use_tgt_mask=None, tgt_location=None, ): - """ - Create regridder to perform regridding from ``src_grid`` to ``tgt_grid``. + """Create regridder to perform regridding from ``src_grid`` to ``tgt_grid``. Parameters ---------- @@ -1174,8 +1155,7 @@ def regridder( class ESMFNearest: - """ - A scheme which can be recognised by :meth:`iris.cube.Cube.regrid`. + """A scheme which can be recognised by :meth:`iris.cube.Cube.regrid`. This class describes a nearest neighbour regridding scheme for regridding between horizontal grids/meshes. It uses :mod:`esmpy` to handle @@ -1200,8 +1180,7 @@ class ESMFNearest: """ def __init__(self, use_src_mask=False, use_tgt_mask=False, tgt_location=None): - """ - Nearest neighbour scheme for regridding between rectilinear grids. + """Nearest neighbour scheme for regridding between rectilinear grids. Parameters ---------- @@ -1231,8 +1210,7 @@ def regridder( use_tgt_mask=None, tgt_location=None, ): - """ - Create regridder to perform regridding from ``src_grid`` to ``tgt_grid``. + """Create regridder to perform regridding from ``src_grid`` to ``tgt_grid``. Parameters ---------- @@ -1294,8 +1272,7 @@ def __init__( tgt_location=None, **kwargs, ): - """ - Create regridder for conversions between ``src`` and ``tgt``. + """Create regridder for conversions between ``src`` and ``tgt``. Parameters ---------- @@ -1353,12 +1330,11 @@ def __init__( kwargs["tgt_location"] = tgt_location else: prepare_func = _regrid_unstructured_to_rectilinear__prepare + elif tgt_is_mesh: + prepare_func = _regrid_rectilinear_to_unstructured__prepare + kwargs["tgt_location"] = tgt_location else: - if tgt_is_mesh: - prepare_func = _regrid_rectilinear_to_unstructured__prepare - kwargs["tgt_location"] = tgt_location - else: - prepare_func = _regrid_rectilinear_to_rectilinear__prepare + prepare_func = _regrid_rectilinear_to_rectilinear__prepare regrid_info = prepare_func(src, tgt, method, **kwargs) # Store regrid info. @@ -1372,8 +1348,7 @@ def __init__( self._src = GridRecord(_get_coord(src, "x"), _get_coord(src, "y")) def __call__(self, cube): - """ - Regrid this :class:`~iris.cube.Cube` onto the target grid of this regridder instance. + """Regrid this :class:`~iris.cube.Cube` onto the target grid of this regridder instance. The given :class:`~iris.cube.Cube` must be defined with the same grid as the source :class:`~iris.cube.Cube` used to create this :class:`_ESMFRegridder` instance. @@ -1417,7 +1392,9 @@ def __call__(self, cube): new_src_x, new_src_y = (_get_coord(cube, "x"), _get_coord(cube, "y")) # Check the source grid matches that used in initialisation - for saved_coord, new_coord in zip(self._src, (new_src_x, new_src_y)): + for saved_coord, new_coord in zip( + self._src, (new_src_x, new_src_y), strict=False + ): # Ignore differences in var_name that might be caused by saving. saved_coord = copy.deepcopy(saved_coord) saved_coord.var_name = new_coord.var_name @@ -1446,11 +1423,10 @@ def __call__(self, cube): perform_func = _regrid_unstructured_to_unstructured__perform else: perform_func = _regrid_unstructured_to_rectilinear__perform + elif tgt_is_mesh: + perform_func = _regrid_rectilinear_to_unstructured__perform else: - if tgt_is_mesh: - perform_func = _regrid_rectilinear_to_unstructured__perform - else: - perform_func = _regrid_rectilinear_to_rectilinear__perform + perform_func = _regrid_rectilinear_to_rectilinear__perform result = perform_func(cube, regrid_info, self.mdtol) return result @@ -1471,8 +1447,7 @@ def __init__( use_tgt_mask=False, tgt_location="face", ): - """ - Create regridder for conversions between ``src`` and ``tgt``. + """Create regridder for conversions between ``src`` and ``tgt``. Parameters ---------- @@ -1553,8 +1528,7 @@ def __init__( use_tgt_mask=False, tgt_location=None, ): - """ - Create regridder for conversions between ``src`` and ``tgt``. + """Create regridder for conversions between ``src`` and ``tgt``. Parameters ---------- @@ -1612,8 +1586,7 @@ def __init__( use_tgt_mask=False, tgt_location=None, ): - """ - Create regridder for conversions between ``src`` and ``tgt``. + """Create regridder for conversions between ``src`` and ``tgt``. Parameters ---------- diff --git a/esmf_regrid/tests/__init__.py b/esmf_regrid/tests/__init__.py index 0de35cdd..59aecb7f 100644 --- a/esmf_regrid/tests/__init__.py +++ b/esmf_regrid/tests/__init__.py @@ -4,14 +4,12 @@ import numpy as np - # Base directory of the test results. _RESULT_PATH = pathlib.Path(__file__).parent.resolve() / "results" def get_result_path(relative_path, unit=True): - """ - Form the absolute path to the results test file. + """Form the absolute path to the results test file. Parameters ---------- @@ -42,8 +40,7 @@ def get_result_path(relative_path, unit=True): def make_grid_args(nx, ny): - """ - Return arguments for a small grid. + """Return arguments for a small grid. Parameters ---------- diff --git a/esmf_regrid/tests/integration/esmf_regridder/test_Regridder.py b/esmf_regrid/tests/integration/esmf_regridder/test_Regridder.py index 0d2c8df7..8210b3fb 100644 --- a/esmf_regrid/tests/integration/esmf_regridder/test_Regridder.py +++ b/esmf_regrid/tests/integration/esmf_regridder/test_Regridder.py @@ -3,15 +3,13 @@ import numpy as np from numpy import ma -from esmf_regrid import Constants -from esmf_regrid import esmpy +from esmf_regrid import Constants, esmpy from esmf_regrid.esmf_regridder import GridInfo, Regridder from esmf_regrid.tests import make_grid_args def test_esmpy_normalisation(): - """ - Integration test for :meth:`~esmf_regrid.esmf_regridder.Regridder`. + """Integration test for :meth:`~esmf_regrid.esmf_regridder.Regridder`. Checks against ESMF to ensure results are consistent. """ diff --git a/esmf_regrid/tests/integration/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py b/esmf_regrid/tests/integration/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py index 5be914b3..0aa33203 100644 --- a/esmf_regrid/tests/integration/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py +++ b/esmf_regrid/tests/integration/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py @@ -20,8 +20,7 @@ def test_real_data(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests with cubes derived from realistic data. """ diff --git a/esmf_regrid/tests/unit/_esmf_sdo/test_GridInfo.py b/esmf_regrid/tests/unit/_esmf_sdo/test_GridInfo.py index 25350676..122b5f6c 100644 --- a/esmf_regrid/tests/unit/_esmf_sdo/test_GridInfo.py +++ b/esmf_regrid/tests/unit/_esmf_sdo/test_GridInfo.py @@ -3,8 +3,8 @@ import numpy as np import pytest +from esmf_regrid import tests from esmf_regrid._esmf_sdo import GridInfo -import esmf_regrid.tests as tests def _make_small_grid_args(): @@ -39,8 +39,7 @@ def test_make_grid(): def test_GridInfo_init_fail(): - """ - Basic test for :meth:`~esmf_regrid.esmf_regridder.Regridder.__init__`. + """Basic test for :meth:`~esmf_regrid.esmf_regridder.Regridder.__init__`. Tests that appropriate errors are raised for invalid data. """ diff --git a/esmf_regrid/tests/unit/_esmf_sdo/test_RefinedGridInfo.py b/esmf_regrid/tests/unit/_esmf_sdo/test_RefinedGridInfo.py index 45f9ca11..53aa488e 100644 --- a/esmf_regrid/tests/unit/_esmf_sdo/test_RefinedGridInfo.py +++ b/esmf_regrid/tests/unit/_esmf_sdo/test_RefinedGridInfo.py @@ -12,8 +12,7 @@ def test_expanded_lons_with_mesh(): - """ - Basic test for regridding with :meth:`~esmf_regrid.esmf_regridder.RefinedGridInfo.make_esmf_field`. + """Basic test for regridding with :meth:`~esmf_regrid.esmf_regridder.RefinedGridInfo.make_esmf_field`. Mirrors the tests in :func:`~esmf_regrid.tests.unit.experimental.unstructured_regrid.test_MeshInfo.test_regrid_with_mesh` but with slightly different expected values due to increased accuracy. diff --git a/esmf_regrid/tests/unit/esmf_regridder/test_Constants.py b/esmf_regrid/tests/unit/esmf_regridder/test_Constants.py index 3be4dbee..40f0a9a6 100644 --- a/esmf_regrid/tests/unit/esmf_regridder/test_Constants.py +++ b/esmf_regrid/tests/unit/esmf_regridder/test_Constants.py @@ -2,7 +2,7 @@ import pytest -from esmf_regrid import check_method, check_norm, Constants +from esmf_regrid import Constants, check_method, check_norm @pytest.mark.parametrize( diff --git a/esmf_regrid/tests/unit/esmf_regridder/test_Regridder.py b/esmf_regrid/tests/unit/esmf_regridder/test_Regridder.py index 81be1302..403a6c8d 100644 --- a/esmf_regrid/tests/unit/esmf_regridder/test_Regridder.py +++ b/esmf_regrid/tests/unit/esmf_regridder/test_Regridder.py @@ -155,8 +155,7 @@ def _give_extra_dims(array): def test_Regridder_init_small(): - """ - Simplified test for :meth:`~esmf_regrid.esmf_regridder.Regridder.regrid`. + """Simplified test for :meth:`~esmf_regrid.esmf_regridder.Regridder.regrid`. This test is designed to be simple enough to generate predictable weights. With predictable weights it is easier to check that the weights are @@ -229,8 +228,7 @@ def _get_points(bounds): def test_Regridder_dtype_handling(): - """ - Basic test for :meth:`~esmf_regrid.esmf_regridder.Regridder.regrid`. + """Basic test for :meth:`~esmf_regrid.esmf_regridder.Regridder.regrid`. Tests that dtype is handled as expected. """ diff --git a/esmf_regrid/tests/unit/experimental/io/test_round_tripping.py b/esmf_regrid/tests/unit/experimental/io/test_round_tripping.py index a53f034f..a80099c2 100644 --- a/esmf_regrid/tests/unit/experimental/io/test_round_tripping.py +++ b/esmf_regrid/tests/unit/experimental/io/test_round_tripping.py @@ -179,7 +179,7 @@ def test_grid_to_mesh_round_trip(tmp_path, method, regridder): original_matrix = original_rg.regridder.weight_matrix loaded_matrix = loaded_rg.regridder.weight_matrix # Ensure the original and loaded weight matrix have identical type. - assert type(original_matrix) is type(loaded_matrix) # noqa E721 + assert type(original_matrix) is type(loaded_matrix) # E721 assert np.array_equal(original_matrix.todense(), loaded_matrix.todense()) # Demonstrate regridding still gives the same results. @@ -293,7 +293,7 @@ def test_MeshESMFRegridder_masked_round_trip(tmp_path, rg_maker, regridder): original_matrix = original_rg.regridder.weight_matrix loaded_matrix = loaded_rg.regridder.weight_matrix # Ensure the original and loaded weight matrix have identical type. - assert type(original_matrix) is type(loaded_matrix) # noqa E721 + assert type(original_matrix) is type(loaded_matrix) # E721 assert np.array_equal(original_matrix.todense(), loaded_matrix.todense()) # Ensure the masks are preserved @@ -337,7 +337,7 @@ def test_mesh_to_grid_round_trip(tmp_path, method, regridder): original_matrix = original_rg.regridder.weight_matrix loaded_matrix = loaded_rg.regridder.weight_matrix # Ensure the original and loaded weight matrix have identical type. - assert type(original_matrix) is type(loaded_matrix) # noqa E721 + assert type(original_matrix) is type(loaded_matrix) # E721 assert np.array_equal(original_matrix.todense(), loaded_matrix.todense()) # Demonstrate regridding still gives the same results. diff --git a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_GridToMeshESMFRegridder.py b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_GridToMeshESMFRegridder.py index c3b11581..3578dbc6 100644 --- a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_GridToMeshESMFRegridder.py +++ b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_GridToMeshESMFRegridder.py @@ -37,8 +37,7 @@ def _add_metadata(cube): def test_flat_cubes(): - """ - Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Tests with flat cubes as input (a 2D grid cube and a 1D mesh cube). """ @@ -80,8 +79,7 @@ def test_flat_cubes(): "method", [Constants.Method.BILINEAR, Constants.Method.NEAREST] ) def test_node_friendly_methods(method, nsi): - """ - Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Tests with method=Constants.Method.BILINEAR and method=Constants.Method.NEAREST. """ @@ -120,8 +118,7 @@ def test_node_friendly_methods(method, nsi): def test_multidim_cubes(): - """ - Test for :class:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Test for :class:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests with multidimensional cubes. The source cube contains coordinates on the dimensions before and after the grid dimensions. @@ -169,8 +166,7 @@ def test_multidim_cubes(): def test_invalid_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Checks that an error is raised when mdtol is out of range. """ @@ -189,8 +185,7 @@ def test_invalid_mdtol(): def test_invalid_method(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Checks that an error is raised when the method is invalid. """ @@ -229,8 +224,7 @@ def test_invalid_method(): def test_invalid_resolution(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Checks that an error is raised when the resolution is invalid. """ @@ -257,8 +251,7 @@ def test_invalid_resolution(): def test_default_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Checks that default mdtol values are as expected. """ @@ -276,8 +269,7 @@ def test_default_mdtol(): def test_mismatched_grids(): - """ - Test error handling in calling of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test error handling in calling of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Checks that an error is raised when the regridder is called with a cube whose grid does not match with the one used when initialising @@ -302,8 +294,7 @@ def test_mismatched_grids(): def test_mask_handling(): - """ - Test masked data handling for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test masked data handling for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Tests masked data handling for multiple valid values for mdtol. """ @@ -372,8 +363,7 @@ def test_laziness(): def test_resolution(): - """ - Test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Tests for the src_resolution keyword. """ @@ -392,8 +382,7 @@ def test_resolution(): def test_curvilinear(): - """ - Test for :class:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Test for :class:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests with curvilinear target cube. """ @@ -443,8 +432,7 @@ def test_curvilinear(): def test_mesh_target(): - """ - Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Tests with a mesh as the target. """ @@ -478,8 +466,7 @@ def test_mesh_target(): "resolution", (None, 2), ids=("no resolution", "with resolution") ) def test_masks(resolution): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Checks that the `use_src_mask` and `use_tgt_mask` keywords work properly. """ diff --git a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_MeshToGridESMFRegridder.py b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_MeshToGridESMFRegridder.py index 563759bf..74546851 100644 --- a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_MeshToGridESMFRegridder.py +++ b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_MeshToGridESMFRegridder.py @@ -37,8 +37,7 @@ def _add_metadata(cube): def test_flat_cubes(): - """ - Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Tests with flat cubes as input (a 1D mesh cube and a 2D grid cube). """ @@ -74,8 +73,7 @@ def test_flat_cubes(): "method", [Constants.Method.BILINEAR, Constants.Method.NEAREST] ) def test_node_friendly_methods(method, nsi): - """ - Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Basic test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Tests with method=Constants.Method.BILINEAR and method=Constants.Method.NEAREST. """ @@ -95,7 +93,6 @@ def test_node_friendly_methods(method, nsi): face_regridder = MeshToGridESMFRegridder(face_src, tgt, method=method) node_regridder = MeshToGridESMFRegridder(node_src, tgt, method=method) - print(node_regridder.regridder.method) assert face_regridder.regridder.method == method assert node_regridder.regridder.method == method @@ -114,8 +111,7 @@ def test_node_friendly_methods(method, nsi): def test_multidim_cubes(): - """ - Test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Tests with multidimensional cubes. The source cube contains coordinates on the dimensions before and after the mesh dimension. @@ -165,8 +161,7 @@ def test_multidim_cubes(): def test_invalid_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when mdtol is out of range. """ @@ -185,8 +180,7 @@ def test_invalid_mdtol(): def test_invalid_method(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when method is invalid. """ @@ -225,8 +219,7 @@ def test_invalid_method(): def test_invalid_resolution(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when the resolution is invalid. """ @@ -253,8 +246,7 @@ def test_invalid_resolution(): def test_default_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that default mdtol values are as expected. """ @@ -271,10 +263,9 @@ def test_default_mdtol(): assert rg_bi.mdtol == 0 -@pytest.mark.xfail +@pytest.mark.xfail() def test_mistmatched_mesh(): - """ - Test the calling of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test the calling of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when the regridder is called with a cube whose mesh does not match the one used for initialisation. @@ -343,8 +334,7 @@ def test_laziness(): def test_resolution(): - """ - Test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Tests for the tgt_resolution keyword. """ @@ -371,8 +361,7 @@ def test_resolution(): def test_curvilinear(): - """ - Test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test for :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Tests with curvilinear source cube. """ @@ -427,8 +416,7 @@ def test_curvilinear(): "resolution", (None, 2), ids=("no resolution", "with resolution") ) def test_masks(resolution): - """ - Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that the `use_src_mask` and `use_tgt_mask` keywords work properly. """ diff --git a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_rectilinear_to_unstructured.py b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_rectilinear_to_unstructured.py index e408a39a..9a9c7b37 100644 --- a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_rectilinear_to_unstructured.py +++ b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_rectilinear_to_unstructured.py @@ -34,8 +34,7 @@ def _add_metadata(cube): def test_flat_cubes(): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests with flat cubes as input (a 2D grid cube and a 1D mesh cube). """ @@ -75,8 +74,7 @@ def test_flat_cubes(): "method", (Constants.Method.BILINEAR, Constants.Method.NEAREST) ) def test_node_friendly_methods(method): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests with the bilinear and nearest method. """ @@ -106,8 +104,7 @@ def test_node_friendly_methods(method): def test_invalid_args(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests that an appropriate error is raised when arguments are invalid. """ @@ -156,8 +153,7 @@ def test_invalid_args(): def test_multidim_cubes(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests with multidimensional cubes. The source cube contains coordinates on the dimensions before and after the grid dimensions. @@ -222,8 +218,7 @@ def test_multidim_cubes(): def test_mask_handling(): - """ - Test masked data handling for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Test masked data handling for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests masked data handling for multiple valid values for mdtol. """ @@ -255,8 +250,7 @@ def test_mask_handling(): def test_resolution(): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_rectilinear_to_unstructured`. Tests the src_resolution keyword with grids that would otherwise not work. """ diff --git a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py index 36f94d44..fefbab0d 100644 --- a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py +++ b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_rectilinear.py @@ -34,8 +34,7 @@ def _add_metadata(cube): def test_flat_cubes(): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests with flat cubes as input (a 1D mesh cube and a 2D grid cube). """ @@ -69,8 +68,7 @@ def test_flat_cubes(): "method", (Constants.Method.BILINEAR, Constants.Method.NEAREST) ) def test_node_friendly_methods(method): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests with the bilinear and nearest method. """ @@ -100,8 +98,7 @@ def test_node_friendly_methods(method): def test_invalid_args(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests that an appropriate error is raised when arguments are invalid. """ @@ -150,8 +147,7 @@ def test_invalid_args(): def test_multidim_cubes(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests with multidimensional cubes. The source cube contains coordinates on the dimensions before and after the mesh dimension. @@ -198,8 +194,7 @@ def test_multidim_cubes(): def test_resolution(): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests the tgt_resolution keyword with grids that would otherwise not work. """ diff --git a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_unstructured.py b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_unstructured.py index 1a596aec..57aec9ea 100644 --- a/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_unstructured.py +++ b/esmf_regrid/tests/unit/experimental/unstructured_scheme/test_regrid_unstructured_to_unstructured.py @@ -30,8 +30,7 @@ def _add_metadata(cube): def test_flat_cubes(): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. Tests with flat cubes as input (a 1D mesh cube and a 2D grid cube). """ @@ -61,8 +60,7 @@ def test_flat_cubes(): @pytest.mark.parametrize("method", ("bilinear", "nearest")) def test_node_friendly_methods(method): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. Tests with the bilinear and nearest method. """ @@ -90,8 +88,7 @@ def test_node_friendly_methods(method): def test_invalid_args(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. Tests that an appropriate error is raised when arguments are invalid. """ @@ -128,13 +125,11 @@ def test_invalid_args(): def test_multidim_cubes(): - """ - Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. + """Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_unstructured`. Tests with multidimensional cubes. The source cube contains coordinates on the dimensions before and after the mesh dimension. """ - mesh = _full_mesh() mesh_length = mesh.connectivity(contains_face=True).shape[0] diff --git a/esmf_regrid/tests/unit/schemes/__init__.py b/esmf_regrid/tests/unit/schemes/__init__.py index c51deffd..38cba843 100644 --- a/esmf_regrid/tests/unit/schemes/__init__.py +++ b/esmf_regrid/tests/unit/schemes/__init__.py @@ -15,8 +15,7 @@ def _test_cube_regrid(scheme, src_type, tgt_type): - """ - Test that `scheme` can be passed to a cubes regrid method. + """Test that `scheme` can be passed to a cubes regrid method. Checks that regridding occurs and that mdtol is used correctly. """ @@ -82,8 +81,7 @@ def _test_cube_regrid(scheme, src_type, tgt_type): def _test_invalid_mdtol(scheme): - """ - Test initialisation of the scheme. + """Test initialisation of the scheme. Checks that an error is raised when mdtol is out of range. """ @@ -95,8 +93,7 @@ def _test_invalid_mdtol(scheme): def _test_mask_from_init(scheme, mask_keyword): - """ - Test initialisation of scheme. + """Test initialisation of scheme. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ @@ -131,8 +128,7 @@ def _test_mask_from_init(scheme, mask_keyword): def _test_mask_from_regridder(scheme, mask_keyword): - """ - Test regridder method of the scheme. + """Test regridder method of the scheme. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ diff --git a/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeighted.py b/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeighted.py index 50af91b3..85bebb50 100644 --- a/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeighted.py +++ b/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeighted.py @@ -24,8 +24,7 @@ ], ) def test_cube_regrid(src_type, tgt_type): - """ - Test that ESMFAreaWeighted can be passed to a cubes regrid method. + """Test that ESMFAreaWeighted can be passed to a cubes regrid method. Checks that regridding occurs and that mdtol is used correctly. """ @@ -33,8 +32,7 @@ def test_cube_regrid(src_type, tgt_type): def test_invalid_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. Checks that an error is raised when mdtol is out of range. """ @@ -43,8 +41,7 @@ def test_invalid_mdtol(): @pytest.mark.parametrize("mask_keyword", ["use_src_mask", "use_tgt_mask"]) def test_mask_from_init(mask_keyword): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ @@ -53,8 +50,7 @@ def test_mask_from_init(mask_keyword): @pytest.mark.parametrize("mask_keyword", ["use_src_mask", "use_tgt_mask"]) def test_mask_from_regridder(mask_keyword): - """ - Test regridder method of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. + """Test regridder method of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ @@ -62,8 +58,7 @@ def test_mask_from_regridder(mask_keyword): def test_invalid_tgt_location(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeighted`. Checks that initialisation fails when tgt_location is not "face". """ diff --git a/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeightedRegridder.py b/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeightedRegridder.py index 8d68958e..3feea430 100644 --- a/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeightedRegridder.py +++ b/esmf_regrid/tests/unit/schemes/test_ESMFAreaWeightedRegridder.py @@ -12,8 +12,7 @@ def test_dim_switching(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that the regridder accepts a cube with dimensions in a different order than the cube which initialised it. Checks that dimension order is @@ -40,8 +39,7 @@ def test_dim_switching(): def test_differing_grids(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that the regridder raises an error when given a cube with a different grid to the one it was initialised with. @@ -69,8 +67,7 @@ def test_differing_grids(): def test_invalid_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that an error is raised when mdtol is out of range. """ @@ -89,8 +86,7 @@ def test_invalid_mdtol(): def test_invalid_tgt_location(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that initialisation fails when tgt_location is not "face". """ @@ -107,8 +103,7 @@ def test_invalid_tgt_location(): def test_curvilinear_equivalence(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that equivalent curvilinear and rectilinear coordinates give the same results. @@ -137,8 +132,7 @@ def extract_weights(regridder): def test_curvilinear_and_rectilinear(): - """ - Test :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that a cube with both curvilinear and rectilinear coords still works. Checks that the DimCoords have priority over AuxCoords. @@ -190,8 +184,7 @@ def test_curvilinear_and_rectilinear(): def test_unit_equivalence(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that equivalent coordinates in degrees and radians give the same results. """ @@ -250,8 +243,7 @@ def extract_weights(regridder): def test_masks(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that the `use_src_mask` and `use_tgt_mask` keywords work properly. """ @@ -293,8 +285,7 @@ def test_masks(): def test_resolution(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFAreaWeightedRegridder`. Checks that the regridder accepts resolution arguments. """ diff --git a/esmf_regrid/tests/unit/schemes/test_ESMFBilinear.py b/esmf_regrid/tests/unit/schemes/test_ESMFBilinear.py index f6a9e30f..7cf02f19 100644 --- a/esmf_regrid/tests/unit/schemes/test_ESMFBilinear.py +++ b/esmf_regrid/tests/unit/schemes/test_ESMFBilinear.py @@ -24,8 +24,7 @@ ], ) def test_cube_regrid(src_type, tgt_type): - """ - Test that ESMFBilinear can be passed to a cubes regrid method. + """Test that ESMFBilinear can be passed to a cubes regrid method. Checks that regridding occurs and that mdtol is used correctly. """ @@ -33,8 +32,7 @@ def test_cube_regrid(src_type, tgt_type): def test_invalid_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinear`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinear`. Checks that an error is raised when mdtol is out of range. """ @@ -43,8 +41,7 @@ def test_invalid_mdtol(): @pytest.mark.parametrize("mask_keyword", ["use_src_mask", "use_tgt_mask"]) def test_mask_from_init(mask_keyword): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinear`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinear`. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ @@ -53,8 +50,7 @@ def test_mask_from_init(mask_keyword): @pytest.mark.parametrize("mask_keyword", ["use_src_mask", "use_tgt_mask"]) def test_mask_from_regridder(mask_keyword): - """ - Test regridder method of :class:`esmf_regrid.schemes.ESMFBilinear`. + """Test regridder method of :class:`esmf_regrid.schemes.ESMFBilinear`. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ diff --git a/esmf_regrid/tests/unit/schemes/test_ESMFBilinearRegridder.py b/esmf_regrid/tests/unit/schemes/test_ESMFBilinearRegridder.py index da60f416..266b6b6b 100644 --- a/esmf_regrid/tests/unit/schemes/test_ESMFBilinearRegridder.py +++ b/esmf_regrid/tests/unit/schemes/test_ESMFBilinearRegridder.py @@ -12,8 +12,7 @@ def test_dim_switching(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that the regridder accepts a cube with dimensions in a different order than the cube which initialised it. Checks that dimension order is @@ -40,8 +39,7 @@ def test_dim_switching(): def test_differing_grids(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that the regridder raises an error when given a cube with a different grid to the one it was initialised with. @@ -69,8 +67,7 @@ def test_differing_grids(): def test_invalid_mdtol(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that an error is raised when mdtol is out of range. """ @@ -90,8 +87,7 @@ def test_invalid_mdtol(): @pytest.mark.parametrize("with_bounds", (False, True)) def test_curvilinear_equivalence(with_bounds): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that equivalent curvilinear and rectilinear coordinates give the same results. @@ -125,8 +121,7 @@ def extract_weights(regridder): def test_curvilinear_and_rectilinear(): - """ - Test :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that a cube with both curvilinear and rectilinear coords still works. Checks that the DimCoords have priority over AuxCoords. @@ -178,8 +173,7 @@ def test_curvilinear_and_rectilinear(): def test_unit_equivalence(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that equivalent coordinates in degrees and radians give the same results. """ @@ -238,8 +232,7 @@ def extract_weights(regridder): def test_masks(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that the `use_src_mask` and `use_tgt_mask` keywords work properly. """ @@ -279,8 +272,7 @@ def test_masks(): def test_regrid_data(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFBilinearRegridder`. Checks that regridding mathematics behaves in an expected way. """ diff --git a/esmf_regrid/tests/unit/schemes/test_ESMFNearest.py b/esmf_regrid/tests/unit/schemes/test_ESMFNearest.py index 6f146e6c..f991750d 100644 --- a/esmf_regrid/tests/unit/schemes/test_ESMFNearest.py +++ b/esmf_regrid/tests/unit/schemes/test_ESMFNearest.py @@ -29,8 +29,7 @@ ], ) def test_cube_regrid(src_type, tgt_type): - """ - Test that ESMFNearest can be passed to a cubes regrid method. + """Test that ESMFNearest can be passed to a cubes regrid method. Checks that regridding occurs. """ @@ -86,8 +85,7 @@ def test_cube_regrid(src_type, tgt_type): @pytest.mark.parametrize("mask_keyword", ["use_src_mask", "use_tgt_mask"]) def test_mask_from_init(mask_keyword): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFNearest`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFNearest`. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ @@ -96,8 +94,7 @@ def test_mask_from_init(mask_keyword): @pytest.mark.parametrize("mask_keyword", ["use_src_mask", "use_tgt_mask"]) def test_mask_from_regridder(mask_keyword): - """ - Test regridder method of :class:`esmf_regrid.schemes.ESMFNearest`. + """Test regridder method of :class:`esmf_regrid.schemes.ESMFNearest`. Checks that use_src_mask and use_tgt_mask are passed down correctly. """ diff --git a/esmf_regrid/tests/unit/schemes/test_ESMFNearestRegridder.py b/esmf_regrid/tests/unit/schemes/test_ESMFNearestRegridder.py index 6c325e4d..657cad45 100644 --- a/esmf_regrid/tests/unit/schemes/test_ESMFNearestRegridder.py +++ b/esmf_regrid/tests/unit/schemes/test_ESMFNearestRegridder.py @@ -15,8 +15,7 @@ def test_dim_switching(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that the regridder accepts a cube with dimensions in a different order than the cube which initialised it. Checks that dimension order is @@ -43,8 +42,7 @@ def test_dim_switching(): def test_differing_grids(): - """ - Test calling of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test calling of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that the regridder raises an error when given a cube with a different grid to the one it was initialised with. @@ -73,8 +71,7 @@ def test_differing_grids(): @pytest.mark.parametrize("with_bounds", (False, True)) def test_curvilinear_equivalence(with_bounds): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that equivalent curvilinear and rectilinear coordinates give the same results. @@ -108,8 +105,7 @@ def extract_weights(regridder): def test_curvilinear_and_rectilinear(): - """ - Test :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that a cube with both curvilinear and rectilinear coords still works. Checks that the DimCoords have priority over AuxCoords. @@ -161,8 +157,7 @@ def test_curvilinear_and_rectilinear(): def test_unit_equivalence(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that equivalent coordinates in degrees and radians give the same results. """ @@ -229,8 +224,7 @@ def extract_weights(regridder): def test_masks(): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that the `use_src_mask` and `use_tgt_mask` keywords work properly. """ @@ -283,8 +277,7 @@ def test_masks(): ], ) def test_regrid_data(src_type, tgt_type): - """ - Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes.ESMFNearestRegridder`. Checks that regridding mathematics behaves in an expected way. """ diff --git a/esmf_regrid/tests/unit/schemes/test__ESMFRegridder.py b/esmf_regrid/tests/unit/schemes/test__ESMFRegridder.py index b5c103fa..0d1b7223 100644 --- a/esmf_regrid/tests/unit/schemes/test__ESMFRegridder.py +++ b/esmf_regrid/tests/unit/schemes/test__ESMFRegridder.py @@ -9,8 +9,7 @@ def test_invalid_method(): - """ - Test initialisation of :class:`esmf_regrid.schemes._ESMFRegridder`. + """Test initialisation of :class:`esmf_regrid.schemes._ESMFRegridder`. Checks that an error is raised when the method is invalid. """ diff --git a/esmf_regrid/tests/unit/schemes/test__cube_to_GridInfo.py b/esmf_regrid/tests/unit/schemes/test__cube_to_GridInfo.py index 386a562c..a735c991 100644 --- a/esmf_regrid/tests/unit/schemes/test__cube_to_GridInfo.py +++ b/esmf_regrid/tests/unit/schemes/test__cube_to_GridInfo.py @@ -287,8 +287,8 @@ def test__contiguous_bounds(masked): # fmt: off expected_vertices = np.array( [ - [0, 1, 11, 30, 40, 50, 51], # noqa: E241 - [100, 101, 12, 130, 140, 141, 52], # noqa: E241 + [0, 1, 11, 30, 40, 50, 51], + [100, 101, 12, 130, 140, 141, 52], [103, 210, 211, 133, 143, 142, 152], [203, 310, 320, 330, 331, 350, 351], [400, 401, 323, 430, 440, 450, 451], @@ -300,7 +300,7 @@ def test__contiguous_bounds(masked): # fmt: off expected_vertices = np.array( [ - [0, 10, 20, 30, 40, 50, 51], # noqa: E241 + [0, 10, 20, 30, 40, 50, 51], [100, 110, 120, 130, 140, 150, 151], [200, 210, 220, 230, 240, 250, 251], [300, 310, 320, 330, 340, 350, 351], diff --git a/esmf_regrid/tests/unit/schemes/test__mesh_to_MeshInfo.py b/esmf_regrid/tests/unit/schemes/test__mesh_to_MeshInfo.py index fb407111..e1aa6b0d 100644 --- a/esmf_regrid/tests/unit/schemes/test__mesh_to_MeshInfo.py +++ b/esmf_regrid/tests/unit/schemes/test__mesh_to_MeshInfo.py @@ -21,8 +21,7 @@ def _pyramid_topology_connectivity_array(): - """ - Generate the face_node_connectivity array for a topological pyramid. + """Generate the face_node_connectivity array for a topological pyramid. The mesh described is a topological pyramid in the sense that there exists a polygonal base (described by the indices [0, 1, 2, 3, 4]) @@ -83,8 +82,7 @@ def _example_mesh(): def _gridlike_mesh(n_lons, n_lats, nsi=0): - """ - Generate a global mesh with geometry similar to a rectilinear grid. + """Generate a global mesh with geometry similar to a rectilinear grid. The resulting mesh will have n_lons cells spanning its longitudes and n_lats cells spanning its latitudes for a total of (n_lons * n_lats) cells. @@ -147,7 +145,7 @@ def _gridlike_mesh(n_lons, n_lats, nsi=0): # Note that fnc_template is created by reshaping a list of indices. These # indices refer to node_lats and node_lons which are generated by reshaping # lat_array and lon_array. Because of the way reshaping preserves order, there - # is a correspondance between an index in a particular position fnc_template + # is a correspondence between an index in a particular position fnc_template # and the latitude and longitude described by lat_array and lon_array in the # same position. node_lats[1:-1] = lat_array.reshape([-1]) diff --git a/esmf_regrid/tests/unit/schemes/test__regrid_unstructured_to_rectilinear__prepare.py b/esmf_regrid/tests/unit/schemes/test__regrid_unstructured_to_rectilinear__prepare.py index bfc52410..a5958ad6 100644 --- a/esmf_regrid/tests/unit/schemes/test__regrid_unstructured_to_rectilinear__prepare.py +++ b/esmf_regrid/tests/unit/schemes/test__regrid_unstructured_to_rectilinear__prepare.py @@ -4,7 +4,6 @@ from iris.cube import Cube import numpy as np - from esmf_regrid import Constants from esmf_regrid.esmf_regridder import GridInfo from esmf_regrid.experimental.unstructured_regrid import MeshInfo @@ -33,8 +32,7 @@ def _full_mesh(): def _flat_mesh_cube(): - """ - Return a 1D cube with a mesh attached. + """Return a 1D cube with a mesh attached. Returned cube has no metadata except for the mesh and two MeshCoords. Returned cube has data consisting of an array of ones. @@ -50,8 +48,7 @@ def _flat_mesh_cube(): def test_flat_cubes(): - """ - Basic test for :func:`esmf_regrid.experimental.unstructured_scheme._regrid_unstructured_to_rectilinear__prepare`. + """Basic test for :func:`esmf_regrid.experimental.unstructured_scheme._regrid_unstructured_to_rectilinear__prepare`. Tests with flat cubes as input (a 1D mesh cube and a 2D grid cube). """ diff --git a/esmf_regrid/tests/unit/schemes/test_regrid_rectilinear_to_rectilinear.py b/esmf_regrid/tests/unit/schemes/test_regrid_rectilinear_to_rectilinear.py index 115de52a..644ecaa7 100644 --- a/esmf_regrid/tests/unit/schemes/test_regrid_rectilinear_to_rectilinear.py +++ b/esmf_regrid/tests/unit/schemes/test_regrid_rectilinear_to_rectilinear.py @@ -16,8 +16,7 @@ def test_rotated_regridding(): - """ - Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. + """Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. Test the regriding of a rotated pole coordinate system. The test is designed to that it should be possible to verify the result by @@ -70,8 +69,7 @@ def test_rotated_regridding(): def test_extra_dims(): - """ - Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. + """Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. Tests the handling of extra dimensions and metadata. Ensures that proper coordinates, attributes, names and units are copied over. @@ -195,8 +193,7 @@ def test_laziness(src_transposed, tgt_transposed): @pytest.mark.parametrize("src_transposed", (False, True)) @pytest.mark.parametrize("tgt_transposed", (False, True)) def test_laziness_curvilinear(src_transposed, tgt_transposed): - """ - Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. + """Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. Tests the handling of lazy data. Ensures that handling is the same for non-lazy data. @@ -264,8 +261,7 @@ def test_laziness_curvilinear(src_transposed, tgt_transposed): def test_extra_dims_curvilinear(): - """ - Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. + """Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. Tests the handling of extra dimensions and metadata. Ensures that proper coordinates, attributes, names and units are copied over. @@ -351,8 +347,7 @@ def _add_metadata(cube): def test_extra_dims_curvilinear_to_rectilinear(): - """ - Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. + """Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. Tests the handling of extra dimensions and metadata. Ensures that proper coordinates, attributes, names and units are copied over. @@ -438,8 +433,7 @@ def _add_metadata(cube): def test_extra_dims_rectilinear_to_curvilinear(): - """ - Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. + """Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`. Tests the handling of extra dimensions and metadata. Ensures that proper coordinates, attributes, names and units are copied over. diff --git a/noxfile.py b/noxfile.py index 19b773fa..562b8f21 100644 --- a/noxfile.py +++ b/noxfile.py @@ -1,5 +1,4 @@ -""" -Perform test automation with nox. +"""Perform test automation with nox. For further details, see https://nox.thea.codes/en/stable/# @@ -16,7 +15,6 @@ from nox.logger import logger import yaml - #: Default to reusing any pre-existing nox environments. nox.options.reuse_existing_virtualenvs = False @@ -41,8 +39,7 @@ def _lockfile_path(py_string: str, platform_placeholder: bool = False) -> Path: - """ - Return a constructed lockfile path for the relevant python string e.g ``py38``. + """Return a constructed lockfile path for the relevant python string e.g ``py38``. Optionally retain the ``{platform}`` placeholder to support conda-lock's ``--filename-template``. @@ -91,8 +88,7 @@ def _venv_changed(session: nox.sessions.Session) -> bool: def _install_and_cache_venv(session: nox.sessions.Session) -> None: - """ - Cache the nox session environment. + """Cache the nox session environment. This consists of saving a hexdigest (sha256) of the associated Conda lock file. @@ -110,8 +106,7 @@ def _install_and_cache_venv(session: nox.sessions.Session) -> None: def _get_iris_github_artifact(session: nox.sessions.Session) -> str: - """ - Determine whether an Iris source artifact from GitHub is required. + """Determine whether an Iris source artifact from GitHub is required. This can be an Iris branch name, commit sha or tag name. @@ -205,8 +200,7 @@ def _prepare_env(session: nox.sessions.Session) -> None: @nox.session def update_lockfiles(session: nox.sessions.Session): - """ - Re-resolve env specs and store as lockfiles (``requirements/locks/``). + """Re-resolve env specs and store as lockfiles (``requirements/locks/``). Original Conda environment specifications are at: ``requirements/py**.yml``. The output lock files denote the dependencies @@ -290,8 +284,7 @@ def update_lockfiles(session: nox.sessions.Session): @nox.session(python=PY_VER, venv_backend="conda") def tests(session: nox.sessions.Session): - """ - Perform esmf-regrid integration and unit tests. + """Perform esmf-regrid integration and unit tests. Parameters ---------- @@ -313,8 +306,7 @@ def tests(session: nox.sessions.Session): @nox.session(python=PY_VER, venv_backend="conda") def wheel(session: nox.sessions.Session): - """ - Perform iris-esmf-regrid local wheel install and import test. + """Perform iris-esmf-regrid local wheel install and import test. Parameters ---------- @@ -324,7 +316,7 @@ def wheel(session: nox.sessions.Session): """ _prepare_env(session) session.cd("dist") - fname = list(Path(".").glob("esmf_regrid-*.whl")) + fname = list(Path().glob("esmf_regrid-*.whl")) if len(fname) == 0: raise ValueError("Cannot find wheel to install.") if len(fname) > 1: diff --git a/pyproject.toml b/pyproject.toml index d83ae88f..9569b003 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,6 @@ # Defined by PEP 518 requires = [ "setuptools>=61", - "wheel", ] # Defined by PEP 517 build-backend = "setuptools.build_meta" @@ -48,11 +47,17 @@ line-length = 88 target-version = ['py310', 'py311', 'py312'] include = '\.pyi?$' +[tool.codespell] +ignore-words-list = "discontiguities" + [tool.pytest.ini_options] -addopts = "-ra -v --doctest-modules" +addopts = ["-ra", "-v", "--doctest-modules", "--strict-config", "--strict-markers"] minversion = "6.0" doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS NUMBER" testpaths = "esmf_regrid" +log_cli_level = "INFO" +xfail_strict = true +filterwarnings = ["error"] [tool.setuptools] license-files = ["LICENSE"] @@ -74,6 +79,10 @@ include = ["esmf_regrid*"] ignore = [ # https://learn.scientific-python.org/development/guides/style/#PC180 "PC180", # Uses prettier + "PC170", + "GH104", + "GH212", + "RF003", ] [tool.mypy] @@ -81,12 +90,14 @@ ignore = [ ignore_missing_imports = true warn_unused_configs = true warn_unreachable = true -enable_error_code = ["ignore-without-code", "truthy-bool"] +enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] exclude = [ 'noxfile\.py', - 'docs/conf\.py' + 'docs/src/conf\.py', + '^benchmarks', ] strict = false # Default value, make true when introducing type hinting. +no_namespace_packages = true [tool.numpydoc_validation] checks = [ @@ -122,6 +133,21 @@ checks = [ # Record temporarily ignored checks below; will be reviewed at a later date: + # TODO: annotate and determine if these ought to be temporary or permanent + "PR01", + "PR02", + "PR04", + "PR05", + "PR07", + "PR09", + "PR10", + "RT01", + "RT03", + "RT05", + "GL08", + "SS02", + "SS05", + ] exclude = [ '\.__eq__$', @@ -149,11 +175,58 @@ ignore = [ # NOTE: This rule may cause conflicts when used with "ruff format". "ISC001", # Implicitly concatenate string literals on one line. - "PR01", - "PR07", - "PR09", - "RT01", - "GL08", + + # TODO: annotate and determine if these ought to be temporary or permanent + "A001", + "ANN001", + "ANN002", + "ANN003", + "ANN101", + "ANN201", + "ANN202", + "ANN204", + "ARG001", + "ARG002", + "B018", + "B028", + "B904", + "C408", + "C901", + "D104", + "E501", + "EM101", + "EM102", + "ERA001", + "F401", + "F403", + "FBT002", + "FIX002", + "FLY002", + "INP001", + "N802", + "N806", + "PERF401", + "PLR0912", + "PLR0913", + "PLR0915", + "PLR2004", + "PLW2901", + "PTH107", + "PTH110", + "PYI024", + "RET503", + "RET504", + "RUF005", + "RUF012", + "S101", + "S603", + "SIM108", + "SLF001", + "TD002", + "TD003", + "TID252", + "TRY003", + ] preview = false select = [ @@ -166,5 +239,45 @@ ignore = [ force-sort-within-sections = true known-first-party = ["iris-esmf-regrid"] +[tool.ruff.lint.per-file-ignores] +# All test scripts + +# TODO: annotate and determine if these ought to be temporary or permanent + +"esmf_regrid/tests/*.py" = [ + # https://docs.astral.sh/ruff/rules/undocumented-public-module/ + "B006", + "N999", + "PT006", + "PT007", + "PT011", + "PTH118", + "PTH123", +] +"benchmarks/*.py" = [ + "ANN205", + "D102", + "D103", + "DTZ005", + "PLW1510", + "S607", + "TRY002", +] +"docs/src/conf.py" = [ + "E402", + "DTZ005", +] +"noxfile.py" = [ + "FBT001", + "PIE810", + "S310", + "S506", + "SIM105", + "T201", +] +"setup.py" = [ + "EXE001", +] + [tool.ruff.lint.pydocstyle] convention = "numpy" diff --git a/setup.py b/setup.py index 192faa1d..7b91d632 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,6 @@ """iris-esmf-regrid setuptools packaging.""" - from setuptools import setup - setup()