diff --git a/nibabel/_compression.py b/nibabel/_compression.py index 75a5e3bbf..b7cfc8f49 100644 --- a/nibabel/_compression.py +++ b/nibabel/_compression.py @@ -17,7 +17,7 @@ from .optpkg import optional_package if ty.TYPE_CHECKING: # pragma: no cover - import indexed_gzip # type: ignore[import-not-found] + import indexed_gzip # type: ignore[import] import pyzstd HAVE_INDEXED_GZIP = True diff --git a/nibabel/benchmarks/bench_arrayproxy_slicing.py b/nibabel/benchmarks/bench_arrayproxy_slicing.py index dc9acfded..305c5215e 100644 --- a/nibabel/benchmarks/bench_arrayproxy_slicing.py +++ b/nibabel/benchmarks/bench_arrayproxy_slicing.py @@ -26,7 +26,7 @@ # if memory_profiler is installed, we get memory usage results try: - from memory_profiler import memory_usage # type: ignore[import-not-found] + from memory_profiler import memory_usage # type: ignore[import] except ImportError: memory_usage = None diff --git a/nibabel/cmdline/dicomfs.py b/nibabel/cmdline/dicomfs.py index dec4011c5..66ffb8ade 100644 --- a/nibabel/cmdline/dicomfs.py +++ b/nibabel/cmdline/dicomfs.py @@ -25,7 +25,7 @@ class dummy_fuse: try: - import fuse # type: ignore[import-not-found] + import fuse # type: ignore[import] uid = os.getuid() gid = os.getgid() diff --git a/nibabel/gifti/tests/test_gifti.py b/nibabel/gifti/tests/test_gifti.py index a2f8395ca..5cc2756c6 100644 --- a/nibabel/gifti/tests/test_gifti.py +++ b/nibabel/gifti/tests/test_gifti.py @@ -14,7 +14,7 @@ from ... import load from ...fileholders import FileHolder from ...nifti1 import data_type_codes -from ...testing import get_test_data +from ...testing import deprecated_to, expires, get_test_data from .. import ( GiftiCoordSystem, GiftiDataArray, @@ -275,27 +275,29 @@ def test_labeltable(): assert len(img.labeltable.labels) == 2 +@expires('6.0.0') def test_metadata(): md = GiftiMetaData(key='value') # Old initialization methods - with pytest.warns(DeprecationWarning) as w: + with deprecated_to('6.0.0'): nvpair = GiftiNVPairs('key', 'value') with pytest.warns(FutureWarning) as w: md2 = GiftiMetaData(nvpair=nvpair) assert len(w) == 1 - with pytest.warns(DeprecationWarning) as w: + with deprecated_to('6.0.0'): md3 = GiftiMetaData.from_dict({'key': 'value'}) assert md == md2 == md3 == {'key': 'value'} # .data as a list of NVPairs is going away - with pytest.warns(DeprecationWarning) as w: + with deprecated_to('6.0.0'): assert md.data[0].name == 'key' + with deprecated_to('6.0.0'): assert md.data[0].value == 'value' - assert len(w) == 2 +@expires('6.0.0') def test_metadata_list_interface(): md = GiftiMetaData(key='value') - with pytest.warns(DeprecationWarning): + with deprecated_to('6.0.0'): mdlist = md.data assert len(mdlist) == 1 assert mdlist[0].name == 'key' @@ -312,7 +314,7 @@ def test_metadata_list_interface(): assert md['foo'] == 'bar' # Append new NVPair - with pytest.warns(DeprecationWarning) as w: + with deprecated_to('6.0.0'): nvpair = GiftiNVPairs('key', 'value') mdlist.append(nvpair) assert len(mdlist) == 2 diff --git a/nibabel/minc2.py b/nibabel/minc2.py index 94e1be76e..912b5d28a 100644 --- a/nibabel/minc2.py +++ b/nibabel/minc2.py @@ -163,7 +163,7 @@ class Minc2Image(Minc1Image): def from_file_map(klass, file_map, *, mmap=True, keep_file_open=None): # Import of h5py might take awhile for MPI-enabled builds # So we are importing it here "on demand" - import h5py # type: ignore[import-not-found] + import h5py # type: ignore[import] holder = file_map['image'] if holder.filename is None: diff --git a/nibabel/spm99analyze.py b/nibabel/spm99analyze.py index c859d702f..3465c5719 100644 --- a/nibabel/spm99analyze.py +++ b/nibabel/spm99analyze.py @@ -275,7 +275,7 @@ def from_file_map(klass, file_map, *, mmap=True, keep_file_open=None): contents = matf.read() if len(contents) == 0: return ret - import scipy.io as sio # type: ignore[import-not-found] + import scipy.io as sio # type: ignore[import] mats = sio.loadmat(BytesIO(contents)) if 'mat' in mats: # this overrides a 'M', and includes any flip diff --git a/nibabel/testing/__init__.py b/nibabel/testing/__init__.py index 5baa5e2b8..21ecadf84 100644 --- a/nibabel/testing/__init__.py +++ b/nibabel/testing/__init__.py @@ -233,3 +233,15 @@ def expires(version): return lambda x: x return pytest.mark.xfail(raises=ExpiredDeprecationError) + + +def deprecated_to(version): + """Context manager to expect DeprecationWarnings until a given version""" + from packaging.version import Version + + from nibabel import __version__ as nbver + + if Version(nbver) < Version(version): + return pytest.deprecated_call() + + return nullcontext() diff --git a/nibabel/tests/test_image_api.py b/nibabel/tests/test_image_api.py index f1fc72071..86c04985f 100644 --- a/nibabel/tests/test_image_api.py +++ b/nibabel/tests/test_image_api.py @@ -48,6 +48,7 @@ bytesio_filemap, bytesio_round_trip, clear_and_catch_warnings, + deprecated_to, expires, nullcontext, ) @@ -80,10 +81,6 @@ from .test_parrec import EXAMPLE_IMAGES as PARREC_EXAMPLE_IMAGES -def maybe_deprecated(meth_name): - return pytest.deprecated_call() if meth_name == 'get_data' else nullcontext() - - class GenericImageAPI(ValidateAPI): """General image validation API""" @@ -194,7 +191,7 @@ def validate_no_slicing(self, imaker, params): @expires('5.0.0') def validate_get_data_deprecated(self, imaker, params): img = imaker() - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): data = img.get_data() assert_array_equal(np.asanyarray(img.dataobj), data) @@ -246,14 +243,12 @@ def validate_data_interface(self, imaker, params): self._check_array_interface(imaker, meth_name) method = getattr(img, meth_name) # Data shape is same as image shape - with maybe_deprecated(meth_name): - assert img.shape == method().shape + assert img.shape == method().shape # Data ndim is same as image ndim - with maybe_deprecated(meth_name): - assert img.ndim == method().ndim + assert img.ndim == method().ndim # Values to get_data caching parameter must be 'fill' or # 'unchanged' - with maybe_deprecated(meth_name), pytest.raises(ValueError): + with pytest.raises(ValueError): method(caching='something') # dataobj is read only fake_data = np.zeros(img.shape, dtype=img.get_data_dtype()) @@ -277,13 +272,11 @@ def _check_proxy_interface(self, imaker, meth_name): assert not img.in_memory # Load with caching='unchanged' method = getattr(img, meth_name) - with maybe_deprecated(meth_name): - data = method(caching='unchanged') + data = method(caching='unchanged') # Still not cached assert not img.in_memory # Default load, does caching - with maybe_deprecated(meth_name): - data = method() + data = method() # Data now cached. in_memory is True if either of the get_data # or get_fdata caches are not-None assert img.in_memory @@ -295,36 +288,30 @@ def _check_proxy_interface(self, imaker, meth_name): # integers, but lets assume that's not true here. assert_array_equal(proxy_data, data) # Now caching='unchanged' does nothing, returns cached version - with maybe_deprecated(meth_name): - data_again = method(caching='unchanged') + data_again = method(caching='unchanged') assert data is data_again # caching='fill' does nothing because the cache is already full - with maybe_deprecated(meth_name): - data_yet_again = method(caching='fill') + data_yet_again = method(caching='fill') assert data is data_yet_again # changing array data does not change proxy data, or reloaded # data data[:] = 42 assert_array_equal(proxy_data, proxy_copy) assert_array_equal(np.asarray(img.dataobj), proxy_copy) - # It does change the result of get_data - with maybe_deprecated(meth_name): - assert_array_equal(method(), 42) + # It does change the result of get_fdata + assert_array_equal(method(), 42) # until we uncache img.uncache() # Which unsets in_memory assert not img.in_memory - with maybe_deprecated(meth_name): - assert_array_equal(method(), proxy_copy) + assert_array_equal(method(), proxy_copy) # Check caching='fill' does cache data img = imaker() method = getattr(img, meth_name) assert not img.in_memory - with maybe_deprecated(meth_name): - data = method(caching='fill') + data = method(caching='fill') assert img.in_memory - with maybe_deprecated(meth_name): - data_again = method() + data_again = method() assert data is data_again # Check that caching refreshes for new floating point type. img.uncache() @@ -368,8 +355,7 @@ def _check_array_caching(self, imaker, meth_name, caching): get_data_func = method if caching is None else partial(method, caching=caching) assert isinstance(img.dataobj, np.ndarray) assert img.in_memory - with maybe_deprecated(meth_name): - data = get_data_func() + data = get_data_func() # Returned data same object as underlying dataobj if using # old ``get_data`` method, or using newer ``get_fdata`` # method, where original array was float64. @@ -377,8 +363,7 @@ def _check_array_caching(self, imaker, meth_name, caching): dataobj_is_data = arr_dtype == np.float64 or method == img.get_data # Set something to the output array. data[:] = 42 - with maybe_deprecated(meth_name): - get_result_changed = np.all(get_data_func() == 42) + get_result_changed = np.all(get_data_func() == 42) assert get_result_changed == (dataobj_is_data or caching != 'unchanged') if dataobj_is_data: assert data is img.dataobj @@ -387,15 +372,13 @@ def _check_array_caching(self, imaker, meth_name, caching): assert_array_equal(np.asarray(img.dataobj), 42) # Uncache has no effect img.uncache() - with maybe_deprecated(meth_name): - assert_array_equal(get_data_func(), 42) + assert_array_equal(get_data_func(), 42) else: assert not data is img.dataobj assert not np.all(np.asarray(img.dataobj) == 42) # Uncache does have an effect img.uncache() - with maybe_deprecated(meth_name): - assert not np.all(get_data_func() == 42) + assert not np.all(get_data_func() == 42) # in_memory is always true for array images, regardless of # cache state. img.uncache() @@ -408,8 +391,7 @@ def _check_array_caching(self, imaker, meth_name, caching): if arr_dtype not in float_types: return for float_type in float_types: - with maybe_deprecated(meth_name): - data = get_data_func(dtype=float_type) + data = get_data_func(dtype=float_type) assert (data is img.dataobj) == (arr_dtype == float_type) def validate_shape(self, imaker, params): diff --git a/nibabel/tests/test_image_load_save.py b/nibabel/tests/test_image_load_save.py index 962a2433b..706a87f10 100644 --- a/nibabel/tests/test_image_load_save.py +++ b/nibabel/tests/test_image_load_save.py @@ -40,7 +40,7 @@ from .. import spm99analyze as spm99 from ..optpkg import optional_package from ..spatialimages import SpatialImage -from ..testing import expires +from ..testing import deprecated_to, expires from ..tmpdirs import InTemporaryDirectory from ..volumeutils import native_code, swapped_code @@ -285,7 +285,7 @@ def test_filename_save(): @expires('5.0.0') def test_guessed_image_type(): # Test whether we can guess the image type from example files - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert nils.guessed_image_type(pjoin(DATA_PATH, 'example4d.nii.gz')) == Nifti1Image assert nils.guessed_image_type(pjoin(DATA_PATH, 'nifti1.hdr')) == Nifti1Pair assert nils.guessed_image_type(pjoin(DATA_PATH, 'example_nifti2.nii.gz')) == Nifti2Image diff --git a/nibabel/tests/test_loadsave.py b/nibabel/tests/test_loadsave.py index 4071b09f7..401ed0453 100644 --- a/nibabel/tests/test_loadsave.py +++ b/nibabel/tests/test_loadsave.py @@ -21,7 +21,7 @@ from ..loadsave import _signature_matches_extension, load, read_img_data from ..openers import Opener from ..optpkg import optional_package -from ..testing import expires +from ..testing import deprecated_to, expires from ..tmpdirs import InTemporaryDirectory _, have_scipy, _ = optional_package('scipy') @@ -50,14 +50,14 @@ def test_read_img_data(): fpath = pathlib.Path(fpath) img = load(fpath) data = img.get_fdata() - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): data2 = read_img_data(img) assert_array_equal(data, data2) # These examples have null scaling - assert prefer=unscaled is the same dao = img.dataobj if hasattr(dao, 'slope') and hasattr(img.header, 'raw_data_from_fileobj'): assert (dao.slope, dao.inter) == (1, 0) - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(read_img_data(img, prefer='unscaled'), data) # Assert all caps filename works as well with TemporaryDirectory() as tmpdir: @@ -140,21 +140,21 @@ def test_read_img_data_nifti(): img = img_class(data, np.eye(4)) img.set_data_dtype(out_dtype) # No filemap => error - with pytest.deprecated_call(), pytest.raises(ImageFileError): + with deprecated_to('5.0.0'), pytest.raises(ImageFileError): read_img_data(img) # Make a filemap froot = f'an_image_{i}' img.file_map = img.filespec_to_file_map(froot) # Trying to read from this filemap will generate an error because # we are going to read from files that do not exist - with pytest.deprecated_call(), pytest.raises(OSError): + with deprecated_to('5.0.0'), pytest.raises(OSError): read_img_data(img) img.to_file_map() # Load - now the scaling and offset correctly applied img_fname = img.file_map['image'].filename img_back = load(img_fname) data_back = img_back.get_fdata() - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(data_back, read_img_data(img_back)) # This is the same as if we loaded the image and header separately hdr_fname = img.file_map['header'].filename if 'header' in img.file_map else img_fname @@ -166,16 +166,16 @@ def test_read_img_data_nifti(): # Unscaled is the same as returned from raw_data_from_fileobj with open(img_fname, 'rb') as fobj: unscaled_back = hdr_back.raw_data_from_fileobj(fobj) - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(unscaled_back, read_img_data(img_back, prefer='unscaled')) # If we futz with the scaling in the header, the result changes - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(data_back, read_img_data(img_back)) has_inter = hdr_back.has_data_intercept old_slope = hdr_back['scl_slope'] old_inter = hdr_back['scl_inter'] if has_inter else 0 est_unscaled = (data_back - old_inter) / old_slope - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): actual_unscaled = read_img_data(img_back, prefer='unscaled') assert_almost_equal(est_unscaled, actual_unscaled) img_back.header['scl_slope'] = 2.1 @@ -185,10 +185,10 @@ def test_read_img_data_nifti(): else: new_inter = 0 # scaled scaling comes from new parameters in header - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert np.allclose(actual_unscaled * 2.1 + new_inter, read_img_data(img_back)) # Unscaled array didn't change - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(actual_unscaled, read_img_data(img_back, prefer='unscaled')) # Check the offset too img.header.set_data_offset(1024) @@ -200,14 +200,14 @@ def test_read_img_data_nifti(): fobj.write(b'\x00\x00') img_back = load(img_fname) data_back = img_back.get_fdata() - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(data_back, read_img_data(img_back)) img_back.header.set_data_offset(1026) # Check we pick up new offset exp_offset = np.zeros((data.size,), data.dtype) + old_inter exp_offset[:-1] = np.ravel(data_back, order='F')[1:] exp_offset = np.reshape(exp_offset, shape, order='F') - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert_array_equal(exp_offset, read_img_data(img_back)) # Delete stuff that might hold onto file references del img, img_back, data_back diff --git a/nibabel/tests/test_onetime.py b/nibabel/tests/test_onetime.py index 426702fa4..b22a4ef3e 100644 --- a/nibabel/tests/test_onetime.py +++ b/nibabel/tests/test_onetime.py @@ -1,12 +1,12 @@ import pytest from nibabel.onetime import auto_attr, setattr_on_read -from nibabel.testing import expires +from nibabel.testing import deprecated_to, expires @expires('5.0.0') def test_setattr_on_read(): - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): class MagicProp: @setattr_on_read diff --git a/nibabel/tests/test_orientations.py b/nibabel/tests/test_orientations.py index 8821fac0e..0094711e7 100644 --- a/nibabel/tests/test_orientations.py +++ b/nibabel/tests/test_orientations.py @@ -26,7 +26,7 @@ ornt2axcodes, ornt_transform, ) -from ..testing import expires +from ..testing import deprecated_to, expires IN_ARRS = [ np.eye(4), @@ -407,6 +407,6 @@ def test_inv_ornt_aff(): def test_flip_axis_deprecation(): a = np.arange(24).reshape((2, 3, 4)) axis = 1 - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): a_flipped = flip_axis(a, axis) assert_array_equal(a_flipped, np.flip(a, axis)) diff --git a/nibabel/tests/test_spatialimages.py b/nibabel/tests/test_spatialimages.py index 5cad23a22..7157d5c45 100644 --- a/nibabel/tests/test_spatialimages.py +++ b/nibabel/tests/test_spatialimages.py @@ -18,7 +18,7 @@ from .. import load as top_load from ..imageclasses import spatial_axes_first from ..spatialimages import HeaderDataError, SpatialHeader, SpatialImage -from ..testing import bytesio_round_trip, expires, memmap_after_ufunc +from ..testing import bytesio_round_trip, deprecated_to, expires, memmap_after_ufunc from ..tmpdirs import InTemporaryDirectory @@ -368,7 +368,7 @@ def test_get_data(self): in_data = in_data_template.copy() img = img_klass(in_data, None) assert in_data is img.dataobj - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): out_data = img.get_data() assert in_data is out_data # and that uncache has no effect @@ -381,18 +381,18 @@ def test_get_data(self): rt_img = bytesio_round_trip(img) assert in_data is not rt_img.dataobj assert (rt_img.dataobj == in_data).all() - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): out_data = rt_img.get_data() assert (out_data == in_data).all() assert rt_img.dataobj is not out_data # cache - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert rt_img.get_data() is out_data out_data[:] = 42 rt_img.uncache() - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert rt_img.get_data() is not out_data - with pytest.deprecated_call(): + with deprecated_to('5.0.0'): assert (rt_img.get_data() == in_data).all() def test_slicer(self):