From 4e770240aef7851e86fd650fb42979c9373fa39a Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sat, 18 Jun 2022 02:45:14 +0100 Subject: [PATCH 1/2] TEST: Suppress new numpy warning on nan-to-int cast --- nibabel/tests/test_volumeutils.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/nibabel/tests/test_volumeutils.py b/nibabel/tests/test_volumeutils.py index b58cbeb60a..237c87eaf2 100644 --- a/nibabel/tests/test_volumeutils.py +++ b/nibabel/tests/test_volumeutils.py @@ -413,7 +413,7 @@ def test_a2f_nan2zero(): # How weird? Look at arr.astype(np.int64) with np.errstate(invalid='ignore'): data_back = write_return(arr, str_io, np.int64, nan2zero=False) - assert_array_equal(data_back, arr.astype(np.int64)) + assert_array_equal(data_back, arr.astype(np.int64)) def test_a2f_nan2zero_scaling(): @@ -692,9 +692,15 @@ def test_a2f_nan2zero_range(): write_return(arr_no_nan, fobj, np.int8, intercept=129) # OK with nan2zero false, but we get whatever nan casts to with pytest.warns(warn_type) if warn_type else error_warnings(): - nan_cast = np.array(np.nan, dtype=dt).astype(np.int8) + # XXX NP1.24 + # Casting nan to int will produce a RuntimeWarning in numpy 1.24 + # Change to expecting this warning when this becomes our minimum + with np.errstate(invalid='ignore'): + nan_cast = np.array(np.nan, dtype=dt).astype(np.int8) with pytest.warns(warn_type) if warn_type else error_warnings(): - back_arr = write_return(arr, fobj, np.int8, intercept=129, nan2zero=False) + # XXX NP1.24 - expect RuntimeWarning + with np.errstate(invalid='ignore'): + back_arr = write_return(arr, fobj, np.int8, intercept=129, nan2zero=False) assert_array_equal([-128, -128, -128, nan_cast], back_arr) # divslope with pytest.warns(warn_type) if warn_type else error_warnings(): @@ -706,8 +712,10 @@ def test_a2f_nan2zero_range(): write_return(arr_no_nan, fobj, np.int8, intercept=257.1, divslope=2) # OK with nan2zero false with pytest.warns(warn_type) if warn_type else error_warnings(): - back_arr = write_return(arr, fobj, np.int8, - intercept=257.1, divslope=2, nan2zero=False) + # XXX NP1.24 - expect RuntimeWarning + with np.errstate(invalid='ignore'): + back_arr = write_return(arr, fobj, np.int8, + intercept=257.1, divslope=2, nan2zero=False) assert_array_equal([-128, -128, -128, nan_cast], back_arr) From 7d3979d189b2f57d83d1abf9944bca95205d9077 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sat, 18 Jun 2022 12:40:59 +0100 Subject: [PATCH 2/2] TEST: Better warnings checks, rather than comments for future improvements --- nibabel/tests/test_volumeutils.py | 38 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/nibabel/tests/test_volumeutils.py b/nibabel/tests/test_volumeutils.py index 237c87eaf2..4994f94e48 100644 --- a/nibabel/tests/test_volumeutils.py +++ b/nibabel/tests/test_volumeutils.py @@ -20,6 +20,7 @@ import bz2 import threading import time +from packaging.version import Version import numpy as np @@ -68,6 +69,8 @@ IUINT_TYPES = INT_TYPES + np.sctypes['uint'] NUMERIC_TYPES = CFLOAT_TYPES + IUINT_TYPES +FP_RUNTIME_WARN = Version(np.__version__) >= Version('1.24.0.dev0+239') + def test__is_compressed_fobj(): # _is_compressed helper function @@ -672,18 +675,21 @@ def test_a2f_nan2zero_range(): arr = np.array([-1, 0, 1, np.nan], dtype=dt) # Error occurs for arrays without nans too arr_no_nan = np.array([-1, 0, 1, 2], dtype=dt) - warn_type = np.ComplexWarning if np.issubdtype(dt, np.complexfloating) else None + complex_warn = (np.ComplexWarning,) if np.issubdtype(dt, np.complexfloating) else () + # Casting nan to int will produce a RuntimeWarning in numpy 1.24 + nan_warn = (RuntimeWarning,) if FP_RUNTIME_WARN else () + c_and_n_warn = complex_warn + nan_warn # No errors from explicit thresholding # mn thresholding excluding zero - with pytest.warns(warn_type) if warn_type else error_warnings(): + with pytest.warns(complex_warn) if complex_warn else error_warnings(): assert_array_equal([1, 1, 1, 0], write_return(arr, fobj, np.int8, mn=1)) # mx thresholding excluding zero - with pytest.warns(warn_type) if warn_type else error_warnings(): + with pytest.warns(complex_warn) if complex_warn else error_warnings(): assert_array_equal([-1, -1, -1, 0], write_return(arr, fobj, np.int8, mx=-1)) # Errors from datatype threshold after scaling - with pytest.warns(warn_type) if warn_type else error_warnings(): + with pytest.warns(complex_warn) if complex_warn else error_warnings(): back_arr = write_return(arr, fobj, np.int8, intercept=128) assert_array_equal([-128, -128, -127, -128], back_arr) with pytest.raises(ValueError): @@ -691,19 +697,13 @@ def test_a2f_nan2zero_range(): with pytest.raises(ValueError): write_return(arr_no_nan, fobj, np.int8, intercept=129) # OK with nan2zero false, but we get whatever nan casts to - with pytest.warns(warn_type) if warn_type else error_warnings(): - # XXX NP1.24 - # Casting nan to int will produce a RuntimeWarning in numpy 1.24 - # Change to expecting this warning when this becomes our minimum - with np.errstate(invalid='ignore'): - nan_cast = np.array(np.nan, dtype=dt).astype(np.int8) - with pytest.warns(warn_type) if warn_type else error_warnings(): - # XXX NP1.24 - expect RuntimeWarning - with np.errstate(invalid='ignore'): - back_arr = write_return(arr, fobj, np.int8, intercept=129, nan2zero=False) + with pytest.warns(c_and_n_warn) if c_and_n_warn else error_warnings(): + nan_cast = np.array(np.nan, dtype=dt).astype(np.int8) + with pytest.warns(c_and_n_warn) if c_and_n_warn else error_warnings(): + back_arr = write_return(arr, fobj, np.int8, intercept=129, nan2zero=False) assert_array_equal([-128, -128, -128, nan_cast], back_arr) # divslope - with pytest.warns(warn_type) if warn_type else error_warnings(): + with pytest.warns(complex_warn) if complex_warn else error_warnings(): back_arr = write_return(arr, fobj, np.int8, intercept=256, divslope=2) assert_array_equal([-128, -128, -128, -128], back_arr) with pytest.raises(ValueError): @@ -711,11 +711,9 @@ def test_a2f_nan2zero_range(): with pytest.raises(ValueError): write_return(arr_no_nan, fobj, np.int8, intercept=257.1, divslope=2) # OK with nan2zero false - with pytest.warns(warn_type) if warn_type else error_warnings(): - # XXX NP1.24 - expect RuntimeWarning - with np.errstate(invalid='ignore'): - back_arr = write_return(arr, fobj, np.int8, - intercept=257.1, divslope=2, nan2zero=False) + with pytest.warns(c_and_n_warn) if c_and_n_warn else error_warnings(): + back_arr = write_return(arr, fobj, np.int8, + intercept=257.1, divslope=2, nan2zero=False) assert_array_equal([-128, -128, -128, nan_cast], back_arr)