Skip to content

Commit 92d0d63

Browse files
authored
Tolerant handling of standard_name and dimension coordinate loading (#6338)
* Basic LOAD_PROBLEMS object. * Minimum docstring for LOAD_PROBLEMS. * Working handling of names and dimension coords. * Warn user of load problems. * Docstring and UX improvements. * What's New entry. * Fix doctests. * Fix tests. * Fix doctests for 3.13. * New tests for actions. * Updated load problems tests for names. * Licence header. * Tidy up code modifications. * Convenience - get_latest_load_problem. * Tests for _add_or_capture. * Test for build_raw_cube. * Make more methods private. * Fix doctest. * Factor out add_method. * Remove stack_trace TODO. * Correct docstring of _add_or_capture. * Extra comments. * Refactor to create the LoadProblems class. * Fix doctest. * What's New improvements. * Encase coordinate name in quotes. * More robust LoadProblems testing. * Remove TODO tags following review discussion. * Propose mail-archive for addition to linkcheck_ignore.
1 parent df5c55f commit 92d0d63

File tree

18 files changed

+1289
-166
lines changed

18 files changed

+1289
-166
lines changed

docs/src/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ def _dotv(version):
405405
"https://twitter.com/scitools_iris",
406406
"https://stackoverflow.com/questions/tagged/python-iris",
407407
"https://www.flaticon.com/",
408+
"https://www.mail-archive.com/[email protected]/msg39091.html",
408409
]
409410

410411
# list of sources to exclude from the build.

docs/src/whatsnew/latest.rst

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ This document explains the changes made to Iris for this release
7373
render text in the bottom right of the plot figure.
7474
(:issue:`6247`, :pull:`6332`)
7575

76+
#. `@trexfeathers`_ and `@pp-mo`_ added :const:`iris.loading.LOAD_PROBLEMS` to
77+
capture objects that could not be loaded correctly, increasing transparency
78+
and helping users to fix loading problems via the Iris API. As a first pass,
79+
this is currently limited to ``standard_name`` and dimension coordinates from
80+
NetCDF files. (:issue:`6317`, :pull:`6338`)
81+
7682

7783
🐛 Bugs Fixed
7884
=============
@@ -99,6 +105,19 @@ This document explains the changes made to Iris for this release
99105
Once conversion from unittest to pytest is completed, :class:`iris.tests.IrisTest`
100106
class will be deprecated.
101107

108+
#. `@trexfeathers`_ and `@pp-mo`_ significantly changed Iris' NetCDF loading
109+
warnings as part of the :const:`~iris.loading.LOAD_PROBLEMS` work. Several
110+
loading operations no longer raise their own warnings; instead their loading
111+
problems are captured in :const:`~iris.loading.LOAD_PROBLEMS`. When
112+
:const:`~iris.loading.LOAD_PROBLEMS` is populated, a single
113+
:class:`~iris.warnings.IrisLoadWarning` is raised; see below.
114+
As a first pass, this changed behaviour is currently limited to
115+
``standard_name`` and dimension coordinates from NetCDF files. (:pull:`6338`)
116+
117+
.. code-block:: none
118+
119+
IrisLoadWarning: Not all file objects were parsed correctly. See iris.loading.LOAD_PROBLEMS for details.
120+
102121
103122
🚀 Performance Enhancements
104123
===========================
@@ -166,7 +185,7 @@ This document explains the changes made to Iris for this release
166185
necessary. (:issue:`6285`, :pull:`6288`)
167186

168187
#. `@trexfeathers`_ improved the handling of benchmark environments, especially
169-
when working across Python versions. (:pull:`6329`)
188+
when working across Python versions. (:pull:`6329`)
170189

171190
#. `@trexfeathers`_ temporarily pinned Sphinx to `<8.2`.
172191
(:pull:`6344`, :issue:`6345`)

lib/iris/common/mixin.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ class LimitedAttributeDict(dict):
7373
7474
"""
7575

76-
#: Attributes with special CF meaning, forbidden in Iris attribute dictionaries.
7776
CF_ATTRS_FORBIDDEN = (
7877
"standard_name",
7978
"long_name",
@@ -94,6 +93,15 @@ class LimitedAttributeDict(dict):
9493
"scale_factor",
9594
"_FillValue",
9695
)
96+
"""Attributes with special CF meaning, forbidden in Iris attribute dictionaries."""
97+
98+
IRIS_RAW = "IRIS_RAW"
99+
"""Key used by Iris to store ALL attributes when problems are encountered during loading.
100+
101+
See Also
102+
--------
103+
iris.loading.LOAD_PROBLEMS: The destination for captured loading problems.
104+
"""
97105

98106
def __init__(self, *args, **kwargs):
99107
dict.__init__(self, *args, **kwargs)

lib/iris/fileformats/_nc_load_rules/actions.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from iris.config import get_logger
4646
import iris.fileformats.cf
4747
import iris.fileformats.pp as pp
48+
from iris.loading import LOAD_PROBLEMS
4849
import iris.warnings
4950

5051
from . import helpers as hh
@@ -104,6 +105,10 @@ def inner(engine, *args, **kwargs):
104105
@action_function
105106
def action_default(engine):
106107
"""Perform standard operations for every cube."""
108+
# Future pattern (iris#6319).
109+
hh.build_and_add_names(engine)
110+
111+
# Legacy pattern.
107112
hh.build_cube_metadata(engine)
108113

109114

@@ -286,6 +291,7 @@ def action_build_dimension_coordinate(engine, providescoord_fact):
286291
cf_var = engine.cf_var.cf_group[var_name]
287292
rule_name = f"fc_build_coordinate_({coord_type})"
288293
coord_grid_class, coord_name = _COORDTYPE_GRIDTYPES_AND_COORDNAMES[coord_type]
294+
succeed = None
289295
if coord_grid_class is None:
290296
# Coordinates not identified with a specific grid-type class (latlon,
291297
# rotated or projected) are always built, but can have no coord-system.
@@ -367,9 +373,28 @@ def action_build_dimension_coordinate(engine, providescoord_fact):
367373
assert coord_grid_class in grid_classes
368374

369375
if succeed:
370-
hh.build_dimension_coordinate(
376+
hh.build_and_add_dimension_coordinate(
371377
engine, cf_var, coord_name=coord_name, coord_system=coord_system
372378
)
379+
380+
else:
381+
message = f"Dimension coordinate {var_name} not created. Debug info:\n"
382+
if succeed is None:
383+
message += "An unexpected error occurred"
384+
error = NotImplementedError(message)
385+
else:
386+
message += rule_name
387+
error = ValueError(message)
388+
389+
try:
390+
raise error
391+
except error.__class__ as error:
392+
_ = LOAD_PROBLEMS.record(
393+
filename=engine.filename,
394+
loaded=hh.build_raw_cube(cf_var, engine.filename),
395+
exception=error,
396+
)
397+
373398
return rule_name
374399

375400

lib/iris/fileformats/_nc_load_rules/engine.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
2020
"""
2121

22+
from iris.coords import _DimensionalMetadata
23+
from iris.cube import Cube
24+
from iris.fileformats.cf import CFDataVariable
25+
2226
from .actions import run_actions
2327

2428

@@ -74,6 +78,11 @@ class Engine:
7478
7579
"""
7680

81+
cf_var: CFDataVariable | None
82+
cube: Cube | None
83+
cube_parts: dict[str, list[tuple[_DimensionalMetadata, str]]] | None
84+
filename: str | None
85+
7786
def __init__(self):
7887
"""Init new engine."""
7988
self.reset()

0 commit comments

Comments
 (0)