Skip to content

Commit 00d4e18

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 79dca43 commit 00d4e18

10 files changed

+117
-54
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 & 21 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,16 @@ 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
217220
218221
Please use the `header` property instead of `get_header`; we will
219222
deprecate this method in future versions of nibabel.
220223
"""
221-
warnings.warn('``get_header`` is deprecated.\n'
222-
'Please use the ``img.header`` property '
223-
'instead',
224-
DeprecationWarning, stacklevel=2)
225224
return self.header
226225

227226
def get_filename(self):
@@ -273,11 +272,11 @@ def from_file_map(klass, file_map):
273272
raise NotImplementedError
274273

275274
@classmethod
275+
@deprecate_with_version('from_files class method is deprecated.\n'
276+
'Please use the ``from_file_map`` class method '
277+
'instead.',
278+
'1.0', '3.0')
276279
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)
281280
return klass.from_file_map(file_map)
282281

283282
@classmethod
@@ -318,11 +317,11 @@ def filespec_to_file_map(klass, filespec):
318317
return file_map
319318

320319
@classmethod
320+
@deprecate_with_version('filespec_to_files class method is deprecated.\n'
321+
'Please use the "filespec_to_file_map" class '
322+
'method instead.',
323+
'1.0', '3.0')
321324
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)
326325
return klass.filespec_to_file_map(filespec)
327326

328327
def to_filename(self, filename):
@@ -342,20 +341,19 @@ def to_filename(self, filename):
342341
self.file_map = self.filespec_to_file_map(filename)
343342
self.to_file_map()
344343

344+
@deprecate_with_version('to_filespec method is deprecated.\n'
345+
'Please use the "to_filename" method instead.',
346+
'1.0', '3.0')
345347
def to_filespec(self, filename):
346-
warnings.warn('``to_filespec`` is deprecated, please '
347-
'use ``to_filename`` instead',
348-
DeprecationWarning, stacklevel=2)
349348
self.to_filename(filename)
350349

351350
def to_file_map(self, file_map=None):
352351
raise NotImplementedError
353352

353+
@deprecate_with_version('to_files method is deprecated.\n'
354+
'Please use the "to_file_map" method instead.',
355+
'1.0', '3.0')
354356
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)
359357
self.to_file_map(file_map)
360358

361359
@classmethod

nibabel/imageclasses.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from .spm99analyze import Spm99AnalyzeImage
2121
from .spm2analyze import Spm2AnalyzeImage
2222
from .volumeutils import Recoder
23+
from .deprecated import deprecate_with_version
2324

2425
from .optpkg import optional_package
2526
_, have_scipy, _ = optional_package('scipy')
@@ -35,9 +36,9 @@
3536
# DEPRECATED: mapping of names to classes and class functionality
3637
class ClassMapDict(dict):
3738

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

4344
class_map = ClassMapDict(
@@ -90,9 +91,9 @@ def __getitem__(self, *args, **kwargs):
9091

9192
class ExtMapRecoder(Recoder):
9293

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

9899
# mapping of extensions to default image class names

nibabel/parrec.py

Lines changed: 4 additions & 3 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,6 +823,9 @@ 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
@@ -836,9 +840,6 @@ def get_voxel_size(self):
836840
-------
837841
vox_size: shape (3,) ndarray
838842
"""
839-
warnings.warn('Please use "get_zooms" instead of "get_voxel_size"',
840-
DeprecationWarning,
841-
stacklevel=2)
842843
# slice orientation for the whole image series
843844
slice_thickness = self._get_unique_image_prop('slice thickness')
844845
voxsize_inplane = self._get_unique_image_prop('pixel spacing')

nibabel/spatialimages.py

Lines changed: 12 additions & 11 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.\n',
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,15 @@ 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
617621
618622
This function deprecated; please use the ``shape`` property instead
619623
"""
620-
warnings.warn('Please use the shape property instead of get_shape',
621-
DeprecationWarning,
622-
stacklevel=2)
623624
return self.shape
624625

625626
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 """

nibabel/tests/test_utils.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
from ..tmpdirs import InTemporaryDirectory
2626
from ..openers import ImageOpener
27+
from .. import volumeutils
2728
from ..volumeutils import (array_from_file,
2829
_is_compressed_fobj,
2930
array_to_file,
@@ -54,7 +55,7 @@
5455
from nose.tools import assert_true, assert_false, assert_equal, assert_raises
5556

5657
from ..testing import (assert_dt_equal, assert_allclose_safely,
57-
suppress_warnings)
58+
suppress_warnings, clear_and_catch_warnings)
5859

5960
#: convenience variables for numpy types
6061
FLOAT_TYPES = np.sctypes['float']
@@ -1033,10 +1034,12 @@ def test_fname_ext_ul_case():
10331034
def test_allopen():
10341035
# This import into volumeutils is for compatibility. The code is the
10351036
# ``openers`` module.
1036-
with warnings.catch_warnings():
1037-
warnings.simplefilter("ignore")
1037+
with clear_and_catch_warnings() as w:
1038+
warnings.filterwarnings('once', category=DeprecationWarning)
10381039
# Test default mode is 'rb'
10391040
fobj = allopen(__file__)
1041+
# Check we got the deprecation warning
1042+
assert_equal(len(w), 1)
10401043
assert_equal(fobj.mode, 'rb')
10411044
# That we can set it
10421045
fobj = allopen(__file__, 'r')

0 commit comments

Comments
 (0)