Skip to content

Commit fb63268

Browse files
committed
Fix test_categorised_warnings() by using ast module.
1 parent f4e6a35 commit fb63268

File tree

1 file changed

+36
-31
lines changed

1 file changed

+36
-31
lines changed

lib/iris/tests/test_coding_standards.py

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
# importing anything else
99
import iris.tests as tests # isort:skip
1010

11+
import ast
1112
from datetime import datetime
1213
from fnmatch import fnmatch
1314
from glob import glob
1415
import os
1516
from pathlib import Path
16-
import re
1717
import subprocess
18-
from typing import List, NamedTuple, Tuple
18+
from typing import List, Tuple
1919

2020
import iris
2121
from iris.fileformats.netcdf import _thread_safe_nc
@@ -145,40 +145,45 @@ def test_categorised_warnings():
145145
Use :func:`~iris.exceptions.warning_combo` .
146146
147147
"""
148-
warn_regex = re.compile(r"(?s)warn\(.*?\)")
149-
150-
class ResultTuple(NamedTuple):
151-
file_path: Path
152-
line_number: int
153-
match_string: str
154-
155-
warns_without_category: list[ResultTuple] = []
156-
warns_with_user_warning: list[ResultTuple] = []
148+
warns_without_category = []
149+
warns_with_user_warning = []
150+
tmp_list = []
157151

158152
for file_path in Path(IRIS_DIR).rglob("*.py"):
159153
file_text = file_path.read_text()
154+
parsed = ast.parse(source=file_text)
155+
calls = filter(lambda node: hasattr(node, "func"), ast.walk(parsed))
156+
warn_calls = filter(
157+
lambda c: getattr(c.func, "attr", None) == "warn", calls
158+
)
160159

161-
matched = warn_regex.search(file_text)
162-
while matched:
163-
start, end = matched.span()
164-
result_tuple = ResultTuple(
165-
file_path=file_path,
166-
line_number=file_text[:start].count("\n") + 1,
167-
match_string=file_text[start:end],
168-
)
169-
if not re.search(r"category=", result_tuple.match_string):
170-
warns_without_category.append(result_tuple)
171-
if re.search(r"\bUserWarning\b", result_tuple.match_string):
172-
warns_with_user_warning.append(result_tuple)
173-
174-
matched = warn_regex.search(file_text, start + 1)
175-
176-
# All warnings raised by Iris must be raised with a category kwarg.
177-
# (This avoids UserWarnings being raised by unwritten default behaviour).
178-
assert warns_without_category == []
160+
warn_call: ast.Call
161+
for warn_call in warn_calls:
162+
warn_ref = f"{file_path}:{warn_call.lineno}"
163+
tmp_list.append(warn_ref)
179164

180-
# No warnings raised by Iris can be the base UserWarning class.
181-
assert warns_with_user_warning == []
165+
category_kwargs = filter(
166+
lambda k: k.arg == "category", warn_call.keywords
167+
)
168+
category_kwarg: ast.keyword = next(category_kwargs, None)
169+
170+
if category_kwarg is None:
171+
warns_without_category.append(warn_ref)
172+
# Work with Attribute or Name instances.
173+
elif (
174+
getattr(category_kwarg.value, "attr", None)
175+
or getattr(category_kwarg.value, "id", None)
176+
) == "UserWarning":
177+
warns_with_user_warning.append(warn_ref)
178+
179+
# This avoids UserWarnings being raised by unwritten default behaviour.
180+
assert (
181+
warns_without_category == []
182+
), "All warnings raised by Iris must be raised with the category kwarg."
183+
184+
assert (
185+
warns_with_user_warning == []
186+
), "No warnings raised by Iris can be the base UserWarning class."
182187

183188

184189
class TestLicenseHeaders(tests.IrisTest):

0 commit comments

Comments
 (0)