Skip to content

Commit c53481e

Browse files
Remove uses of logging.warn (SciTools#5488)
* Align UGRID CF warnings with other CF warnings. * Replace remaining uses of logging warnings. * Assert for UserWarnings * Better test variable names. * What's New entry. --------- Co-authored-by: Henry Wright <[email protected]>
1 parent 8b336e9 commit c53481e

File tree

7 files changed

+113
-115
lines changed

7 files changed

+113
-115
lines changed

docs/src/whatsnew/latest.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,14 @@ This document explains the changes made to Iris for this release
7979
working properly. (Main pull request: :pull:`5437`, more detail:
8080
:pull:`5430`, :pull:`5431`, :pull:`5432`, :pull:`5434`, :pull:`5436`)
8181

82+
#. `@trexfeathers`_ replaced all uses of the ``logging.WARNING`` level, in
83+
favour of using Python warnings, following team agreement. (:pull:`5488`)
84+
8285
#. `@trexfeathers`_ adapted benchmarking to work with ASV ``>=v0.6`` by no
8386
longer using the ``--strict`` argument. (:pull:`5496`)
8487

8588

89+
8690
.. comment
8791
Whatsnew author names (@github name) in alphabetical order. Note that,
8892
core dev names are automatically included by the common_links.inc:

lib/iris/experimental/ugrid/cf.py

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,11 @@
1010
Eventual destination: :mod:`iris.fileformats.cf`.
1111
1212
"""
13-
import logging
13+
import warnings
1414

15-
from ...config import get_logger
1615
from ...fileformats import cf
1716
from .mesh import Connectivity
1817

19-
# Configure the logger.
20-
logger = get_logger(__name__, propagate=True, handler=False)
21-
2218

2319
class CFUGridConnectivityVariable(cf.CFVariable):
2420
"""
@@ -50,8 +46,6 @@ class CFUGridConnectivityVariable(cf.CFVariable):
5046
def identify(cls, variables, ignore=None, target=None, warn=True):
5147
result = {}
5248
ignore, target = cls._identify_common(variables, ignore, target)
53-
# TODO: reconsider logging level when we have consistent practice.
54-
log_level = logging.WARNING if warn else logging.DEBUG
5549

5650
# Identify all CF-UGRID connectivity variables.
5751
for nc_var_name, nc_var in target.items():
@@ -70,11 +64,8 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
7064
f"{name}, referenced by netCDF variable "
7165
f"{nc_var_name}"
7266
)
73-
logger.log(
74-
level=log_level,
75-
msg=message,
76-
extra=dict(cls=cls.__name__),
77-
)
67+
if warn:
68+
warnings.warn(message)
7869
else:
7970
# Restrict to non-string type i.e. not a
8071
# CFLabelVariable.
@@ -88,11 +79,8 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
8879
f"as a CF-UGRID connectivity - is a "
8980
f"CF-netCDF label variable."
9081
)
91-
logger.log(
92-
level=log_level,
93-
msg=message,
94-
extra=dict(cls=cls.__name__),
95-
)
82+
if warn:
83+
warnings.warn(message)
9684

9785
return result
9886

@@ -131,8 +119,6 @@ class CFUGridAuxiliaryCoordinateVariable(cf.CFVariable):
131119
def identify(cls, variables, ignore=None, target=None, warn=True):
132120
result = {}
133121
ignore, target = cls._identify_common(variables, ignore, target)
134-
# TODO: reconsider logging level when we have consistent practice.
135-
log_level = logging.WARNING if warn else logging.DEBUG
136122

137123
# Identify any CF-UGRID-relevant auxiliary coordinate variables.
138124
for nc_var_name, nc_var in target.items():
@@ -149,11 +135,8 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
149135
f"variable {name}, referenced by netCDF "
150136
f"variable {nc_var_name}"
151137
)
152-
logger.log(
153-
level=log_level,
154-
msg=message,
155-
extra=dict(cls=cls.__name__),
156-
)
138+
if warn:
139+
warnings.warn(message)
157140
else:
158141
# Restrict to non-string type i.e. not a
159142
# CFLabelVariable.
@@ -170,11 +153,8 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
170153
f"auxiliary coordinate - is a "
171154
f"CF-netCDF label variable."
172155
)
173-
logger.log(
174-
level=log_level,
175-
msg=message,
176-
extra=dict(cls=cls.__name__),
177-
)
156+
if warn:
157+
warnings.warn(message)
178158

