diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index d0aefd02c1..25c0c5f3c9 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -79,6 +79,12 @@ This document explains the changes made to Iris for this release #. `@rcomer`_ removed some old redundant code that prevented determining the order of time cells. (:issue:`4697`, :pull:`4729`) +#. `@stephenworsley`_ improved the accuracy of the error messages for + :meth:`~iris.cube.Cube.coord` when failing to find coordinates in the case where + a coordinate is given as the argument. Similarly, improved the error messages for + :meth:`~iris.cube.Cube.cell_measure` and :meth:`~iris.cube.Cube.ancillary_variable`. + (:issue:`4898`, :pull:`4928`) + 💣 Incompatible Changes ======================= diff --git a/lib/iris/cube.py b/lib/iris/cube.py index 9779558506..4e24c099fe 100644 --- a/lib/iris/cube.py +++ b/lib/iris/cube.py @@ -1990,6 +1990,12 @@ def coord( if name_or_coord is not None: if not isinstance(name_or_coord, str): _name = name_or_coord.name() + emsg = ( + "Expected to find exactly 1 coordinate matching the given " + f"{_name!r} coordinate's metadata, but found none." + ) + raise iris.exceptions.CoordinateNotFoundError(emsg) + bad_name = _name or standard_name or long_name or "" emsg = ( f"Expected to find exactly 1 {bad_name!r} coordinate, " @@ -2194,9 +2200,15 @@ def cell_measure(self, name_or_cell_measure=None): bad_name = ( name_or_cell_measure and name_or_cell_measure.name() ) or "" + if name_or_cell_measure is not None: + emsg = ( + "Expected to find exactly 1 cell measure matching the given " + f"{bad_name!r} cell measure's metadata, but found none." + ) + raise iris.exceptions.CellMeasureNotFoundError(emsg) msg = ( - "Expected to find exactly 1 %s cell_measure, but found " - "none." % bad_name + f"Expected to find exactly 1 {bad_name!r} cell measure, " + "but found none." ) raise iris.exceptions.CellMeasureNotFoundError(msg) @@ -2281,9 +2293,16 @@ def ancillary_variable(self, name_or_ancillary_variable=None): name_or_ancillary_variable and name_or_ancillary_variable.name() ) or "" + if name_or_ancillary_variable is not None: + emsg = ( + "Expected to find exactly 1 ancillary_variable matching the " + f"given {bad_name!r} ancillary_variable's metadata, but found " + "none." + ) + raise iris.exceptions.AncillaryVariableNotFoundError(emsg) msg = ( - "Expected to find exactly 1 {!s} ancillary_variable, but " - "found none.".format(bad_name) + f"Expected to find exactly 1 {bad_name!r} ancillary_variable, " + "but found none." ) raise iris.exceptions.AncillaryVariableNotFoundError(msg) diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index 62c719aab9..7a6a200890 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -2528,6 +2528,25 @@ def test_fail_remove_ancilliary_variable_by_name(self): self.cube.remove_ancillary_variable("notname") +class TestCoords(tests.IrisTest): + def setUp(self): + cube = Cube(np.arange(6).reshape(2, 3)) + x_coord = DimCoord(points=np.array([2, 3, 4]), long_name="x") + cube.add_dim_coord(x_coord, 1) + self.x_coord = x_coord + self.cube = cube + + def test_bad_coord(self): + bad_coord = self.x_coord.copy() + bad_coord.attributes = {"bad": "attribute"} + re = ( + "Expected to find exactly 1 coordinate matching the given " + "'x' coordinate's metadata, but found none." + ) + with self.assertRaisesRegex(CoordinateNotFoundError, re): + _ = self.cube.coord(bad_coord) + + class Test__getitem_CellMeasure(tests.IrisTest): def setUp(self): cube = Cube(np.arange(6).reshape(2, 3))