From 73151451437fa6ce0d8b5f033c1e005885f63cf8 Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Mon, 22 Oct 2018 17:40:08 -0700 Subject: ENH: __array_function__ support for np.lib, part 2/2 (#12119) * ENH: __array_function__ support for np.lib, part 2 xref GH12028 np.lib.npyio through np.lib.ufunclike * Fix failures in numpy/core/tests/test_overrides.py * CLN: handle depreaction in dispatchers for np.lib.ufunclike * CLN: fewer dispatchers in lib.twodim_base * CLN: fewer dispatchers in lib.shape_base * CLN: more dispatcher consolidation * BUG: fix test failure * Use all method instead of function in assert_equal * DOC: indicate n is array_like in scimath.logn * MAINT: updates per review * MAINT: more conservative changes in assert_array_equal * MAINT: add back in comment * MAINT: casting tweaks in assert_array_equal * MAINT: fixes and tests for assert_array_equal on subclasses --- numpy/testing/_private/utils.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index a3832fcde..b37dac69d 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -19,7 +19,7 @@ from warnings import WarningMessage import pprint from numpy.core import( - float32, empty, arange, array_repr, ndarray, isnat, array) + bool_, float32, empty, arange, array_repr, ndarray, isnat, array) from numpy.lib.utils import deprecate if sys.version_info[0] >= 3: @@ -352,7 +352,7 @@ def assert_equal(actual, desired, err_msg='', verbose=True): # XXX: catch ValueError for subclasses of ndarray where iscomplex fail try: usecomplex = iscomplexobj(actual) or iscomplexobj(desired) - except ValueError: + except (ValueError, TypeError): usecomplex = False if usecomplex: @@ -705,15 +705,20 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, at the same locations. """ - # Both the != True comparison here and the cast to bool_ at the end are - # done to deal with `masked`, which cannot be compared usefully, and - # for which np.all yields masked. The use of the function np.all is - # for back compatibility with ndarray subclasses that changed the - # return values of the all method. We are not committed to supporting - # such subclasses, but some used to work. x_id = func(x) y_id = func(y) - if npall(x_id == y_id) != True: + # We include work-arounds here to handle three types of slightly + # pathological ndarray subclasses: + # (1) all() on `masked` array scalars can return masked arrays, so we + # use != True + # (2) __eq__ on some ndarray subclasses returns Python booleans + # instead of element-wise comparisons, so we cast to bool_() and + # use isinstance(..., bool) checks + # (3) subclasses with bare-bones __array_function__ implemenations may + # not implement np.all(), so favor using the .all() method + # We are not committed to supporting such subclasses, but it's nice to + # support them if possible. + if bool_(x_id == y_id).all() != True: msg = build_err_msg([x, y], err_msg + '\nx and y %s location mismatch:' % (hasval), verbose=verbose, header=header, @@ -721,9 +726,9 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, raise AssertionError(msg) # If there is a scalar, then here we know the array has the same # flag as it everywhere, so we should return the scalar flag. - if x_id.ndim == 0: + if isinstance(x_id, bool) or x_id.ndim == 0: return bool_(x_id) - elif y_id.ndim == 0: + elif isinstance(x_id, bool) or y_id.ndim == 0: return bool_(y_id) else: return y_id -- cgit v1.2.1 From be5ea7d92d542e7c7eb055c5831a79850f4bfbee Mon Sep 17 00:00:00 2001 From: "wtli@Dirac" Date: Mon, 22 Oct 2018 22:30:32 +0800 Subject: BUG: Fix misleading assert message in assert_almost_equal #12200 Fixes #12200 by making a copy of the matrix before NaN's are excluded. Add a test for it. --- numpy/testing/_private/utils.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index a3832fcde..24b32cf00 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -692,6 +692,9 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, x = array(x, copy=False, subok=True) y = array(y, copy=False, subok=True) + # original array for output formating + ox, oy = x, y + def isnumber(x): return x.dtype.char in '?bhilqpBHILQPefdgFDG' @@ -780,10 +783,10 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, # do not trigger a failure (np.ma.masked != True evaluates as # np.ma.masked, which is falsy). if cond != True: - match = 100-100.0*reduced.count(1)/len(reduced) - msg = build_err_msg([x, y], + mismatch = 100.0 * reduced.count(0) / ox.size + msg = build_err_msg([ox, oy], err_msg - + '\n(mismatch %s%%)' % (match,), + + '\n(mismatch %s%%)' % (mismatch,), verbose=verbose, header=header, names=('x', 'y'), precision=precision) raise AssertionError(msg) -- cgit v1.2.1 From 45cef38cda80868355a920b5e94211dcf662ea07 Mon Sep 17 00:00:00 2001 From: Roman Yurchak Date: Thu, 6 Dec 2018 20:05:08 +0100 Subject: MAINT: Review F401,F841,F842 flake8 errors (unused variables and imports) (#12448) * Review F401,F841,F842 flake8 errors (unused variables, imports) * Review comments * More tests in test_installed_npymath_ini * Review comments --- numpy/testing/_private/utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 20a7dfd0b..55306e499 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -19,7 +19,7 @@ from warnings import WarningMessage import pprint from numpy.core import( - bool_, float32, empty, arange, array_repr, ndarray, isnat, array) + float32, empty, arange, array_repr, ndarray, isnat, array) from numpy.lib.utils import deprecate if sys.version_info[0] >= 3: @@ -687,7 +687,6 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, equal_inf=True): __tracebackhide__ = True # Hide traceback for py.test from numpy.core import array, isnan, inf, bool_ - from numpy.core.fromnumeric import all as npall x = array(x, copy=False, subok=True) y = array(y, copy=False, subok=True) @@ -946,7 +945,7 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): """ __tracebackhide__ = True # Hide traceback for py.test - from numpy.core import around, number, float_, result_type, array + from numpy.core import number, float_, result_type, array from numpy.core.numerictypes import issubdtype from numpy.core.fromnumeric import any as npany -- cgit v1.2.1 From 250861059b106371cb232456eeccd6d9e97d8f00 Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Wed, 14 Nov 2018 11:36:59 -0800 Subject: TST, DOC: enable refguide_check * ported the refguide_check module from SciPy for usage in NumPy docstring execution/ verification; added the refguide_check run to Azure Mac OS CI * adjusted NumPy docstrings such that refguide_check passes --- numpy/testing/_private/utils.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 55306e499..4059f6ee6 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -521,7 +521,6 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True): ... : Arrays are not almost equal - (mismatch 50.0%) x: array([ 1. , 2.33333333]) y: array([ 1. , 2.33333334]) @@ -854,7 +853,6 @@ def assert_array_equal(x, y, err_msg='', verbose=True): : AssertionError: Arrays are not equal - (mismatch 50.0%) x: array([ 1. , 3.14159265, NaN]) y: array([ 1. , 3.14159265, NaN]) @@ -930,7 +928,6 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): : AssertionError: Arrays are not almost equal - (mismatch 50.0%) x: array([ 1. , 2.33333, NaN]) y: array([ 1. , 2.33339, NaN]) -- cgit v1.2.1 From a16fc9499eaa7cc9d7532f8a51725c6ed647cd1b Mon Sep 17 00:00:00 2001 From: Stephan Hoyer Date: Tue, 1 Jan 2019 22:50:29 -0800 Subject: ENH: add "max difference" messages to np.testing.assert_array_equal (#12591) Example behavior: >>> x = np.array([1, 2, 3]) >>> y = np.array([1, 2, 3.0001]) >>> np.testing.assert_allclose(x, y) AssertionError: Not equal to tolerance rtol=1e-07, atol=0 Mismatch: 33.3% Max absolute difference: 0.0001 Max relative difference: 3.33322223e-05 x: array([1, 2, 3]) y: array([1. , 2. , 3.0001]) Motivation: when writing numerical algorithms, I frequently find myself experimenting to pick the right value of `atol` and `rtol` for `np.testing.assert_allclose()`. If I make the tolerance too generous, I risk missing regressions in accuracy, so I usually try to pick the smallest values for which tests pass. This change immediately reveals appropriate values to use for these parameters, so I don't need to guess and check. --- numpy/testing/_private/utils.py | 203 ++++++++++++++++++++++++---------------- 1 file changed, 121 insertions(+), 82 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 4059f6ee6..1f7b516b3 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -318,8 +318,9 @@ def assert_equal(actual, desired, err_msg='', verbose=True): Examples -------- >>> np.testing.assert_equal([4,5], [4,6]) - ... - : + Traceback (most recent call last): + ... + AssertionError: Items are not equal: item=1 ACTUAL: 5 @@ -510,20 +511,24 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True): >>> import numpy.testing as npt >>> npt.assert_almost_equal(2.3333333333333, 2.33333334) >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10) - ... - : - Items are not equal: - ACTUAL: 2.3333333333333002 - DESIRED: 2.3333333399999998 + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 10 decimals + ACTUAL: 2.3333333333333 + DESIRED: 2.33333334 >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]), ... np.array([1.0,2.33333334]), decimal=9) - ... - : - Arrays are not almost equal - (mismatch 50.0%) - x: array([ 1. , 2.33333333]) - y: array([ 1. , 2.33333334]) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 9 decimals + Mismatch: 50% + Max absolute difference: 6.66669964e-09 + Max relative difference: 2.85715698e-09 + x: array([1. , 2.333333333]) + y: array([1. , 2.33333334]) """ __tracebackhide__ = True # Hide traceback for py.test @@ -625,14 +630,15 @@ def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True): -------- >>> np.testing.assert_approx_equal(0.12345677777777e-20, 0.1234567e-20) >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345671e-20, - significant=8) + ... significant=8) >>> np.testing.assert_approx_equal(0.12345670e-20, 0.12345672e-20, - significant=8) - ... - : + ... significant=8) + Traceback (most recent call last): + ... + AssertionError: Items are not equal to 8 significant digits: - ACTUAL: 1.234567e-021 - DESIRED: 1.2345672000000001e-021 + ACTUAL: 1.234567e-21 + DESIRED: 1.2345672e-21 the evaluated condition that raises the exception is @@ -659,10 +665,10 @@ def assert_approx_equal(actual,desired,significant=7,err_msg='',verbose=True): sc_actual = actual/scale except ZeroDivisionError: sc_actual = 0.0 - msg = build_err_msg([actual, desired], err_msg, - header='Items are not equal to %d significant digits:' % - significant, - verbose=verbose) + msg = build_err_msg( + [actual, desired], err_msg, + header='Items are not equal to %d significant digits:' % significant, + verbose=verbose) try: # If one of desired/actual is not finite, handle it specially here: # check that both are nan if any is a nan, and test for equality @@ -685,7 +691,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='', precision=6, equal_nan=True, equal_inf=True): __tracebackhide__ = True # Hide traceback for py.test - from numpy.core import array, isnan, inf, bool_ + from numpy.core import array, array2string, isnan, inf, bool_, errstate x = array(x, copy=False, subok=True) y = array(y, copy=False, subok=True) @@ -781,15 +787,31 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, reduced = val.ravel() cond = reduced.all() reduced = reduced.tolist() + # The below comparison is a hack to ensure that fully masked # results, for which val.ravel().all() returns np.ma.masked, # do not trigger a failure (np.ma.masked != True evaluates as # np.ma.masked, which is falsy). if cond != True: mismatch = 100.0 * reduced.count(0) / ox.size - msg = build_err_msg([ox, oy], - err_msg - + '\n(mismatch %s%%)' % (mismatch,), + remarks = ['Mismatch: {:.3g}%'.format(mismatch)] + + with errstate(invalid='ignore', divide='ignore'): + # ignore errors for non-numeric types + with contextlib.suppress(TypeError): + error = abs(x - y) + max_abs_error = error.max() + remarks.append('Max absolute difference: ' + + array2string(max_abs_error)) + + # note: this definition of relative error matches that one + # used by assert_allclose (found in np.isclose) + max_rel_error = (error / abs(y)).max() + remarks.append('Max relative difference: ' + + array2string(max_rel_error)) + + err_msg += '\n' + '\n'.join(remarks) + msg = build_err_msg([ox, oy], err_msg, verbose=verbose, header=header, names=('x', 'y'), precision=precision) raise AssertionError(msg) @@ -849,13 +871,15 @@ def assert_array_equal(x, y, err_msg='', verbose=True): >>> np.testing.assert_array_equal([1.0,np.pi,np.nan], ... [1, np.sqrt(np.pi)**2, np.nan]) - ... - : + Traceback (most recent call last): + ... AssertionError: Arrays are not equal - (mismatch 50.0%) - x: array([ 1. , 3.14159265, NaN]) - y: array([ 1. , 3.14159265, NaN]) + Mismatch: 33.3% + Max absolute difference: 4.4408921e-16 + Max relative difference: 1.41357986e-16 + x: array([1. , 3.141593, nan]) + y: array([1. , 3.141593, nan]) Use `assert_allclose` or one of the nulp (number of floating point values) functions for these cases instead: @@ -920,25 +944,29 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True): the first assert does not raise an exception >>> np.testing.assert_array_almost_equal([1.0,2.333,np.nan], - [1.0,2.333,np.nan]) + ... [1.0,2.333,np.nan]) >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan], ... [1.0,2.33339,np.nan], decimal=5) - ... - : + Traceback (most recent call last): + ... AssertionError: - Arrays are not almost equal - (mismatch 50.0%) - x: array([ 1. , 2.33333, NaN]) - y: array([ 1. , 2.33339, NaN]) + Arrays are not almost equal to 5 decimals + Mismatch: 33.3% + Max absolute difference: 6.e-05 + Max relative difference: 2.57136612e-05 + x: array([1. , 2.33333, nan]) + y: array([1. , 2.33339, nan]) >>> np.testing.assert_array_almost_equal([1.0,2.33333,np.nan], ... [1.0,2.33333, 5], decimal=5) - : - ValueError: - Arrays are not almost equal - x: array([ 1. , 2.33333, NaN]) - y: array([ 1. , 2.33333, 5. ]) + Traceback (most recent call last): + ... + AssertionError: + Arrays are not almost equal to 5 decimals + x and y nan location mismatch: + x: array([1. , 2.33333, nan]) + y: array([1. , 2.33333, 5. ]) """ __tracebackhide__ = True # Hide traceback for py.test @@ -1019,27 +1047,34 @@ def assert_array_less(x, y, err_msg='', verbose=True): -------- >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1.1, 2.0, np.nan]) >>> np.testing.assert_array_less([1.0, 1.0, np.nan], [1, 2.0, np.nan]) - ... - : + Traceback (most recent call last): + ... + AssertionError: Arrays are not less-ordered - (mismatch 50.0%) - x: array([ 1., 1., NaN]) - y: array([ 1., 2., NaN]) + Mismatch: 33.3% + Max absolute difference: 1. + Max relative difference: 0.5 + x: array([ 1., 1., nan]) + y: array([ 1., 2., nan]) >>> np.testing.assert_array_less([1.0, 4.0], 3) - ... - : + Traceback (most recent call last): + ... + AssertionError: Arrays are not less-ordered - (mismatch 50.0%) - x: array([ 1., 4.]) + Mismatch: 50% + Max absolute difference: 2. + Max relative difference: 0.66666667 + x: array([1., 4.]) y: array(3) >>> np.testing.assert_array_less([1.0, 2.0, 3.0], [4]) - ... - : + Traceback (most recent call last): + ... + AssertionError: Arrays are not less-ordered (shapes (3,), (1,) mismatch) - x: array([ 1., 2., 3.]) + x: array([1., 2., 3.]) y: array([4]) """ @@ -1144,7 +1179,7 @@ def rundocs(filename=None, raise_on_error=True): argument to the ``test()`` call. For example, to run all tests (including doctests) for `numpy.lib`: - >>> np.lib.test(doctests=True) #doctest: +SKIP + >>> np.lib.test(doctests=True) # doctest: +SKIP """ from numpy.compat import npy_load_module import doctest @@ -1326,7 +1361,7 @@ def decorate_methods(cls, decorator, testmatch=None): return -def measure(code_str,times=1,label=None): +def measure(code_str, times=1, label=None): """ Return elapsed time for executing code in the namespace of the caller. @@ -1353,9 +1388,9 @@ def measure(code_str,times=1,label=None): Examples -------- - >>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)', - ... times=times) - >>> print("Time for a single execution : ", etime / times, "s") + >>> times = 10 + >>> etime = np.testing.measure('for i in range(1000): np.sqrt(i**2)', times=times) + >>> print("Time for a single execution : ", etime / times, "s") # doctest: +SKIP Time for a single execution : 0.005 s """ @@ -1440,7 +1475,7 @@ def assert_allclose(actual, desired, rtol=1e-7, atol=0, equal_nan=True, -------- >>> x = [1e-5, 1e-3, 1e-1] >>> y = np.arccos(np.cos(x)) - >>> assert_allclose(x, y, rtol=1e-5, atol=0) + >>> np.testing.assert_allclose(x, y, rtol=1e-5, atol=0) """ __tracebackhide__ = True # Hide traceback for py.test @@ -1894,7 +1929,8 @@ class clear_and_catch_warnings(warnings.catch_warnings): Examples -------- >>> import warnings - >>> with clear_and_catch_warnings(modules=[np.core.fromnumeric]): + >>> with np.testing.clear_and_catch_warnings( + ... modules=[np.core.fromnumeric]): ... warnings.simplefilter('always') ... warnings.filterwarnings('ignore', module='np.core.fromnumeric') ... # do something that raises a warning but ignore those in @@ -1975,25 +2011,28 @@ class suppress_warnings(object): Examples -------- - >>> with suppress_warnings() as sup: - ... sup.filter(DeprecationWarning, "Some text") - ... sup.filter(module=np.ma.core) - ... log = sup.record(FutureWarning, "Does this occur?") - ... command_giving_warnings() - ... # The FutureWarning was given once, the filtered warnings were - ... # ignored. All other warnings abide outside settings (may be - ... # printed/error) - ... assert_(len(log) == 1) - ... assert_(len(sup.log) == 1) # also stored in log attribute - - Or as a decorator: - - >>> sup = suppress_warnings() - >>> sup.filter(module=np.ma.core) # module must match exact - >>> @sup - >>> def some_function(): - ... # do something which causes a warning in np.ma.core - ... pass + + With a context manager:: + + with np.testing.suppress_warnings() as sup: + sup.filter(DeprecationWarning, "Some text") + sup.filter(module=np.ma.core) + log = sup.record(FutureWarning, "Does this occur?") + command_giving_warnings() + # The FutureWarning was given once, the filtered warnings were + # ignored. All other warnings abide outside settings (may be + # printed/error) + assert_(len(log) == 1) + assert_(len(sup.log) == 1) # also stored in log attribute + + Or as a decorator:: + + sup = np.testing.suppress_warnings() + sup.filter(module=np.ma.core) # module must match exactly + @sup + def some_function(): + # do something which causes a warning in np.ma.core + pass """ def __init__(self, forwarding_rule="always"): self._entered = False -- cgit v1.2.1 From c09fadcc8220f4ac80f0dcc4d82d22f58ef2d6c1 Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 19 Dec 2018 09:25:12 +0200 Subject: DEV: add pypy3 to azure CI --- numpy/testing/_private/utils.py | 1 + 1 file changed, 1 insertion(+) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 1f7b516b3..3ace84415 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -2245,6 +2245,7 @@ def _assert_no_gc_cycles_context(name=None): # not meaningful to test if there is no refcounting if not HAS_REFCOUNT: + yield return assert_(gc.isenabled()) -- cgit v1.2.1 From a641ef245a9f8d320fac5cdea5632649db5fab4a Mon Sep 17 00:00:00 2001 From: mattip Date: Wed, 17 Apr 2019 11:33:54 +0300 Subject: MAINT: move gc.collect to function (from review) --- numpy/testing/_private/utils.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 3ace84415..24e26d65c 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -6,6 +6,7 @@ from __future__ import division, absolute_import, print_function import os import sys +import platform import re import gc import operator @@ -39,6 +40,7 @@ __all__ = [ 'SkipTest', 'KnownFailureException', 'temppath', 'tempdir', 'IS_PYPY', 'HAS_REFCOUNT', 'suppress_warnings', 'assert_array_compare', '_assert_valid_refcount', '_gen_alignment_data', 'assert_no_gc_cycles', + 'break_cycles', ] @@ -50,7 +52,7 @@ class KnownFailureException(Exception): KnownFailureTest = KnownFailureException # backwards compat verbose = 0 -IS_PYPY = '__pypy__' in sys.modules +IS_PYPY = platform.python_implementation() == 'PyPy' HAS_REFCOUNT = getattr(sys, 'getrefcount', None) is not None @@ -2324,3 +2326,19 @@ def assert_no_gc_cycles(*args, **kwargs): args = args[1:] with _assert_no_gc_cycles_context(name=func.__name__): func(*args, **kwargs) + +def break_cycles(): + """ + Break reference cycles by calling gc.collect + Objects can call other objects' methods (for instance, another object's + __del__) inside their own __del__. On PyPy, the interpreter only runs + between calls to gc.collect, so multiple calls are needed to completely + release all cycles. + """ + + gc.collect() + if IS_PYPY: + # interpreter runs now, to call deleted objects' __del__ methods + gc.collect() + # one more, just to make sure + gc.collect() -- cgit v1.2.1 From 5d248def4ebb0cbb96c4aebe0e2f17b9914119b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Werthm=C3=BCller?= Date: Fri, 26 Apr 2019 08:02:42 +0200 Subject: DOC: defaults in allclose not the same as in assert_allclose (#13395) * DOC: defaults in allclose not the same as in assert_allclose --- numpy/testing/_private/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 24e26d65c..c22348103 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -1441,9 +1441,9 @@ def assert_allclose(actual, desired, rtol=1e-7, atol=0, equal_nan=True, Raises an AssertionError if two objects are not equal up to desired tolerance. - The test is equivalent to ``allclose(actual, desired, rtol, atol)``. - It compares the difference between `actual` and `desired` to - ``atol + rtol * abs(desired)``. + The test is equivalent to ``allclose(actual, desired, rtol, atol)`` (note + that ``allclose`` has different default values). It compares the difference + between `actual` and `desired` to ``atol + rtol * abs(desired)``. .. versionadded:: 1.5.0 -- cgit v1.2.1 From a92417e20623690343c1839afb847ac32027873f Mon Sep 17 00:00:00 2001 From: Warren Weckesser Date: Sun, 5 May 2019 19:20:57 -0400 Subject: DOC: testing: Mention the handling of nan in the assert_equal docstring. --- numpy/testing/_private/utils.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index c22348103..b6ec768d3 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -301,6 +301,11 @@ def assert_equal(actual, desired, err_msg='', verbose=True): check that all elements of these objects are equal. An exception is raised at the first conflicting values. + This function handles NaN comparisons as if NaN was a "normal" number. + That is, no assertion is raised if both objects have NaNs in the same + positions. This is in contrast to the IEEE standard on NaNs, which says + that NaN compared to anything must return False. + Parameters ---------- actual : array_like @@ -328,6 +333,11 @@ def assert_equal(actual, desired, err_msg='', verbose=True): ACTUAL: 5 DESIRED: 6 + The following comparison does not raise an exception. There are NaNs + in the inputs, but they are in the same positions. + + >>> np.testing.assert_equal(np.array([1.0, 2.0, np.nan]), [1, 2, np.nan]) + """ __tracebackhide__ = True # Hide traceback for py.test if isinstance(desired, dict): -- cgit v1.2.1 From e6b68e55ab1cfa66ae046ccc949b557a94a7c366 Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Thu, 9 May 2019 16:56:16 -0400 Subject: MNT: implement assert_array_compare without converting array to python list. --- numpy/testing/_private/utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index c22348103..3953439f0 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -20,7 +20,8 @@ from warnings import WarningMessage import pprint from numpy.core import( - float32, empty, arange, array_repr, ndarray, isnat, array) + intp, float32, empty, arange, array_repr, ndarray, isnat, array, + logical_not) from numpy.lib.utils import deprecate if sys.version_info[0] >= 3: @@ -784,18 +785,18 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, if isinstance(val, bool): cond = val - reduced = [0] + reduced = array([0]) else: reduced = val.ravel() cond = reduced.all() - reduced = reduced.tolist() # The below comparison is a hack to ensure that fully masked # results, for which val.ravel().all() returns np.ma.masked, # do not trigger a failure (np.ma.masked != True evaluates as # np.ma.masked, which is falsy). if cond != True: - mismatch = 100.0 * reduced.count(0) / ox.size + logical_not(reduced, out=reduced) + mismatch = 100.0 * reduced.sum(dtype=intp) / ox.size remarks = ['Mismatch: {:.3g}%'.format(mismatch)] with errstate(invalid='ignore', divide='ignore'): -- cgit v1.2.1 From 8c3411a334d8a46b46d3148b96ecb4dfcd4e3c7b Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Sun, 12 May 2019 12:57:55 -0400 Subject: Fixup: address eric-wieser's comments --- numpy/testing/_private/utils.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 3953439f0..75685f7fd 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -20,8 +20,7 @@ from warnings import WarningMessage import pprint from numpy.core import( - intp, float32, empty, arange, array_repr, ndarray, isnat, array, - logical_not) + intp, float32, empty, arange, array_repr, ndarray, isnat, array) from numpy.lib.utils import deprecate if sys.version_info[0] >= 3: @@ -785,7 +784,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, if isinstance(val, bool): cond = val - reduced = array([0]) + reduced = array(val) else: reduced = val.ravel() cond = reduced.all() @@ -795,8 +794,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, # do not trigger a failure (np.ma.masked != True evaluates as # np.ma.masked, which is falsy). if cond != True: - logical_not(reduced, out=reduced) - mismatch = 100.0 * reduced.sum(dtype=intp) / ox.size + mismatch = 100. * (reduced.size - reduced.sum(dtype=intp)) / ox.size remarks = ['Mismatch: {:.3g}%'.format(mismatch)] with errstate(invalid='ignore', divide='ignore'): -- cgit v1.2.1 From 366f9b8fc3dbc92baf7c5ba82a44b3fdb72e863d Mon Sep 17 00:00:00 2001 From: Mark Harfouche Date: Sun, 12 May 2019 13:03:22 -0400 Subject: Ensure that reduced is a 1D array --- numpy/testing/_private/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 75685f7fd..0e739ae00 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -784,7 +784,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, if isinstance(val, bool): cond = val - reduced = array(val) + reduced = array([val]) else: reduced = val.ravel() cond = reduced.all() -- cgit v1.2.1 From 0d3d1b172b7f4c4775cd12138ec56edfac8a6dc2 Mon Sep 17 00:00:00 2001 From: mattip Date: Mon, 27 May 2019 20:17:52 +0300 Subject: BUG: special case object arrays when printing rel-, abs-error --- numpy/testing/_private/utils.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index ee8eac9e8..53181bc49 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -812,14 +812,22 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, with contextlib.suppress(TypeError): error = abs(x - y) max_abs_error = error.max() - remarks.append('Max absolute difference: ' - + array2string(max_abs_error)) + if error.dtype == 'object': + remarks.append('Max absolute difference: ' + + str(max_abs_error)) + else: + remarks.append('Max absolute difference: ' + + array2string(max_abs_error)) # note: this definition of relative error matches that one # used by assert_allclose (found in np.isclose) max_rel_error = (error / abs(y)).max() - remarks.append('Max relative difference: ' - + array2string(max_rel_error)) + if error.dtype == 'object': + remarks.append('Max relative difference: ' + + str(max_rel_error)) + else: + remarks.append('Max relative difference: ' + + array2string(max_rel_error)) err_msg += '\n' + '\n'.join(remarks) msg = build_err_msg([ox, oy], err_msg, -- cgit v1.2.1 From 0c70787c04d7b0febacb14edfe214cb68d87b6c3 Mon Sep 17 00:00:00 2001 From: luzpaz Date: Fri, 31 May 2019 03:13:33 -0400 Subject: MAINT: Misc. typo fixes (#13664) * DOC, MAINT: Misc. typo fixes Found via `codespell` --- numpy/testing/_private/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 53181bc49..ead5d264d 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -708,7 +708,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, x = array(x, copy=False, subok=True) y = array(y, copy=False, subok=True) - # original array for output formating + # original array for output formatting ox, oy = x, y def isnumber(x): @@ -733,7 +733,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, # (2) __eq__ on some ndarray subclasses returns Python booleans # instead of element-wise comparisons, so we cast to bool_() and # use isinstance(..., bool) checks - # (3) subclasses with bare-bones __array_function__ implemenations may + # (3) subclasses with bare-bones __array_function__ implementations may # not implement np.all(), so favor using the .all() method # We are not committed to supporting such subclasses, but it's nice to # support them if possible. -- cgit v1.2.1 From 94d6a3759d5b56b7c1c2ba4c327f891aedde2ebc Mon Sep 17 00:00:00 2001 From: MSeifert04 Date: Mon, 1 Jul 2019 21:19:51 +0200 Subject: MAINT: Replace integers in places where booleans are expected --- numpy/testing/_private/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index ead5d264d..87e66e06f 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -1145,7 +1145,7 @@ def assert_string_equal(actual, desired): if desired == actual: return - diff = list(difflib.Differ().compare(actual.splitlines(1), desired.splitlines(1))) + diff = list(difflib.Differ().compare(actual.splitlines(True), desired.splitlines(True))) diff_list = [] while diff: d1 = diff.pop(0) -- cgit v1.2.1 From 4b95b70eba7a721f1f4f4b7f7988ba06eda2bf89 Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Thu, 15 Aug 2019 11:00:04 +0200 Subject: ENH: Improve mismatch message of np.testing.assert_array_equal (#14203) The original message included "Mismatch: 33.3%". It's not obvious what this percentage means. This commit changes the text to "Mismatched elements: 1 / 3 (33.3%)". --- numpy/testing/_private/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 87e66e06f..7aa5ef033 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -804,8 +804,11 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, # do not trigger a failure (np.ma.masked != True evaluates as # np.ma.masked, which is falsy). if cond != True: - mismatch = 100. * (reduced.size - reduced.sum(dtype=intp)) / ox.size - remarks = ['Mismatch: {:.3g}%'.format(mismatch)] + n_mismatch = reduced.size - reduced.sum(dtype=intp) + percent_mismatch = 100 * n_mismatch / ox.size + remarks = [ + 'Mismatched elements: {} / {} ({:.3g}%)'.format( + n_mismatch, ox.size, percent_mismatch)] with errstate(invalid='ignore', divide='ignore'): # ignore errors for non-numeric types -- cgit v1.2.1 From 99b7afc519ff4708ed3b66f288125a404efced2e Mon Sep 17 00:00:00 2001 From: Maxwell Aladago Date: Thu, 22 Aug 2019 12:42:15 -0400 Subject: DEP: numpy.testing.rand (#14325) * Deprecation: numpy.testing.rand --- numpy/testing/_private/utils.py | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 7aa5ef033..97a5eac17 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -21,7 +21,6 @@ import pprint from numpy.core import( intp, float32, empty, arange, array_repr, ndarray, isnat, array) -from numpy.lib.utils import deprecate if sys.version_info[0] >= 3: from io import StringIO @@ -33,7 +32,7 @@ __all__ = [ 'assert_array_equal', 'assert_array_less', 'assert_string_equal', 'assert_array_almost_equal', 'assert_raises', 'build_err_msg', 'decorate_methods', 'jiffies', 'memusage', 'print_assert_equal', - 'raises', 'rand', 'rundocs', 'runstring', 'verbose', 'measure', + 'raises', 'rundocs', 'runstring', 'verbose', 'measure', 'assert_', 'assert_array_almost_equal_nulp', 'assert_raises_regex', 'assert_array_max_ulp', 'assert_warns', 'assert_no_warnings', 'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings', @@ -154,22 +153,6 @@ def gisinf(x): return st -@deprecate(message="numpy.testing.rand is deprecated in numpy 1.11. " - "Use numpy.random.rand instead.") -def rand(*args): - """Returns an array of random numbers with the given shape. - - This only uses the standard library, so it is useful for testing purposes. - """ - import random - from numpy.core import zeros, float64 - results = zeros(args, float64) - f = results.flat - for i in range(len(f)): - f[i] = random.random() - return results - - if os.name == 'nt': # Code "stolen" from enthought/debug/memusage.py def GetPerformanceAttributes(object, counter, instance=None, -- cgit v1.2.1 From 3dccd841476d26b5807156b904b55c04c6a3d370 Mon Sep 17 00:00:00 2001 From: CakeWithSteak <37267737+CakeWithSteak@users.noreply.github.com> Date: Thu, 5 Sep 2019 16:20:13 +0200 Subject: BUG: Fixed maximum relative error reporting in assert_allclose (gh-13802) Fixed maximum relative error reporting in assert_allclose: In cases where the two arrays have zeros at the same positions it will no longer report nan as the max relative error --- numpy/testing/_private/utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 97a5eac17..4ac0715bf 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -686,7 +686,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='', precision=6, equal_nan=True, equal_inf=True): __tracebackhide__ = True # Hide traceback for py.test - from numpy.core import array, array2string, isnan, inf, bool_, errstate + from numpy.core import array, array2string, isnan, inf, bool_, errstate, all x = array(x, copy=False, subok=True) y = array(y, copy=False, subok=True) @@ -807,7 +807,12 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, # note: this definition of relative error matches that one # used by assert_allclose (found in np.isclose) - max_rel_error = (error / abs(y)).max() + # Filter values where the divisor would be zero + nonzero = bool_(y != 0) + if all(~nonzero): + max_rel_error = array(inf) + else: + max_rel_error = (error[nonzero] / abs(y[nonzero])).max() if error.dtype == 'object': remarks.append('Max relative difference: ' + str(max_rel_error)) -- cgit v1.2.1 From 151802288ba4ffb2595ac3f6e07ee08b654863b6 Mon Sep 17 00:00:00 2001 From: Maxwell Aladago Date: Fri, 6 Sep 2019 14:39:42 -0400 Subject: assert_array_compare --- numpy/testing/_private/utils.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'numpy/testing/_private/utils.py') diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py index 4ac0715bf..8a31fcf15 100644 --- a/numpy/testing/_private/utils.py +++ b/numpy/testing/_private/utils.py @@ -686,7 +686,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='', precision=6, equal_nan=True, equal_inf=True): __tracebackhide__ = True # Hide traceback for py.test - from numpy.core import array, array2string, isnan, inf, bool_, errstate, all + from numpy.core import array, array2string, isnan, inf, bool_, errstate, all, max, object_ x = array(x, copy=False, subok=True) y = array(y, copy=False, subok=True) @@ -788,17 +788,18 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, # np.ma.masked, which is falsy). if cond != True: n_mismatch = reduced.size - reduced.sum(dtype=intp) - percent_mismatch = 100 * n_mismatch / ox.size + n_elements = flagged.size if flagged.ndim != 0 else reduced.size + percent_mismatch = 100 * n_mismatch / n_elements remarks = [ 'Mismatched elements: {} / {} ({:.3g}%)'.format( - n_mismatch, ox.size, percent_mismatch)] + n_mismatch, n_elements, percent_mismatch)] with errstate(invalid='ignore', divide='ignore'): # ignore errors for non-numeric types with contextlib.suppress(TypeError): error = abs(x - y) - max_abs_error = error.max() - if error.dtype == 'object': + max_abs_error = max(error) + if getattr(error, 'dtype', object_) == object_: remarks.append('Max absolute difference: ' + str(max_abs_error)) else: @@ -812,8 +813,8 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, if all(~nonzero): max_rel_error = array(inf) else: - max_rel_error = (error[nonzero] / abs(y[nonzero])).max() - if error.dtype == 'object': + max_rel_error = max(error[nonzero] / abs(y[nonzero])) + if getattr(error, 'dtype', object_) == object_: remarks.append('Max relative difference: ' + str(max_rel_error)) else: -- cgit v1.2.1