From 2f94071547caa3db6017c7a72fe4b9d902271299 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:17:02 -0400 Subject: [PATCH 01/17] MNT: Set fallback version to 5.0.0.dev0 --- nibabel/info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nibabel/info.py b/nibabel/info.py index ad5d473f74..38690246c3 100644 --- a/nibabel/info.py +++ b/nibabel/info.py @@ -10,8 +10,8 @@ # This is a fall-back for versioneer when installing from a git archive. # This should be set to the intended next version + dev to indicate a # development (pre-release) version. -_version_major = 4 -_version_minor = 1 +_version_major = 5 +_version_minor = 0 _version_micro = 0 _version_extra = '.dev0' From 89929bbd0e52895962073262c5ea2f903750fd60 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:18:23 -0400 Subject: [PATCH 02/17] MNT: Remove nibabel.keywordonly --- nibabel/conftest.py | 2 -- nibabel/keywordonly.py | 34 --------------------- nibabel/tests/test_keywordonly.py | 49 ------------------------------- 3 files changed, 85 deletions(-) delete mode 100644 nibabel/keywordonly.py delete mode 100644 nibabel/tests/test_keywordonly.py diff --git a/nibabel/conftest.py b/nibabel/conftest.py index 751afd9654..697eef4ad6 100644 --- a/nibabel/conftest.py +++ b/nibabel/conftest.py @@ -1,8 +1,6 @@ import pytest # Pre-load deprecated modules to avoid cluttering warnings -with pytest.deprecated_call(): - import nibabel.keywordonly with pytest.warns(FutureWarning): import nibabel.py3k diff --git a/nibabel/keywordonly.py b/nibabel/keywordonly.py deleted file mode 100644 index b6267d5010..0000000000 --- a/nibabel/keywordonly.py +++ /dev/null @@ -1,34 +0,0 @@ -""" Decorator for labeling keyword arguments as keyword only -""" - -from functools import wraps -import warnings - -warnings.warn("We will remove the 'keywordonly' module from nibabel 5.0. " - "Please use the built-in Python `*` argument to ensure " - "keyword-only parameters (see PEP 3102).", - DeprecationWarning, - stacklevel=2) - - -def kw_only_func(n): - """ Return function decorator enforcing maximum of `n` positional arguments - """ - def decorator(func): - @wraps(func) - def wrapper(*args, **kwargs): - if len(args) > n: - raise TypeError( - f"{func.__name__} takes at most {n} positional argument{'s' if n > 1 else ''}") - return func(*args, **kwargs) - return wrapper - return decorator - - -def kw_only_meth(n): - """ Return method decorator enforcing maximum of `n` positional arguments - - The method has at least one positional argument ``self`` or ``cls``; allow - for that. - """ - return kw_only_func(n + 1) diff --git a/nibabel/tests/test_keywordonly.py b/nibabel/tests/test_keywordonly.py deleted file mode 100644 index 0ef631dbf4..0000000000 --- a/nibabel/tests/test_keywordonly.py +++ /dev/null @@ -1,49 +0,0 @@ -""" Test kw_only decorators """ - -from ..keywordonly import kw_only_func, kw_only_meth - -import pytest - - -def test_kw_only_func(): - # Test decorator - def func(an_arg): - "My docstring" - return an_arg - assert func(1) == 1 - with pytest.raises(TypeError): - func(1, 2) - dec_func = kw_only_func(1)(func) - assert dec_func(1) == 1 - with pytest.raises(TypeError): - dec_func(1, 2) - with pytest.raises(TypeError): - dec_func(1, akeyarg=3) - assert dec_func.__doc__ == 'My docstring' - - @kw_only_func(1) - def kw_func(an_arg, a_kwarg='thing'): - "Another docstring" - return an_arg, a_kwarg - assert kw_func(1) == (1, 'thing') - with pytest.raises(TypeError): - kw_func(1, 2) - assert kw_func(1, a_kwarg=2) == (1, 2) - with pytest.raises(TypeError): - kw_func(1, akeyarg=3) - assert kw_func.__doc__ == 'Another docstring' - - class C: - - @kw_only_meth(1) - def kw_meth(self, an_arg, a_kwarg='thing'): - "Method docstring" - return an_arg, a_kwarg - c = C() - assert c.kw_meth(1) == (1, 'thing') - with pytest.raises(TypeError): - c.kw_meth(1, 2) - assert c.kw_meth(1, a_kwarg=2) == (1, 2) - with pytest.raises(TypeError): - c.kw_meth(1, akeyarg=3) - assert c.kw_meth.__doc__ == 'Method docstring' From 494ad70c972701cd7e8d2dc85d3fc90f51a09b68 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:28:34 -0400 Subject: [PATCH 03/17] TEST: Bump some final removals to 6.0 --- nibabel/tests/test_removalschedule.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nibabel/tests/test_removalschedule.py b/nibabel/tests/test_removalschedule.py index d94b1d0f9d..0595e48360 100644 --- a/nibabel/tests/test_removalschedule.py +++ b/nibabel/tests/test_removalschedule.py @@ -17,10 +17,10 @@ ("6.0.0", [("nibabel.loadsave", "guessed_image_type"), ("nibabel.loadsave", "read_img_data"), ("nibabel.orientations", "flip_axis"), - ]), - ("5.0.0", [("nibabel.pydicom_compat", "dicom_test"), + ("nibabel.pydicom_compat", "dicom_test"), ("nibabel.onetime", "setattr_on_read"), - ("nibabel.gifti.gifti", "data_tag"), + ]), + ("5.0.0", [("nibabel.gifti.gifti", "data_tag"), ("nibabel.gifti.giftiio", "read"), ("nibabel.gifti.giftiio", "write"), ("nibabel.gifti.parse_gifti_fast", "Outputter"), From 3aaf8d14d0ddc770f566f0a28921e4aebfd5dc76 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:28:58 -0400 Subject: [PATCH 04/17] MNT: Remove gifti.gifti.data_tag and accommodating hacks --- nibabel/gifti/gifti.py | 22 +--------------------- nibabel/gifti/tests/test_gifti.py | 6 ------ 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/nibabel/gifti/gifti.py b/nibabel/gifti/gifti.py index 6fbc9245a7..adc7f83b56 100644 --- a/nibabel/gifti/gifti.py +++ b/nibabel/gifti/gifti.py @@ -378,21 +378,6 @@ def print_summary(self): print('Affine Transformation Matrix: \n', self.xform) -@deprecate_with_version( - "data_tag is an internal API that will be discontinued.", - '2.1', '4.0') -def data_tag(dataarray, encoding, datatype, ordering): - class DataTag(xml.XmlSerializable): - - def __init__(self, *args): - self.args = args - - def _to_xml_element(self): - return _data_tag_element(*self.args) - - return DataTag(dataarray, encoding, datatype, ordering).to_xml() - - def _data_tag_element(dataarray, encoding, dtype, ordering): """ Creates data tag with given `encoding`, returns as XML element """ @@ -400,13 +385,8 @@ def _data_tag_element(dataarray, encoding, dtype, ordering): order = array_index_order_codes.npcode[ordering] enclabel = gifti_encoding_codes.label[encoding] if enclabel == 'ASCII': - # XXX Accommodating data_tag API - # On removal (nibabel 4.0) drop str case - da = _arr2txt(dataarray, dtype if isinstance(dtype, str) else KIND2FMT[dtype.kind]) + da = _arr2txt(dataarray, KIND2FMT[dtype.kind]) elif enclabel in ('B64BIN', 'B64GZ'): - # XXX Accommodating data_tag API - don't try to fix dtype - if isinstance(dtype, str): - dtype = dataarray.dtype out = np.asanyarray(dataarray, dtype).tobytes(order) if enclabel == 'B64GZ': out = zlib.compress(out) diff --git a/nibabel/gifti/tests/test_gifti.py b/nibabel/gifti/tests/test_gifti.py index 8249d01f92..31b930b7cd 100644 --- a/nibabel/gifti/tests/test_gifti.py +++ b/nibabel/gifti/tests/test_gifti.py @@ -12,7 +12,6 @@ from .. import (GiftiImage, GiftiDataArray, GiftiLabel, GiftiLabelTable, GiftiMetaData, GiftiNVPairs, GiftiCoordSystem) -from ..gifti import data_tag from ...nifti1 import data_type_codes from ...fileholders import FileHolder from ...deprecator import ExpiredDeprecationError @@ -376,11 +375,6 @@ def test_gifti_coord(): gcs.to_xml() -def test_data_tag_deprecated(): - with pytest.raises(ExpiredDeprecationError): - data_tag(np.array([]), 'ASCII', '%i', 1) - - def test_gifti_round_trip(): # From section 14.4 in GIFTI Surface Data Format Version 1.0 # (with some adaptations) From eeaa4ba9de442791de005e6b351d904b3cc6658e Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:33:55 -0400 Subject: [PATCH 05/17] MNT: Complete various GIFTI removals --- nibabel/gifti/gifti.py | 152 ------------------- nibabel/gifti/tests/test_gifti.py | 40 ----- nibabel/gifti/tests/test_parse_gifti_fast.py | 27 ---- nibabel/tests/test_removalschedule.py | 2 - 4 files changed, 221 deletions(-) diff --git a/nibabel/gifti/gifti.py b/nibabel/gifti/gifti.py index adc7f83b56..31df1d813e 100644 --- a/nibabel/gifti/gifti.py +++ b/nibabel/gifti/gifti.py @@ -122,13 +122,6 @@ def data(self): def from_dict(klass, data_dict): return klass(data_dict) - @deprecate_with_version( - 'get_metadata method deprecated. ' - "Use the metadata property instead.", - '2.1', '4.0') - def get_metadata(self): - return dict(self) - @property @deprecate_with_version( 'metadata property deprecated. Use GiftiMetaData object ' @@ -274,13 +267,6 @@ def __repr__(self): r, g, b, a = chars.astype('u1') return f'' - @deprecate_with_version( - 'get_rgba method deprecated. ' - "Use the rgba property instead.", - '2.1', '4.0') - def get_rgba(self): - return self.rgba - @property def rgba(self): """ Returns RGBA as tuple """ @@ -488,68 +474,6 @@ def __repr__(self): def num_dim(self): return len(self.dims) - # Setter for backwards compatibility with pymvpa - @num_dim.setter - @deprecate_with_version( - "num_dim will be read-only in future versions of nibabel", - '2.1', '4.0') - def num_dim(self, value): - if value != len(self.dims): - raise ValueError(f'num_dim value {value} != number of ' - f'dimensions len(self.dims) {len(self.dims)}') - - @classmethod - @deprecate_with_version( - 'from_array method is deprecated. ' - 'Please use GiftiDataArray constructor instead.', - '2.1', '4.0') - def from_array(klass, - darray, - intent="NIFTI_INTENT_NONE", - datatype=None, - encoding="GIFTI_ENCODING_B64GZ", - endian=sys.byteorder, - coordsys=None, - ordering="C", - meta=None): - """ Creates a new Gifti data array - - Parameters - ---------- - darray : ndarray - NumPy data array - intent : string - NIFTI intent code, see nifti1.intent_codes - datatype : None or string, optional - NIFTI data type codes, see nifti1.data_type_codes - If None, the datatype of the NumPy array is taken. - encoding : string, optionaal - Encoding of the data, see util.gifti_encoding_codes; - default: GIFTI_ENCODING_B64GZ - endian : string, optional - The Endianness to store the data array. Should correspond to the - machine endianness. default: system byteorder - coordsys : GiftiCoordSystem, optional - If None, a identity transformation is taken. - ordering : string, optional - The ordering of the array. see util.array_index_order_codes; - default: RowMajorOrder - C ordering - meta : None or dict, optional - A dictionary for metadata information. If None, gives empty dict. - - Returns - ------- - da : instance of our own class - """ - return klass(data=darray, - intent=intent, - datatype=datatype, - encoding=encoding, - endian=endian, - coordsys=coordsys, - ordering=ordering, - meta=meta) - def _to_xml_element(self): # fix endianness to machine endianness self.endian = gifti_endian_codes.code[sys.byteorder] @@ -580,40 +504,6 @@ def _to_xml_element(self): return data_array - @deprecate_with_version( - 'to_xml_open method deprecated. ' - 'Use the to_xml() function instead.', - '2.1', '4.0') - def to_xml_open(self): - out = """\n""" - di = "" - for i, n in enumerate(self.dims): - di = di + f'\tDim{i}="{n}\"\n' - return out % (intent_codes.niistring[self.intent], - data_type_codes.niistring[self.datatype], - array_index_order_codes.label[self.ind_ord], - str(self.num_dim), - str(di), - gifti_encoding_codes.specs[self.encoding], - gifti_endian_codes.specs[self.endian], - self.ext_fname, - self.ext_offset, - ) - - @deprecate_with_version( - 'to_xml_close method deprecated. ' - 'Use the to_xml() function instead.', - '2.1', '4.0') - def to_xml_close(self): - return "\n" - def print_summary(self): print('Intent: ', intent_codes.niistring[self.intent]) print('DataType: ', data_type_codes.niistring[self.datatype]) @@ -630,13 +520,6 @@ def print_summary(self): print('Coordinate System:') print(self.coordsys.print_summary()) - @deprecate_with_version( - 'get_metadata method deprecated. ' - "Use the metadata property instead.", - '2.1', '4.0') - def get_metadata(self): - return dict(self.meta) - @property def metadata(self): """ Returns metadata as dictionary """ @@ -718,20 +601,6 @@ def labeltable(self, labeltable): raise TypeError("Not a valid GiftiLabelTable instance") self._labeltable = labeltable - @deprecate_with_version( - 'set_labeltable method deprecated. ' - "Use the gifti_img.labeltable property instead.", - '2.1', '4.0') - def set_labeltable(self, labeltable): - self.labeltable = labeltable - - @deprecate_with_version( - 'get_labeltable method deprecated. ' - "Use the gifti_img.labeltable property instead.", - '2.1', '4.0') - def get_labeltable(self): - return self.labeltable - @property def meta(self): return self._meta @@ -748,20 +617,6 @@ def meta(self, meta): raise TypeError("Not a valid GiftiMetaData instance") self._meta = meta - @deprecate_with_version( - 'set_meta method deprecated. ' - "Use the gifti_img.meta property instead.", - '2.1', '4.0') - def set_metadata(self, meta): - self.meta = meta - - @deprecate_with_version( - 'get_meta method deprecated. ' - "Use the gifti_img.meta property instead.", - '2.1', '4.0') - def get_meta(self): - return self.meta - def add_gifti_data_array(self, dataarr): """ Adds a data array to the GiftiImage @@ -925,13 +780,6 @@ def agg_data(self, intent_code=None): return all_data - @deprecate_with_version( - 'getArraysFromIntent method deprecated. ' - "Use get_arrays_from_intent instead.", - '2.1', '4.0') - def getArraysFromIntent(self, intent): - return self.get_arrays_from_intent(intent) - def print_summary(self): print('----start----') print('Source filename: ', self.get_filename()) diff --git a/nibabel/gifti/tests/test_gifti.py b/nibabel/gifti/tests/test_gifti.py index 31b930b7cd..1fa4eb8917 100644 --- a/nibabel/gifti/tests/test_gifti.py +++ b/nibabel/gifti/tests/test_gifti.py @@ -14,7 +14,6 @@ GiftiCoordSystem) from ...nifti1 import data_type_codes from ...fileholders import FileHolder -from ...deprecator import ExpiredDeprecationError from numpy.testing import assert_array_almost_equal, assert_array_equal import pytest @@ -182,32 +181,6 @@ def test_dataarray_init(): assert gda(ext_offset=12).ext_offset == 12 -def test_dataarray_from_array(): - with pytest.raises(ExpiredDeprecationError): - GiftiDataArray.from_array(np.ones((3, 4))) - - -def test_to_xml_open_close_deprecations(): - # Smoke test on deprecated functions - da = GiftiDataArray(np.ones((1,)), 'triangle') - with pytest.raises(ExpiredDeprecationError): - da.to_xml_open() - with pytest.raises(ExpiredDeprecationError): - da.to_xml_close() - - -def test_num_dim_deprecation(): - da = GiftiDataArray(np.ones((2, 3, 4))) - # num_dim is property, set automatically from len(da.dims) - assert da.num_dim == 3 - # setting num_dim to correct value is deprecated - with pytest.raises(ExpiredDeprecationError): - da.num_dim = 3 - # setting num_dim to incorrect value is also deprecated - with pytest.raises(ExpiredDeprecationError): - da.num_dim = 4 - - def test_labeltable(): img = GiftiImage() assert len(img.labeltable.labels) == 0 @@ -217,12 +190,6 @@ def test_labeltable(): img.labeltable = new_table assert len(img.labeltable.labels) == 2 - # Test deprecations - with pytest.raises(ExpiredDeprecationError): - newer_table = GiftiLabelTable() - newer_table.labels += ['test', 'me', 'again'] - img.set_labeltable(newer_table) - def test_metadata(): md = GiftiMetaData(key='value') @@ -240,9 +207,6 @@ def test_metadata(): assert md.data[0].name == 'key' assert md.data[0].value == 'value' assert len(w) == 2 - # Test deprecation - with pytest.raises(ExpiredDeprecationError): - md.get_metadata() def test_metadata_list_interface(): @@ -347,10 +311,6 @@ def assign_rgba(gl, val): pytest.raises(ValueError, assign_rgba, gl3, rgba[:2]) pytest.raises(ValueError, assign_rgba, gl3, rgba.tolist() + rgba.tolist()) - # Test deprecation - with pytest.raises(ExpiredDeprecationError): - gl3.get_rgba() - # Test default value gl4 = GiftiLabel() assert len(gl4.rgba) == 4 diff --git a/nibabel/gifti/tests/test_parse_gifti_fast.py b/nibabel/gifti/tests/test_parse_gifti_fast.py index 14a576d25b..a02761027a 100644 --- a/nibabel/gifti/tests/test_parse_gifti_fast.py +++ b/nibabel/gifti/tests/test_parse_gifti_fast.py @@ -185,18 +185,6 @@ def test_load_metadata(): assert img.version == '1.0' -def test_metadata_deprecations(): - img = load(datafiles[0]) - me = img.meta - - # Test deprecation - with pytest.raises(ExpiredDeprecationError): - img.get_meta() - - with pytest.raises(ExpiredDeprecationError): - img.set_metadata(me) - - def test_load_dataarray1(): img1 = load(DATA_FILE1) # Round trip @@ -319,9 +307,6 @@ def test_load_getbyintent(): da = img.get_arrays_from_intent("NIFTI_INTENT_POINTSET") assert len(da) == 1 - with pytest.raises(ExpiredDeprecationError): - img.getArraysFromIntent("NIFTI_INTENT_POINTSET") - da = img.get_arrays_from_intent("NIFTI_INTENT_TRIANGLE") assert len(da) == 1 @@ -349,18 +334,6 @@ def test_load_labeltable(): assert img.labeltable.labels[1].alpha == 1 -def test_labeltable_deprecations(): - img = load(DATA_FILE6) - lt = img.labeltable - - # Test deprecation - with pytest.raises(ExpiredDeprecationError): - img.get_labeltable() - - with pytest.raises(ExpiredDeprecationError): - img.set_labeltable(lt) - - def test_parse_dataarrays(): fn = 'bad_daa.gii' img = gi.GiftiImage() diff --git a/nibabel/tests/test_removalschedule.py b/nibabel/tests/test_removalschedule.py index 0595e48360..abafe4a1a7 100644 --- a/nibabel/tests/test_removalschedule.py +++ b/nibabel/tests/test_removalschedule.py @@ -47,7 +47,6 @@ ]), ("5.0.0", [("nibabel.dataobj_images", "DataobjImage", "get_data"), ("nibabel.freesurfer.mghformat", "MGHHeader", "_header_data"), - ("nibabel.gifti.gifti", "GiftiDataArray", "num_dim"), ("nibabel.gifti.gifti", "GiftiDataArray", "from_array"), ("nibabel.gifti.gifti", "GiftiDataArray", "to_xml_open"), ("nibabel.gifti.gifti", "GiftiDataArray", "to_xml_close"), @@ -57,7 +56,6 @@ ("nibabel.gifti.gifti", "GiftiImage", "get_metadata"), ("nibabel.gifti.gifti", "GiftiImage", "set_metadata"), ("nibabel.gifti.gifti", "GiftiImage", "getArraysFromIntent"), - ("nibabel.gifti.gifti", "GiftiImage", "getArraysFromIntent"), ("nibabel.gifti.gifti", "GiftiMetaData", "get_metadata"), ("nibabel.gifti.gifti", "GiftiLabel", "get_rgba"), ("nibabel.nicom.dicomwrappers", "Wrapper", "get_affine"), From 1b7a4a02afc932b25963b22e0a8a165118ec8e7e Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:36:45 -0400 Subject: [PATCH 06/17] MNT: Remove imagclasses.{ext,class}_map --- nibabel/__init__.py | 2 +- nibabel/imageclasses.py | 88 ------------------------------ nibabel/tests/test_imageclasses.py | 11 +--- 3 files changed, 2 insertions(+), 99 deletions(-) diff --git a/nibabel/__init__.py b/nibabel/__init__.py index 777cd575ff..152710cccf 100644 --- a/nibabel/__init__.py +++ b/nibabel/__init__.py @@ -61,7 +61,7 @@ from .orientations import (io_orientation, orientation_affine, flip_axis, OrientationError, apply_orientation, aff2axcodes) -from .imageclasses import class_map, ext_map, all_image_classes +from .imageclasses import all_image_classes from . import mriutils from . import streamlines from . import viewers diff --git a/nibabel/imageclasses.py b/nibabel/imageclasses.py index f657822977..6b26ac0c05 100644 --- a/nibabel/imageclasses.py +++ b/nibabel/imageclasses.py @@ -20,12 +20,6 @@ from .parrec import PARRECImage from .spm99analyze import Spm99AnalyzeImage from .spm2analyze import Spm2AnalyzeImage -from .volumeutils import Recoder -from .deprecated import deprecate_with_version - -from .optpkg import optional_package -_, have_scipy, _ = optional_package('scipy') - # Ordered by the load/save priority. all_image_classes = [Nifti1Pair, Nifti1Image, Nifti2Pair, @@ -34,88 +28,6 @@ Minc1Image, Minc2Image, MGHImage, PARRECImage, GiftiImage, AFNIImage] - -# DEPRECATED: mapping of names to classes and class functionality -class ClassMapDict(dict): - - @deprecate_with_version('class_map is deprecated.', - '2.1', '4.0') - def __getitem__(self, *args, **kwargs): - return super(ClassMapDict, self).__getitem__(*args, **kwargs) - - -class_map = ClassMapDict( - analyze={'class': AnalyzeImage, # Image class - 'ext': '.img', # characteristic image extension - 'has_affine': False, # class can store an affine - 'makeable': True, # empty image can be easily made in memory - 'rw': True}, # image can be written - spm99analyze={'class': Spm99AnalyzeImage, - 'ext': '.img', - 'has_affine': True, - 'makeable': True, - 'rw': have_scipy}, - spm2analyze={'class': Spm2AnalyzeImage, - 'ext': '.img', - 'has_affine': True, - 'makeable': True, - 'rw': have_scipy}, - nifti_pair={'class': Nifti1Pair, - 'ext': '.img', - 'has_affine': True, - 'makeable': True, - 'rw': True}, - nifti_single={'class': Nifti1Image, - 'ext': '.nii', - 'has_affine': True, - 'makeable': True, - 'rw': True}, - minc={'class': Minc1Image, - 'ext': '.mnc', - 'has_affine': True, - 'makeable': True, - 'rw': False}, - mgh={'class': MGHImage, - 'ext': '.mgh', - 'has_affine': True, - 'makeable': True, - 'rw': True}, - mgz={'class': MGHImage, - 'ext': '.mgz', - 'has_affine': True, - 'makeable': True, - 'rw': True}, - par={'class': PARRECImage, - 'ext': '.par', - 'has_affine': True, - 'makeable': False, - 'rw': False}, - afni={'class': AFNIImage, - 'ext': '.brik', - 'has_affine': True, - 'makeable': False, - 'rw': False}) - - -class ExtMapRecoder(Recoder): - - @deprecate_with_version('ext_map is deprecated.', - '2.1', '4.0') - def __getitem__(self, *args, **kwargs): - return super(ExtMapRecoder, self).__getitem__(*args, **kwargs) - - -# mapping of extensions to default image class names -ext_map = ExtMapRecoder(( - ('nifti_single', '.nii'), - ('nifti_pair', '.img', '.hdr'), - ('minc', '.mnc'), - ('mgh', '.mgh'), - ('mgz', '.mgz'), - ('par', '.par'), - ('brik', '.brik') -)) - # Image classes known to require spatial axes to be first in index ordering. # When adding an image class, consider whether the new class should be listed # here. diff --git a/nibabel/tests/test_imageclasses.py b/nibabel/tests/test_imageclasses.py index 43096e4347..601414e012 100644 --- a/nibabel/tests/test_imageclasses.py +++ b/nibabel/tests/test_imageclasses.py @@ -14,10 +14,9 @@ from nibabel.nifti2 import Nifti2Image from nibabel import imageclasses -from nibabel.imageclasses import spatial_axes_first, class_map, ext_map +from nibabel.imageclasses import spatial_axes_first from nibabel.optpkg import optional_package -from nibabel.deprecator import ExpiredDeprecationError have_h5py = optional_package('h5py')[1] @@ -49,11 +48,3 @@ def test_spatial_axes_first(): img = nib.load(pjoin(DATA_DIR, fname)) assert len(img.shape) == 4 assert not spatial_axes_first(img) - - -def test_deprecations(): - with pytest.raises(ExpiredDeprecationError): - class_map['nifti_single'] - with pytest.raises(ExpiredDeprecationError): - nifti_ext = ext_map['.nii'] - From 7dd75f83b9d549206562aedc4511a093efe6859f Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:37:51 -0400 Subject: [PATCH 07/17] MNT: Remove loadsave.which_analyze_type --- nibabel/loadsave.py | 42 --------------------------- nibabel/tests/test_image_load_save.py | 9 ------ 2 files changed, 51 deletions(-) diff --git a/nibabel/loadsave.py b/nibabel/loadsave.py index ff176f541d..763bf20788 100644 --- a/nibabel/loadsave.py +++ b/nibabel/loadsave.py @@ -282,45 +282,3 @@ def read_img_data(img, prefer='scaled'): if prefer == 'scaled': return hdr.data_from_fileobj(fileobj) return hdr.raw_data_from_fileobj(fileobj) - - -@deprecate_with_version('which_analyze_type deprecated.', '3.2', '4.0') -def which_analyze_type(binaryblock): - """ Is `binaryblock` from NIfTI1, NIfTI2 or Analyze header? - - Parameters - ---------- - binaryblock : bytes - The `binaryblock` is 348 bytes that might be NIfTI1, NIfTI2, Analyze, - or None of the the above. - - Returns - ------- - hdr_type : str - * a nifti1 header (pair or single) -> return 'nifti1' - * a nifti2 header (pair or single) -> return 'nifti2' - * an Analyze header -> return 'analyze' - * None of the above -> return None - - Notes - ----- - Algorithm: - - * read in the first 4 bytes from the file as 32-bit int ``sizeof_hdr`` - * if ``sizeof_hdr`` is 540 or byteswapped 540 -> assume nifti2 - * Check for 'ni1', 'n+1' magic -> assume nifti1 - * if ``sizeof_hdr`` is 348 or byteswapped 348 assume Analyze - * Return None - """ - from .nifti1 import header_dtype - hdr_struct = np.ndarray(shape=(), dtype=header_dtype, buffer=binaryblock) - bs_hdr_struct = hdr_struct.byteswap() - sizeof_hdr = hdr_struct['sizeof_hdr'] - bs_sizeof_hdr = bs_hdr_struct['sizeof_hdr'] - if 540 in (sizeof_hdr, bs_sizeof_hdr): - return 'nifti2' - if hdr_struct['magic'] in (b'ni1', b'n+1'): - return 'nifti1' - if 348 in (sizeof_hdr, bs_sizeof_hdr): - return 'analyze' - return None diff --git a/nibabel/tests/test_image_load_save.py b/nibabel/tests/test_image_load_save.py index 07c8bf8c5d..12a49ecd7d 100644 --- a/nibabel/tests/test_image_load_save.py +++ b/nibabel/tests/test_image_load_save.py @@ -29,7 +29,6 @@ from ..volumeutils import native_code, swapped_code from ..optpkg import optional_package from ..spatialimages import SpatialImage -from ..deprecator import ExpiredDeprecationError from numpy.testing import assert_array_equal, assert_array_almost_equal import pytest @@ -271,14 +270,6 @@ def test_filename_save(): shutil.rmtree(pth) -def test_analyze_detection(): - # Test detection of Analyze, Nifti1 and Nifti2 - # Algorithm is as described in loadsave:which_analyze_type - hdr = Nifti1Header(b'\0' * 348, check=False) - with pytest.raises(ExpiredDeprecationError): - nils.which_analyze_type(hdr.binaryblock) - - def test_guessed_image_type(): # Test whether we can guess the image type from example files with pytest.deprecated_call(): From c185da2d1d3135020765a293b934670be9373913 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:39:14 -0400 Subject: [PATCH 08/17] MNT: Remove volumeutils.BinOpener/allopen --- nibabel/tests/test_openers.py | 6 ------ nibabel/tests/test_volumeutils.py | 9 --------- nibabel/volumeutils.py | 32 +------------------------------ 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/nibabel/tests/test_openers.py b/nibabel/tests/test_openers.py index 0a687353e3..b25dc2db6d 100644 --- a/nibabel/tests/test_openers.py +++ b/nibabel/tests/test_openers.py @@ -23,7 +23,6 @@ DeterministicGzipFile, ) from ..tmpdirs import InTemporaryDirectory -from ..volumeutils import BinOpener from ..optpkg import optional_package import unittest @@ -114,11 +113,6 @@ def test_Opener_various(): assert fobj.fileno() != 0 -def test_BinOpener(): - with pytest.raises(ExpiredDeprecationError): - BinOpener('test.txt', 'r') - - class MockIndexedGzipFile(GzipFile): def __init__(self, *args, **kwargs): self._drop_handles = kwargs.pop('drop_handles', False) diff --git a/nibabel/tests/test_volumeutils.py b/nibabel/tests/test_volumeutils.py index 67e776daf1..3e6ba1bab4 100644 --- a/nibabel/tests/test_volumeutils.py +++ b/nibabel/tests/test_volumeutils.py @@ -29,7 +29,6 @@ from ..volumeutils import (array_from_file, _is_compressed_fobj, array_to_file, - allopen, # for backwards compatibility fname_ext_ul_case, write_zeros, seek_tell, @@ -49,7 +48,6 @@ from ..openers import Opener, BZ2File from ..casting import (floor_log2, type_info, OK_FLOATS, shared_range) -from ..deprecator import ExpiredDeprecationError from ..optpkg import optional_package from numpy.testing import (assert_array_almost_equal, @@ -1042,13 +1040,6 @@ def test_fname_ext_ul_case(): assert fname_ext_ul_case('afile.TxT') == 'afile.TxT' -def test_allopen_deprecated(): - # This import into volumeutils is for compatibility. The code is the - # ``openers`` module. - with pytest.raises(ExpiredDeprecationError): - fobj = allopen(__file__) - - def test_shape_zoom_affine(): shape = (3, 5, 7) zooms = (3, 2, 1) diff --git a/nibabel/volumeutils.py b/nibabel/volumeutils.py index 4e22c6ce29..7f18c20f3f 100644 --- a/nibabel/volumeutils.py +++ b/nibabel/volumeutils.py @@ -19,8 +19,7 @@ import numpy as np from .casting import shared_range, OK_FLOATS -from .openers import Opener, BZ2File, IndexedGzipFile -from .deprecated import deprecate_with_version +from .openers import BZ2File, IndexedGzipFile from .externals.oset import OrderedSet from .optpkg import optional_package @@ -1337,17 +1336,6 @@ def rec2dict(rec): return dct -class BinOpener(Opener): - """ Deprecated class that used to handle .mgz through specialized logic.""" - __doc__ = Opener.__doc__ - - @deprecate_with_version('BinOpener class deprecated. ' - "Please use Opener class instead.", - '2.1', '4.0') - def __init__(self, *args, **kwargs): - return super(BinOpener, self).__init__(*args, **kwargs) - - def fname_ext_ul_case(fname): """ `fname` with ext changed to upper / lower case if file exists @@ -1378,21 +1366,3 @@ def fname_ext_ul_case(fname): if exists(mod_fname): return mod_fname return fname - - -@deprecate_with_version('allopen is deprecated. ' - 'Please use "Opener" class instead.', - '2.0', '4.0') -def allopen(fileish, *args, **kwargs): - """ Compatibility wrapper for old ``allopen`` function - - Wraps creation of ``Opener`` instance, while picking up module global - ``default_compresslevel``. - - Please see docstring of ``Opener`` for details. - """ - - class MyOpener(Opener): - default_compresslevel = default_compresslevel - - return MyOpener(fileish, *args, **kwargs) From 1fb2b4e6b83f2be6f2cc28be4a2ef0b0c04c8b58 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:40:05 -0400 Subject: [PATCH 09/17] MNT: Remove orientations.orientation_affine --- nibabel/__init__.py | 3 +-- nibabel/orientations.py | 8 -------- nibabel/tests/test_orientations.py | 9 +-------- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/nibabel/__init__.py b/nibabel/__init__.py index 152710cccf..f96e80f0eb 100644 --- a/nibabel/__init__.py +++ b/nibabel/__init__.py @@ -58,8 +58,7 @@ from .freesurfer import MGHImage from .funcs import (squeeze_image, concat_images, four_to_three, as_closest_canonical) -from .orientations import (io_orientation, orientation_affine, - flip_axis, OrientationError, +from .orientations import (io_orientation, flip_axis, OrientationError, apply_orientation, aff2axcodes) from .imageclasses import all_image_classes from . import mriutils diff --git a/nibabel/orientations.py b/nibabel/orientations.py index 1cfb07e55f..fab106cab5 100644 --- a/nibabel/orientations.py +++ b/nibabel/orientations.py @@ -228,14 +228,6 @@ def inv_ornt_aff(ornt, shape): return np.dot(undo_flip, undo_reorder) -@deprecate_with_version('orientation_affine deprecated. ' - 'Please use inv_ornt_aff instead.', - '3.0', - '4.0') -def orientation_affine(ornt, shape): - return inv_ornt_aff(ornt, shape) - - @deprecate_with_version('flip_axis is deprecated. ' 'Please use numpy.flip instead.', '3.2', diff --git a/nibabel/tests/test_orientations.py b/nibabel/tests/test_orientations.py index 22d899c4dc..77b892acbc 100644 --- a/nibabel/tests/test_orientations.py +++ b/nibabel/tests/test_orientations.py @@ -17,11 +17,9 @@ from ..orientations import (io_orientation, ornt_transform, inv_ornt_aff, flip_axis, apply_orientation, OrientationError, - ornt2axcodes, axcodes2ornt, aff2axcodes, - orientation_affine) + ornt2axcodes, axcodes2ornt, aff2axcodes) from ..affines import from_matvec, to_matvec -from ..deprecator import ExpiredDeprecationError IN_ARRS = [np.eye(4), @@ -355,11 +353,6 @@ def test_inv_ornt_aff(): inv_ornt_aff([[0, 1], [1, -1], [np.nan, np.nan]], (3, 4, 5)) -def test_orientation_affine_deprecation(): - with pytest.raises(ExpiredDeprecationError): - orientation_affine([[0, 1], [1, -1], [2, 1]], (3, 4, 5)) - - def test_flip_axis_deprecation(): a = np.arange(24).reshape((2, 3, 4)) axis = 1 From 60e3a13c90770602d2fab652bd0c81180718afd4 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:42:00 -0400 Subject: [PATCH 10/17] MNT: Complete deprecations in spatialimages --- nibabel/spatialimages.py | 24 ------------------------ nibabel/tests/test_ecat.py | 4 ---- nibabel/tests/test_image_api.py | 9 +-------- nibabel/tests/test_spatialimages.py | 10 +--------- 4 files changed, 2 insertions(+), 45 deletions(-) diff --git a/nibabel/spatialimages.py b/nibabel/spatialimages.py index d2e69a0fc5..09744d0149 100644 --- a/nibabel/spatialimages.py +++ b/nibabel/spatialimages.py @@ -21,9 +21,6 @@ methods: * .get_fdata() - * .get_data() (deprecated, use get_fdata() instead) - * .get_affine() (deprecated, use affine property instead) - * .get_header() (deprecated, use header property instead) * .to_filename(fname) - writes data to filename(s) derived from ``fname``, where the derivation may differ between formats. * to_file_map() - save image to files with which the image is already @@ -141,7 +138,6 @@ from .viewers import OrthoSlicer3D from .volumeutils import shape_zoom_affine from .fileslice import canonical_slicers -from .deprecated import deprecate_with_version from .orientations import apply_orientation, inv_ornt_aff @@ -307,17 +303,6 @@ def supported_np_types(obj): return set(supported) -class Header(SpatialHeader): - """Alias for SpatialHeader; kept for backwards compatibility.""" - - @deprecate_with_version('Header class is deprecated.\n' - 'Please use SpatialHeader instead.' - 'instead.', - '2.1', '4.0') - def __init__(self, *args, **kwargs): - super(Header, self).__init__(*args, **kwargs) - - class ImageDataError(Exception): pass @@ -527,15 +512,6 @@ def get_data_dtype(self): def set_data_dtype(self, dtype): self._header.set_data_dtype(dtype) - @deprecate_with_version('get_affine method is deprecated.\n' - 'Please use the ``img.affine`` property ' - 'instead.', - '2.1', '4.0') - def get_affine(self): - """ Get affine from image - """ - return self.affine - @classmethod def from_image(klass, img): """ Class method to create new instance of own class from `img` diff --git a/nibabel/tests/test_ecat.py b/nibabel/tests/test_ecat.py index 3a48f204d3..adda5433d1 100644 --- a/nibabel/tests/test_ecat.py +++ b/nibabel/tests/test_ecat.py @@ -240,10 +240,6 @@ def test_isolation(self): aff[0, 0] = 99 assert not np.all(img.affine == aff) - def test_get_affine_deprecated(self): - with pytest.raises(ExpiredDeprecationError): - self.img.get_affine() - def test_float_affine(self): # Check affines get converted to float img_klass = self.image_class diff --git a/nibabel/tests/test_image_api.py b/nibabel/tests/test_image_api.py index 21c7b14086..aa4fa84736 100644 --- a/nibabel/tests/test_image_api.py +++ b/nibabel/tests/test_image_api.py @@ -502,8 +502,7 @@ def validate_header_shape(self, imaker, params): class AffineMixin: """ Adds test of affine property, method - Add this one if your image has an ``affine`` property. If so, it should - (for now) also have a ``get_affine`` method returning the same result. + Add this one if your image has an ``affine`` property. """ def validate_affine(self, imaker, params): @@ -517,12 +516,6 @@ def validate_affine(self, imaker, params): with pytest.raises(AttributeError): img.affine = np.eye(4) - def validate_affine_deprecated(self, imaker, params): - # Check deprecated affine API - img = imaker() - with pytest.raises(ExpiredDeprecationError): - img.get_affine() - class SerializeMixin: def validate_to_from_stream(self, imaker, params): diff --git a/nibabel/tests/test_spatialimages.py b/nibabel/tests/test_spatialimages.py index e7cad0de2c..fc11452151 100644 --- a/nibabel/tests/test_spatialimages.py +++ b/nibabel/tests/test_spatialimages.py @@ -15,7 +15,7 @@ import numpy as np from io import BytesIO -from ..spatialimages import SpatialHeader, SpatialImage, HeaderDataError, Header +from ..spatialimages import SpatialHeader, SpatialImage, HeaderDataError from ..imageclasses import spatial_axes_first import pytest @@ -30,7 +30,6 @@ ) from ..tmpdirs import InTemporaryDirectory -from ..deprecator import ExpiredDeprecationError from .. import load as top_load def test_header_init(): @@ -605,10 +604,3 @@ def test_load_mmap(self): func(param1, mmap='rw') with pytest.raises(ValueError): func(param1, mmap='r+') - - -def test_header_deprecated(): - class MyHeader(Header): - pass - with pytest.raises(ExpiredDeprecationError): - MyHeader() From e0386150dae9f28f136f05fcc6c8192cb7a16cf4 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:42:51 -0400 Subject: [PATCH 11/17] MNT: Remove nicom.dicomwrappers.Wrapper.get_affine --- nibabel/nicom/dicomwrappers.py | 9 --------- nibabel/nicom/tests/test_dicomwrappers.py | 3 --- 2 files changed, 12 deletions(-) diff --git a/nibabel/nicom/dicomwrappers.py b/nibabel/nicom/dicomwrappers.py index d1ca3ee173..9f180a86a3 100755 --- a/nibabel/nicom/dicomwrappers.py +++ b/nibabel/nicom/dicomwrappers.py @@ -22,7 +22,6 @@ from .dwiparams import B2q, nearest_pos_semi_def, q2bg from ..openers import ImageOpener from ..onetime import auto_attr as one_time -from ..deprecated import deprecate_with_version pydicom = optional_package("pydicom")[0] @@ -101,7 +100,6 @@ class Wrapper: Methods: - * get_affine() (deprecated, use affine property instead) * get_data() * get_pixel_array() * is_same_series(other) @@ -293,13 +291,6 @@ def get(self, key, default=None): """ Get values from underlying dicom data """ return self.dcm_data.get(key, default) - @deprecate_with_version('get_affine method is deprecated.\n' - 'Please use the ``img.affine`` property ' - 'instead.', - '2.5.1', '4.0') - def get_affine(self): - return self.affine - @property def affine(self): """ Mapping between voxel and DICOM coordinate system diff --git a/nibabel/nicom/tests/test_dicomwrappers.py b/nibabel/nicom/tests/test_dicomwrappers.py index fcb3cc1703..d65afc6d27 100755 --- a/nibabel/nicom/tests/test_dicomwrappers.py +++ b/nibabel/nicom/tests/test_dicomwrappers.py @@ -13,7 +13,6 @@ from .. import dicomwrappers as didw from .. import dicomreaders as didr from ...volumeutils import endian_codes -from ...deprecator import ExpiredDeprecationError import pytest from unittest import TestCase @@ -632,8 +631,6 @@ def test_affine(self): # Make sure we find orientation/position/spacing info dw = didw.wrapper_from_file(DATA_FILE_4D) aff = dw.affine - with pytest.raises(ExpiredDeprecationError): - dw.get_affine() @dicom_test def test_data_real(self): From aec9bd65f2e0e8b337ab8f01a1c26663096e2bbf Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:43:42 -0400 Subject: [PATCH 12/17] MNT: Remove ArraySequence.data property --- nibabel/streamlines/array_sequence.py | 12 ------------ nibabel/streamlines/tests/test_array_sequence.py | 6 ------ 2 files changed, 18 deletions(-) diff --git a/nibabel/streamlines/array_sequence.py b/nibabel/streamlines/array_sequence.py index 5d40937b1c..cff930aaee 100644 --- a/nibabel/streamlines/array_sequence.py +++ b/nibabel/streamlines/array_sequence.py @@ -5,8 +5,6 @@ import numpy as np -from ..deprecated import deprecate_with_version - MEGABYTE = 1024 * 1024 @@ -154,16 +152,6 @@ def total_nb_rows(self): """ Total number of rows in this array sequence. """ return np.sum(self._lengths) - @property - @deprecate_with_version("'ArraySequence.data' property is deprecated.\n" - "Please use the 'ArraySequence.get_data()' method instead", - '3.0', '4.0') - def data(self): - """ Elements in this array sequence. """ - view = self._data.view() - view.setflags(write=False) - return view - def get_data(self): """ Returns a *copy* of the elements in this array sequence. diff --git a/nibabel/streamlines/tests/test_array_sequence.py b/nibabel/streamlines/tests/test_array_sequence.py index 4a5c21aa2e..b75b4432d3 100644 --- a/nibabel/streamlines/tests/test_array_sequence.py +++ b/nibabel/streamlines/tests/test_array_sequence.py @@ -10,7 +10,6 @@ from numpy.testing import assert_array_equal from ..array_sequence import ArraySequence, is_array_sequence, concatenate -from ...deprecator import ExpiredDeprecationError SEQ_DATA = {} @@ -95,11 +94,6 @@ def test_creating_arraysequence_from_list(self): check_arr_seq(ArraySequence(iter(SEQ_DATA['data']), buffer_size), SEQ_DATA['data']) - def test_deprecated_data_attribute(self): - seq = ArraySequence(SEQ_DATA['data']) - with pytest.raises(ExpiredDeprecationError): - seq.data - def test_creating_arraysequence_from_generator(self): gen_1, gen_2 = itertools.tee((e for e in SEQ_DATA['data'])) seq = ArraySequence(gen_1) From f7592083571555a1bc6f86a62aa8535ee3403ead Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:44:13 -0400 Subject: [PATCH 13/17] MNT: Remove EcatImage.from_filespec --- nibabel/ecat.py | 9 --------- nibabel/tests/test_ecat.py | 6 ------ 2 files changed, 15 deletions(-) diff --git a/nibabel/ecat.py b/nibabel/ecat.py index 494ea95e2d..54f600f147 100644 --- a/nibabel/ecat.py +++ b/nibabel/ecat.py @@ -54,7 +54,6 @@ from .arraywriters import make_array_writer from .wrapstruct import WrapStruct from .fileslice import canonical_slicers, predict_shape, slice2outax -from .deprecated import deprecate_with_version BLOCK_SIZE = 512 @@ -863,14 +862,6 @@ def get_subheaders(self): """get access to subheaders""" return self._subheader - @classmethod - @deprecate_with_version('from_filespec class method is deprecated.\n' - 'Please use the ``from_file_map`` class method ' - 'instead.', - '2.1', '4.0') - def from_filespec(klass, filespec): - return klass.from_filename(filespec) - @staticmethod def _get_fileholders(file_map): """ returns files specific to header and image of the image diff --git a/nibabel/tests/test_ecat.py b/nibabel/tests/test_ecat.py index adda5433d1..9e56fd73c7 100644 --- a/nibabel/tests/test_ecat.py +++ b/nibabel/tests/test_ecat.py @@ -23,7 +23,6 @@ from ..testing import data_path, suppress_warnings from ..tmpdirs import InTemporaryDirectory -from ..deprecator import ExpiredDeprecationError from . import test_wrapstruct as tws from .test_fileslice import slicer_samples @@ -268,8 +267,3 @@ def test_mlist_regression(self): # Test mlist is as same as for nibabel 1.3.0 assert_array_equal(self.img.get_mlist(), [[16842758, 3, 3011, 1]]) - - -def test_from_filespec_deprecation(): - with pytest.raises(ExpiredDeprecationError): - EcatImage.from_filespec(ecat_file) From 5e3314c337bd037a03f6247f42c1de8d56354bc4 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:44:48 -0400 Subject: [PATCH 14/17] MNT: Remove FileBasedImage.get_header --- nibabel/filebasedimages.py | 11 ----------- nibabel/tests/test_image_api.py | 6 ------ 2 files changed, 17 deletions(-) diff --git a/nibabel/filebasedimages.py b/nibabel/filebasedimages.py index 5162263a28..17ac3e8180 100644 --- a/nibabel/filebasedimages.py +++ b/nibabel/filebasedimages.py @@ -15,7 +15,6 @@ from .filename_parser import (types_filenames, TypesFilenamesError, splitext_addext) from .openers import ImageOpener -from .deprecated import deprecate_with_version class ImageFileError(Exception): @@ -79,7 +78,6 @@ class FileBasedImage: methods: - * get_header() (deprecated, use header property instead) * to_filename(fname) - writes data to filename(s) derived from ``fname``, where the derivation may differ between formats. * to_file_map() - save image to files with which the image is already @@ -208,15 +206,6 @@ def __getitem__(self, key): """ raise TypeError("Cannot slice image objects.") - @deprecate_with_version('get_header method is deprecated.\n' - 'Please use the ``img.header`` property ' - 'instead.', - '2.1', '4.0') - def get_header(self): - """ Get header from image - """ - return self.header - def get_filename(self): """ Fetch the image filename diff --git a/nibabel/tests/test_image_api.py b/nibabel/tests/test_image_api.py index aa4fa84736..680458659d 100644 --- a/nibabel/tests/test_image_api.py +++ b/nibabel/tests/test_image_api.py @@ -119,12 +119,6 @@ def validate_header(self, imaker, params): with pytest.raises(AttributeError): img.header = hdr - def validate_header_deprecated(self, imaker, params): - # Check deprecated header API - img = imaker() - with pytest.raises(ExpiredDeprecationError): - hdr = img.get_header() - def validate_filenames(self, imaker, params): # Validate the filename, file_map interface From 420ea32a0979c14a6979f1d7b7374a5be50af426 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:48:21 -0400 Subject: [PATCH 15/17] MNT: Remove nan2zero argument to ArrayWriter.to_fileobj --- nibabel/arraywriters.py | 29 +++-------------------------- nibabel/tests/test_arraywriters.py | 17 ----------------- 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/nibabel/arraywriters.py b/nibabel/arraywriters.py index cdbec32fc6..c2bbb2912c 100644 --- a/nibabel/arraywriters.py +++ b/nibabel/arraywriters.py @@ -34,7 +34,6 @@ def __init__(self, array, out_dtype=None) from .casting import (int_to_float, as_int, int_abs, type_info, floor_exact, best_float, shared_range) from .volumeutils import finite_range, array_to_file -from .deprecator import ExpiredDeprecationError class WriterError(Exception): @@ -185,19 +184,6 @@ def finite_range(self): self._has_nan = has_nan return self._finite_range - def _check_nan2zero(self, nan2zero): - if nan2zero is None: - return - if nan2zero != self._nan2zero: - raise WriterError('Deprecated `nan2zero` argument to `to_fileobj` ' - 'must be same as class value set in __init__') - raise ExpiredDeprecationError( - 'Please remove `nan2zero` from call to `to_fileobj` ' - 'and use in instance __init__ instead.\n' - '* deprecated in version: 2.0\n' - '* Raises ExpiredDeprecationError as of version: 4.0\n' - ) - def _needs_nan2zero(self): """ True if nan2zero check needed for writing array """ return (self._nan2zero and @@ -205,7 +191,7 @@ def _needs_nan2zero(self): self.out_dtype.kind in 'iu' and self.has_nan) - def to_fileobj(self, fileobj, order='F', nan2zero=None): + def to_fileobj(self, fileobj, order='F'): """ Write array into `fileobj` Parameters @@ -213,10 +199,7 @@ def to_fileobj(self, fileobj, order='F', nan2zero=None): fileobj : file-like object order : {'F', 'C'} order (Fortran or C) to which to write array - nan2zero : {None, True, False}, optional, deprecated - Deprecated version of argument to __init__ with same name """ - self._check_nan2zero(nan2zero) array_to_file(self._array, fileobj, self._out_dtype, @@ -362,7 +345,7 @@ def _writing_range(self): return mn, mx return None, None - def to_fileobj(self, fileobj, order='F', nan2zero=None): + def to_fileobj(self, fileobj, order='F'): """ Write array into `fileobj` Parameters @@ -370,10 +353,7 @@ def to_fileobj(self, fileobj, order='F', nan2zero=None): fileobj : file-like object order : {'F', 'C'} order (Fortran or C) to which to write array - nan2zero : {None, True, False}, optional, deprecated - Deprecated version of argument to __init__ with same name """ - self._check_nan2zero(nan2zero) mn, mx = self._writing_range() array_to_file(self._array, fileobj, @@ -536,7 +516,7 @@ def _set_inter(self, val): self._inter = np.squeeze(self.scaler_dtype.type(val)) inter = property(_get_inter, _set_inter, None, 'get/set inter') - def to_fileobj(self, fileobj, order='F', nan2zero=None): + def to_fileobj(self, fileobj, order='F'): """ Write array into `fileobj` Parameters @@ -544,10 +524,7 @@ def to_fileobj(self, fileobj, order='F', nan2zero=None): fileobj : file-like object order : {'F', 'C'} order (Fortran or C) to which to write array - nan2zero : {None, True, False}, optional, deprecated - Deprecated version of argument to __init__ with same name """ - self._check_nan2zero(nan2zero) mn, mx = self._writing_range() array_to_file(self._array, fileobj, diff --git a/nibabel/tests/test_arraywriters.py b/nibabel/tests/test_arraywriters.py index df50b4cd6b..de55cd334b 100644 --- a/nibabel/tests/test_arraywriters.py +++ b/nibabel/tests/test_arraywriters.py @@ -13,7 +13,6 @@ make_array_writer, get_slope_inter) from ..casting import int_abs, type_info, shared_range, on_powerpc from ..volumeutils import array_from_file, apply_read_scaling, _dt_min_max -from ..deprecator import ExpiredDeprecationError from numpy.testing import assert_array_almost_equal, assert_array_equal import pytest @@ -506,14 +505,6 @@ def test_nan2zero(): aw = awt(arr, np.float32, **kwargs) data_back = round_trip(aw) assert_array_equal(np.isnan(data_back), [True, False]) - # Expired deprecation error for nan2zero as argument to `to_fileobj` - with pytest.raises(ExpiredDeprecationError): - aw.to_fileobj(BytesIO(), 'F', True) - with pytest.raises(ExpiredDeprecationError): - aw.to_fileobj(BytesIO(), 'F', nan2zero=True) - # Error if nan2zero is not the value set at initialization - with pytest.raises(WriterError): - aw.to_fileobj(BytesIO(), 'F', False) # set explicitly aw = awt(arr, np.float32, nan2zero=True, **kwargs) data_back = round_trip(aw) @@ -527,14 +518,6 @@ def test_nan2zero(): data_back = round_trip(aw) astype_res = np.array(np.nan).astype(np.int32) assert_array_equal(data_back, [astype_res, 99]) - # Expired deprecation error for nan2zero as argument to `to_fileobj` - with pytest.raises(ExpiredDeprecationError): - aw.to_fileobj(BytesIO(), 'F', False) - with pytest.raises(ExpiredDeprecationError): - aw.to_fileobj(BytesIO(), 'F', nan2zero=False) - # Error if nan2zero is not the value set at initialization - with pytest.raises(WriterError): - aw.to_fileobj(BytesIO(), 'F', True) def test_byte_orders(): From 9463ca25d0de53570f48c64ff7f96cc47d263dd2 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:52:37 -0400 Subject: [PATCH 16/17] MNT: Various removals not listed in removal schedule --- nibabel/dataobj_images.py | 7 -- nibabel/freesurfer/mghformat.py | 40 --------- nibabel/freesurfer/tests/test_mghformat.py | 15 ---- nibabel/gifti/__init__.py | 1 - nibabel/gifti/giftiio.py | 85 -------------------- nibabel/gifti/parse_gifti_fast.py | 21 ----- nibabel/gifti/tests/test_giftiio.py | 25 ------ nibabel/gifti/tests/test_parse_gifti_fast.py | 14 +--- nibabel/parrec.py | 24 ------ nibabel/tests/test_image_api.py | 10 --- nibabel/tests/test_parrec.py | 7 -- 11 files changed, 1 insertion(+), 248 deletions(-) delete mode 100644 nibabel/gifti/giftiio.py delete mode 100644 nibabel/gifti/tests/test_giftiio.py diff --git a/nibabel/dataobj_images.py b/nibabel/dataobj_images.py index 7480a5cbfc..f1c6b663c0 100644 --- a/nibabel/dataobj_images.py +++ b/nibabel/dataobj_images.py @@ -48,13 +48,6 @@ def __init__(self, dataobj, header=None, extra=None, file_map=None): def dataobj(self): return self._dataobj - @property - @deprecate_with_version('_data attribute not part of public API. ' - 'please use "dataobj" property instead.', - '2.0', '4.0') - def _data(self): - return self._dataobj - @deprecate_with_version('get_data() is deprecated in favor of get_fdata(),' ' which has a more predictable return type. To ' 'obtain get_data() behavior going forward, use ' diff --git a/nibabel/freesurfer/mghformat.py b/nibabel/freesurfer/mghformat.py index d23c8e571f..9d2cdb905b 100644 --- a/nibabel/freesurfer/mghformat.py +++ b/nibabel/freesurfer/mghformat.py @@ -24,7 +24,6 @@ from ..openers import ImageOpener from ..batteryrunners import BatteryRunner, Report from ..wrapstruct import LabeledWrapStruct -from ..deprecated import deprecate_with_version # mgh header # See https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/MghFormat @@ -462,45 +461,6 @@ def diagnose_binaryblock(klass, binaryblock, endianness=None): return '\n'.join([report.message for report in reports if report.message]) - class _HeaderData: - """ Provide interface to deprecated MGHHeader fields""" - def __init__(self, structarr): - self._structarr = structarr - - def __getitem__(self, item): - sa = self._structarr - if item == 'mrparams': - return np.hstack((sa['tr'], sa['flip_angle'], sa['te'], sa['ti'])) - return sa[item] - - def __setitem__(self, item, val): - sa = self._structarr - if item == 'mrparams': - sa['tr'], sa['flip_angle'], sa['te'], sa['ti'] = val - else: - sa[item] = val - - @property - @deprecate_with_version('_header_data is deprecated.\n' - 'Please use the _structarr interface instead.\n' - 'Note also that some fields have changed name and ' - 'shape.', - '2.3', '4.0') - def _header_data(self): - """ Deprecated field-access interface """ - return self._HeaderData(self._structarr) - - def __getitem__(self, item): - if item == 'mrparams': - return self._header_data[item] - return super(MGHHeader, self).__getitem__(item) - - def __setitem__(self, item, value): - if item == 'mrparams': - self._header_data[item] = value - else: - super(MGHHeader, self).__setitem__(item, value) - class MGHImage(SpatialImage, SerializableImage): """ Class for MGH format image diff --git a/nibabel/freesurfer/tests/test_mghformat.py b/nibabel/freesurfer/tests/test_mghformat.py index 9c75d06208..4c812087c2 100644 --- a/nibabel/freesurfer/tests/test_mghformat.py +++ b/nibabel/freesurfer/tests/test_mghformat.py @@ -22,7 +22,6 @@ from ...volumeutils import sys_is_le from ...wrapstruct import WrapStructError from ... import imageglobals -from ...deprecator import ExpiredDeprecationError import pytest @@ -340,20 +339,6 @@ def test_mghheader_default_structarr(): MGHHeader.default_structarr(endianness=endianness) -def test_deprecated_fields(): - hdr = MGHHeader() - hdr_data = MGHHeader._HeaderData(hdr.structarr) - - # mrparams is the only deprecated field at the moment - # Accessing hdr_data is equivalent to accessing hdr, so double all checks, - # but expect success on hdr_data['mrparams'] - with pytest.raises(ExpiredDeprecationError): - hdr['mrparams'] - with pytest.raises(ExpiredDeprecationError): - hdr['mrparams'] = [1, 2, 3, 4] - assert_array_equal(hdr_data['mrparams'], 0) - - class TestMGHImage(tsi.TestSpatialImage, tsi.MmapImageMixin): """ Apply general image tests to MGHImage """ diff --git a/nibabel/gifti/__init__.py b/nibabel/gifti/__init__.py index c9bf85b3a0..54bfbd0ffa 100644 --- a/nibabel/gifti/__init__.py +++ b/nibabel/gifti/__init__.py @@ -17,6 +17,5 @@ gifti """ -from .giftiio import read, write from .gifti import (GiftiMetaData, GiftiNVPairs, GiftiLabelTable, GiftiLabel, GiftiCoordSystem, GiftiDataArray, GiftiImage) diff --git a/nibabel/gifti/giftiio.py b/nibabel/gifti/giftiio.py deleted file mode 100644 index 46219e8c1d..0000000000 --- a/nibabel/gifti/giftiio.py +++ /dev/null @@ -1,85 +0,0 @@ -# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- -# vi: set ft=python sts=4 ts=4 sw=4 et: -### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## -# -# See COPYING file distributed along with the NiBabel package for the -# copyright and license terms. -# -### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## -# General Gifti Input - Output to and from the filesystem -# Stephan Gerhard, Oktober 2010 -############## - -from ..deprecated import deprecate_with_version - - -@deprecate_with_version('giftiio.read function deprecated. ' - "Use nibabel.load() instead.", - '2.1', '4.0') -def read(filename): - """ Load a Gifti image from a file - - Parameters - ---------- - filename : string - The Gifti file to open, it has usually ending .gii - - Returns - ------- - img : GiftiImage - Returns a GiftiImage - """ - from ..loadsave import load - return load(filename) - - -@deprecate_with_version('giftiio.write function deprecated. ' - "Use nibabel.save() instead.", - '2.1', '4.0') -def write(image, filename): - """ Save the current image to a new file - - Parameters - ---------- - image : GiftiImage - A GiftiImage instance to store - filename : string - Filename to store the Gifti file to - - Returns - ------- - None - - Notes - ----- - We write all files with utf-8 encoding, and specify this at the top of the - XML file with the ``encoding`` attribute. - - The Gifti spec suggests using the following suffixes to your - filename when saving each specific type of data: - - .gii - Generic GIFTI File - .coord.gii - Coordinates - .func.gii - Functional - .label.gii - Labels - .rgba.gii - RGB or RGBA - .shape.gii - Shape - .surf.gii - Surface - .tensor.gii - Tensors - .time.gii - Time Series - .topo.gii - Topology - - The Gifti file is stored in endian convention of the current machine. - """ - from ..loadsave import save - return save(image, filename) diff --git a/nibabel/gifti/parse_gifti_fast.py b/nibabel/gifti/parse_gifti_fast.py index 17ae695e55..ed55fd97ea 100644 --- a/nibabel/gifti/parse_gifti_fast.py +++ b/nibabel/gifti/parse_gifti_fast.py @@ -24,7 +24,6 @@ gifti_endian_codes) from ..nifti1 import data_type_codes, xform_codes, intent_codes from ..xmlutils import XmlParser -from ..deprecated import deprecate_with_version class GiftiParseError(ExpatError): @@ -409,23 +408,3 @@ def flush_chardata(self): def pending_data(self): """True if there is character data pending for processing""" return self._char_blocks is not None - - -class Outputter(GiftiImageParser): - - @deprecate_with_version('Outputter class deprecated. ' - "Use GiftiImageParser instead.", - '2.1', '4.0') - def __init__(self): - super(Outputter, self).__init__() - - def initialize(self): - """ Initialize outputter""" - self.__init__() - - -@deprecate_with_version('parse_gifti_file deprecated. ' - "Use GiftiImageParser.parse() instead.", - '2.1', '4.0') -def parse_gifti_file(fname=None, fptr=None, buffer_size=None): - GiftiImageParser(buffer_size=buffer_size).parse(fname=fname, fptr=fptr) diff --git a/nibabel/gifti/tests/test_giftiio.py b/nibabel/gifti/tests/test_giftiio.py deleted file mode 100644 index f2e2458120..0000000000 --- a/nibabel/gifti/tests/test_giftiio.py +++ /dev/null @@ -1,25 +0,0 @@ -# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- -# vi: set ft=python sts=4 ts=4 sw=4 et: -### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## -# -# See COPYING file distributed along with the NiBabel package for the -# copyright and license terms. -# -### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## - -from ..gifti import GiftiImage -from ..giftiio import read, write -from .test_parse_gifti_fast import DATA_FILE1 -from ...deprecator import ExpiredDeprecationError - -import pytest - - -def test_read_deprecated(tmp_path): - with pytest.raises(ExpiredDeprecationError): - read(DATA_FILE1) - - img = GiftiImage.from_filename(DATA_FILE1) - fname = tmp_path / 'test.gii' - with pytest.raises(ExpiredDeprecationError): - write(img, fname) diff --git a/nibabel/gifti/tests/test_parse_gifti_fast.py b/nibabel/gifti/tests/test_parse_gifti_fast.py index a02761027a..d376611581 100644 --- a/nibabel/gifti/tests/test_parse_gifti_fast.py +++ b/nibabel/gifti/tests/test_parse_gifti_fast.py @@ -17,12 +17,10 @@ from .. import gifti as gi from ..util import gifti_endian_codes -from ..parse_gifti_fast import (Outputter, parse_gifti_file, GiftiParseError, - GiftiImageParser) +from ..parse_gifti_fast import GiftiParseError, GiftiImageParser from ...loadsave import load, save from ...nifti1 import xform_codes from ...tmpdirs import InTemporaryDirectory -from ...deprecator import ExpiredDeprecationError from numpy.testing import assert_array_almost_equal @@ -354,16 +352,6 @@ def test_parse_dataarrays(): assert img.numDA == 0 -def test_parse_deprecated(): - - # Test deprecation - with pytest.raises(ExpiredDeprecationError): - Outputter() - - with pytest.raises(ExpiredDeprecationError): - parse_gifti_file() - - def test_parse_with_buffersize(): for buff_sz in [None, 1, 2**12]: img2 = load(DATA_FILE2, buffer_size=buff_sz) diff --git a/nibabel/parrec.py b/nibabel/parrec.py index c2d7160806..304c0c2cc0 100644 --- a/nibabel/parrec.py +++ b/nibabel/parrec.py @@ -137,7 +137,6 @@ from .nifti1 import unit_codes from .fileslice import fileslice, strided_scalar from .openers import ImageOpener -from .deprecated import deprecate_with_version # PSL to RAS affine PSL_TO_RAS = np.array([[0, 0, -1, 0], # L -> R @@ -871,29 +870,6 @@ def _get_unique_image_prop(self, name): f'({props}). This is not supported.') return props[0] - @deprecate_with_version('get_voxel_size deprecated. ' - 'Please use "get_zooms" instead.', - '2.0', '4.0') - def get_voxel_size(self): - """Returns the spatial extent of a voxel. - - Does not include the slice gap in the slice extent. - - If you need the slice thickness not including the slice gap, use - ``self.image_defs['slice thickness']``. - - Returns - ------- - vox_size: shape (3,) ndarray - """ - # slice orientation for the whole image series - slice_thickness = self._get_unique_image_prop('slice thickness') - voxsize_inplane = self._get_unique_image_prop('pixel spacing') - voxsize = np.array((voxsize_inplane[0], - voxsize_inplane[1], - slice_thickness)) - return voxsize - def get_data_offset(self): """ PAR header always has 0 data offset (into REC file) """ return 0 diff --git a/nibabel/tests/test_image_api.py b/nibabel/tests/test_image_api.py index 680458659d..16003fd79c 100644 --- a/nibabel/tests/test_image_api.py +++ b/nibabel/tests/test_image_api.py @@ -412,16 +412,6 @@ def _check_array_caching(self, imaker, meth_name, caching): data = get_data_func(dtype=float_type) assert (data is img.dataobj) == (arr_dtype == float_type) - def validate_data_deprecated(self, imaker, params): - # Check _data property still exists, but raises warning - img = imaker() - with pytest.raises(ExpiredDeprecationError): - assert_data_similar(img._data, params) - # Check setting _data raises error - fake_data = np.zeros(img.shape).astype(img.get_data_dtype()) - with pytest.raises(AttributeError): - img._data = fake_data - def validate_shape(self, imaker, params): # Validate shape img = imaker() diff --git a/nibabel/tests/test_parrec.py b/nibabel/tests/test_parrec.py index f40bf3b80a..22e805cb8f 100644 --- a/nibabel/tests/test_parrec.py +++ b/nibabel/tests/test_parrec.py @@ -23,7 +23,6 @@ import pytest from ..testing import (clear_and_catch_warnings, suppress_warnings, assert_arr_dict_equal) -from ..deprecator import ExpiredDeprecationError from .test_arrayproxy import check_mmap from . import test_spatialimages as tsi @@ -262,12 +261,6 @@ def test_affine_regression(): assert_almost_equal(hdr.get_affine(), exp_affine) -def test_get_voxel_size_deprecated(): - hdr = PARRECHeader(HDR_INFO, HDR_DEFS) - with pytest.raises(ExpiredDeprecationError): - hdr.get_voxel_size() - - def test_get_sorted_slice_indices(): # Test sorted slice indices hdr = PARRECHeader(HDR_INFO, HDR_DEFS) From 4d4fc99ddde6dce1d54ad21ebb7e76fcf7392f64 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 2 Oct 2022 20:53:06 -0400 Subject: [PATCH 17/17] MNT: Remove nibabel.py3k --- nibabel/conftest.py | 4 ---- nibabel/py3k.py | 9 --------- nibabel/tests/test_removalschedule.py | 2 +- 3 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 nibabel/py3k.py diff --git a/nibabel/conftest.py b/nibabel/conftest.py index 697eef4ad6..1f9ecd09cf 100644 --- a/nibabel/conftest.py +++ b/nibabel/conftest.py @@ -1,9 +1,5 @@ import pytest -# Pre-load deprecated modules to avoid cluttering warnings -with pytest.warns(FutureWarning): - import nibabel.py3k - # Ignore warning requesting help with nicom with pytest.warns(UserWarning): import nibabel.nicom diff --git a/nibabel/py3k.py b/nibabel/py3k.py deleted file mode 100644 index 02dd1f16e7..0000000000 --- a/nibabel/py3k.py +++ /dev/null @@ -1,9 +0,0 @@ -import warnings - -warnings.warn("We no longer carry a copy of the 'py3k' module in nibabel; " - "Please import from the 'numpy.compat.py3k' module directly. " - "Full removal scheduled for nibabel 4.0.", - FutureWarning, - stacklevel=2) - -from numpy.compat.py3k import * # noqa diff --git a/nibabel/tests/test_removalschedule.py b/nibabel/tests/test_removalschedule.py index abafe4a1a7..c54a069e55 100644 --- a/nibabel/tests/test_removalschedule.py +++ b/nibabel/tests/test_removalschedule.py @@ -4,7 +4,7 @@ import pytest MODULE_SCHEDULE = [ - ("5.0.0", ["nibabel.keywordonly"]), + ("5.0.0", ["nibabel.keywordonly", "nibabel.py3k"]), ("4.0.0", ["nibabel.trackvis"]), ("3.0.0", ["nibabel.minc", "nibabel.checkwarns"]), # Verify that the test will be quiet if the schedule outlives the modules