179159
return result
180160

@@ -205,8 +185,6 @@ class CFUGridMeshVariable(cf.CFVariable):
205185
def identify(cls, variables, ignore=None, target=None, warn=True):
206186
result = {}
207187
ignore, target = cls._identify_common(variables, ignore, target)
208-
# TODO: reconsider logging level when we have consistent practice.
209-
log_level = logging.WARNING if warn else logging.DEBUG
210188

211189
# Identify all CF-UGRID mesh variables.
212190
all_vars = target == variables
@@ -232,11 +210,8 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
232210
f"Missing CF-UGRID mesh variable {name}, "
233211
f"referenced by netCDF variable {nc_var_name}"
234212
)
235-
logger.log(
236-
level=log_level,
237-
msg=message,
238-
extra=dict(cls=cls.__name__),
239-
)
213+
if warn:
214+
warnings.warn(message)
240215
else:
241216
# Restrict to non-string type i.e. not a
242217
# CFLabelVariable.
@@ -250,11 +225,8 @@ def identify(cls, variables, ignore=None, target=None, warn=True):
250225
f"CF-UGRID mesh - is a CF-netCDF label "
251226
f"variable."
252227
)
253-
logger.log(
254-
level=log_level,
255-
msg=message,
256-
extra=dict(cls=cls.__name__),
257-
)
228+
if warn:
229+
warnings.warn(message)
258230

259231
return result
260232

lib/iris/experimental/ugrid/load.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from itertools import groupby
1616
from pathlib import Path
1717
import threading
18+
import warnings
1819

1920
from ...config import get_logger
2021
from ...coords import AuxCoord
@@ -350,8 +351,7 @@ def _build_mesh(cf, mesh_var, file_path):
350351
)
351352
if cf_role_message:
352353
cf_role_message += " Correcting to 'mesh_topology'."
353-
# TODO: reconsider logging level when we have consistent practice.
354-
logger.warning(cf_role_message, extra=dict(cls=None))
354+
warnings.warn(cf_role_message)
355355

356356
if hasattr(mesh_var, "volume_node_connectivity"):
357357
topology_dimension = 3
@@ -369,8 +369,7 @@ def _build_mesh(cf, mesh_var, file_path):
369369
f" : *Assuming* topology_dimension={topology_dimension}"
370370
", consistent with the attached connectivities."
371371
)
372-
# TODO: reconsider logging level when we have consistent practice.
373-
logger.warning(msg, extra=dict(cls=None))
372+
warnings.warn(msg)
374373
else:
375374
quoted_topology_dimension = mesh_var.topology_dimension
376375
if quoted_topology_dimension != topology_dimension:
@@ -382,8 +381,7 @@ def _build_mesh(cf, mesh_var, file_path):
382381
f"{quoted_topology_dimension}"
383382
" -- ignoring this as it is inconsistent."
384383
)
385-
# TODO: reconsider logging level when we have consistent practice.
386-
logger.warning(msg=msg, extra=dict(cls=None))
384+
warnings.warn(msg)
387385

388386
node_dimension = None
389387
edge_dimension = getattr(mesh_var, "edge_dimension", None)

lib/iris/tests/integration/experimental/test_ugrid_load.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616

1717
from collections.abc import Iterable
1818

