diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index 957b364560..58e3f5f956 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -52,6 +52,9 @@ This document explains the changes made to Iris for this release #. `@rcomer`_ enabled partial collapse of multi-dimensional string coordinates, fixing :issue:`3653`. (:pull:`5955`) +#. `@ukmo-ccbunney`_ improved error handling for malformed `cell_method` + attribute. Also made cell_method string parsing more lenient w.r.t. + whitespace. (:pull:`6083`) 💣 Incompatible Changes ======================= diff --git a/lib/iris/fileformats/_nc_load_rules/helpers.py b/lib/iris/fileformats/_nc_load_rules/helpers.py index 5aed21bebf..faf40ad210 100644 --- a/lib/iris/fileformats/_nc_load_rules/helpers.py +++ b/lib/iris/fileformats/_nc_load_rules/helpers.py @@ -202,11 +202,11 @@ _CM_INTERVAL = "interval" _CM_METHOD = "method" _CM_NAME = "name" -_CM_PARSE_NAME = re.compile(r"([\w_]+\s*?:\s+)+") +_CM_PARSE_NAME = re.compile(r"([\w_]+\s*?:\s*)+") _CM_PARSE = re.compile( r""" - (?P([\w_]+\s*?:\s+)+) - (?P[\w_\s]+(?![\w_]*\s*?:))\s* + (?P([\w_]+\s*?:\s*)+) + (?P[^\s][\w_\s]+(?![\w_]*\s*?:))\s* (?: \(\s* (?P.+) @@ -296,6 +296,12 @@ def _split_cell_methods(nc_cell_methods: str) -> List[re.Match]: for m in _CM_PARSE_NAME.finditer(nc_cell_methods): name_start_inds.append(m.start()) + # No matches? Must be malformed cell_method string; warn and return + if not name_start_inds: + msg = f"Failed to parse cell method string: {nc_cell_methods}" + warnings.warn(msg, category=iris.warnings.IrisCfLoadWarning, stacklevel=2) + return [] + # Remove those that fall inside brackets bracket_depth = 0 for ind, cha in enumerate(nc_cell_methods): 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 0f8fd0152f..528e9d7579 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 @@ -19,6 +19,7 @@ class Test(tests.IrisTest): def test_simple(self): cell_method_strings = [ "time: mean", + "time:mean", "time : mean", ] expected = (CellMethod(method="mean", coords="time"),) @@ -125,6 +126,7 @@ def test_badly_formatted_warning(self): cell_method_strings = [ # "time: maximum (interval: 1 hr comment: first bit " # "time: mean (interval: 1 day comment: second bit)", + "time", "time: (interval: 1 hr comment: first bit) " "time: mean (interval: 1 day comment: second bit)", "time: maximum (interval: 1 hr comment: first bit) "