From 8647185b81161ca17f8f5f1c64c9d7548926cc99 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Tue, 20 Feb 2024 14:11:50 +0000 Subject: [PATCH 1/2] Refactor warnings into iris.warnings. --- .../src/further_topics/filtering_warnings.rst | 24 +-- docs/src/whatsnew/latest.rst | 2 +- lib/iris/_concatenate.py | 3 +- lib/iris/_shapefiles.py | 2 +- lib/iris/analysis/_regrid.py | 2 +- lib/iris/analysis/calculus.py | 2 +- lib/iris/analysis/cartography.py | 13 +- lib/iris/analysis/geometry.py | 9 +- lib/iris/analysis/maths.py | 3 +- lib/iris/aux_factory.py | 2 +- lib/iris/config.py | 6 +- lib/iris/coord_systems.py | 6 +- lib/iris/coords.py | 9 +- lib/iris/cube.py | 5 +- lib/iris/exceptions.py | 183 ------------------ lib/iris/experimental/regrid.py | 2 +- lib/iris/experimental/ugrid/cf.py | 2 +- lib/iris/experimental/ugrid/load.py | 2 +- lib/iris/fileformats/_ff.py | 3 +- .../fileformats/_nc_load_rules/actions.py | 10 +- .../fileformats/_nc_load_rules/helpers.py | 47 ++--- lib/iris/fileformats/cf.py | 24 +-- lib/iris/fileformats/name_loaders.py | 3 +- lib/iris/fileformats/netcdf/loader.py | 10 +- lib/iris/fileformats/netcdf/saver.py | 27 +-- lib/iris/fileformats/nimrod_load_rules.py | 4 +- lib/iris/fileformats/pp.py | 15 +- lib/iris/fileformats/pp_save_rules.py | 2 +- lib/iris/fileformats/rules.py | 7 +- lib/iris/iterate.py | 2 +- lib/iris/pandas.py | 2 +- lib/iris/plot.py | 3 +- lib/iris/tests/graphics/idiff.py | 2 +- .../experimental/test_ugrid_load.py | 2 +- .../integration/netcdf/test_delayed_save.py | 2 +- .../tests/integration/netcdf/test_general.py | 5 +- .../netcdf/test_self_referencing.py | 2 +- lib/iris/tests/integration/test_pp.py | 3 +- lib/iris/tests/test_coding_standards.py | 2 +- lib/iris/tests/test_concatenate.py | 2 +- lib/iris/tests/test_coord_api.py | 1 - lib/iris/tests/test_coordsystem.py | 2 +- lib/iris/tests/test_hybrid.py | 2 +- lib/iris/tests/test_iterate.py | 2 +- lib/iris/tests/test_netcdf.py | 2 +- .../unit/analysis/cartography/test_project.py | 2 +- .../geometry/test_geometry_area_weights.py | 2 +- lib/iris/tests/unit/coords/test_Coord.py | 3 +- lib/iris/tests/unit/cube/test_Cube.py | 3 +- .../unit/cube/test_Cube__aggregated_by.py | 1 - ...test_CFUGridAuxiliaryCoordinateVariable.py | 8 +- .../cf/test_CFUGridConnectivityVariable.py | 8 +- .../ugrid/cf/test_CFUGridMeshVariable.py | 8 +- .../tests/unit/fileformats/ff/test_FF2PP.py | 3 +- .../name_loaders/test__build_cell_methods.py | 2 +- .../nc_load_rules/actions/__init__.py | 2 +- .../helpers/test__normalise_bounds_units.py | 2 +- .../helpers/test_parse_cell_methods.py | 2 +- .../netcdf/loader/test__load_aux_factory.py | 2 +- .../fileformats/netcdf/saver/test_Saver.py | 2 +- .../saver/test_Saver__lazy_stream_data.py | 2 +- .../netcdf/saver/test__fillvalue_report.py | 2 +- .../tests/unit/fileformats/pp/test_PPField.py | 2 +- .../util/test_mask_cube_from_shapefile.py | 2 +- lib/iris/warnings.py | 180 +++++++++++++++++ 65 files changed, 356 insertions(+), 347 deletions(-) create mode 100644 lib/iris/warnings.py diff --git a/docs/src/further_topics/filtering_warnings.rst b/docs/src/further_topics/filtering_warnings.rst index a3a7aed7a9..f39e6153f2 100644 --- a/docs/src/further_topics/filtering_warnings.rst +++ b/docs/src/further_topics/filtering_warnings.rst @@ -16,7 +16,7 @@ you to ``ignore`` Warnings which you do not find helpful. import iris import iris.coord_systems - import iris.exceptions + import iris.warnings # Hack to ensure doctests actually see Warnings that are raised, and that # they have a relative path (so a test pass is not machine-dependent). @@ -48,7 +48,7 @@ Warnings: >>> my_operation() ... iris/coord_systems.py:442: IrisUserWarning: Setting inverse_flattening does not affect other properties of the GeogCS object. To change other properties set them explicitly or create a new GeogCS instance. - warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) + warnings.warn(wmsg, category=iris.warnings.IrisUserWarning) iris/coord_systems.py:768: IrisDefaultingWarning: Discarding false_easting and false_northing that are not used by Cartopy. warnings.warn( @@ -111,7 +111,7 @@ You can target specific Warning messages, e.g. ... my_operation() ... iris/coord_systems.py:442: IrisUserWarning: Setting inverse_flattening does not affect other properties of the GeogCS object. To change other properties set them explicitly or create a new GeogCS instance. - warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) + warnings.warn(wmsg, category=iris.warnings.IrisUserWarning) :: @@ -176,7 +176,7 @@ Warnings of a Common Type code you are calling.** The below example will ``ignore`` any -:class:`~iris.exceptions.IrisDefaultingWarning` that gets raised by *any* +:class:`~iris.warnings.IrisDefaultingWarning` that gets raised by *any* module during execution: .. doctest:: filtering_warnings @@ -184,25 +184,25 @@ module during execution: >>> with warnings.catch_warnings(): ... warnings.filterwarnings( ... "ignore", - ... category=iris.exceptions.IrisDefaultingWarning + ... category=iris.warnings.IrisDefaultingWarning ... ) ... my_operation() ... iris/coord_systems.py:442: IrisUserWarning: Setting inverse_flattening does not affect other properties of the GeogCS object. To change other properties set them explicitly or create a new GeogCS instance. - warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) + warnings.warn(wmsg, category=iris.warnings.IrisUserWarning) ---- -Using :class:`~iris.exceptions.IrisUserWarning` in the filter will ``ignore`` -both Warnings, since :class:`~iris.exceptions.IrisDefaultingWarning` subclasses -:class:`~iris.exceptions.IrisUserWarning` : +Using :class:`~iris.warnings.IrisUserWarning` in the filter will ``ignore`` +both Warnings, since :class:`~iris.warnings.IrisDefaultingWarning` subclasses +:class:`~iris.warnings.IrisUserWarning` : .. doctest:: filtering_warnings >>> with warnings.catch_warnings(): ... warnings.filterwarnings( ... "ignore", - ... category=iris.exceptions.IrisUserWarning + ... category=iris.warnings.IrisUserWarning ... ) ... my_operation() @@ -220,10 +220,10 @@ There are several built-in Python warning categories that can be used here (:class:`DeprecationWarning` being a popular example, see :external+python:mod:`warnings` for more). Since Iris has so many different warnings that might be raised, Iris subclasses -:class:`UserWarning` to :class:`~iris.exceptions.IrisUserWarning`, which itself +:class:`UserWarning` to :class:`~iris.warnings.IrisUserWarning`, which itself has **many** specialised subclasses. These subclasses exist to give you more granularity in your warning filtering; you can see the full list by -searching the :mod:`iris.exceptions` page for ``warning`` . +viewing the :mod:`iris.warnings` module. .. attention:: diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index ed42de42f4..fe22f9cfa1 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -46,7 +46,7 @@ This document explains the changes made to Iris for this release #. `@trexfeathers`_ and `@HGWright`_ (reviewer) sub-categorised all Iris' :class:`UserWarning`\s for richer filtering. The full index of - sub-categories can be seen here: :mod:`iris.exceptions` . (:pull:`5498`) + sub-categories can be seen here: :mod:`iris.warnings` . (:pull:`5498`) #. `@trexfeathers`_ added the :class:`~iris.coord_systems.ObliqueMercator` and :class:`~iris.coord_systems.RotatedMercator` coordinate systems, diff --git a/lib/iris/_concatenate.py b/lib/iris/_concatenate.py index 2a73fcacea..7011df0924 100644 --- a/lib/iris/_concatenate.py +++ b/lib/iris/_concatenate.py @@ -14,6 +14,7 @@ import iris.cube import iris.exceptions from iris.util import array_equal, guess_coord_axis +import iris.warnings # # TODO: @@ -911,7 +912,7 @@ def register( raise iris.exceptions.ConcatenateError([msg]) elif not match: msg = f"Found cubes with overlap on concatenate axis {candidate_axis}, skipping concatenation for these cubes" - warnings.warn(msg, category=iris.exceptions.IrisUserWarning) + warnings.warn(msg, category=iris.warnings.IrisUserWarning) # Check for compatible AuxCoords. if match: diff --git a/lib/iris/_shapefiles.py b/lib/iris/_shapefiles.py index 6213128cf6..351e798ae5 100644 --- a/lib/iris/_shapefiles.py +++ b/lib/iris/_shapefiles.py @@ -17,7 +17,7 @@ import shapely.geometry as sgeom import shapely.ops -from iris.exceptions import IrisDefaultingWarning, IrisUserWarning +from iris.warnings import IrisDefaultingWarning, IrisUserWarning def create_shapefile_mask( diff --git a/lib/iris/analysis/_regrid.py b/lib/iris/analysis/_regrid.py index 4a8ba0bb67..b85265e5d9 100644 --- a/lib/iris/analysis/_regrid.py +++ b/lib/iris/analysis/_regrid.py @@ -19,8 +19,8 @@ snapshot_grid, ) from iris.analysis._scipy_interpolate import _RegularGridInterpolator -from iris.exceptions import IrisImpossibleUpdateWarning from iris.util import _meshgrid, guess_coord_axis +from iris.warnings import IrisImpossibleUpdateWarning def _transform_xy_arrays(crs_from, x, y, crs_to): diff --git a/lib/iris/analysis/calculus.py b/lib/iris/analysis/calculus.py index 560b9b1d5c..6955e847dc 100644 --- a/lib/iris/analysis/calculus.py +++ b/lib/iris/analysis/calculus.py @@ -22,8 +22,8 @@ import iris.analysis.maths import iris.coord_systems import iris.coords -from iris.exceptions import IrisUserWarning from iris.util import delta +from iris.warnings import IrisUserWarning __all__ = ["DIRECTIONAL_NAMES", "cube_delta", "curl", "differentiate"] diff --git a/lib/iris/analysis/cartography.py b/lib/iris/analysis/cartography.py index d57f8ce8a3..bd1958581f 100644 --- a/lib/iris/analysis/cartography.py +++ b/lib/iris/analysis/cartography.py @@ -19,6 +19,7 @@ import iris.coords import iris.exceptions from iris.util import _meshgrid +import iris.warnings from ._grid_angles import gridcell_angles, rotate_grid_vectors @@ -412,7 +413,7 @@ def area_weights(cube, normalize=False): if cs.inverse_flattening != 0.0: warnings.warn( "Assuming spherical earth from ellipsoid.", - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) radius_of_earth = cs.semi_major_axis elif isinstance(cs, iris.coord_systems.RotatedGeogCS) and ( @@ -421,13 +422,13 @@ def area_weights(cube, normalize=False): if cs.ellipsoid.inverse_flattening != 0.0: warnings.warn( "Assuming spherical earth from ellipsoid.", - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) radius_of_earth = cs.ellipsoid.semi_major_axis else: warnings.warn( "Using DEFAULT_SPHERICAL_EARTH_RADIUS.", - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) radius_of_earth = DEFAULT_SPHERICAL_EARTH_RADIUS @@ -569,7 +570,7 @@ def cosine_latitude_weights(cube): ): warnings.warn( "Out of range latitude values will be clipped to the valid range.", - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) points = lat.points l_weights = np.cos(points).clip(0.0, 1.0) @@ -686,7 +687,7 @@ def project(cube, target_proj, nx=None, ny=None): warnings.warn( "Coordinate system of latitude and longitude " "coordinates is not specified. Assuming WGS84 Geodetic.", - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) orig_cs = iris.coord_systems.GeogCS( semi_major_axis=6378137.0, inverse_flattening=298.257223563 @@ -877,7 +878,7 @@ def project(cube, target_proj, nx=None, ny=None): lon_coord.name(), [coord.name() for coord in discarded_coords], ), - category=iris.exceptions.IrisIgnoringWarning, + category=iris.warnings.IrisIgnoringWarning, ) # TODO handle derived coords/aux_factories diff --git a/lib/iris/analysis/geometry.py b/lib/iris/analysis/geometry.py index 271858716c..120b6dfaa6 100644 --- a/lib/iris/analysis/geometry.py +++ b/lib/iris/analysis/geometry.py @@ -15,6 +15,7 @@ from shapely.geometry import Polygon import iris.exceptions +import iris.warnings def _extract_relevant_cube_slice(cube, geometry): @@ -71,7 +72,7 @@ def _extract_relevant_cube_slice(cube, geometry): except ValueError: warnings.warn( "The geometry exceeds the cube's x dimension at the lower end.", - category=iris.exceptions.IrisGeometryExceedWarning, + category=iris.warnings.IrisGeometryExceedWarning, ) x_min_ix = 0 if x_ascending else x_coord.points.size - 1 @@ -81,7 +82,7 @@ def _extract_relevant_cube_slice(cube, geometry): except ValueError: warnings.warn( "The geometry exceeds the cube's x dimension at the upper end.", - category=iris.exceptions.IrisGeometryExceedWarning, + category=iris.warnings.IrisGeometryExceedWarning, ) x_max_ix = x_coord.points.size - 1 if x_ascending else 0 @@ -91,7 +92,7 @@ def _extract_relevant_cube_slice(cube, geometry): except ValueError: warnings.warn( "The geometry exceeds the cube's y dimension at the lower end.", - category=iris.exceptions.IrisGeometryExceedWarning, + category=iris.warnings.IrisGeometryExceedWarning, ) y_min_ix = 0 if y_ascending else y_coord.points.size - 1 @@ -101,7 +102,7 @@ def _extract_relevant_cube_slice(cube, geometry): except ValueError: warnings.warn( "The geometry exceeds the cube's y dimension at the upper end.", - category=iris.exceptions.IrisGeometryExceedWarning, + category=iris.warnings.IrisGeometryExceedWarning, ) y_max_ix = y_coord.points.size - 1 if y_ascending else 0 diff --git a/lib/iris/analysis/maths.py b/lib/iris/analysis/maths.py index f20972d1e5..caf4aea0a8 100644 --- a/lib/iris/analysis/maths.py +++ b/lib/iris/analysis/maths.py @@ -23,6 +23,7 @@ import iris.coords import iris.exceptions import iris.util +import iris.warnings # Configure the logger. logger = get_logger(__name__) @@ -941,7 +942,7 @@ def _broadcast_cube_coord_data(cube, other, operation_name, dim=None): warnings.warn( "Using {!r} with a bounded coordinate is not well " "defined; ignoring bounds.".format(operation_name), - category=iris.exceptions.IrisIgnoringBoundsWarning, + category=iris.warnings.IrisIgnoringBoundsWarning, ) points = other.points diff --git a/lib/iris/aux_factory.py b/lib/iris/aux_factory.py index 61b7c7ef46..d63ab157fa 100644 --- a/lib/iris/aux_factory.py +++ b/lib/iris/aux_factory.py @@ -13,7 +13,7 @@ from iris.common import CFVariableMixin, CoordMetadata, metadata_manager_factory import iris.coords -from iris.exceptions import IrisIgnoringBoundsWarning +from iris.warnings import IrisIgnoringBoundsWarning class AuxCoordFactory(CFVariableMixin, metaclass=ABCMeta): diff --git a/lib/iris/config.py b/lib/iris/config.py index c617783dec..9cec602a95 100644 --- a/lib/iris/config.py +++ b/lib/iris/config.py @@ -31,7 +31,7 @@ import os.path import warnings -import iris.exceptions +import iris.warnings def get_logger(name, datefmt=None, fmt=None, level=None, propagate=None, handler=True): @@ -139,7 +139,7 @@ def get_dir_option(section, option, default=None): ) warnings.warn( msg.format(section, option, c_path), - category=iris.exceptions.IrisIgnoringWarning, + category=iris.warnings.IrisIgnoringWarning, ) return path @@ -246,7 +246,7 @@ def __setattr__(self, name, value): ) warnings.warn( wmsg.format(value, name, good_value), - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) value = good_value self.__dict__[name] = value diff --git a/lib/iris/coord_systems.py b/lib/iris/coord_systems.py index 5b4e593d83..35eea98764 100644 --- a/lib/iris/coord_systems.py +++ b/lib/iris/coord_systems.py @@ -13,7 +13,7 @@ import numpy as np from iris._deprecation import warn_deprecated -import iris.exceptions +import iris.warnings def _arg_default(value, default, cast_as=float): @@ -439,7 +439,7 @@ def inverse_flattening(self, value): "the GeogCS object. To change other properties set them explicitly" " or create a new GeogCS instance." ) - warnings.warn(wmsg, category=iris.exceptions.IrisUserWarning) + warnings.warn(wmsg, category=iris.warnings.IrisUserWarning) value = float(value) self._inverse_flattening = value @@ -768,7 +768,7 @@ def as_cartopy_crs(self): warnings.warn( "Discarding false_easting and false_northing that are " "not used by Cartopy.", - category=iris.exceptions.IrisDefaultingWarning, + category=iris.warnings.IrisDefaultingWarning, ) return ccrs.Orthographic( diff --git a/lib/iris/coords.py b/lib/iris/coords.py index 8ba5e32397..d9de063ea3 100644 --- a/lib/iris/coords.py +++ b/lib/iris/coords.py @@ -32,6 +32,7 @@ import iris.exceptions import iris.time import iris.util +import iris.warnings #: The default value for ignore_axis which controls guess_coord_axis' behaviour DEFAULT_IGNORE_AXIS = False @@ -1977,7 +1978,7 @@ def contiguous_bounds(self): warnings.warn( "Coordinate {!r} is not bounded, guessing " "contiguous bounds.".format(self.name()), - category=iris.exceptions.IrisGuessBoundsWarning, + category=iris.warnings.IrisGuessBoundsWarning, ) bounds = self._guess_bounds() elif self.ndim == 2: @@ -2138,7 +2139,7 @@ def serialize(x): ) warnings.warn( msg.format(self.name()), - category=iris.exceptions.IrisVagueMetadataWarning, + category=iris.warnings.IrisVagueMetadataWarning, ) else: try: @@ -2151,7 +2152,7 @@ def serialize(x): ) warnings.warn( msg.format(str(exc), self.name()), - category=iris.exceptions.IrisVagueMetadataWarning, + category=iris.warnings.IrisVagueMetadataWarning, ) self.bounds = None else: @@ -2162,7 +2163,7 @@ def serialize(x): ) warnings.warn( msg.format(self.name()), - category=iris.exceptions.IrisVagueMetadataWarning, + category=iris.warnings.IrisVagueMetadataWarning, ) if self.has_bounds(): diff --git a/lib/iris/cube.py b/lib/iris/cube.py index 49876a023e..e77646993e 100644 --- a/lib/iris/cube.py +++ b/lib/iris/cube.py @@ -45,6 +45,7 @@ import iris.coords import iris.exceptions import iris.util +import iris.warnings __all__ = ["Cube", "CubeAttrsDict", "CubeList"] @@ -4051,7 +4052,7 @@ def collapsed(self, coords, aggregator, **kwargs): for coord in lat_match: warnings.warn( msg.format(coord.name()), - category=iris.exceptions.IrisUserWarning, + category=iris.warnings.IrisUserWarning, ) # Determine the dimensions we need to collapse (and those we don't) @@ -4605,7 +4606,7 @@ def rolling_window(self, coord, aggregator, window, **kwargs): warnings.warn( "The bounds of coordinate %r were ignored in " "the rolling window operation." % coord_.name(), - category=iris.exceptions.IrisIgnoringBoundsWarning, + category=iris.warnings.IrisIgnoringBoundsWarning, ) if coord_.ndim != 1: diff --git a/lib/iris/exceptions.py b/lib/iris/exceptions.py index 0fb06f3b26..d6d2084d3c 100644 --- a/lib/iris/exceptions.py +++ b/lib/iris/exceptions.py @@ -161,186 +161,3 @@ class CannotAddError(ValueError): """Raised when an object (e.g. coord) cannot be added to a :class:`~iris.cube.Cube`.""" pass - - -############################################################################### -# WARNINGS -# Please namespace all warning objects (i.e. prefix with Iris...). - - -class IrisUserWarning(UserWarning): - r"""Base class for :class:`UserWarning` generated by Iris.""" - - pass - - -class IrisLoadWarning(IrisUserWarning): - """Any warning relating to loading.""" - - pass - - -class IrisSaveWarning(IrisUserWarning): - """Any warning relating to saving.""" - - pass - - -class IrisCfWarning(IrisUserWarning): - """Any warning relating to :term:`CF Conventions` .""" - - pass - - -class IrisIgnoringWarning(IrisUserWarning): - """Any warning that involves an Iris operation not using some information. - - E.g. :class:`~iris.aux_factory.AuxCoordFactory` generation disregarding - bounds. - """ - - pass - - -class IrisDefaultingWarning(IrisUserWarning): - """Any warning that involves Iris changing invalid/missing information. - - E.g. creating a :class:`~iris.coords.AuxCoord` from an invalid - :class:`~iris.coords.DimCoord` definition. - """ - - pass - - -class IrisVagueMetadataWarning(IrisUserWarning): - """Warnings where object metadata may not be fully descriptive.""" - - pass - - -class IrisUnsupportedPlottingWarning(IrisUserWarning): - """Warnings where support for a plotting module/function is not guaranteed.""" - - pass - - -class IrisImpossibleUpdateWarning(IrisUserWarning): - """Warnings where it is not possible to update an object. - - Mainly generated during regridding where the necessary information for - updating an :class:`~iris.aux_factory.AuxCoordFactory` is no longer - present. - """ - - pass - - -class IrisGeometryExceedWarning(IrisUserWarning): - """:mod:`iris.analysis.geometry` warnings about geometry exceeding dimensions.""" - - pass - - -class IrisMaskValueMatchWarning(IrisUserWarning): - """Warnings where the value representing masked data is actually present in data.""" - - pass - - -######## - - -class IrisCfLoadWarning(IrisCfWarning, IrisLoadWarning): - """Any warning relating to both loading and :term:`CF Conventions` .""" - - pass - - -class IrisCfSaveWarning(IrisCfWarning, IrisSaveWarning): - """Any warning relating to both saving and :term:`CF Conventions` .""" - - pass - - -class IrisCfInvalidCoordParamWarning(IrisCfLoadWarning): - """Warnings where incorrect information for CF coord construction is in a file.""" - - pass - - -class IrisCfMissingVarWarning(IrisCfLoadWarning): - """Warnings where a CF variable references another variable that is not in the file.""" - - pass - - -class IrisCfLabelVarWarning(IrisCfLoadWarning, IrisIgnoringWarning): - """Warnings where a CF string/label variable is being used inappropriately.""" - - pass - - -class IrisCfNonSpanningVarWarning(IrisCfLoadWarning, IrisIgnoringWarning): - """Warnings where a CF variable is ignored because it does not span the required dimension.""" - - pass - - -######## - - -class IrisIgnoringBoundsWarning(IrisIgnoringWarning): - """Warnings where bounds information has not been used by an Iris operation.""" - - pass - - -class IrisCannotAddWarning(IrisIgnoringWarning): - """Warnings where a member object cannot be added to a :class:`~iris.cube.Cube` .""" - - pass - - -class IrisGuessBoundsWarning(IrisDefaultingWarning): - """Warnings where Iris has filled absent bounds information with a best estimate.""" - - pass - - -class IrisPpClimModifiedWarning(IrisSaveWarning, IrisDefaultingWarning): - """Warnings where a climatology has been modified while saving :term:`Post Processing (PP) Format` .""" - - pass - - -class IrisFactoryCoordNotFoundWarning(IrisLoadWarning): - """Warnings where a referenced factory coord can not be found when loading a variable in :term:`NetCDF Format`.""" - - pass - - -class IrisNimrodTranslationWarning(IrisLoadWarning): - """For unsupported vertical coord types in :mod:`iris.file_formats.nimrod_load_rules`. - - (Pre-dates the full categorisation of Iris UserWarnings). - """ - - pass - - -class IrisUnknownCellMethodWarning(IrisCfLoadWarning): - """If a loaded :class:`~iris.coords.CellMethod` is not one the method names known to Iris. - - (Pre-dates the full categorisation of Iris UserWarnings). - """ - - pass - - -class IrisSaverFillValueWarning(IrisMaskValueMatchWarning, IrisSaveWarning): - """For fill value complications during Iris file saving :term:`NetCDF Format`. - - (Pre-dates the full categorisation of Iris UserWarnings). - """ - - pass diff --git a/lib/iris/experimental/regrid.py b/lib/iris/experimental/regrid.py index 1bea933fbf..c1d209cac0 100644 --- a/lib/iris/experimental/regrid.py +++ b/lib/iris/experimental/regrid.py @@ -37,8 +37,8 @@ import iris.analysis.cartography import iris.coord_systems import iris.cube -from iris.exceptions import IrisImpossibleUpdateWarning from iris.util import _meshgrid +from iris.warnings import IrisImpossibleUpdateWarning wmsg = ( "The 'iris.experimental.regrid' package is deprecated since version 3.2, " diff --git a/lib/iris/experimental/ugrid/cf.py b/lib/iris/experimental/ugrid/cf.py index d00fd6ef24..6897b4ca67 100644 --- a/lib/iris/experimental/ugrid/cf.py +++ b/lib/iris/experimental/ugrid/cf.py @@ -10,8 +10,8 @@ """ import warnings -from ...exceptions import IrisCfLabelVarWarning, IrisCfMissingVarWarning from ...fileformats import cf +from ...warnings import IrisCfLabelVarWarning, IrisCfMissingVarWarning from .mesh import Connectivity diff --git a/lib/iris/experimental/ugrid/load.py b/lib/iris/experimental/ugrid/load.py index 8ba7448e8c..630c179fd9 100644 --- a/lib/iris/experimental/ugrid/load.py +++ b/lib/iris/experimental/ugrid/load.py @@ -19,11 +19,11 @@ from ...config import get_logger from ...coords import AuxCoord -from ...exceptions import IrisCfWarning, IrisDefaultingWarning, IrisIgnoringWarning from ...fileformats._nc_load_rules.helpers import get_attr_units, get_names from ...fileformats.netcdf import loader as nc_loader from ...io import decode_uri, expand_filespecs from ...util import guess_coord_axis +from ...warnings import IrisCfWarning, IrisDefaultingWarning, IrisIgnoringWarning from .cf import ( CFUGridAuxiliaryCoordinateVariable, CFUGridConnectivityVariable, diff --git a/lib/iris/fileformats/_ff.py b/lib/iris/fileformats/_ff.py index d2ce1bcefb..18c1aa766e 100644 --- a/lib/iris/fileformats/_ff.py +++ b/lib/iris/fileformats/_ff.py @@ -10,12 +10,11 @@ import numpy as np from iris.exceptions import ( - IrisDefaultingWarning, - IrisLoadWarning, NotYetImplementedError, ) from iris.fileformats._ff_cross_references import STASH_TRANS +from ..warnings import IrisDefaultingWarning, IrisLoadWarning from . import pp IMDI = -32768 diff --git a/lib/iris/fileformats/_nc_load_rules/actions.py b/lib/iris/fileformats/_nc_load_rules/actions.py index fefa58ad10..1611ef7160 100644 --- a/lib/iris/fileformats/_nc_load_rules/actions.py +++ b/lib/iris/fileformats/_nc_load_rules/actions.py @@ -43,9 +43,9 @@ import warnings from iris.config import get_logger -import iris.exceptions import iris.fileformats.cf import iris.fileformats.pp as pp +import iris.warnings from . import helpers as hh @@ -54,8 +54,8 @@ class _WarnComboCfLoadIgnoring( - iris.exceptions.IrisCfLoadWarning, - iris.exceptions.IrisIgnoringWarning, + iris.warnings.IrisCfLoadWarning, + iris.warnings.IrisIgnoringWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -63,8 +63,8 @@ class _WarnComboCfLoadIgnoring( class _WarnComboLoadIgnoring( - iris.exceptions.IrisLoadWarning, - iris.exceptions.IrisIgnoringWarning, + iris.warnings.IrisLoadWarning, + iris.warnings.IrisIgnoringWarning, ): """One-off combination of warning classes - enhances user filtering.""" diff --git a/lib/iris/fileformats/_nc_load_rules/helpers.py b/lib/iris/fileformats/_nc_load_rules/helpers.py index 3cf6aab945..dc68274a36 100644 --- a/lib/iris/fileformats/_nc_load_rules/helpers.py +++ b/lib/iris/fileformats/_nc_load_rules/helpers.py @@ -36,6 +36,7 @@ from iris.fileformats.netcdf.loader import _get_cf_var_data import iris.std_names import iris.util +import iris.warnings if TYPE_CHECKING: from numpy.ma import MaskedArray @@ -231,8 +232,8 @@ class _WarnComboIgnoringLoad( - iris.exceptions.IrisIgnoringWarning, - iris.exceptions.IrisLoadWarning, + iris.warnings.IrisIgnoringWarning, + iris.warnings.IrisLoadWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -240,8 +241,8 @@ class _WarnComboIgnoringLoad( class _WarnComboDefaultingLoad( - iris.exceptions.IrisDefaultingWarning, - iris.exceptions.IrisLoadWarning, + iris.warnings.IrisDefaultingWarning, + iris.warnings.IrisLoadWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -249,8 +250,8 @@ class _WarnComboDefaultingLoad( class _WarnComboDefaultingCfLoad( - iris.exceptions.IrisCfLoadWarning, - iris.exceptions.IrisDefaultingWarning, + iris.warnings.IrisCfLoadWarning, + iris.warnings.IrisDefaultingWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -258,8 +259,8 @@ class _WarnComboDefaultingCfLoad( class _WarnComboIgnoringCfLoad( - iris.exceptions.IrisIgnoringWarning, - iris.exceptions.IrisCfLoadWarning, + iris.warnings.IrisIgnoringWarning, + iris.warnings.IrisCfLoadWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -309,7 +310,7 @@ def _split_cell_methods(nc_cell_methods: str) -> List[re.Match]: ) warnings.warn( msg, - category=iris.exceptions.IrisCfLoadWarning, + category=iris.warnings.IrisCfLoadWarning, stacklevel=2, ) if bracket_depth > 0 and ind in name_start_inds: @@ -328,15 +329,15 @@ def _split_cell_methods(nc_cell_methods: str) -> List[re.Match]: nc_cell_method_match = _CM_PARSE.match(nc_cell_method_str.strip()) if not nc_cell_method_match: msg = f"Failed to fully parse cell method string: {nc_cell_methods}" - warnings.warn(msg, category=iris.exceptions.IrisCfLoadWarning, stacklevel=2) + warnings.warn(msg, category=iris.warnings.IrisCfLoadWarning, stacklevel=2) continue nc_cell_methods_matches.append(nc_cell_method_match) return nc_cell_methods_matches -class UnknownCellMethodWarning(iris.exceptions.IrisUnknownCellMethodWarning): - """Backwards compatible form of :class:`iris.exceptions.IrisUnknownCellMethodWarning`.""" +class UnknownCellMethodWarning(iris.warnings.IrisUnknownCellMethodWarning): + """Backwards compatible form of :class:`iris.warnings.IrisUnknownCellMethodWarning`.""" # TODO: remove at the next major release. pass @@ -559,7 +560,7 @@ def build_rotated_coordinate_system(engine, cf_grid_var): if north_pole_latitude is None or north_pole_longitude is None: warnings.warn( "Rotated pole position is not fully specified", - category=iris.exceptions.IrisCfLoadWarning, + category=iris.warnings.IrisCfLoadWarning, ) north_pole_grid_lon = getattr(cf_grid_var, CF_ATTR_GRID_NORTH_POLE_GRID_LON, 0.0) @@ -1077,7 +1078,7 @@ def _normalise_bounds_units( f"{bounds_units.origin!r}." ) warnings.warn( - wmsg, category=iris.exceptions.IrisCfLoadWarning, stacklevel=2 + wmsg, category=iris.warnings.IrisCfLoadWarning, stacklevel=2 ) bounds_data = None @@ -1194,7 +1195,7 @@ def build_dimension_coordinate( except iris.exceptions.CannotAddError as e_msg: warnings.warn( coord_skipped_msg.format(error=e_msg), - category=iris.exceptions.IrisCannotAddWarning, + category=iris.warnings.IrisCannotAddWarning, ) coord_skipped = True else: @@ -1208,7 +1209,7 @@ def build_dimension_coordinate( except iris.exceptions.CannotAddError as e_msg: warnings.warn( coord_skipped_msg.format(error=e_msg), - category=iris.exceptions.IrisCannotAddWarning, + category=iris.warnings.IrisCannotAddWarning, ) coord_skipped = True @@ -1284,7 +1285,7 @@ def build_auxiliary_coordinate( msg = "{name!r} coordinate not added to Cube: {error}" warnings.warn( msg.format(name=str(cf_coord_var.cf_name), error=e_msg), - category=iris.exceptions.IrisCannotAddWarning, + category=iris.warnings.IrisCannotAddWarning, ) else: # Make a list with names, stored on the engine, so we can find them all later. @@ -1336,7 +1337,7 @@ def build_cell_measures(engine, cf_cm_var): msg = "{name!r} cell measure not added to Cube: {error}" warnings.warn( msg.format(name=str(cf_cm_var.cf_name), error=e_msg), - category=iris.exceptions.IrisCannotAddWarning, + category=iris.warnings.IrisCannotAddWarning, ) else: # Make a list with names, stored on the engine, so we can find them all later. @@ -1384,7 +1385,7 @@ def build_ancil_var(engine, cf_av_var): msg = "{name!r} ancillary variable not added to Cube: {error}" warnings.warn( msg.format(name=str(cf_av_var.cf_name), error=e_msg), - category=iris.exceptions.IrisCannotAddWarning, + category=iris.warnings.IrisCannotAddWarning, ) else: # Make a list with names, stored on the engine, so we can find them all later. @@ -1586,7 +1587,7 @@ def has_supported_mercator_parameters(engine, cf_name): warnings.warn( "It does not make sense to provide both " '"scale_factor_at_projection_origin" and "standard_parallel".', - category=iris.exceptions.IrisCfInvalidCoordParamWarning, + category=iris.warnings.IrisCfInvalidCoordParamWarning, ) is_valid = False @@ -1616,7 +1617,7 @@ def has_supported_polar_stereographic_parameters(engine, cf_name): if latitude_of_projection_origin != 90 and latitude_of_projection_origin != -90: warnings.warn( '"latitude_of_projection_origin" must be +90 or -90.', - category=iris.exceptions.IrisCfInvalidCoordParamWarning, + category=iris.warnings.IrisCfInvalidCoordParamWarning, ) is_valid = False @@ -1624,7 +1625,7 @@ def has_supported_polar_stereographic_parameters(engine, cf_name): warnings.warn( "It does not make sense to provide both " '"scale_factor_at_projection_origin" and "standard_parallel".', - category=iris.exceptions.IrisCfInvalidCoordParamWarning, + category=iris.warnings.IrisCfInvalidCoordParamWarning, ) is_valid = False @@ -1632,7 +1633,7 @@ def has_supported_polar_stereographic_parameters(engine, cf_name): warnings.warn( 'One of "scale_factor_at_projection_origin" and ' '"standard_parallel" is required.', - category=iris.exceptions.IrisCfInvalidCoordParamWarning, + category=iris.warnings.IrisCfInvalidCoordParamWarning, ) is_valid = False diff --git a/lib/iris/fileformats/cf.py b/lib/iris/fileformats/cf.py index 5a0230d5eb..0dc505d522 100644 --- a/lib/iris/fileformats/cf.py +++ b/lib/iris/fileformats/cf.py @@ -23,9 +23,9 @@ import numpy as np import numpy.ma as ma -import iris.exceptions from iris.fileformats.netcdf import _thread_safe_nc import iris.util +import iris.warnings # # CF parse pattern common to both formula terms and measure CF variables. @@ -278,7 +278,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF ancillary data variable %r, referenced by netCDF variable %r" warnings.warn( message % (name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: result[name] = CFAncillaryDataVariable( @@ -327,7 +327,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF auxiliary coordinate variable %r, referenced by netCDF variable %r" warnings.warn( message % (name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: # Restrict to non-string type i.e. not a CFLabelVariable. @@ -377,7 +377,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF boundary variable %r, referenced by netCDF variable %r" warnings.warn( message % (name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: result[name] = CFBoundaryVariable(name, variables[name]) @@ -453,7 +453,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF climatology variable %r, referenced by netCDF variable %r" warnings.warn( message % (name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: result[name] = CFClimatologyVariable(name, variables[name]) @@ -593,7 +593,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF formula term variable %r, referenced by netCDF variable %r" warnings.warn( message % (variable_name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: if variable_name not in result: @@ -660,7 +660,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF grid mapping variable %r, referenced by netCDF variable %r" warnings.warn( message % (name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: result[name] = CFGridMappingVariable(name, variables[name]) @@ -701,7 +701,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF label variable %r, referenced by netCDF variable %r" warnings.warn( message % (name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: # Register variable, but only allow string type. @@ -876,7 +876,7 @@ def identify(cls, variables, ignore=None, target=None, warn=True): message = "Missing CF-netCDF measure variable %r, referenced by netCDF variable %r" warnings.warn( message % (variable_name, nc_var_name), - category=iris.exceptions.IrisCfMissingVarWarning, + category=iris.warnings.IrisCfMissingVarWarning, ) else: result[variable_name] = CFMeasureVariable( @@ -1083,7 +1083,7 @@ def __init__(self, file_source, warn=False, monotonic=False): warnings.warn( "Optimise CF-netCDF loading by converting data from NetCDF3 " 'to NetCDF4 file format using the "nccopy" command.', - category=iris.exceptions.IrisLoadWarning, + category=iris.warnings.IrisLoadWarning, ) self._check_monotonic = monotonic @@ -1221,7 +1221,7 @@ def _build(cf_variable): ) warnings.warn( msg, - category=iris.exceptions.IrisCfNonSpanningVarWarning, + category=iris.warnings.IrisCfNonSpanningVarWarning, ) # Build CF data variable relationships. @@ -1270,7 +1270,7 @@ def _build(cf_variable): ) warnings.warn( msg, - category=iris.exceptions.IrisCfNonSpanningVarWarning, + category=iris.warnings.IrisCfNonSpanningVarWarning, ) # Add the CF group to the variable. diff --git a/lib/iris/fileformats/name_loaders.py b/lib/iris/fileformats/name_loaders.py index 3e337383cb..fe53308cb0 100644 --- a/lib/iris/fileformats/name_loaders.py +++ b/lib/iris/fileformats/name_loaders.py @@ -16,8 +16,9 @@ import iris.coord_systems from iris.coords import AuxCoord, CellMethod, DimCoord import iris.cube -from iris.exceptions import IrisLoadWarning, TranslationError +from iris.exceptions import TranslationError import iris.util +from iris.warnings import IrisLoadWarning EARTH_RADIUS = 6371229.0 NAMEIII_DATETIME_FORMAT = "%d/%m/%Y %H:%M %Z" diff --git a/lib/iris/fileformats/netcdf/loader.py b/lib/iris/fileformats/netcdf/loader.py index e25806db1c..4e205ad7f3 100644 --- a/lib/iris/fileformats/netcdf/loader.py +++ b/lib/iris/fileformats/netcdf/loader.py @@ -34,12 +34,12 @@ import iris.config import iris.coord_systems import iris.coords -import iris.exceptions import iris.fileformats.cf from iris.fileformats.netcdf import _thread_safe_nc from iris.fileformats.netcdf.saver import _CF_ATTRS import iris.io import iris.util +import iris.warnings # Show actions activation statistics. DEBUG = False @@ -53,8 +53,8 @@ class _WarnComboIgnoringBoundsLoad( - iris.exceptions.IrisIgnoringBoundsWarning, - iris.exceptions.IrisLoadWarning, + iris.warnings.IrisIgnoringBoundsWarning, + iris.warnings.IrisLoadWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -415,7 +415,7 @@ def coord_from_term(term): return coord warnings.warn( "Unable to find coordinate for variable {!r}".format(name), - category=iris.exceptions.IrisFactoryCoordNotFoundWarning, + category=iris.warnings.IrisFactoryCoordNotFoundWarning, ) if formula_type == "atmosphere_sigma_coordinate": @@ -646,7 +646,7 @@ def load_cubes(file_sources, callback=None, constraints=None): except ValueError as e: warnings.warn( "{}".format(e), - category=iris.exceptions.IrisLoadWarning, + category=iris.warnings.IrisLoadWarning, ) # Perform any user registered callback function. diff --git a/lib/iris/fileformats/netcdf/saver.py b/lib/iris/fileformats/netcdf/saver.py index 086732e597..42616d7fd1 100644 --- a/lib/iris/fileformats/netcdf/saver.py +++ b/lib/iris/fileformats/netcdf/saver.py @@ -49,6 +49,7 @@ from iris.fileformats.netcdf import _dask_locks, _thread_safe_nc import iris.io import iris.util +import iris.warnings # Get the logger : shared logger for all in 'iris.fileformats.netcdf'. from . import logger @@ -161,8 +162,8 @@ class _WarnComboMaskSave( - iris.exceptions.IrisMaskValueMatchWarning, - iris.exceptions.IrisSaveWarning, + iris.warnings.IrisMaskValueMatchWarning, + iris.warnings.IrisSaveWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -318,8 +319,8 @@ def _data_fillvalue_check(arraylib, data, check_value): return is_masked, contains_value -class SaverFillValueWarning(iris.exceptions.IrisSaverFillValueWarning): - """Backwards compatible form of :class:`iris.exceptions.IrisSaverFillValueWarning`.""" +class SaverFillValueWarning(iris.warnings.IrisSaverFillValueWarning): + """Backwards compatible form of :class:`iris.warnings.IrisSaverFillValueWarning`.""" # TODO: remove at the next major release. pass @@ -737,7 +738,7 @@ def write( cf_patch(profile, self._dataset, cf_var_cube) else: msg = "cf_profile is available but no {} defined.".format("cf_patch") - warnings.warn(msg, category=iris.exceptions.IrisCfSaveWarning) + warnings.warn(msg, category=iris.warnings.IrisCfSaveWarning) @staticmethod def check_attribute_compliance(container, data_dtype): @@ -1133,7 +1134,7 @@ def _add_aux_factories(self, cube, cf_var_cube, dimension_names): msg = "Unable to determine formula terms for AuxFactory: {!r}".format( factory ) - warnings.warn(msg, category=iris.exceptions.IrisSaveWarning) + warnings.warn(msg, category=iris.warnings.IrisSaveWarning) else: # Override `standard_name`, `long_name`, and `axis` of the # primary coord that signals the presence of a dimensionless @@ -2084,7 +2085,7 @@ def add_ellipsoid(ellipsoid): elif isinstance(cs, iris.coord_systems.OSGB): warnings.warn( "OSGB coordinate system not yet handled", - category=iris.exceptions.IrisSaveWarning, + category=iris.warnings.IrisSaveWarning, ) # lambert azimuthal equal area @@ -2172,7 +2173,7 @@ def add_ellipsoid(ellipsoid): "Unable to represent the horizontal " "coordinate system. The coordinate system " "type %r is not yet implemented." % type(cs), - category=iris.exceptions.IrisSaveWarning, + category=iris.warnings.IrisSaveWarning, ) self._coord_systems.append(cs) @@ -2342,7 +2343,7 @@ def set_packing_ncattrs(cfvar): "attribute, but {attr_name!r} should only be a CF " "global attribute.".format(attr_name=attr_name) ) - warnings.warn(msg, category=iris.exceptions.IrisCfSaveWarning) + warnings.warn(msg, category=iris.warnings.IrisCfSaveWarning) _setncattr(cf_var, attr_name, value) @@ -2565,7 +2566,7 @@ def complete(self, issue_warnings=True) -> List[Warning]: if issue_warnings: # Issue any delayed warnings from the compute. for delayed_warning in result_warnings: - warnings.warn(delayed_warning, category=iris.exceptions.IrisSaveWarning) + warnings.warn(delayed_warning, category=iris.warnings.IrisSaveWarning) return result_warnings @@ -2815,7 +2816,7 @@ def attr_values_equal(val1, val2): f"Saving the cube global attributes {sorted(invalid_globals)} as local " "(i.e. data-variable) attributes, where possible, since they are not " "the same on all input cubes.", - category=iris.exceptions.IrisSaveWarning, + category=iris.warnings.IrisSaveWarning, ) cubes = cubes.copy() # avoiding modifying the actual input arg. for i_cube in range(len(cubes)): @@ -2831,7 +2832,7 @@ def attr_values_equal(val1, val2): f"Global cube attributes {sorted(blocked_attrs)} " f'of cube "{cube.name()}" were not saved, overlaid ' "by existing local attributes with the same names.", - category=iris.exceptions.IrisSaveWarning, + category=iris.warnings.IrisSaveWarning, ) demote_attrs -= blocked_attrs if demote_attrs: @@ -2973,7 +2974,7 @@ def is_valid_packspec(p): msg = "cf_profile is available but no {} defined.".format( "cf_patch_conventions" ) - warnings.warn(msg, category=iris.exceptions.IrisCfSaveWarning) + warnings.warn(msg, category=iris.warnings.IrisCfSaveWarning) # Add conventions attribute. if iris.FUTURE.save_split_attrs: diff --git a/lib/iris/fileformats/nimrod_load_rules.py b/lib/iris/fileformats/nimrod_load_rules.py index 5ca9ef4be3..16f23c8a6f 100644 --- a/lib/iris/fileformats/nimrod_load_rules.py +++ b/lib/iris/fileformats/nimrod_load_rules.py @@ -17,9 +17,9 @@ from iris.coords import DimCoord from iris.exceptions import ( CoordinateNotFoundError, - IrisNimrodTranslationWarning, TranslationError, ) +from iris.warnings import IrisNimrodTranslationWarning __all__ = ["run"] @@ -32,7 +32,7 @@ class TranslationWarning(IrisNimrodTranslationWarning): - """Backwards compatible form of :class:`iris.exceptions.IrisNimrodTranslationWarning`.""" + """Backwards compatible form of :class:`iris.warnings.IrisNimrodTranslationWarning`.""" # TODO: remove at the next major release. pass diff --git a/lib/iris/fileformats/pp.py b/lib/iris/fileformats/pp.py index 2780c52625..c39c1a53a7 100644 --- a/lib/iris/fileformats/pp.py +++ b/lib/iris/fileformats/pp.py @@ -32,6 +32,7 @@ import iris.fileformats.pp_load_rules from iris.fileformats.pp_save_rules import verify import iris.fileformats.rules +import iris.warnings try: import mo_pack @@ -216,8 +217,8 @@ class _WarnComboLoadingMask( - iris.exceptions.IrisLoadWarning, - iris.exceptions.IrisMaskValueMatchWarning, + iris.warnings.IrisLoadWarning, + iris.warnings.IrisMaskValueMatchWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -225,8 +226,8 @@ class _WarnComboLoadingMask( class _WarnComboLoadingDefaulting( - iris.exceptions.IrisDefaultingWarning, - iris.exceptions.IrisLoadWarning, + iris.warnings.IrisDefaultingWarning, + iris.warnings.IrisLoadWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -234,8 +235,8 @@ class _WarnComboLoadingDefaulting( class _WarnComboIgnoringLoad( - iris.exceptions.IrisIgnoringWarning, - iris.exceptions.IrisLoadWarning, + iris.warnings.IrisIgnoringWarning, + iris.warnings.IrisLoadWarning, ): """One-off combination of warning classes - enhances user filtering.""" @@ -1698,7 +1699,7 @@ def _interpret_fields(fields): "Landmask compressed fields existed without a " "landmask to decompress with. The data will have " "a shape of (0, 0) and will not read.", - category=iris.exceptions.IrisLoadWarning, + category=iris.warnings.IrisLoadWarning, ) mask_shape = (0, 0) else: diff --git a/lib/iris/fileformats/pp_save_rules.py b/lib/iris/fileformats/pp_save_rules.py index 20ed0bd618..73331268e4 100644 --- a/lib/iris/fileformats/pp_save_rules.py +++ b/lib/iris/fileformats/pp_save_rules.py @@ -11,7 +11,6 @@ import iris from iris.aux_factory import HybridHeightFactory, HybridPressureFactory -from iris.exceptions import IrisPpClimModifiedWarning from iris.fileformats._ff_cross_references import STASH_TRANS from iris.fileformats._pp_lbproc_pairs import LBPROC_MAP from iris.fileformats.rules import ( @@ -23,6 +22,7 @@ ) from iris.fileformats.um_cf_map import CF_TO_LBFC from iris.util import is_regular, regular_step +from iris.warnings import IrisPpClimModifiedWarning def _basic_coord_system_rules(cube, pp): diff --git a/lib/iris/fileformats/rules.py b/lib/iris/fileformats/rules.py index aa3d4696bc..be04f0bb5d 100644 --- a/lib/iris/fileformats/rules.py +++ b/lib/iris/fileformats/rules.py @@ -13,6 +13,7 @@ import iris.cube import iris.exceptions import iris.fileformats.um_cf_map +import iris.warnings Factory = collections.namedtuple("Factory", ["factory_class", "args"]) ReferenceTarget = collections.namedtuple("ReferenceTarget", ("name", "transform")) @@ -42,7 +43,7 @@ def as_cube(self): if len(src_cubes) > 1: warnings.warn( "Multiple reference cubes for {}".format(self.name), - category=iris.exceptions.IrisUserWarning, + category=iris.warnings.IrisUserWarning, ) src_cube = src_cubes[-1] @@ -313,7 +314,7 @@ def _make_cube(field, converter): cube.units = metadata.units except ValueError: msg = "Ignoring PP invalid units {!r}".format(metadata.units) - warnings.warn(msg, category=iris.exceptions.IrisIgnoringWarning) + warnings.warn(msg, category=iris.warnings.IrisIgnoringWarning) cube.attributes["invalid_units"] = metadata.units cube.units = cf_units._UNKNOWN_UNIT_STRING @@ -336,7 +337,7 @@ def _resolve_factory_references( factory_name = factory.factory_class.__name__ warnings.warn( msg.format(factory=factory_name), - category=iris.exceptions.IrisUserWarning, + category=iris.warnings.IrisUserWarning, ) else: aux_factory = factory.factory_class(*args) diff --git a/lib/iris/iterate.py b/lib/iris/iterate.py index be2a436a5e..0cf7a035be 100644 --- a/lib/iris/iterate.py +++ b/lib/iris/iterate.py @@ -10,7 +10,7 @@ import numpy as np -from iris.exceptions import IrisUserWarning +from iris.warnings import IrisUserWarning __all__ = ["izip"] diff --git a/lib/iris/pandas.py b/lib/iris/pandas.py index d60b46011e..1e79e1b31e 100644 --- a/lib/iris/pandas.py +++ b/lib/iris/pandas.py @@ -27,7 +27,7 @@ from iris._deprecation import warn_deprecated from iris.coords import AncillaryVariable, AuxCoord, CellMeasure, DimCoord from iris.cube import Cube, CubeList -from iris.exceptions import IrisIgnoringWarning +from iris.warnings import IrisIgnoringWarning def _get_dimensional_metadata(name, values, calendar=None, dm_class=None): diff --git a/lib/iris/plot.py b/lib/iris/plot.py index c727607449..e9f73bd86b 100644 --- a/lib/iris/plot.py +++ b/lib/iris/plot.py @@ -30,11 +30,12 @@ import iris.coord_systems import iris.coords import iris.cube -from iris.exceptions import IrisError, IrisUnsupportedPlottingWarning +from iris.exceptions import IrisError # Importing iris.palette to register the brewer palettes. import iris.palette from iris.util import _meshgrid +from iris.warnings import IrisUnsupportedPlottingWarning # Cynthia Brewer citation text. BREWER_CITE = "Colours based on ColorBrewer.org" diff --git a/lib/iris/tests/graphics/idiff.py b/lib/iris/tests/graphics/idiff.py index 2e2ef75776..64d690e55d 100755 --- a/lib/iris/tests/graphics/idiff.py +++ b/lib/iris/tests/graphics/idiff.py @@ -26,7 +26,7 @@ from matplotlib.testing.exceptions import ImageComparisonFailure # noqa import matplotlib.widgets as mwidget # noqa -from iris.exceptions import IrisIgnoringWarning # noqa +from iris.warnings import IrisIgnoringWarning # noqa import iris.tests # noqa import iris.tests.graphics as graphics # noqa diff --git a/lib/iris/tests/integration/experimental/test_ugrid_load.py b/lib/iris/tests/integration/experimental/test_ugrid_load.py index 63406f1ba0..d513d02497 100644 --- a/lib/iris/tests/integration/experimental/test_ugrid_load.py +++ b/lib/iris/tests/integration/experimental/test_ugrid_load.py @@ -17,13 +17,13 @@ import pytest from iris import Constraint, load -from iris.exceptions import IrisCfWarning from iris.experimental.ugrid.load import PARSE_UGRID_ON_LOAD, load_mesh, load_meshes from iris.experimental.ugrid.mesh import Mesh from iris.tests.stock.netcdf import ( _file_from_cdl_template as create_file_from_cdl_template, ) from iris.tests.unit.tests.stock.test_netcdf import XIOSFileMixin +from iris.warnings import IrisCfWarning def ugrid_load(uris, constraints=None, callback=None): diff --git a/lib/iris/tests/integration/netcdf/test_delayed_save.py b/lib/iris/tests/integration/netcdf/test_delayed_save.py index 62bfac7b45..cb375cc592 100644 --- a/lib/iris/tests/integration/netcdf/test_delayed_save.py +++ b/lib/iris/tests/integration/netcdf/test_delayed_save.py @@ -15,10 +15,10 @@ import pytest import iris -from iris.exceptions import IrisSaverFillValueWarning from iris.fileformats.netcdf._thread_safe_nc import default_fillvals import iris.tests from iris.tests.stock import realistic_4d +from iris.warnings import IrisSaverFillValueWarning class Test__lazy_stream_data: diff --git a/lib/iris/tests/integration/netcdf/test_general.py b/lib/iris/tests/integration/netcdf/test_general.py index 751c160805..1020ddbb96 100644 --- a/lib/iris/tests/integration/netcdf/test_general.py +++ b/lib/iris/tests/integration/netcdf/test_general.py @@ -29,6 +29,7 @@ # Get the netCDF4 module, but in a sneaky way that avoids triggering the "do not import # netCDF4" check in "iris.tests.test_coding_standards.test_netcdf4_import()". import iris.fileformats.netcdf._thread_safe_nc as threadsafe_nc +import iris.warnings nc = threadsafe_nc.netCDF4 @@ -138,7 +139,7 @@ def test_unknown_method(self): warning_messages = [ warn for warn in warning_messages - if isinstance(warn, iris.exceptions.IrisUnknownCellMethodWarning) + if isinstance(warn, iris.warnings.IrisUnknownCellMethodWarning) ] self.assertEqual(len(warning_messages), 1) message = warning_messages[0].args[0] @@ -515,7 +516,7 @@ def test_datum_once(self): warnings.simplefilter("default") for fpath in fpaths: iris.load(fpath) - warnings.warn("Dummy warning", category=iris.exceptions.IrisUserWarning) + warnings.warn("Dummy warning", category=iris.warnings.IrisUserWarning) assert len(record) == 2 diff --git a/lib/iris/tests/integration/netcdf/test_self_referencing.py b/lib/iris/tests/integration/netcdf/test_self_referencing.py index 7f52f722ae..b2b9b6d4e1 100644 --- a/lib/iris/tests/integration/netcdf/test_self_referencing.py +++ b/lib/iris/tests/integration/netcdf/test_self_referencing.py @@ -15,8 +15,8 @@ import numpy as np import iris -from iris.exceptions import IrisCfMissingVarWarning from iris.fileformats.netcdf import _thread_safe_nc +from iris.warnings import IrisCfMissingVarWarning @tests.skip_data diff --git a/lib/iris/tests/integration/test_pp.py b/lib/iris/tests/integration/test_pp.py index e8dd367187..1ed9dca853 100644 --- a/lib/iris/tests/integration/test_pp.py +++ b/lib/iris/tests/integration/test_pp.py @@ -17,12 +17,13 @@ from iris.aux_factory import HybridHeightFactory, HybridPressureFactory from iris.coords import AuxCoord, CellMethod, DimCoord from iris.cube import Cube -from iris.exceptions import IgnoreCubeException, IrisUserWarning +from iris.exceptions import IgnoreCubeException import iris.fileformats.pp from iris.fileformats.pp import load_pairs_from_fields import iris.fileformats.pp_load_rules from iris.fileformats.pp_save_rules import verify import iris.util +from iris.warnings import IrisUserWarning class TestVertical(tests.IrisTest): diff --git a/lib/iris/tests/test_coding_standards.py b/lib/iris/tests/test_coding_standards.py index 9db9433938..2f14ea703e 100644 --- a/lib/iris/tests/test_coding_standards.py +++ b/lib/iris/tests/test_coding_standards.py @@ -130,7 +130,7 @@ def test_categorised_warnings(): r"""To ensure that all UserWarnings raised by Iris are categorised, for ease of use. No obvious category? Use the parent: - :class:`iris.exceptions.IrisUserWarning`. + :class:`iris.warnings.IrisUserWarning`. Warning matches multiple categories? Create a one-off combo class. For example: diff --git a/lib/iris/tests/test_concatenate.py b/lib/iris/tests/test_concatenate.py index d4be638087..de324e6dd3 100644 --- a/lib/iris/tests/test_concatenate.py +++ b/lib/iris/tests/test_concatenate.py @@ -16,8 +16,8 @@ from iris.aux_factory import HybridHeightFactory from iris.coords import AncillaryVariable, AuxCoord, CellMeasure, DimCoord import iris.cube -from iris.exceptions import IrisUserWarning import iris.tests.stock as stock +from iris.warnings import IrisUserWarning def _make_cube( diff --git a/lib/iris/tests/test_coord_api.py b/lib/iris/tests/test_coord_api.py index 70cbd15899..50ae3b2696 100644 --- a/lib/iris/tests/test_coord_api.py +++ b/lib/iris/tests/test_coord_api.py @@ -16,7 +16,6 @@ import iris.aux_factory import iris.coord_systems import iris.coords -import iris.exceptions import iris.tests.stock diff --git a/lib/iris/tests/test_coordsystem.py b/lib/iris/tests/test_coordsystem.py index 69aeeaa1b1..f7ee34d0fc 100644 --- a/lib/iris/tests/test_coordsystem.py +++ b/lib/iris/tests/test_coordsystem.py @@ -17,8 +17,8 @@ ) import iris.coords import iris.cube -from iris.exceptions import IrisUserWarning import iris.tests.stock +from iris.warnings import IrisUserWarning def osgb(): diff --git a/lib/iris/tests/test_hybrid.py b/lib/iris/tests/test_hybrid.py index da7cabe765..1bc8f2e70e 100644 --- a/lib/iris/tests/test_hybrid.py +++ b/lib/iris/tests/test_hybrid.py @@ -14,8 +14,8 @@ import iris from iris.aux_factory import HybridHeightFactory, HybridPressureFactory -from iris.exceptions import IrisIgnoringBoundsWarning import iris.tests.stock +from iris.warnings import IrisIgnoringBoundsWarning @tests.skip_plot diff --git a/lib/iris/tests/test_iterate.py b/lib/iris/tests/test_iterate.py index 662707c327..749e8650db 100644 --- a/lib/iris/tests/test_iterate.py +++ b/lib/iris/tests/test_iterate.py @@ -18,9 +18,9 @@ import iris import iris.analysis -from iris.exceptions import IrisUserWarning import iris.iterate import iris.tests.stock +from iris.warnings import IrisUserWarning @tests.skip_data diff --git a/lib/iris/tests/test_netcdf.py b/lib/iris/tests/test_netcdf.py index 049ff55369..3cdac260b3 100644 --- a/lib/iris/tests/test_netcdf.py +++ b/lib/iris/tests/test_netcdf.py @@ -22,7 +22,6 @@ from iris._lazy_data import is_lazy_data import iris.analysis.trajectory import iris.coord_systems as icoord_systems -from iris.exceptions import IrisCfSaveWarning from iris.fileformats._nc_load_rules import helpers as ncload_helpers import iris.fileformats.netcdf from iris.fileformats.netcdf import _thread_safe_nc @@ -31,6 +30,7 @@ import iris.tests.stock as stock from iris.tests.stock.netcdf import ncgen_from_cdl import iris.util +from iris.warnings import IrisCfSaveWarning @tests.skip_data diff --git a/lib/iris/tests/unit/analysis/cartography/test_project.py b/lib/iris/tests/unit/analysis/cartography/test_project.py index 35c22af363..65796b5611 100644 --- a/lib/iris/tests/unit/analysis/cartography/test_project.py +++ b/lib/iris/tests/unit/analysis/cartography/test_project.py @@ -15,9 +15,9 @@ import iris.coord_systems import iris.coords import iris.cube -from iris.exceptions import IrisDefaultingWarning import iris.tests import iris.tests.stock +from iris.warnings import IrisDefaultingWarning ROBINSON = ccrs.Robinson() diff --git a/lib/iris/tests/unit/analysis/geometry/test_geometry_area_weights.py b/lib/iris/tests/unit/analysis/geometry/test_geometry_area_weights.py index 5d7d39dfc4..d98f47975d 100644 --- a/lib/iris/tests/unit/analysis/geometry/test_geometry_area_weights.py +++ b/lib/iris/tests/unit/analysis/geometry/test_geometry_area_weights.py @@ -16,8 +16,8 @@ from iris.analysis.geometry import geometry_area_weights from iris.coords import DimCoord from iris.cube import Cube -from iris.exceptions import IrisGeometryExceedWarning import iris.tests.stock as stock +from iris.warnings import IrisGeometryExceedWarning class Test(tests.IrisTest): diff --git a/lib/iris/tests/unit/coords/test_Coord.py b/lib/iris/tests/unit/coords/test_Coord.py index c6f740c492..c0accfe071 100644 --- a/lib/iris/tests/unit/coords/test_Coord.py +++ b/lib/iris/tests/unit/coords/test_Coord.py @@ -19,8 +19,9 @@ import iris from iris.coords import AuxCoord, Coord, DimCoord from iris.cube import Cube -from iris.exceptions import IrisVagueMetadataWarning, UnitConversionError +from iris.exceptions import UnitConversionError from iris.tests.unit.coords import CoordTestMixin +from iris.warnings import IrisVagueMetadataWarning Pair = collections.namedtuple("Pair", "points bounds") diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index 3de44eefa0..ec94e346b2 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -33,12 +33,11 @@ AncillaryVariableNotFoundError, CellMeasureNotFoundError, CoordinateNotFoundError, - IrisUserWarning, - IrisVagueMetadataWarning, UnitConversionError, ) import iris.tests.stock as stock from iris.tests.stock.mesh import sample_mesh, sample_mesh_cube, sample_meshcoord +from iris.warnings import IrisUserWarning, IrisVagueMetadataWarning class Test___init___data(tests.IrisTest): diff --git a/lib/iris/tests/unit/cube/test_Cube__aggregated_by.py b/lib/iris/tests/unit/cube/test_Cube__aggregated_by.py index 67d66373ff..64c99ebd4b 100644 --- a/lib/iris/tests/unit/cube/test_Cube__aggregated_by.py +++ b/lib/iris/tests/unit/cube/test_Cube__aggregated_by.py @@ -20,7 +20,6 @@ import iris.coords from iris.coords import AncillaryVariable, AuxCoord, CellMeasure, DimCoord from iris.cube import Cube -import iris.exceptions from iris.tests.stock import realistic_4d diff --git a/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridAuxiliaryCoordinateVariable.py b/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridAuxiliaryCoordinateVariable.py index 5f613840a3..4a45e9a4df 100644 --- a/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridAuxiliaryCoordinateVariable.py +++ b/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridAuxiliaryCoordinateVariable.py @@ -18,11 +18,11 @@ import numpy as np import pytest -import iris.exceptions from iris.experimental.ugrid.cf import CFUGridAuxiliaryCoordinateVariable from iris.tests.unit.experimental.ugrid.cf.test_CFUGridReader import ( netcdf_ugrid_variable, ) +import iris.warnings def named_variable(name): @@ -201,7 +201,7 @@ def test_warn(self): def operation(warn: bool): warnings.warn( "emit at least 1 warning", - category=iris.exceptions.IrisUserWarning, + category=iris.warnings.IrisUserWarning, ) result = CFUGridAuxiliaryCoordinateVariable.identify(vars_all, warn=warn) self.assertDictEqual({}, result) @@ -210,7 +210,7 @@ def operation(warn: bool): warn_regex = ( rf"Missing CF-netCDF auxiliary coordinate variable {subject_name}.*" ) - with pytest.warns(iris.exceptions.IrisCfMissingVarWarning, match=warn_regex): + with pytest.warns(iris.warnings.IrisCfMissingVarWarning, match=warn_regex): operation(warn=True) with pytest.warns() as record: operation(warn=False) @@ -220,7 +220,7 @@ def operation(warn: bool): # String variable warning. warn_regex = r".*is a CF-netCDF label variable.*" vars_all[subject_name] = netcdf_ugrid_variable(subject_name, "", np.bytes_) - with pytest.warns(iris.exceptions.IrisCfLabelVarWarning, match=warn_regex): + with pytest.warns(iris.warnings.IrisCfLabelVarWarning, match=warn_regex): operation(warn=True) with pytest.warns() as record: operation(warn=False) diff --git a/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridConnectivityVariable.py b/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridConnectivityVariable.py index dcddfa08b8..5144729c7f 100644 --- a/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridConnectivityVariable.py +++ b/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridConnectivityVariable.py @@ -18,12 +18,12 @@ import numpy as np import pytest -import iris.exceptions from iris.experimental.ugrid.cf import CFUGridConnectivityVariable from iris.experimental.ugrid.mesh import Connectivity from iris.tests.unit.experimental.ugrid.cf.test_CFUGridReader import ( netcdf_ugrid_variable, ) +import iris.warnings def named_variable(name): @@ -186,14 +186,14 @@ def test_warn(self): def operation(warn: bool): warnings.warn( "emit at least 1 warning", - category=iris.exceptions.IrisUserWarning, + category=iris.warnings.IrisUserWarning, ) result = CFUGridConnectivityVariable.identify(vars_all, warn=warn) self.assertDictEqual({}, result) # Missing warning. warn_regex = rf"Missing CF-UGRID connectivity variable {subject_name}.*" - with pytest.warns(iris.exceptions.IrisCfMissingVarWarning, match=warn_regex): + with pytest.warns(iris.warnings.IrisCfMissingVarWarning, match=warn_regex): operation(warn=True) with pytest.warns() as record: operation(warn=False) @@ -203,7 +203,7 @@ def operation(warn: bool): # String variable warning. warn_regex = r".*is a CF-netCDF label variable.*" vars_all[subject_name] = netcdf_ugrid_variable(subject_name, "", np.bytes_) - with pytest.warns(iris.exceptions.IrisCfLabelVarWarning, match=warn_regex): + with pytest.warns(iris.warnings.IrisCfLabelVarWarning, match=warn_regex): operation(warn=True) with pytest.warns() as record: operation(warn=False) diff --git a/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridMeshVariable.py b/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridMeshVariable.py index ccefe01b3c..ef5447382a 100644 --- a/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridMeshVariable.py +++ b/lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridMeshVariable.py @@ -18,11 +18,11 @@ import numpy as np import pytest -import iris.exceptions from iris.experimental.ugrid.cf import CFUGridMeshVariable from iris.tests.unit.experimental.ugrid.cf.test_CFUGridReader import ( netcdf_ugrid_variable, ) +import iris.warnings def named_variable(name): @@ -233,14 +233,14 @@ def test_warn(self): def operation(warn: bool): warnings.warn( "emit at least 1 warning", - category=iris.exceptions.IrisUserWarning, + category=iris.warnings.IrisUserWarning, ) result = CFUGridMeshVariable.identify(vars_all, warn=warn) self.assertDictEqual({}, result) # Missing warning. warn_regex = rf"Missing CF-UGRID mesh variable {subject_name}.*" - with pytest.warns(iris.exceptions.IrisCfMissingVarWarning, match=warn_regex): + with pytest.warns(iris.warnings.IrisCfMissingVarWarning, match=warn_regex): operation(warn=True) with pytest.warns() as record: operation(warn=False) @@ -250,7 +250,7 @@ def operation(warn: bool): # String variable warning. warn_regex = r".*is a CF-netCDF label variable.*" vars_all[subject_name] = netcdf_ugrid_variable(subject_name, "", np.bytes_) - with pytest.warns(iris.exceptions.IrisCfLabelVarWarning, match=warn_regex): + with pytest.warns(iris.warnings.IrisCfLabelVarWarning, match=warn_regex): operation(warn=True) with pytest.warns() as record: operation(warn=False) diff --git a/lib/iris/tests/unit/fileformats/ff/test_FF2PP.py b/lib/iris/tests/unit/fileformats/ff/test_FF2PP.py index 2c19bdc12e..4d031ac4a6 100644 --- a/lib/iris/tests/unit/fileformats/ff/test_FF2PP.py +++ b/lib/iris/tests/unit/fileformats/ff/test_FF2PP.py @@ -14,10 +14,11 @@ import numpy as np -from iris.exceptions import IrisLoadWarning, NotYetImplementedError +from iris.exceptions import NotYetImplementedError import iris.fileformats._ff as ff from iris.fileformats._ff import FF2PP import iris.fileformats.pp as pp +from iris.warnings import IrisLoadWarning # PP-field: LBPACK N1 values. _UNPACKED = 0 diff --git a/lib/iris/tests/unit/fileformats/name_loaders/test__build_cell_methods.py b/lib/iris/tests/unit/fileformats/name_loaders/test__build_cell_methods.py index 98dc5000bc..ff80acf95b 100644 --- a/lib/iris/tests/unit/fileformats/name_loaders/test__build_cell_methods.py +++ b/lib/iris/tests/unit/fileformats/name_loaders/test__build_cell_methods.py @@ -11,8 +11,8 @@ from unittest import mock import iris.coords -from iris.exceptions import IrisLoadWarning from iris.fileformats.name_loaders import _build_cell_methods +from iris.warnings import IrisLoadWarning class Tests(tests.IrisTest): diff --git a/lib/iris/tests/unit/fileformats/nc_load_rules/actions/__init__.py b/lib/iris/tests/unit/fileformats/nc_load_rules/actions/__init__.py index ac20e95682..845b88536a 100644 --- a/lib/iris/tests/unit/fileformats/nc_load_rules/actions/__init__.py +++ b/lib/iris/tests/unit/fileformats/nc_load_rules/actions/__init__.py @@ -8,12 +8,12 @@ import tempfile import warnings -from iris.exceptions import IrisLoadWarning import iris.fileformats._nc_load_rules.engine from iris.fileformats.cf import CFReader import iris.fileformats.netcdf from iris.fileformats.netcdf.loader import _load_cube from iris.tests.stock.netcdf import ncgen_from_cdl +from iris.warnings import IrisLoadWarning """ Notes on testing method. diff --git a/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test__normalise_bounds_units.py b/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test__normalise_bounds_units.py index f6233847e4..337279426e 100644 --- a/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test__normalise_bounds_units.py +++ b/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test__normalise_bounds_units.py @@ -12,11 +12,11 @@ import numpy as np import pytest -from iris.exceptions import IrisCfLoadWarning from iris.fileformats._nc_load_rules.helpers import ( _normalise_bounds_units, _WarnComboIgnoringCfLoad, ) +from iris.warnings import IrisCfLoadWarning BOUNDS = mock.sentinel.bounds CF_NAME = "dummy_bnds" diff --git a/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test_parse_cell_methods.py b/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test_parse_cell_methods.py index 500ecd51d8..0f8fd0152f 100644 --- a/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test_parse_cell_methods.py +++ b/lib/iris/tests/unit/fileformats/nc_load_rules/helpers/test_parse_cell_methods.py @@ -11,8 +11,8 @@ from unittest import mock from iris.coords import CellMethod -from iris.exceptions import IrisCfLoadWarning from iris.fileformats._nc_load_rules.helpers import parse_cell_methods +from iris.warnings import IrisCfLoadWarning class Test(tests.IrisTest): diff --git a/lib/iris/tests/unit/fileformats/netcdf/loader/test__load_aux_factory.py b/lib/iris/tests/unit/fileformats/netcdf/loader/test__load_aux_factory.py index eacdee2782..5aafeaf0fc 100644 --- a/lib/iris/tests/unit/fileformats/netcdf/loader/test__load_aux_factory.py +++ b/lib/iris/tests/unit/fileformats/netcdf/loader/test__load_aux_factory.py @@ -15,8 +15,8 @@ from iris.coords import DimCoord from iris.cube import Cube -from iris.exceptions import IrisFactoryCoordNotFoundWarning from iris.fileformats.netcdf.loader import _load_aux_factory +from iris.warnings import IrisFactoryCoordNotFoundWarning class TestAtmosphereHybridSigmaPressureCoordinate(tests.IrisTest): diff --git a/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver.py b/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver.py index 28ef972c8c..744051f02d 100644 --- a/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver.py +++ b/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver.py @@ -32,9 +32,9 @@ ) from iris.coords import AuxCoord, DimCoord from iris.cube import Cube -from iris.exceptions import IrisMaskValueMatchWarning from iris.fileformats.netcdf import Saver, _thread_safe_nc import iris.tests.stock as stock +from iris.warnings import IrisMaskValueMatchWarning class Test_write(tests.IrisTest): diff --git a/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__lazy_stream_data.py b/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__lazy_stream_data.py index 69eabac5f5..c1bc411564 100644 --- a/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__lazy_stream_data.py +++ b/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__lazy_stream_data.py @@ -16,9 +16,9 @@ import numpy as np import pytest -from iris.exceptions import IrisMaskValueMatchWarning import iris.fileformats.netcdf._thread_safe_nc as threadsafe_nc from iris.fileformats.netcdf.saver import Saver, _FillvalueCheckInfo +from iris.warnings import IrisMaskValueMatchWarning class Test__lazy_stream_data: diff --git a/lib/iris/tests/unit/fileformats/netcdf/saver/test__fillvalue_report.py b/lib/iris/tests/unit/fileformats/netcdf/saver/test__fillvalue_report.py index c0046e547a..0b37070241 100644 --- a/lib/iris/tests/unit/fileformats/netcdf/saver/test__fillvalue_report.py +++ b/lib/iris/tests/unit/fileformats/netcdf/saver/test__fillvalue_report.py @@ -8,9 +8,9 @@ import numpy as np import pytest -from iris.exceptions import IrisSaverFillValueWarning from iris.fileformats.netcdf._thread_safe_nc import default_fillvals from iris.fileformats.netcdf.saver import _fillvalue_report, _FillvalueCheckInfo +from iris.warnings import IrisSaverFillValueWarning class Test__fillvaluereport: diff --git a/lib/iris/tests/unit/fileformats/pp/test_PPField.py b/lib/iris/tests/unit/fileformats/pp/test_PPField.py index de7c2b1ba5..f3aed0bea2 100644 --- a/lib/iris/tests/unit/fileformats/pp/test_PPField.py +++ b/lib/iris/tests/unit/fileformats/pp/test_PPField.py @@ -12,9 +12,9 @@ import numpy as np -from iris.exceptions import IrisDefaultingWarning, IrisMaskValueMatchWarning import iris.fileformats.pp as pp from iris.fileformats.pp import PPField, SplittableInt +from iris.warnings import IrisDefaultingWarning, IrisMaskValueMatchWarning # The PPField class is abstract, so to test we define a minimal, # concrete subclass with the `t1` and `t2` properties. diff --git a/lib/iris/tests/unit/util/test_mask_cube_from_shapefile.py b/lib/iris/tests/unit/util/test_mask_cube_from_shapefile.py index bde8007ee2..7a03ea91aa 100644 --- a/lib/iris/tests/unit/util/test_mask_cube_from_shapefile.py +++ b/lib/iris/tests/unit/util/test_mask_cube_from_shapefile.py @@ -11,9 +11,9 @@ from iris.coord_systems import RotatedGeogCS from iris.coords import DimCoord import iris.cube -from iris.exceptions import IrisUserWarning import iris.tests as tests from iris.util import mask_cube_from_shapefile +from iris.warnings import IrisUserWarning class TestBasicCubeMasking(tests.IrisTest): diff --git a/lib/iris/warnings.py b/lib/iris/warnings.py new file mode 100644 index 0000000000..1a885f60a3 --- /dev/null +++ b/lib/iris/warnings.py @@ -0,0 +1,180 @@ +# Copyright Iris contributors +# +# This file is part of Iris and is released under the BSD license. +# See LICENSE in the root of the repository for full licensing details. +"""Warnings specific to the :mod:`iris` package. + +PLEASE NAMESPACE ALL WARNING CLASSES (i.e. prefix with Iris...). +""" + + +class IrisUserWarning(UserWarning): + r"""Base class for :class:`UserWarning` generated by Iris.""" + + pass + + +class IrisLoadWarning(IrisUserWarning): + """Any warning relating to loading.""" + + pass + + +class IrisSaveWarning(IrisUserWarning): + """Any warning relating to saving.""" + + pass + + +class IrisCfWarning(IrisUserWarning): + """Any warning relating to :term:`CF Conventions` .""" + + pass + + +class IrisIgnoringWarning(IrisUserWarning): + """Any warning that involves an Iris operation not using some information. + + E.g. :class:`~iris.aux_factory.AuxCoordFactory` generation disregarding + bounds. + """ + + pass + + +class IrisDefaultingWarning(IrisUserWarning): + """Any warning that involves Iris changing invalid/missing information. + + E.g. creating a :class:`~iris.coords.AuxCoord` from an invalid + :class:`~iris.coords.DimCoord` definition. + """ + + pass + + +class IrisVagueMetadataWarning(IrisUserWarning): + """Warnings where object metadata may not be fully descriptive.""" + + pass + + +class IrisUnsupportedPlottingWarning(IrisUserWarning): + """Warnings where support for a plotting module/function is not guaranteed.""" + + pass + + +class IrisImpossibleUpdateWarning(IrisUserWarning): + """Warnings where it is not possible to update an object. + + Mainly generated during regridding where the necessary information for + updating an :class:`~iris.aux_factory.AuxCoordFactory` is no longer + present. + """ + + pass + + +class IrisGeometryExceedWarning(IrisUserWarning): + """:mod:`iris.analysis.geometry` warnings about geometry exceeding dimensions.""" + + pass + + +class IrisMaskValueMatchWarning(IrisUserWarning): + """Warnings where the value representing masked data is actually present in data.""" + + pass + + +class IrisCfLoadWarning(IrisCfWarning, IrisLoadWarning): + """Any warning relating to both loading and :term:`CF Conventions` .""" + + pass + + +class IrisCfSaveWarning(IrisCfWarning, IrisSaveWarning): + """Any warning relating to both saving and :term:`CF Conventions` .""" + + pass + + +class IrisCfInvalidCoordParamWarning(IrisCfLoadWarning): + """Warnings where incorrect information for CF coord construction is in a file.""" + + pass + + +class IrisCfMissingVarWarning(IrisCfLoadWarning): + """Warnings where a CF variable references another variable that is not in the file.""" + + pass + + +class IrisCfLabelVarWarning(IrisCfLoadWarning, IrisIgnoringWarning): + """Warnings where a CF string/label variable is being used inappropriately.""" + + pass + + +class IrisCfNonSpanningVarWarning(IrisCfLoadWarning, IrisIgnoringWarning): + """Warnings where a CF variable is ignored because it does not span the required dimension.""" + + pass + + +class IrisIgnoringBoundsWarning(IrisIgnoringWarning): + """Warnings where bounds information has not been used by an Iris operation.""" + + pass + + +class IrisCannotAddWarning(IrisIgnoringWarning): + """Warnings where a member object cannot be added to a :class:`~iris.cube.Cube` .""" + + pass + + +class IrisGuessBoundsWarning(IrisDefaultingWarning): + """Warnings where Iris has filled absent bounds information with a best estimate.""" + + pass + + +class IrisPpClimModifiedWarning(IrisSaveWarning, IrisDefaultingWarning): + """Warnings where a climatology has been modified while saving :term:`Post Processing (PP) Format` .""" + + pass + + +class IrisFactoryCoordNotFoundWarning(IrisLoadWarning): + """Warnings where a referenced factory coord can not be found when loading a variable in :term:`NetCDF Format`.""" + + pass + + +class IrisNimrodTranslationWarning(IrisLoadWarning): + """For unsupported vertical coord types in :mod:`iris.file_formats.nimrod_load_rules`. + + (Pre-dates the full categorisation of Iris UserWarnings). + """ + + pass + + +class IrisUnknownCellMethodWarning(IrisCfLoadWarning): + """If a loaded :class:`~iris.coords.CellMethod` is not one the method names known to Iris. + + (Pre-dates the full categorisation of Iris UserWarnings). + """ + + pass + + +class IrisSaverFillValueWarning(IrisMaskValueMatchWarning, IrisSaveWarning): + """For fill value complications during Iris file saving :term:`NetCDF Format`. + + (Pre-dates the full categorisation of Iris UserWarnings). + """ + + pass From c2f1f2ba58df024284c7caa8e0dc617317fa543b Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Tue, 20 Feb 2024 14:14:26 +0000 Subject: [PATCH 2/2] What's New entry. --- docs/src/whatsnew/latest.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index fe22f9cfa1..da6e7893e2 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -46,7 +46,8 @@ This document explains the changes made to Iris for this release #. `@trexfeathers`_ and `@HGWright`_ (reviewer) sub-categorised all Iris' :class:`UserWarning`\s for richer filtering. The full index of - sub-categories can be seen here: :mod:`iris.warnings` . (:pull:`5498`) + sub-categories can be seen here: :mod:`iris.warnings` . (:pull:`5498`, + :pull:`5760`) #. `@trexfeathers`_ added the :class:`~iris.coord_systems.ObliqueMercator` and :class:`~iris.coord_systems.RotatedMercator` coordinate systems,