19+
import pytest
20+
1921
from iris import Constraint, load
20-
from iris.experimental.ugrid import logger
2122
from iris.experimental.ugrid.load import (
2223
PARSE_UGRID_ON_LOAD,
2324
load_mesh,
@@ -168,8 +169,8 @@ def create_synthetic_file(self, **create_kwargs):
168169

169170
def test_mesh_bad_topology_dimension(self):
170171
# Check that the load generates a suitable warning.
171-
log_regex = r"topology_dimension.* ignoring"
172-
with self.assertLogs(logger, level="WARNING", msg_regex=log_regex):
172+
warn_regex = r"topology_dimension.* ignoring"
173+
with pytest.warns(UserWarning, match=warn_regex):
173174
template = "minimal_bad_topology_dim"
174175
dim_line = "mesh_var:topology_dimension = 1 ;" # which is wrong !
175176
cube = self.create_synthetic_test_cube(
@@ -181,8 +182,8 @@ def test_mesh_bad_topology_dimension(self):
181182

182183
def test_mesh_no_topology_dimension(self):
183184
# Check that the load generates a suitable warning.
184-
log_regex = r"Mesh variable.* has no 'topology_dimension'"
185-
with self.assertLogs(logger, level="WARNING", msg_regex=log_regex):
185+
warn_regex = r"Mesh variable.* has no 'topology_dimension'"
186+
with pytest.warns(UserWarning, match=warn_regex):
186187
template = "minimal_bad_topology_dim"
187188
dim_line = "" # don't create ANY topology_dimension property
188189
cube = self.create_synthetic_test_cube(
@@ -194,8 +195,8 @@ def test_mesh_no_topology_dimension(self):
194195

195196
def test_mesh_bad_cf_role(self):
196197
# Check that the load generates a suitable warning.
197-
log_regex = r"inappropriate cf_role"
198-
with self.assertLogs(logger, level="WARNING", msg_regex=log_regex):
198+
warn_regex = r"inappropriate cf_role"
199+
with pytest.warns(UserWarning, match=warn_regex):
199200
template = "minimal_bad_mesh_cf_role"
200201
dim_line = 'mesh_var:cf_role = "foo" ;'
201202
_ = self.create_synthetic_test_cube(
@@ -204,8 +205,8 @@ def test_mesh_bad_cf_role(self):
204205

205206
def test_mesh_no_cf_role(self):
206207
# Check that the load generates a suitable warning.
207-
log_regex = r"no cf_role attribute"
208-
with self.assertLogs(logger, level="WARNING", msg_regex=log_regex):
208+
warn_regex = r"no cf_role attribute"
209+
with pytest.warns(UserWarning, match=warn_regex):
209210
template = "minimal_bad_mesh_cf_role"
210211
dim_line = ""
211212
_ = self.create_synthetic_test_cube(

lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridAuxiliaryCoordinateVariable.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
# importing anything else.
1515
import iris.tests as tests # isort:skip
1616

17+
import re
18+
import warnings
19+
1720
import numpy as np
21+
import pytest
1822

19-
from iris.experimental.ugrid.cf import (
20-
CFUGridAuxiliaryCoordinateVariable,
21-
logger,
22-
)
23+
from iris.experimental.ugrid.cf import CFUGridAuxiliaryCoordinateVariable
2324
from iris.tests.unit.experimental.ugrid.cf.test_CFUGridReader import (
2425
netcdf_ugrid_variable,
2526
)
@@ -213,26 +214,30 @@ def test_warn(self):
213214
"ref_source": ref_source,
214215
}
215216

216-
# The warn kwarg and expected corresponding log level.
217-
warn_and_level = {True: "WARNING", False: "DEBUG"}
217+
def operation(warn: bool):
218+
warnings.warn("emit at least 1 warning")
219+
result = CFUGridAuxiliaryCoordinateVariable.identify(
220+
vars_all, warn=warn
221+
)
222+
self.assertDictEqual({}, result)
218223

219224
# Missing warning.
220-
log_regex = rf"Missing CF-netCDF auxiliary coordinate variable {subject_name}.*"
221-
for warn, level in warn_and_level.items():
222-
with self.assertLogs(logger, level=level, msg_regex=log_regex):
223-
result = CFUGridAuxiliaryCoordinateVariable.identify(
224-
vars_all, warn=warn
225-
)
226-
self.assertDictEqual({}, result)
225+
warn_regex = rf"Missing CF-netCDF auxiliary coordinate variable {subject_name}.*"
226+
with pytest.warns(UserWarning, match=warn_regex):
227+
operation(warn=True)
228+
with pytest.warns() as record:
229+
operation(warn=False)
230+
warn_list = [str(w.message) for w in record]
231+
assert list(filter(re.compile(warn_regex).match, warn_list)) == []
227232

228233
# String variable warning.
229-
log_regex = r".*is a CF-netCDF label variable.*"
230-
for warn, level in warn_and_level.items():
231-
with self.assertLogs(logger, level=level, msg_regex=log_regex):
232-
vars_all[subject_name] = netcdf_ugrid_variable(
233-
subject_name, "", np.bytes_
234-
)
235-
result = CFUGridAuxiliaryCoordinateVariable.identify(
236-
vars_all, warn=warn
237-
)
238-
self.assertDictEqual({}, result)
234+
warn_regex = r".*is a CF-netCDF label variable.*"
235+
vars_all[subject_name] = netcdf_ugrid_variable(
236+
subject_name, "", np.bytes_
237+
)
238+
with pytest.warns(UserWarning, match=warn_regex):
239+
operation(warn=True)
240+
with pytest.warns() as record:
241+
operation(warn=False)
242+
warn_list = [str(w.message) for w in record]
243+
assert list(filter(re.compile(warn_regex).match, warn_list)) == []

lib/iris/tests/unit/experimental/ugrid/cf/test_CFUGridConnectivityVariable.py

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414
# importing anything else.
1515
import iris.tests as tests # isort:skip
1616

17+
import re
18+
import warnings
19+
1720
import numpy as np
21+
import pytest
1822

19-
from iris.experimental.ugrid.cf import CFUGridConnectivityVariable, logger
23+
from iris.experimental.ugrid.cf import CFUGridConnectivityVariable
2024
from iris.experimental.ugrid.mesh import Connectivity
2125
from iris.tests.unit.experimental.ugrid.cf.test_CFUGridReader import (
2226
netcdf_ugrid_variable,
@@ -199,26 +203,30 @@ def test_warn(self):
199203
"ref_source": ref_source,
200204
}
201205

202-
# The warn kwarg and expected corresponding log level.
203-
warn_and_level = {True: "WARNING", False: "DEBUG"}
206+
def operation(warn: bool):
207+
warnings.warn("emit at least 1 warning")
208+
result = CFUGridConnectivityVariable.identify(vars_all, warn=warn)
209+
self.assertDictEqual({}, result)
204210

205211
# Missing warning.
206-
log_regex = rf"Missing CF-UGRID connectivity variable {subject_name}.*"
207-
for warn, level in warn_and_level.items():
208-
with self.assertLogs(logger, level=level, msg_regex=log_regex):
209-
result = CFUGridConnectivityVariable.identify(
210-
vars_all, warn=warn
211-
)
212-
self.assertDictEqual({}, result)
212+
warn_regex = (
213+
rf"Missing CF-UGRID connectivity variable {subject_name}.*"
214+
)
215+
with pytest.warns(UserWarning, match=warn_regex):
216+
operation(warn=True)
217+
with pytest.warns() as record:
218+
operation(warn=False)
219+
warn_list = [str(w.message) for w in record]
220+
assert list(filter(re.compile(warn_regex).match, warn_list)) == []
213221

214222
# String variable warning.
215-
log_regex = r".*is a CF-netCDF label variable.*"
216-
for warn, level in warn_and_level.items():
217-
with self.assertLogs(logger, level=level, msg_regex=log_regex):
218-
vars_all[subject_name] = netcdf_ugrid_variable(
219-
subject_name, "", np.bytes_
220-
)
221-
result = CFUGridConnectivityVariable.identify(
222-
vars_all, warn=warn
223-
)
224-
self.assertDictEqual({}, result)
223+
warn_regex = r".*is a CF-netCDF label variable.*"
224+
vars_all[subject_name] = netcdf_ugrid_variable(
225+
subject_name, "", np.bytes_
226+
)
227+
with pytest.warns(UserWarning, match=warn_regex):
228+
operation(warn=True)
229+
with pytest.warns() as record:
230+
operation(warn=False)
231+
warn_list = [str(w.message) for w in record]
232+
assert list(filter(re.compile(warn_regex).match, warn_list)) == []

0 commit comments

Comments
 (0)