Skip to content

Commit 150535b

Browse files
authored
Merge pull request #3696 from abrammer/approx_numpy_tolerance_bugfix
bugfix in ApproxNumpy initialisation, use keywords for arguments to fix
2 parents f1ec02c + 535fd1f commit 150535b

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

changelog/3695.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix ``ApproxNumpy`` initialisation argument mixup, ``abs`` and ``rel`` tolerances were flipped causing strange comparsion results.
2+
Add tests to check ``abs`` and ``rel`` tolerances for ``np.array`` and test for expecting ``nan`` with ``np.array()``

src/_pytest/python_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def __eq__(self, actual):
211211
the pre-specified tolerance.
212212
"""
213213
if _is_numpy_array(actual):
214-
return ApproxNumpy(actual, self.abs, self.rel, self.nan_ok) == self.expected
214+
return all(a == self for a in actual.flat)
215215

216216
# Short-circuit exact equality.
217217
if actual == self.expected:

testing/python/approx.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,68 @@ def test_numpy_array(self):
342342
assert actual == approx(list(expected), rel=5e-7, abs=0)
343343
assert actual != approx(list(expected), rel=5e-8, abs=0)
344344

345+
def test_numpy_tolerance_args(self):
346+
"""
347+
Check that numpy rel/abs args are handled correctly
348+
for comparison against an np.array
349+
Check both sides of the operator, hopefully it doesn't impact things.
350+
Test all permutations of where the approx and np.array() can show up
351+
"""
352+
np = pytest.importorskip("numpy")
353+
expected = 100.
354+
actual = 99.
355+
abs_diff = expected - actual
356+
rel_diff = (expected - actual) / expected
357+
358+
tests = [
359+
(eq, abs_diff, 0),
360+
(eq, 0, rel_diff),
361+
(ne, 0, rel_diff / 2.), # rel diff fail
362+
(ne, abs_diff / 2., 0), # abs diff fail
363+
]
364+
365+
for op, _abs, _rel in tests:
366+
assert op(np.array(actual), approx(expected, abs=_abs, rel=_rel)) # a, b
367+
assert op(approx(expected, abs=_abs, rel=_rel), np.array(actual)) # b, a
368+
369+
assert op(actual, approx(np.array(expected), abs=_abs, rel=_rel)) # a, b
370+
assert op(approx(np.array(expected), abs=_abs, rel=_rel), actual) # b, a
371+
372+
assert op(np.array(actual), approx(np.array(expected), abs=_abs, rel=_rel))
373+
assert op(approx(np.array(expected), abs=_abs, rel=_rel), np.array(actual))
374+
375+
def test_numpy_expecting_nan(self):
376+
np = pytest.importorskip("numpy")
377+
examples = [
378+
(eq, nan, nan),
379+
(eq, -nan, -nan),
380+
(eq, nan, -nan),
381+
(ne, 0.0, nan),
382+
(ne, inf, nan),
383+
]
384+
for op, a, x in examples:
385+
# Nothing is equal to NaN by default.
386+
assert np.array(a) != approx(x)
387+
assert a != approx(np.array(x))
388+
389+
# If ``nan_ok=True``, then NaN is equal to NaN.
390+
assert op(np.array(a), approx(x, nan_ok=True))
391+
assert op(a, approx(np.array(x), nan_ok=True))
392+
393+
def test_numpy_expecting_inf(self):
394+
np = pytest.importorskip("numpy")
395+
examples = [
396+
(eq, inf, inf),
397+
(eq, -inf, -inf),
398+
(ne, inf, -inf),
399+
(ne, 0.0, inf),
400+
(ne, nan, inf),
401+
]
402+
for op, a, x in examples:
403+
assert op(np.array(a), approx(x))
404+
assert op(a, approx(np.array(x)))
405+
assert op(np.array(a), approx(np.array(x)))
406+
345407
def test_numpy_array_wrong_shape(self):
346408
np = pytest.importorskip("numpy")
347409

0 commit comments

Comments
 (0)