Skip to content

Commit 590a2f2

Browse files
committed
RF+TST: specify versions for DeprecationWarnings
Specify version at which DeprecationWarning was first raised, and planned version for removal. Add tests for some deprecations that were not being tested.
1 parent f616c57 commit 590a2f2

11 files changed

+124
-70
lines changed

nibabel/arraywriters.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,9 @@ def _check_nan2zero(self, nan2zero):
194194
raise WriterError('Deprecated `nan2zero` argument to `to_fileobj` '
195195
'must be same as class value set in __init__')
196196
warnings.warn('Please remove `nan2zero` from call to ' '`to_fileobj` '
197-
'and use in instance __init__ instead',
197+
'and use in instance __init__ instead.\n'
198+
'* deprecated in version: 2.0\n'
199+
'* will raise error in version: 4.0\n',
198200
DeprecationWarning, stacklevel=3)
199201

200202
def _needs_nan2zero(self):

nibabel/filebasedimages.py

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,12 @@
88
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
99
''' Common interface for any image format--volume or surface, binary or xml.'''
1010

11-
import warnings
12-
1311
from .externals.six import string_types
1412
from .fileholders import FileHolder
1513
from .filename_parser import (types_filenames, TypesFilenamesError,
1614
splitext_addext)
1715
from .openers import ImageOpener
16+
from .deprecated import deprecate_with_version
1817

1918

2019
class ImageFileError(Exception):
@@ -212,16 +211,13 @@ def __getitem__(self):
212211
'''
213212
raise TypeError("Cannot slice image objects.")
214213

214+
@deprecate_with_version('get_header method is deprecated.\n'
215+
'Please use the ``img.header`` property '
216+
'instead.',
217+
'2.1', '4.0')
215218
def get_header(self):
216219
""" Get header from image
217-
218-
Please use the `header` property instead of `get_header`; we will
219-
deprecate this method in future versions of nibabel.
220220
"""
221-
warnings.warn('``get_header`` is deprecated.\n'
222-
'Please use the ``img.header`` property '
223-
'instead',
224-
DeprecationWarning, stacklevel=2)
225221
return self.header
226222

227223
def get_filename(self):
@@ -273,11 +269,11 @@ def from_file_map(klass, file_map):
273269
raise NotImplementedError
274270

275271
@classmethod
272+
@deprecate_with_version('from_files class method is deprecated.\n'
273+
'Please use the ``from_file_map`` class method '
274+
'instead.',
275+
'1.0', '3.0')
276276
def from_files(klass, file_map):
277-
warnings.warn('``from_files`` class method is deprecated\n'
278-
'Please use the ``from_file_map`` class method '
279-
'instead',
280-
DeprecationWarning, stacklevel=2)
281277
return klass.from_file_map(file_map)
282278

283279
@classmethod
@@ -318,11 +314,11 @@ def filespec_to_file_map(klass, filespec):
318314
return file_map
319315

320316
@classmethod
317+
@deprecate_with_version('filespec_to_files class method is deprecated.\n'
318+
'Please use the "filespec_to_file_map" class '
319+
'method instead.',
320+
'1.0', '3.0')
321321
def filespec_to_files(klass, filespec):
322-
warnings.warn('``filespec_to_files`` class method is deprecated\n'
323-
'Please use the ``filespec_to_file_map`` class method '
324-
'instead',
325-
DeprecationWarning, stacklevel=2)
326322
return klass.filespec_to_file_map(filespec)
327323

328324
def to_filename(self, filename):
@@ -342,20 +338,19 @@ def to_filename(self, filename):
342338
self.file_map = self.filespec_to_file_map(filename)
343339
self.to_file_map()
344340

341+
@deprecate_with_version('to_filespec method is deprecated.\n'
342+
'Please use the "to_filename" method instead.',
343+
'1.0', '3.0')
345344
def to_filespec(self, filename):
346-
warnings.warn('``to_filespec`` is deprecated, please '
347-
'use ``to_filename`` instead',
348-
DeprecationWarning, stacklevel=2)
349345
self.to_filename(filename)
350346

351347
def to_file_map(self, file_map=None):
352348
raise NotImplementedError
353349

350+
@deprecate_with_version('to_files method is deprecated.\n'
351+
'Please use the "to_file_map" method instead.',
352+
'1.0', '3.0')
354353
def to_files(self, file_map=None):
355-
warnings.warn('``to_files`` method is deprecated\n'
356-
'Please use the ``to_file_map`` method '
357-
'instead',
358-
DeprecationWarning, stacklevel=2)
359354
self.to_file_map(file_map)
360355

361356
@classmethod

nibabel/imageclasses.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#
88
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
99
''' Define supported image classes and names '''
10-
import warnings
1110

1211
from .analyze import AnalyzeImage
1312
from .freesurfer import MGHImage
@@ -20,6 +19,7 @@
2019
from .spm99analyze import Spm99AnalyzeImage
2120
from .spm2analyze import Spm2AnalyzeImage
2221
from .volumeutils import Recoder
22+
from .deprecated import deprecate_with_version
2323

2424
from .optpkg import optional_package
2525
_, have_scipy, _ = optional_package('scipy')
@@ -35,9 +35,9 @@
3535
# DEPRECATED: mapping of names to classes and class functionality
3636
class ClassMapDict(dict):
3737

38+
@deprecate_with_version('class_map is deprecated.',
39+
'2.1', '4.0')
3840
def __getitem__(self, *args, **kwargs):
39-
warnings.warn("class_map is deprecated.", DeprecationWarning,
40-
stacklevel=2)
4141
return super(ClassMapDict, self).__getitem__(*args, **kwargs)
4242

4343
class_map = ClassMapDict(
@@ -90,9 +90,9 @@ def __getitem__(self, *args, **kwargs):
9090

9191
class ExtMapRecoder(Recoder):
9292

93+
@deprecate_with_version('ext_map is deprecated.',
94+
'2.1', '4.0')
9395
def __getitem__(self, *args, **kwargs):
94-
warnings.warn("ext_map is deprecated.", DeprecationWarning,
95-
stacklevel=2)
9696
return super(ExtMapRecoder, self).__getitem__(*args, **kwargs)
9797

9898
# mapping of extensions to default image class names

nibabel/loadsave.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,11 @@ def save(img, filename):
131131
def read_img_data(img, prefer='scaled'):
132132
""" Read data from image associated with files
133133
134-
We've deprecated this function and will remove it soon. If you want
135-
unscaled data, please use ``img.dataobj.get_unscaled()`` instead. If you
136-
want scaled data, use ``img.get_data()`` (which will cache the loaded
137-
array) or ``np.array(img.dataobj)`` (which won't cache the array). If you
138-
want to load the data as for a modified header, save the image with the
139-
modified header, and reload.
134+
If you want unscaled data, please use ``img.dataobj.get_unscaled()``
135+
instead. If you want scaled data, use ``img.get_data()`` (which will cache
136+
the loaded array) or ``np.array(img.dataobj)`` (which won't cache the
137+
array). If you want to load the data as for a modified header, save the
138+
image with the modified header, and reload.
140139
141140
Parameters
142141
----------

nibabel/parrec.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
from .nifti1 import unit_codes
140140
from .fileslice import fileslice, strided_scalar
141141
from .openers import ImageOpener
142+
from .deprecated import deprecate_with_version
142143

143144
# PSL to RAS affine
144145
PSL_TO_RAS = np.array([[0, 0, -1, 0], # L -> R
@@ -822,23 +823,21 @@ def _get_unique_image_prop(self, name):
822823
'not suppported.'.format(name, props))
823824
return props[0]
824825

826+
@deprecate_with_version('get_voxel_size deprecated. '
827+
'Please use "get_zooms" instead.',
828+
'2.0', '4.0')
825829
def get_voxel_size(self):
826830
"""Returns the spatial extent of a voxel.
827831
828832
Does not include the slice gap in the slice extent.
829833
830-
This function is deprecated and we will remove it in future versions of
831-
nibabel. Please use ``get_zooms`` instead. If you need the slice
832-
thickness not including the slice gap, use ``self.image_defs['slice
833-
thickness']``.
834+
If you need the slice thickness not including the slice gap, use
835+
``self.image_defs['slice thickness']``.
834836
835837
Returns
836838
-------
837839
vox_size: shape (3,) ndarray
838840
"""
839-
warnings.warn('Please use "get_zooms" instead of "get_voxel_size"',
840-
DeprecationWarning,
841-
stacklevel=2)
842841
# slice orientation for the whole image series
843842
slice_thickness = self._get_unique_image_prop('slice thickness')
844843
voxsize_inplane = self._get_unique_image_prop('pixel spacing')

nibabel/spatialimages.py

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,13 @@
133133
134134
'''
135135

