From 54a39255251ebafde3a3165741aca652deeafe6b Mon Sep 17 00:00:00 2001 From: Genevieve Buckley <30920819+GenevieveBuckley@users.noreply.github.com> Date: Tue, 14 May 2024 17:53:55 +1000 Subject: [PATCH] Maintenance: fix CI test errors (#366) * np.bool8 is deprecated, use np.bool_ instead * Remove runtime warning check from pytest imread tests * Update pytest fixtures (class syntax may no longer be supported in the way we use it here) * pytest.warns no longer accepts None as input * These examples no longer produce a warning, index.ndim is not greater than 1 * pytest.skip reason needs to be an unnamed argument --------- Co-authored-by: jakirkham --- dask_image/ndmorph/_utils.py | 6 +- .../test_dask_image/test_imread/test_core.py | 31 ++- .../test_ndfilters/test__threshold.py | 203 +++++++++--------- .../test_ndinterp/test_spline_filter.py | 2 +- .../test_ndmeasure/test__utils.py | 4 +- .../test_ndmorph/test__utils.py | 6 +- 6 files changed, 129 insertions(+), 123 deletions(-) diff --git a/dask_image/ndmorph/_utils.py b/dask_image/ndmorph/_utils.py index 372b5b8a..3b298c1e 100644 --- a/dask_image/ndmorph/_utils.py +++ b/dask_image/ndmorph/_utils.py @@ -26,7 +26,7 @@ def _get_structure(image, structure): raise RuntimeError( "`structure` must have the same rank as `image`." ) - if not issubclass(structure.dtype.type, np.bool8): + if not issubclass(structure.dtype.type, np.bool_): structure = (structure != 0) else: raise TypeError("`structure` must be an array.") @@ -59,9 +59,9 @@ def _get_mask(image, mask): if isinstance(mask, (np.ndarray, da.Array)): if mask.shape != image.shape: raise RuntimeError("`mask` must have the same shape as `image`.") - if not issubclass(mask_type, np.bool8): + if not issubclass(mask_type, np.bool_): mask = (mask != 0) - elif issubclass(mask_type, np.bool8): + elif issubclass(mask_type, np.bool_): mask = bool(mask) else: raise TypeError("`mask` must be a Boolean or an array.") diff --git a/tests/test_dask_image/test_imread/test_core.py b/tests/test_dask_image/test_imread/test_core.py index ddebc70c..cb1e4773 100644 --- a/tests/test_dask_image/test_imread/test_core.py +++ b/tests/test_dask_image/test_imread/test_core.py @@ -33,17 +33,17 @@ def test_errs_imread(err_type, nframes): ] ) @pytest.mark.parametrize( - "nframes, shape, runtime_warning", + "nframes, shape", [ - (1, (1, 4, 3), None), - (-1, (1, 4, 3), None), - (3, (1, 4, 3), "`nframes` larger than"), - (1, (5, 4, 3), None), - (2, (5, 4, 3), "`nframes` does not nicely divide"), - (1, (10, 5, 4, 3), None), - (5, (10, 5, 4, 3), None), - (10, (10, 5, 4, 3), None), - (-1, (10, 5, 4, 3), None), + (1, (1, 4, 3)), + (-1, (1, 4, 3)), + (3, (1, 4, 3)), + (1, (5, 4, 3)), + (2, (5, 4, 3)), + (1, (10, 5, 4, 3)), + (5, (10, 5, 4, 3)), + (10, (10, 5, 4, 3)), + (-1, (10, 5, 4, 3)), ] ) @pytest.mark.parametrize( @@ -61,7 +61,7 @@ def test_errs_imread(err_type, nframes): False, ] ) -def test_tiff_imread(tmpdir, seed, nframes, shape, runtime_warning, dtype, is_pathlib_Path): # noqa: E501 +def test_tiff_imread(tmpdir, seed, nframes, shape, dtype, is_pathlib_Path): # noqa: E501 np.random.seed(seed) dirpth = tmpdir.mkdir("test_imread") @@ -77,12 +77,9 @@ def test_tiff_imread(tmpdir, seed, nframes, shape, runtime_warning, dtype, is_pa with tifffile.TiffWriter(fn) as fh: for i in range(len(a)): fh.save(a[i], contiguous=True) - - with pytest.warns(None if runtime_warning is None - else RuntimeWarning, match=runtime_warning): - if is_pathlib_Path: - fn = pathlib.Path(fn) - d = dask_image.imread.imread(fn, nframes=nframes) + if is_pathlib_Path: + fn = pathlib.Path(fn) + d = dask_image.imread.imread(fn, nframes=nframes) if nframes == -1: nframes = shape[0] diff --git a/tests/test_dask_image/test_ndfilters/test__threshold.py b/tests/test_dask_image/test_ndfilters/test__threshold.py index 12fa2681..431af1f5 100644 --- a/tests/test_dask_image/test_ndfilters/test__threshold.py +++ b/tests/test_dask_image/test_ndfilters/test__threshold.py @@ -5,6 +5,62 @@ from dask_image.ndfilters import threshold_local +@pytest.fixture +def simple_test_image(): + image = da.from_array(np.array( + [[0, 0, 1, 3, 5], + [0, 1, 4, 3, 4], + [1, 2, 5, 4, 1], + [2, 4, 5, 2, 1], + [4, 5, 1, 0, 0]], dtype=int), chunks=(5, 5)) + return image + + +# ================================================== +# Test Threshold Filters +# ================================================== + +@pytest.mark.parametrize('block_size', [ + 3, + [3, 3], + np.array([3, 3]), + da.from_array(np.array([3, 3]), chunks=1), + da.from_array(np.array([3, 3]), chunks=2), +]) +def test_threshold_local_gaussian(simple_test_image, block_size): + ref = np.array( + [[False, False, False, False, True], + [False, False, True, False, True], + [False, False, True, True, False], + [False, True, True, False, False], + [True, True, False, False, False]] + ) + out = threshold_local(simple_test_image, block_size, method='gaussian') + assert_equal(ref, (simple_test_image > out).compute()) + + out = threshold_local(simple_test_image, block_size, method='gaussian', + param=1./3.) + assert_equal(ref, (simple_test_image > out).compute()) + + +@pytest.mark.parametrize('block_size', [ + 3, + [3, 3], + np.array([3, 3]), + da.from_array(np.array([3, 3]), chunks=1), + da.from_array(np.array([3, 3]), chunks=2), +]) +def test_threshold_local_mean(simple_test_image, block_size): + ref = np.array( + [[False, False, False, False, True], + [False, False, True, False, True], + [False, False, True, True, False], + [False, True, True, False, False], + [True, True, False, False, False]] + ) + out = threshold_local(simple_test_image, block_size, method='mean') + assert_equal(ref, (simple_test_image > out).compute()) + @pytest.mark.parametrize('block_size', [ 3, @@ -13,99 +69,54 @@ da.from_array(np.array([3, 3]), chunks=1), da.from_array(np.array([3, 3]), chunks=2), ]) -class TestSimpleImage: - def setup(self): - self.image = da.from_array(np.array( - [[0, 0, 1, 3, 5], - [0, 1, 4, 3, 4], - [1, 2, 5, 4, 1], - [2, 4, 5, 2, 1], - [4, 5, 1, 0, 0]], dtype=int), chunks=(5, 5)) - - def test_threshold_local_gaussian(self, block_size): - ref = np.array( - [[False, False, False, False, True], - [False, False, True, False, True], - [False, False, True, True, False], - [False, True, True, False, False], - [True, True, False, False, False]] - ) - out = threshold_local(self.image, block_size, method='gaussian') - assert_equal(ref, (self.image > out).compute()) - - out = threshold_local(self.image, block_size, method='gaussian', - param=1./3.) - assert_equal(ref, (self.image > out).compute()) - - def test_threshold_local_mean(self, block_size): - ref = np.array( - [[False, False, False, False, True], - [False, False, True, False, True], - [False, False, True, True, False], - [False, True, True, False, False], - [True, True, False, False, False]] - ) - out = threshold_local(self.image, block_size, method='mean') - assert_equal(ref, (self.image > out).compute()) - - def test_threshold_local_median(self, block_size): - ref = np.array( - [[False, False, False, False, True], - [False, False, True, False, False], - [False, False, True, False, False], - [False, False, True, True, False], - [False, True, False, False, False]] - ) - out = threshold_local(self.image, block_size, method='median') - assert_equal(ref, (self.image > out).compute()) - - -class TestGenericFilter: - def setup(self): - self.image = da.from_array(np.array( - [[0, 0, 1, 3, 5], - [0, 1, 4, 3, 4], - [1, 2, 5, 4, 1], - [2, 4, 5, 2, 1], - [4, 5, 1, 0, 0]], dtype=int), chunks=(5, 5)) - - def test_threshold_local_generic(self): - ref = np.array( - [[1., 7., 16., 29., 37.], - [5., 14., 23., 30., 30.], - [13., 24., 30., 29., 21.], - [25., 29., 28., 19., 10.], - [34., 31., 23., 10., 4.]] - ) - unchanged = threshold_local(self.image, 1, method='generic', param=sum) - out = threshold_local(self.image, 3, method='generic', param=sum) - assert np.allclose(unchanged.compute(), self.image.compute()) - assert np.allclose(out.compute(), ref) - - def test_threshold_local_generic_invalid(self): - expected_error_message = "Must include a valid function to use as " - "the 'param' keyword argument." - with pytest.raises(ValueError) as e: - threshold_local(self.image, 3, method='generic', param='sum') - assert e == expected_error_message - - -class TestInvalidArguments: - def setup(self): - self.image = da.from_array(np.array( - [[0, 0, 1, 3, 5], - [0, 1, 4, 3, 4], - [1, 2, 5, 4, 1], - [2, 4, 5, 2, 1], - [4, 5, 1, 0, 0]], dtype=int), chunks=(5, 5)) - - @pytest.mark.parametrize("method, block_size, error_type", [ - ('median', np.nan, TypeError), - ]) - def test_nan_blocksize(self, method, block_size, error_type): - with pytest.raises(error_type): - threshold_local(self.image, block_size, method=method) - - def test_invalid_threshold_method(self): - with pytest.raises(ValueError): - threshold_local(self.image, 3, method='invalid') +def test_threshold_local_median(simple_test_image, block_size): + ref = np.array( + [[False, False, False, False, True], + [False, False, True, False, False], + [False, False, True, False, False], + [False, False, True, True, False], + [False, True, False, False, False]] + ) + out = threshold_local(simple_test_image, block_size, method='median') + assert_equal(ref, (simple_test_image > out).compute()) + + +# ================================================== +# Test Generic Filters +# ================================================== + +def test_threshold_local_generic(simple_test_image): + ref = np.array( + [[1., 7., 16., 29., 37.], + [5., 14., 23., 30., 30.], + [13., 24., 30., 29., 21.], + [25., 29., 28., 19., 10.], + [34., 31., 23., 10., 4.]] + ) + unchanged = threshold_local(simple_test_image, 1, method='generic', param=sum) + out = threshold_local(simple_test_image, 3, method='generic', param=sum) + assert np.allclose(unchanged.compute(), simple_test_image.compute()) + assert np.allclose(out.compute(), ref) + +def test_threshold_local_generic_invalid(simple_test_image): + expected_error_message = "Must include a valid function to use as " + "the 'param' keyword argument." + with pytest.raises(ValueError) as e: + threshold_local(simple_test_image, 3, method='generic', param='sum') + assert e == expected_error_message + + +# ================================================== +# Test Invalid Arguments +# ================================================== + +@pytest.mark.parametrize("method, block_size, error_type", [ + ('median', np.nan, TypeError), +]) +def test_nan_blocksize(simple_test_image, method, block_size, error_type): + with pytest.raises(error_type): + threshold_local(simple_test_image, block_size, method=method) + +def test_invalid_threshold_method(simple_test_image): + with pytest.raises(ValueError): + threshold_local(simple_test_image, 3, method='invalid') diff --git a/tests/test_dask_image/test_ndinterp/test_spline_filter.py b/tests/test_dask_image/test_ndinterp/test_spline_filter.py index da733813..f5300c95 100644 --- a/tests/test_dask_image/test_ndinterp/test_spline_filter.py +++ b/tests/test_dask_image/test_ndinterp/test_spline_filter.py @@ -172,7 +172,7 @@ def test_spline_filter1d_general( axis, ): if axis == 1 and n < 2: - pytest.skip(msg="skip axis=1 for 1d signals") + pytest.skip("skip axis=1 for 1d signals") validate_spline_filter( n=n, diff --git a/tests/test_dask_image/test_ndmeasure/test__utils.py b/tests/test_dask_image/test_ndmeasure/test__utils.py index 828f4544..69b3ee2f 100644 --- a/tests/test_dask_image/test_ndmeasure/test__utils.py +++ b/tests/test_dask_image/test_ndmeasure/test__utils.py @@ -55,8 +55,6 @@ def test__norm_input_labels_index(): @pytest.mark.parametrize( "shape, chunks, ind", [ - ((15, 16), (4, 5), 1), - ((15, 16), (4, 5), [1]), ((15, 16), (4, 5), [[1, 2, 3, 4]]), ((15, 16), (4, 5), [[1, 2], [3, 4]]), ((15, 16), (4, 5), [[[1], [2], [3], [4]]]), @@ -78,7 +76,7 @@ def test__norm_input_labels_index_warn(shape, chunks, ind): ind = np.array(ind) d_ind = da.from_array(ind, chunks=1) - with pytest.warns(None) as w: + with pytest.warns(FutureWarning) as w: dask_image.ndmeasure._utils._norm_input_labels_index( d, d_lbls, d_ind ) diff --git a/tests/test_dask_image/test_ndmorph/test__utils.py b/tests/test_dask_image/test_ndmorph/test__utils.py index a9177446..9b859e45 100644 --- a/tests/test_dask_image/test_ndmorph/test__utils.py +++ b/tests/test_dask_image/test_ndmorph/test__utils.py @@ -129,7 +129,7 @@ def test__get_iterations(expected, iterations): @pytest.mark.parametrize( "expected, a", [ - (np.bool8, False), + (np.bool_, False), (np.int_, 2), (np.float64, 3.1), (np.complex128, 1 + 2j), @@ -150,12 +150,12 @@ def test__get_dtype(expected, a): ( True, da.arange(2, dtype=bool, chunks=(2,)), - np.bool8(True) + np.bool_(True) ), ( False, da.arange(2, dtype=bool, chunks=(2,)), - np.bool8(False) + np.bool_(False) ), ( np.arange(2, dtype=bool),