diff --git a/.travis.yml b/.travis.yml index 28393a0b7..7882c300e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,9 @@ jobs: - env: TOXENV=py36-freeze python: '3.6' - env: TOXENV=py37 - python: 'nightly' + python: 3.7 + sudo: required + dist: xenial - stage: deploy python: '3.6' diff --git a/appveyor.yml b/appveyor.yml index 54cd6c921..40a171021 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ environment: - TOXENV: "py34" - TOXENV: "py35" - TOXENV: "py36" + - TOXENV: "py37" # - TOXENV: "pypy" reenable when we are able to provide a scandir wheel or build scandir - TOXENV: "py27-pexpect" - TOXENV: "py27-xdist" diff --git a/changelog/3295.doc.rst b/changelog/3295.doc.rst new file mode 100644 index 000000000..c4e351efb --- /dev/null +++ b/changelog/3295.doc.rst @@ -0,0 +1 @@ +Correct the usage documentation of ``--last-failed-no-failures`` by adding the missing ``--last-failed`` argument in the presented examples, for they are missleading and lead to think that the missing argument is not needed. diff --git a/changelog/3695.bugfix.rst b/changelog/3695.bugfix.rst new file mode 100644 index 000000000..42d07336b --- /dev/null +++ b/changelog/3695.bugfix.rst @@ -0,0 +1,2 @@ +Fix ``ApproxNumpy`` initialisation argument mixup, ``abs`` and ``rel`` tolerances were flipped causing strange comparsion results. +Add tests to check ``abs`` and ``rel`` tolerances for ``np.array`` and test for expecting ``nan`` with ``np.array()`` diff --git a/doc/en/cache.rst b/doc/en/cache.rst index 37bcf7070..08f204655 100644 --- a/doc/en/cache.rst +++ b/doc/en/cache.rst @@ -162,8 +162,8 @@ When no tests failed in the last run, or when no cached ``lastfailed`` data was found, ``pytest`` can be configured either to run all of the tests or no tests, using the ``--last-failed-no-failures`` option, which takes one of the following values:: - pytest --last-failed-no-failures all # run all tests (default behavior) - pytest --last-failed-no-failures none # run no tests and exit + pytest --last-failed --last-failed-no-failures all # run all tests (default behavior) + pytest --last-failed --last-failed-no-failures none # run no tests and exit The new config.cache object -------------------------------- diff --git a/src/_pytest/python_api.py b/src/_pytest/python_api.py index d88d1c88b..5331d8a84 100644 --- a/src/_pytest/python_api.py +++ b/src/_pytest/python_api.py @@ -211,7 +211,7 @@ class ApproxScalar(ApproxBase): the pre-specified tolerance. """ if _is_numpy_array(actual): - return ApproxNumpy(actual, self.abs, self.rel, self.nan_ok) == self.expected + return all(a == self for a in actual.flat) # Short-circuit exact equality. if actual == self.expected: diff --git a/testing/python/approx.py b/testing/python/approx.py index 39f10a821..0509fa672 100644 --- a/testing/python/approx.py +++ b/testing/python/approx.py @@ -342,6 +342,68 @@ class TestApprox(object): assert actual == approx(list(expected), rel=5e-7, abs=0) assert actual != approx(list(expected), rel=5e-8, abs=0) + def test_numpy_tolerance_args(self): + """ + Check that numpy rel/abs args are handled correctly + for comparison against an np.array + Check both sides of the operator, hopefully it doesn't impact things. + Test all permutations of where the approx and np.array() can show up + """ + np = pytest.importorskip("numpy") + expected = 100. + actual = 99. + abs_diff = expected - actual + rel_diff = (expected - actual) / expected + + tests = [ + (eq, abs_diff, 0), + (eq, 0, rel_diff), + (ne, 0, rel_diff / 2.), # rel diff fail + (ne, abs_diff / 2., 0), # abs diff fail + ] + + for op, _abs, _rel in tests: + assert op(np.array(actual), approx(expected, abs=_abs, rel=_rel)) # a, b + assert op(approx(expected, abs=_abs, rel=_rel), np.array(actual)) # b, a + + assert op(actual, approx(np.array(expected), abs=_abs, rel=_rel)) # a, b + assert op(approx(np.array(expected), abs=_abs, rel=_rel), actual) # b, a + + assert op(np.array(actual), approx(np.array(expected), abs=_abs, rel=_rel)) + assert op(approx(np.array(expected), abs=_abs, rel=_rel), np.array(actual)) + + def test_numpy_expecting_nan(self): + np = pytest.importorskip("numpy") + examples = [ + (eq, nan, nan), + (eq, -nan, -nan), + (eq, nan, -nan), + (ne, 0.0, nan), + (ne, inf, nan), + ] + for op, a, x in examples: + # Nothing is equal to NaN by default. + assert np.array(a) != approx(x) + assert a != approx(np.array(x)) + + # If ``nan_ok=True``, then NaN is equal to NaN. + assert op(np.array(a), approx(x, nan_ok=True)) + assert op(a, approx(np.array(x), nan_ok=True)) + + def test_numpy_expecting_inf(self): + np = pytest.importorskip("numpy") + examples = [ + (eq, inf, inf), + (eq, -inf, -inf), + (ne, inf, -inf), + (ne, 0.0, inf), + (ne, nan, inf), + ] + for op, a, x in examples: + assert op(np.array(a), approx(x)) + assert op(a, approx(np.array(x))) + assert op(np.array(a), approx(np.array(x))) + def test_numpy_array_wrong_shape(self): np = pytest.importorskip("numpy")