136-
import warnings
137-
138136
import numpy as np
139137

140138
from .filebasedimages import FileBasedHeader, FileBasedImage
141139
from .filebasedimages import ImageFileError # flake8: noqa; for back-compat
142140
from .viewers import OrthoSlicer3D
143141
from .volumeutils import shape_zoom_affine
142+
from .deprecated import deprecate_with_version
144143

145144

146145
class HeaderDataError(Exception):
@@ -308,9 +307,11 @@ def supported_np_types(obj):
308307
class Header(SpatialHeader):
309308
'''Alias for SpatialHeader; kept for backwards compatibility.'''
310309

310+
@deprecate_with_version('Header class is deprecated.\n'
311+
'Please use SpatialHeader instead.'
312+
'instead.',
313+
'2.1', '4.0')
311314
def __init__(self, *args, **kwargs):
312-
warnings.warn('Header is deprecated, use SpatialHeader',
313-
DeprecationWarning, stacklevel=2)
314315
super(Header, self).__init__(*args, **kwargs)
315316

316317

@@ -373,11 +374,10 @@ def __init__(self, dataobj, affine, header=None,
373374
self._data_cache = None
374375

375376
@property
377+
@deprecate_with_version('_data attribute not part of public API. '
378+
'please use "dataobj" property instead.',
379+
'2.0', '4.0')
376380
def _data(self):
377-
warnings.warn('Please use ``dataobj`` instead of ``_data``; '
378-
'We will remove this wrapper for ``_data`` soon',
379-
FutureWarning,
380-
stacklevel=2)
381381
return self._dataobj
382382

383383
@property
@@ -612,14 +612,13 @@ def uncache(self):
612612
def shape(self):
613613
return self._dataobj.shape
614614

615+
@deprecate_with_version('get_shape method is deprecated.\n'
616+
'Please use the ``img.shape`` property '
617+
'instead.',
618+
'1.2', '3.0')
615619
def get_shape(self):
616620
""" Return shape for image
617-
618-
This function deprecated; please use the ``shape`` property instead
619621
"""
620-
warnings.warn('Please use the shape property instead of get_shape',
621-
DeprecationWarning,
622-
stacklevel=2)
623622
return self.shape
624623

625624
def get_data_dtype(self):

nibabel/tests/test_image_api.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ def validate_shape(self, imaker, params):
153153
# Read only
154154
assert_raises(AttributeError, setattr, img, 'shape', np.eye(4))
155155

156+
def validate_shape_deprecated(self, imaker, params):
157+
# Check deprecated get_shape API
158+
with clear_and_catch_warnings() as w:
159+
warnings.simplefilter('always', DeprecationWarning)
160+
img = imaker()
161+
assert_equal(img.get_shape(), params['shape'])
162+
assert_equal(len(w), 1)
163+
156164
def validate_dtype(self, imaker, params):
157165
# data / storage dtype
158166
img = imaker()
@@ -246,7 +254,7 @@ def validate_data_deprecated(self, imaker, params):
246254
with warnings.catch_warnings(record=True) as warns:
247255
warnings.simplefilter("always")
248256
assert_data_similar(img._data, params)
249-
assert_equal(warns.pop(0).category, FutureWarning)
257+
assert_equal(warns.pop(0).category, DeprecationWarning)
250258
# Check setting _data raises error
251259
fake_data = np.zeros(img.shape).astype(img.get_data_dtype())
252260
assert_raises(AttributeError, setattr, img, '_data', fake_data)

nibabel/tests/test_imageclasses.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""
33

44
from os.path import dirname, join as pjoin
5+
import warnings
56

67
import numpy as np
78

@@ -12,9 +13,13 @@
1213
from nibabel.nifti1 import Nifti1Image
1314
from nibabel.nifti2 import Nifti2Image
1415

15-
from nibabel.imageclasses import spatial_axes_first
16+
from nibabel import imageclasses
17+
from nibabel.imageclasses import spatial_axes_first, class_map, ext_map
18+
19+
from nose.tools import (assert_true, assert_false, assert_equal)
20+
21+
from nibabel.testing import clear_and_catch_warnings
1622

17-
from nose.tools import (assert_true, assert_false)
1823

1924
DATA_DIR = pjoin(dirname(__file__), 'data')
2025

@@ -46,3 +51,15 @@ def test_spatial_axes_first():
4651
img = nib.load(pjoin(DATA_DIR, fname))
4752
assert_true(len(img.shape) == 4)
4853
assert_false(spatial_axes_first(img))
54+
55+
56+
def test_deprecations():
57+
with clear_and_catch_warnings(modules=[imageclasses]) as w:
58+
warnings.filterwarnings('always', category=DeprecationWarning)
59+
nifti_single = class_map['nifti_single']
60+
assert_equal(nifti_single['class'], Nifti1Image)
61+
assert_equal(len(w), 1)
62+
nifti_ext = ext_map['.nii']
63+
assert_equal(nifti_ext, 'nifti_single')
64+
assert_equal(len(w), 2)
65+

nibabel/tests/test_spatialimages.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,39 @@ def test_get_data(self):
335335
assert_false(rt_img.get_data() is out_data)
336336
assert_array_equal(rt_img.get_data(), in_data)
337337

338+
def test_api_deprecations(self):
339+
340+
class FakeImage(self.image_class):
341+
342+
files_types = (('image', '.foo'),)
343+
344+
@classmethod
345+
def to_file_map(self, file_map=None):
346+
pass
347+
348+
@classmethod
349+
def from_file_map(self, file_map=None):
350+
pass
351+
352+
arr = np.arange(24, dtype=np.int16).reshape((2, 3, 4))
353+
aff = np.eye(4)
354+
img = FakeImage(arr, aff)
355+
bio = BytesIO()
356+
file_map = FakeImage.make_file_map({'image': bio})
357+
358+
with clear_and_catch_warnings() as w:
359+
warnings.simplefilter('always', DeprecationWarning)
360+
img.to_files(file_map)
361+
assert_equal(len(w), 1)
362+
img.to_filespec('an_image')
363+
assert_equal(len(w), 2)
364+
img = FakeImage.from_files(file_map)
365+
assert_equal(len(w), 3)
366+
file_map = FakeImage.filespec_to_files('an_image')
367+
assert_equal(list(file_map), ['image'])
368+
assert_equal(file_map['image'].filename, 'an_image.foo')
369+
assert_equal(len(w), 4)
370+
338371

339372
class MmapImageMixin(object):
340373
""" Mixin for testing images that may return memory maps """

0 commit comments

Comments
 (0)