Skip to content

Commit b7685b9

Browse files
pp-mofnattinopre-commit-ci[bot]
authored
Avoid computing lazy scalar coordinates when printing a Cube (v2) (#5896)
* avoid running coord.cell for lazy data and bounds * Special case for printing scalar hybrid coords. * Convert test_CubeSummary to pytest. * Add tests for cube printout of real/lazy/hybrid scalar coordinates. * Review change. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added whatsnew. --------- Co-authored-by: Francesco Nattino <f.nattino@esciencecenter.nl> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 03a2d5c commit b7685b9

File tree

3 files changed

+181
-86
lines changed

3 files changed

+181
-86
lines changed

docs/src/whatsnew/latest.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ This document explains the changes made to Iris for this release
6464
:func:`dask.array.map_blocks`; known specifically to be a problem in the
6565
:class:`iris.analysis.AreaWeighted` regridder. (:pull:`5767`)
6666

67+
#. `@fnattino`_ and `@pp-mo`_ prevented cube printout from showing the values of lazy
68+
scalar coordinates, since this can involve a lengthy computation that must be
69+
re-computed each time. (:pull:`5896`)
70+
6771

6872
🔥 Deprecations
6973
===============
@@ -105,7 +109,7 @@ This document explains the changes made to Iris for this release
105109
core dev names are automatically included by the common_links.inc:
106110
107111
.. _@jfrost-mo: https://github.com/jfrost-mo
108-
112+
.. _@fnattino: https://github.com/fnattino
109113

110114

111115
.. comment

lib/iris/_representation/cube_summary.py

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
import re
88

9+
import numpy as np
10+
11+
import iris._lazy_data as _lazy
912
from iris.common.metadata import hexdigest
1013
import iris.util
1114

@@ -149,32 +152,71 @@ def __init__(self, cube, coord):
149152
self.unit = ""
150153
else:
151154
self.unit = " {!s}".format(coord.units)
152-
coord_cell = coord.cell(0)
153-
if isinstance(coord_cell.point, str):
155+
156+
# Don't print values of lazy coords, as computing them could cost a lot.
157+
safe_to_print = not _lazy.is_lazy_data(coord.core_points())
158+
if not safe_to_print:
159+
# However there is a special case: If it is a *factory* coord, then those
160+
# are generally lazy. If all the dependencies are real, then it is useful
161+
# (and safe) to compute + print the value.
162+
for factory in cube._aux_factories:
163+
# Note : a factory doesn't have a ".metadata" which can be matched
164+
# against a coord. For now, just assume that it has a 'standard_name'
165+
# property (also not actually guaranteed), and require them to match.
166+
if coord.standard_name == factory.standard_name:
167+
all_deps_real = True
168+
for dependency_coord in factory.dependencies.values():
169+
if (
170+
dependency_coord.has_lazy_points()
171+
or dependency_coord.has_lazy_bounds()
172+
):
173+
all_deps_real = False
174+
175+
if all_deps_real:
176+
safe_to_print = True
177+
178+
if safe_to_print:
179+
coord_cell = coord.cell(0)
180+
else:
181+
coord_cell = None
182+
183+
if coord.dtype.type is np.str_:
154184
self.string_type = True
155-
# 'lines' is value split on '\n', and _each one_ length-clipped.
156-
self.lines = [
157-
iris.util.clip_string(str(item))
158-
for item in coord_cell.point.split("\n")
159-
]
185+
if coord_cell is not None:
186+
# 'lines' is value split on '\n', and _each one_ length-clipped.
187+
self.lines = [
188+
iris.util.clip_string(str(item))
189+
for item in coord_cell.point.split("\n")
190+
]
191+
# 'content' contains a one-line printable version of the string,
192+
content = string_repr(coord_cell.point)
193+
content = iris.util.clip_string(content)
194+
else:
195+
content = "<lazy>"
196+
self.lines = [content]
160197
self.point = None
161198
self.bound = None
162-
# 'content' contains a one-line printable version of the string,
163-
content = string_repr(coord_cell.point)
164-
content = iris.util.clip_string(content)
165199
self.content = content
166200
else:
167201
self.string_type = False
168202
self.lines = None
169-
self.point = "{!s}".format(coord_cell.point)
170-
coord_cell_cbound = coord_cell.bound
203+
coord_cell_cbound = None
204+
if coord_cell is not None:
205+
self.point = "{!s}".format(coord_cell.point)
206+
coord_cell_cbound = coord_cell.bound
207+
else:
208+
self.point = "<lazy>"
209+
171210
if coord_cell_cbound is not None:
172211
self.bound = "({})".format(
173212
", ".join(str(val) for val in coord_cell_cbound)
174213
)
175214
self.content = "{}{}, bound={}{}".format(
176215
self.point, self.unit, self.bound, self.unit
177216
)
217+
elif coord.has_bounds():
218+
self.bound = "+bound"
219+
self.content = "{}{}".format(self.point, self.bound)
178220
else:
179221
self.bound = None
180222
self.content = "{}{}".format(self.point, self.unit)

0 commit comments

Comments
 (0)