From 9378a3bfeec52c29858d30fe8bbd15153b902f72 Mon Sep 17 00:00:00 2001 From: Max White Date: Tue, 24 Jun 2025 12:03:49 +0100 Subject: [PATCH 1/2] Fix failing tests following environment change. --- improver/metadata/forecast_times.py | 4 +++- improver_tests/metadata/test_check_datatypes.py | 15 +++++++-------- improver_tests/metadata/test_utilities.py | 13 ++++++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/improver/metadata/forecast_times.py b/improver/metadata/forecast_times.py index a3e3652e3e..b84c2e5799 100644 --- a/improver/metadata/forecast_times.py +++ b/improver/metadata/forecast_times.py @@ -322,5 +322,7 @@ def _find_latest_cycletime(cubelist: Union[CubeList, List[Cube]]) -> datetime: next_coord.convert_units(frt_coord.units) if next_coord.points[0] > frt_coord.points[0]: frt_coord = next_coord - (cycletime,) = frt_coord.units.num2date(frt_coord.points) + (cycletime,) = frt_coord.units.num2date( + frt_coord.points, only_use_cftime_datetimes=False + ) return cycletime diff --git a/improver_tests/metadata/test_check_datatypes.py b/improver_tests/metadata/test_check_datatypes.py index 73c2c9e82c..f07134ae00 100644 --- a/improver_tests/metadata/test_check_datatypes.py +++ b/improver_tests/metadata/test_check_datatypes.py @@ -9,7 +9,6 @@ import numpy as np from iris.coords import AuxCoord from iris.cube import CubeList -from iris.tests import IrisTest from improver.metadata.check_datatypes import ( check_mandatory_standards, @@ -23,7 +22,7 @@ ) -class Test_check_mandatory_standards(IrisTest): +class Test_check_mandatory_standards(unittest.TestCase): """Test whether a cube conforms to mandatory dtype and units standards.""" def setUp(self): @@ -76,7 +75,7 @@ def test_conformant_cubes(self): # describing all aspects of the cube (including a checksum of the # data) to verify that nothing has been changed anywhere on the # cube. - self.assertStringEqual( + self.assertEqual( CubeList([cube]).xml(checksum=True), CubeList([result]).xml(checksum=True), ) @@ -154,7 +153,7 @@ def test_multiple_errors(self): check_mandatory_standards(self.percentile_cube) -class Test_enforce_dtypes(IrisTest): +class Test_enforce_dtypes(unittest.TestCase): """Test whether a cube conforms to mandatory dtype and units standards.""" def setUp(self): @@ -186,7 +185,7 @@ def test_ok(self): enforce_dtype("add", inputs, result) result_checksums = [CubeList([c]).xml(checksum=True) for c in inputs + [result]] for a, b in zip(expected_checksums, result_checksums): - self.assertStringEqual(a, b) + self.assertEqual(a, b) def test_fail(self): """Test non-conformant data (error is thrown and inputs are not changed)""" @@ -208,10 +207,10 @@ def test_fail(self): enforce_dtype("add", inputs, result) result_checksums = [CubeList([c]).xml(checksum=True) for c in inputs + [result]] for a, b in zip(expected_checksums, result_checksums): - self.assertStringEqual(a, b) + self.assertEqual(a, b) -class Test_check_units(IrisTest): +class Test_check_units(unittest.TestCase): """Test method to check object units""" def setUp(self): @@ -230,7 +229,7 @@ def test_pass_cube(self): # The following statement renders each cube into an XML string # describing all aspects of the cube (including a checksum of the # data) to verify that nothing has been changed anywhere on the cube. - self.assertStringEqual( + self.assertEqual( CubeList([self.cube]).xml(checksum=True), CubeList([input_cube]).xml(checksum=True), ) diff --git a/improver_tests/metadata/test_utilities.py b/improver_tests/metadata/test_utilities.py index 21d75031f4..d3e6a7d25f 100644 --- a/improver_tests/metadata/test_utilities.py +++ b/improver_tests/metadata/test_utilities.py @@ -11,6 +11,7 @@ import iris import numpy as np import pytest +from iris.coords import CellMethod from iris.cube import Cube, CubeList from numpy.testing import assert_array_equal @@ -37,7 +38,9 @@ def setUp(self): self.template_cube = set_up_variable_cube( 280 * np.ones((3, 5, 5), dtype=np.float32), standard_grid_metadata="uk_det" ) - self.template_cube.add_cell_method("time (max): 1 hour") + self.template_cube.add_cell_method( + CellMethod(method="max", coords="time", intervals="1 hour") + ) self.name = "lwe_precipitation_rate" self.units = "mm h-1" self.mandatory_attributes = MANDATORY_ATTRIBUTE_DEFAULTS.copy() @@ -57,7 +60,7 @@ def test_basic(self): result.coords(dim_coords=False), self.template_cube.coords(dim_coords=False) ) self.assertFalse(np.allclose(result.data, self.template_cube.data)) - self.assertDictEqual(result.attributes, self.mandatory_attributes) + self.assertDictEqual(dict(result.attributes), self.mandatory_attributes) self.assertFalse(result.cell_methods) self.assertEqual(result.data.dtype, np.float32) @@ -74,7 +77,7 @@ def test_attributes(self): self.mandatory_attributes, optional_attributes=attributes, ) - self.assertDictEqual(result.attributes, expected_attributes) + self.assertDictEqual(dict(result.attributes), expected_attributes) def test_missing_mandatory_attribute(self): """Test error is raised if any mandatory attribute is missing""" @@ -265,7 +268,7 @@ def test_coordinate_input(self): cube = set_up_variable_cube(np.ones((3, 3)).astype(np.float32)) hash_input = cube.coord("latitude") result = generate_hash(hash_input) - expected = "ee6a057f5eeef0e94a853cfa98f3c22b121dda31ada3378ce9466e48d06f9887" + expected = "8648557d66ca6ee8bf765d00e85dff1963c827af4140d47b6fe16be854b28796" self.assertIsInstance(result, str) self.assertEqual(result, expected) @@ -299,7 +302,7 @@ def test_basic(self): hash_input = set_up_variable_cube(np.zeros((3, 3)).astype(np.float32)) result = create_coordinate_hash(hash_input) - expected = "54812a6fed0f92fe75d180d63a6bd6c916407ea1e7e5fd32a5f20f86ea997fac" + expected = "f167a9ea5d46e575a1b7918fb04f49697d07299c1b21010e40cd21ec351ab4c7" self.assertIsInstance(result, str) self.assertEqual(result, expected) From 4ae84fd8a4a0603675ef2ad7d11a9665e797d56d Mon Sep 17 00:00:00 2001 From: Max White Date: Wed, 25 Jun 2025 16:00:42 +0100 Subject: [PATCH 2/2] Handle bug where num2date is returning cftime datetime instead of python datetime where it shouldn't --- improver/metadata/forecast_times.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/improver/metadata/forecast_times.py b/improver/metadata/forecast_times.py index b84c2e5799..9d499d2b04 100644 --- a/improver/metadata/forecast_times.py +++ b/improver/metadata/forecast_times.py @@ -323,6 +323,8 @@ def _find_latest_cycletime(cubelist: Union[CubeList, List[Cube]]) -> datetime: if next_coord.points[0] > frt_coord.points[0]: frt_coord = next_coord (cycletime,) = frt_coord.units.num2date( - frt_coord.points, only_use_cftime_datetimes=False + frt_coord.points, + only_use_cftime_datetimes=False, + only_use_python_datetimes=True, ) return cycletime