Skip to content

Commit 45c3618

Browse files
authored
ensure warnings cannot become errors in assert_ (#4864)
* ensure warnings cannot become errors in assert_ * also assert_duckarray_allclose * add whats new * ensure warnings are raised * Update doc/whats-new.rst * use a decorator
1 parent 4e97b33 commit 45c3618

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ Internal Changes
130130
in ipython (:issue:`4741`, :pull:`4742`). By `Richard Kleijn <https://github.com/rhkleijn>`_.
131131
- Added the ``set_close`` method to ``Dataset`` and ``DataArray`` for beckends to specify how to voluntary release
132132
all resources. (:pull:`#4809`), By `Alessandro Amici <https://github.com/alexamici>`_.
133+
- Ensure warnings cannot be turned into exceptions in :py:func:`testing.assert_equal` and
134+
the other ``assert_*`` functions (:pull:`4864`). By `Mathias Hauser <https://github.com/mathause>`_.
133135

134136
.. _whats-new.0.16.2:
135137

@@ -146,7 +148,7 @@ Deprecations
146148

147149
- :py:attr:`~core.accessor_dt.DatetimeAccessor.weekofyear` and :py:attr:`~core.accessor_dt.DatetimeAccessor.week`
148150
have been deprecated. Use ``DataArray.dt.isocalendar().week``
149-
instead (:pull:`4534`). By `Mathias Hauser <https://github.com/mathause>`_,
151+
instead (:pull:`4534`). By `Mathias Hauser <https://github.com/mathause>`_.
150152
`Maximilian Roos <https://github.com/max-sixty>`_, and `Spencer Clark <https://github.com/spencerkclark>`_.
151153
- :py:attr:`DataArray.rolling` and :py:attr:`Dataset.rolling` no longer support passing ``keep_attrs``
152154
via its constructor. Pass ``keep_attrs`` via the applied function, i.e. use

xarray/testing.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Testing functions exposed to the user API"""
22
import functools
3+
import warnings
34
from typing import Hashable, Set, Union
45

56
import numpy as np
@@ -21,6 +22,19 @@
2122
)
2223

2324

25+
def ensure_warnings(func):
26+
# sometimes tests elevate warnings to errors
27+
# -> make sure that does not happen in the assert_* functions
28+
@functools.wraps(func)
29+
def wrapper(*args, **kwargs):
30+
with warnings.catch_warnings():
31+
warnings.simplefilter("always")
32+
33+
return func(*args, **kwargs)
34+
35+
return wrapper
36+
37+
2438
def _decode_string_data(data):
2539
if data.dtype.kind == "S":
2640
return np.core.defchararray.decode(data, "utf-8", "replace")
@@ -38,6 +52,7 @@ def _data_allclose_or_equiv(arr1, arr2, rtol=1e-05, atol=1e-08, decode_bytes=Tru
3852
return duck_array_ops.allclose_or_equiv(arr1, arr2, rtol=rtol, atol=atol)
3953

4054

55+
@ensure_warnings
4156
def assert_equal(a, b):
4257
"""Like :py:func:`numpy.testing.assert_array_equal`, but for xarray
4358
objects.
@@ -69,6 +84,7 @@ def assert_equal(a, b):
6984
raise TypeError("{} not supported by assertion comparison".format(type(a)))
7085

7186

87+
@ensure_warnings
7288
def assert_identical(a, b):
7389
"""Like :py:func:`xarray.testing.assert_equal`, but also matches the
7490
objects' names and attributes.
@@ -99,6 +115,7 @@ def assert_identical(a, b):
99115
raise TypeError("{} not supported by assertion comparison".format(type(a)))
100116

101117

118+
@ensure_warnings
102119
def assert_allclose(a, b, rtol=1e-05, atol=1e-08, decode_bytes=True):
103120
"""Like :py:func:`numpy.testing.assert_allclose`, but for xarray objects.
104121
@@ -182,6 +199,7 @@ def _format_message(x, y, err_msg, verbose):
182199
return "\n".join(parts)
183200

184201

202+
@ensure_warnings
185203
def assert_duckarray_allclose(
186204
actual, desired, rtol=1e-07, atol=0, err_msg="", verbose=True
187205
):
@@ -192,6 +210,7 @@ def assert_duckarray_allclose(
192210
assert allclose, _format_message(actual, desired, err_msg=err_msg, verbose=verbose)
193211

194212

213+
@ensure_warnings
195214
def assert_duckarray_equal(x, y, err_msg="", verbose=True):
196215
""" Like `np.testing.assert_array_equal`, but for duckarrays """
197216
__tracebackhide__ = True

xarray/tests/test_testing.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import warnings
2+
13
import numpy as np
24
import pytest
35

@@ -127,3 +129,41 @@ def test_assert_duckarray_equal(duckarray, obj1, obj2):
127129
b = duckarray(obj2)
128130

129131
xr.testing.assert_duckarray_equal(a, b)
132+
133+
134+
@pytest.mark.parametrize(
135+
"func",
136+
[
137+
"assert_equal",
138+
"assert_identical",
139+
"assert_allclose",
140+
"assert_duckarray_equal",
141+
"assert_duckarray_allclose",
142+
],
143+
)
144+
def test_ensure_warnings_not_elevated(func):
145+
# make sure warnings are not elevated to errors in the assertion functions
146+
# e.g. by @pytest.mark.filterwarnings("error")
147+
# see https://github.com/pydata/xarray/pull/4760#issuecomment-774101639
148+
149+
# define a custom Variable class that raises a warning in assert_*
150+
class WarningVariable(xr.Variable):
151+
@property # type: ignore
152+
def dims(self):
153+
warnings.warn("warning in test")
154+
return super().dims
155+
156+
def __array__(self):
157+
warnings.warn("warning in test")
158+
return super().__array__()
159+
160+
a = WarningVariable("x", [1])
161+
b = WarningVariable("x", [2])
162+
163+
with warnings.catch_warnings(record=True) as w:
164+
# elevate warnings to errors
165+
warnings.filterwarnings("error")
166+
with pytest.raises(AssertionError):
167+
getattr(xr.testing, func)(a, b)
168+
169+
assert len(w) > 0

0 commit comments

Comments
 (0)