Skip to content

TEST: Accommodate pytest 8 changes #1297

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion nibabel/_compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion nibabel/benchmarks/bench_arrayproxy_slicing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion nibabel/cmdline/dicomfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
16 changes: 9 additions & 7 deletions nibabel/gifti/tests/test_gifti.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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'
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion nibabel/minc2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion nibabel/spm99analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions nibabel/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
56 changes: 19 additions & 37 deletions nibabel/tests/test_image_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
bytesio_filemap,
bytesio_round_trip,
clear_and_catch_warnings,
deprecated_to,
expires,
nullcontext,
)
Expand Down Expand Up @@ -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"""

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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())
Expand All @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -368,17 +355,15 @@ 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.
arr_dtype = img.dataobj.dtype
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
Expand All @@ -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()
Expand All @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions nibabel/tests/test_image_load_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
26 changes: 13 additions & 13 deletions nibabel/tests/test_loadsave.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Loading