Skip to content

Commit

Permalink
Quieter datum warning (SciTools#6050)
Browse files Browse the repository at this point in the history
* Only warn about datum handling if a datum is present
.

* Partial conversion to PyTest.

* Add test to confirm warnings not raised if no datum is present.

* What's New entry.

* Rewrite duplicate warning testing.

* What's New typo.
  • Loading branch information
trexfeathers authored Jul 17, 2024
1 parent 17dd34a commit c66703a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 38 deletions.
4 changes: 4 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ This document explains the changes made to Iris for this release
#. `@pp-mo`_ corrected the use of mesh dimensions when saving with multiple
meshes. (:issue:`5908`, :pull:`6004`)

#. `@trexfeathers`_ fixed the datum :class:`python:FutureWarning` to only be raised if
the ``datum_support`` :class:`~iris.Future` flag is disabled AND a datum is
present on the loaded NetCDF grid mapping. (:issue:`5749`, :pull:`6050`)


💣 Incompatible Changes
=======================
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/fileformats/_nc_load_rules/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ def _get_ellipsoid(cf_grid_var):
if datum == "unknown":
datum = None

if not iris.FUTURE.datum_support:
if datum is not None and not iris.FUTURE.datum_support:
wmsg = (
"Ignoring a datum in netCDF load for consistency with existing "
"behaviour. In a future version of Iris, this datum will be "
Expand Down
33 changes: 23 additions & 10 deletions lib/iris/tests/integration/netcdf/test_coord_systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
from os.path import join as path_join
import shutil
import tempfile
import warnings

import pytest

import iris
from iris.coords import DimCoord
Expand Down Expand Up @@ -135,15 +138,25 @@ def test_load_datum_wkt(self):
cube = iris.load_cube(nc_path)
test_crs = cube.coord("projection_y_coordinate").coord_system
actual = str(test_crs.as_cartopy_crs().datum)
self.assertMultiLineEqual(expected, actual)
assert actual == expected

def test_no_load_datum_wkt(self):
nc_path = tlc.cdl_to_nc(self.datum_wkt_cdl)
with self.assertWarnsRegex(FutureWarning, "iris.FUTURE.datum_support"):
with pytest.warns(FutureWarning, match="iris.FUTURE.datum_support"):
cube = iris.load_cube(nc_path)
test_crs = cube.coord("projection_y_coordinate").coord_system
actual = str(test_crs.as_cartopy_crs().datum)
self.assertMultiLineEqual(actual, "unknown")
assert actual == "unknown"

def test_no_datum_no_warn(self):
new_cdl = self.datum_wkt_cdl.splitlines()
new_cdl = [line for line in new_cdl if "DATUM" not in line]
new_cdl = "\n".join(new_cdl)
nc_path = tlc.cdl_to_nc(new_cdl)
with warnings.catch_warnings():
# pytest's recommended way to assert for no warnings.
warnings.simplefilter("error", FutureWarning)
_ = iris.load_cube(nc_path)

def test_load_datum_cf_var(self):
expected = "OSGB 1936"
Expand All @@ -152,15 +165,15 @@ def test_load_datum_cf_var(self):
cube = iris.load_cube(nc_path)
test_crs = cube.coord("projection_y_coordinate").coord_system
actual = str(test_crs.as_cartopy_crs().datum)
self.assertMultiLineEqual(expected, actual)
assert actual == expected

def test_no_load_datum_cf_var(self):
nc_path = tlc.cdl_to_nc(self.datum_cf_var_cdl)
with self.assertWarnsRegex(FutureWarning, "iris.FUTURE.datum_support"):
with pytest.warns(FutureWarning, match="iris.FUTURE.datum_support"):
cube = iris.load_cube(nc_path)
test_crs = cube.coord("projection_y_coordinate").coord_system
actual = str(test_crs.as_cartopy_crs().datum)
self.assertMultiLineEqual(actual, "unknown")
assert actual == "unknown"

def test_save_datum(self):
expected = "OSGB 1936"
Expand Down Expand Up @@ -199,7 +212,7 @@ def test_save_datum(self):

test_crs = cube.coord("projection_y_coordinate").coord_system
actual = str(test_crs.as_cartopy_crs().datum)
self.assertMultiLineEqual(expected, actual)
assert actual == expected


class TestLoadMinimalGeostationary(tests.IrisTest):
Expand Down Expand Up @@ -270,9 +283,9 @@ def test_geostationary_no_false_offsets(self):
cube = iris.load_cube(self.path_test_nc)
# Check the coordinate system properties has the correct default properties.
cs = cube.coord_system()
self.assertIsInstance(cs, iris.coord_systems.Geostationary)
self.assertEqual(cs.false_easting, 0.0)
self.assertEqual(cs.false_northing, 0.0)
assert isinstance(cs, iris.coord_systems.Geostationary)
assert cs.false_easting == 0.0
assert cs.false_northing == 0.0


if __name__ == "__main__":
Expand Down
55 changes: 28 additions & 27 deletions lib/iris/tests/integration/netcdf/test_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,37 +488,38 @@ def test_path_string_save_same(self):

@tests.skip_data
class TestWarningRepeats(tests.IrisTest):
def test_datum_once(self):
"""Tests for warnings being duplicated.
def test_warning_repeats(self):
"""Confirm Iris load does not break Python duplicate warning handling."""
# units.nc is designed for testing Iris' 'ignoring invalid units'
# warning; it contains two variables with invalid units, producing two
# unique warnings (due to two different messages).
file_path = tests.get_data_path(("NetCDF", "testing", "units.nc"))

Notes
-----
This test relies on `iris.load` throwing a warning. This warning might
be removed in the future, in which case `assert len(record) == 2 should`
be change to `assert len(record) == 1`.
toa_brightness_temperature.nc has an AuxCoord with lazy data, and triggers a
specific part of dask which contains a `catch_warnings()` call which
causes warnings to be repeated, and so has been removed from the
`fnames` list until a solution is found for such a file.
"""
#
fnames = [
"false_east_north_merc.nc",
"non_unit_scale_factor_merc.nc",
# toa_brightness_temperature.nc,
]
fpaths = [
tests.get_data_path(("NetCDF", "mercator", fname)) for fname in fnames
]
def _raise_warning() -> None:
# Contain in function so warning always has identical line number.
warnings.warn("Dummy warning", category=iris.warnings.IrisUserWarning)

with warnings.catch_warnings(record=True) as record:
warnings.simplefilter("default")
for fpath in fpaths:
iris.load(fpath)
warnings.warn("Dummy warning", category=iris.warnings.IrisUserWarning)
assert len(record) == 2

# Warn before Iris has been invoked.
_raise_warning()
assert len(record) == 1

# This Iris call should raise 2 warnings and should NOT affect
# Python's duplicate warning handling.
_ = iris.load(file_path)
assert len(record) == 3
# Raise a duplicate warning.
_raise_warning()
assert len(record) == 3

# Repeated identical calls should only raise duplicate warnings
# and therefore not affect the record.
for i in range(2):
_ = iris.load(file_path)
_raise_warning()
assert len(record) == 3


if __name__ == "__main__":
Expand Down

0 comments on commit c66703a

Please sign in to comment.