Skip to content

TEST: Suppress expected warnings #949

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Sep 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f0ab879
TEST: Suppress expected warnings
effigies Aug 22, 2020
2f461be
FIX: Avoid/suppress expected warnings
effigies Aug 22, 2020
d4f2216
FIX: Bad deprecate_with_version calls
effigies Aug 22, 2020
f879473
PY36: Backport nullcontext
effigies Aug 22, 2020
8903f0b
DOCTEST: Suppress deprecation warnings in doctests of deprecated methods
effigies Aug 22, 2020
c7fad2e
TEST: Suppress warnings in freesurfer
effigies Aug 22, 2020
7acde5a
MNT: Add pytest-doctestplus to ignore warnings in doctests
effigies Aug 23, 2020
72fa2d2
TEST: Suppress and check warnings in streamlines
effigies Aug 23, 2020
470995d
TEST: Use get_fdata, check for expected warning
effigies Aug 23, 2020
dc36a28
RF: Drop calls to deprecated get_affine()
effigies Aug 23, 2020
86b8f6c
FIX: Escape backslashes before parsing strings
effigies Aug 23, 2020
3694a9a
MNT: Reset deprecation clock
effigies Sep 2, 2020
963aee4
FIX: Remove doubled-up fix for divide-by-zero warning
effigies Sep 2, 2020
786cf99
TEST: Small cleanups
effigies Sep 2, 2020
0634da4
FIX: Construct sliceobj from object array; addresses numpy deprecatio…
effigies Sep 2, 2020
27146c6
TEST: Use skipIf rather than warn + return for test_multiload
effigies Sep 2, 2020
dae2f86
TEST: Check import-time warnings on modules via conftest
effigies Sep 2, 2020
36a1adf
TEST: Use matches or comments to make clear expected warnings
effigies Sep 6, 2020
4707222
TEST: Unused imports
effigies Sep 6, 2020
f1bfc39
TEST: Simplify lazy_load conditional warning check
effigies Sep 6, 2020
1dc4e8d
Update nibabel/streamlines/tests/test_tck.py
effigies Sep 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ script:
mkdir for_testing
cd for_testing
cp ../.coveragerc .
pytest --doctest-modules --cov nibabel -v --pyargs nibabel
pytest --doctest-modules --doctest-plus --cov nibabel -v --pyargs nibabel
else
false
fi
Expand Down
6 changes: 4 additions & 2 deletions nibabel/casting.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
casting. Others work round numpy casting to and from python ints
"""

import warnings
from numbers import Integral
from platform import processor, machine

Expand Down Expand Up @@ -349,8 +350,9 @@ def _check_maxexp(np_type, maxexp):
dt = np.dtype(np_type)
np_type = dt.type
two = np_type(2).reshape((1,)) # to avoid upcasting
return (np.isfinite(two ** (maxexp - 1)) and
not np.isfinite(two ** maxexp))
with warnings.catch_warnings():
warnings.simplefilter("ignore", RuntimeWarning) # Expected overflow warning
return np.isfinite(two ** (maxexp - 1)) and not np.isfinite(two ** maxexp)


def as_int(x, check=True):
Expand Down
2 changes: 1 addition & 1 deletion nibabel/cifti2/cifti2.py
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,7 @@ def update_headers(self):

>>> import numpy as np
>>> data = np.zeros((2,3,4))
>>> img = Cifti2Image(data)
>>> img = Cifti2Image(data) # doctest: +IGNORE_WARNINGS
>>> img.shape == (2, 3, 4)
True
>>> img.update_headers()
Expand Down
13 changes: 13 additions & 0 deletions nibabel/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import pytest

# Pre-load deprecated modules to avoid cluttering warnings
with pytest.deprecated_call():
import nibabel.keywordonly
with pytest.deprecated_call():
import nibabel.trackvis
with pytest.warns(FutureWarning):
import nibabel.py3k

# Ignore warning requesting help with nicom
with pytest.warns(UserWarning):
import nibabel.nicom
29 changes: 26 additions & 3 deletions nibabel/deprecator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@

_LEADING_WHITE = re.compile(r'^(\s*)')

TESTSETUP = """

.. testsetup::

>>> import pytest
>>> import warnings
>>> _suppress_warnings = pytest.deprecated_call()
>>> _ = _suppress_warnings.__enter__()

"""

TESTCLEANUP = """

.. testcleanup::

>>> warnings.warn("Avoid error if no doctests to run...", DeprecationWarning)
>>> _ = _suppress_warnings.__exit__(None, None, None)

"""


class ExpiredDeprecationError(RuntimeError):
""" Error for expired deprecation
Expand All @@ -25,7 +45,7 @@ def _ensure_cr(text):
return text.rstrip() + '\n'


def _add_dep_doc(old_doc, dep_doc):
def _add_dep_doc(old_doc, dep_doc, setup='', cleanup=''):
""" Add deprecation message `dep_doc` to docstring in `old_doc`

Parameters
Expand Down Expand Up @@ -56,8 +76,11 @@ def _add_dep_doc(old_doc, dep_doc):
# nothing following first paragraph, just append message
return old_doc + '\n' + dep_doc
indent = _LEADING_WHITE.match(old_lines[next_line]).group()
setup_lines = [indent + L for L in setup.splitlines()]
dep_lines = [indent + L for L in [''] + dep_doc.splitlines() + ['']]
return '\n'.join(new_lines + dep_lines + old_lines[next_line:]) + '\n'
cleanup_lines = [indent + L for L in cleanup.splitlines()]
return '\n'.join(new_lines + dep_lines + setup_lines +
old_lines[next_line:] + cleanup_lines + [''])


class Deprecator(object):
Expand Down Expand Up @@ -160,7 +183,7 @@ def deprecated_func(*args, **kwargs):
return func(*args, **kwargs)

deprecated_func.__doc__ = _add_dep_doc(deprecated_func.__doc__,
message)
message, TESTSETUP, TESTCLEANUP)
return deprecated_func

return deprecator
14 changes: 6 additions & 8 deletions nibabel/freesurfer/tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,15 @@ def test_geometry():

# now write an incomplete file
write_geometry(surf_path, coords, faces)
with clear_and_catch_warnings() as w:
warnings.filterwarnings('always', category=DeprecationWarning)
with pytest.warns(UserWarning) as w:
read_geometry(surf_path, read_metadata=True)

assert any('volume information contained' in str(ww.message) for ww in w)
assert any('extension code' in str(ww.message) for ww in w)

volume_info['head'] = [1, 2]
with clear_and_catch_warnings() as w:
with pytest.warns(UserWarning, match="Unknown extension"):
write_geometry(surf_path, coords, faces, create_stamp, volume_info)
assert any('Unknown extension' in str(ww.message) for ww in w)

volume_info['a'] = 0
with pytest.raises(ValueError):
write_geometry(surf_path, coords, faces, create_stamp, volume_info)
Expand Down Expand Up @@ -266,10 +265,9 @@ def test_write_annot_fill_ctab():
# values back.
badannot = (10 * np.arange(nlabels, dtype=np.int32)).reshape(-1, 1)
rgbal = np.hstack((rgba, badannot))
with clear_and_catch_warnings() as w:
with pytest.warns(UserWarning,
match=f'Annotation values in {annot_path} will be incorrect'):
write_annot(annot_path, labels, rgbal, names, fill_ctab=False)
assert any(f'Annotation values in {annot_path} will be incorrect' == str(ww.message)
for ww in w)
labels2, rgbal2, names2 = read_annot(annot_path, orig_ids=True)
names2 = [n.decode('ascii') for n in names2]
assert np.all(np.isclose(rgbal2[:, :4], rgba))
Expand Down
15 changes: 10 additions & 5 deletions nibabel/freesurfer/tests/test_mghformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,14 @@ def test_deprecated_fields():

# mrparams is the only deprecated field at the moment
# Accessing hdr_data is equivalent to accessing hdr, so double all checks
assert_array_equal(hdr['mrparams'], 0)
with pytest.deprecated_call(match="from version: 2.3"):
assert_array_equal(hdr['mrparams'], 0)
assert_array_equal(hdr_data['mrparams'], 0)

hdr['mrparams'] = [1, 2, 3, 4]
assert_array_almost_equal(hdr['mrparams'], [1, 2, 3, 4])
with pytest.deprecated_call(match="from version: 2.3"):
hdr['mrparams'] = [1, 2, 3, 4]
with pytest.deprecated_call(match="from version: 2.3"):
assert_array_almost_equal(hdr['mrparams'], [1, 2, 3, 4])
assert hdr['tr'] == 1
assert hdr['flip_angle'] == 2
assert hdr['te'] == 3
Expand All @@ -366,14 +369,16 @@ def test_deprecated_fields():
hdr['flip_angle'] = 6
hdr['te'] = 7
hdr['ti'] = 8
assert_array_almost_equal(hdr['mrparams'], [5, 6, 7, 8])
with pytest.deprecated_call(match="from version: 2.3"):
assert_array_almost_equal(hdr['mrparams'], [5, 6, 7, 8])
assert_array_almost_equal(hdr_data['mrparams'], [5, 6, 7, 8])

hdr_data['tr'] = 9
hdr_data['flip_angle'] = 10
hdr_data['te'] = 11
hdr_data['ti'] = 12
assert_array_almost_equal(hdr['mrparams'], [9, 10, 11, 12])
with pytest.deprecated_call(match="from version: 2.3"):
assert_array_almost_equal(hdr['mrparams'], [9, 10, 11, 12])
assert_array_almost_equal(hdr_data['mrparams'], [9, 10, 11, 12])


Expand Down
2 changes: 1 addition & 1 deletion nibabel/keywordonly.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from functools import wraps
import warnings

warnings.warn("We will remove this module from nibabel 5.0. "
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,
Expand Down
16 changes: 6 additions & 10 deletions nibabel/loadsave.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ def load(filename, **kwargs):
raise ImageFileError(f'Cannot work out file type of "{filename}"')


@deprecate_with_version('guessed_image_type deprecated.'
'2.1',
'4.0')
@deprecate_with_version('guessed_image_type deprecated.', '3.2', '5.0')
def guessed_image_type(filename):
""" Guess image type from file `filename`

Expand Down Expand Up @@ -149,10 +147,10 @@ def save(img, filename):
converted.to_filename(filename)


@deprecate_with_version('read_img_data deprecated.'
'Please use ``img.dataobj.get_unscaled()`` instead.'
'2.0.1',
'4.0')
@deprecate_with_version('read_img_data deprecated. '
'Please use ``img.dataobj.get_unscaled()`` instead.',
'3.2',
'5.0')
def read_img_data(img, prefer='scaled'):
""" Read data from image associated with files

Expand Down Expand Up @@ -236,9 +234,7 @@ def read_img_data(img, prefer='scaled'):
return hdr.raw_data_from_fileobj(fileobj)


@deprecate_with_version('which_analyze_type deprecated.'
'2.1',
'4.0')
@deprecate_with_version('which_analyze_type deprecated.', '3.2', '4.0')
def which_analyze_type(binaryblock):
""" Is `binaryblock` from NIfTI1, NIfTI2 or Analyze header?

Expand Down
2 changes: 1 addition & 1 deletion nibabel/nicom/ascconv.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def parse_ascconv(ascconv_str, str_delim='"'):
attrs, content = ASCCONV_RE.match(ascconv_str).groups()
attrs = OrderedDict((tuple(x.split('=')) for x in attrs.split()))
# Normalize string start / end markers to something Python understands
content = content.replace(str_delim, '"""')
content = content.replace(str_delim, '"""').replace("\\", "\\\\")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one seems like a reasonable fix, but it should get @matthew-brett's or @moloney's eyes to be sure. Previously the line:

tSequenceFileName                        = ""%SiemensSeq%\ep2d_diff""

Resulted in ast.parse() emitting:

nibabel/nicom/tests/test_ascconv.py::test_ascconv_parse
  <unknown>:2: DeprecationWarning: invalid escape sequence \e

# Use Python's own parser to parse modified ASCCONV assignments
tree = ast.parse(content)

Expand Down
4 changes: 2 additions & 2 deletions nibabel/nicom/dicomreaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def mosaic_to_nii(dcm_data):
if not dcm_w.is_mosaic:
raise DicomReadError('data does not appear to be in mosaic format')
data = dcm_w.get_data()
aff = np.dot(DPCS_TO_TAL, dcm_w.get_affine())
aff = np.dot(DPCS_TO_TAL, dcm_w.affine)
return Nifti1Image(data, aff)


Expand Down Expand Up @@ -106,7 +106,7 @@ def read_mosaic_dir(dicom_path,
g = dcm_w.b_vector
b_values.append(b)
gradients.append(g)
affine = np.dot(DPCS_TO_TAL, dcm_w.get_affine())
affine = np.dot(DPCS_TO_TAL, dcm_w.affine)
return (np.concatenate(arrays, -1),
affine,
np.array(b_values),
Expand Down
2 changes: 1 addition & 1 deletion nibabel/nicom/tests/test_dicomreaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
@dicom_test
def test_read_dwi():
img = didr.mosaic_to_nii(DATA)
arr = img.get_data()
arr = img.get_fdata()
assert arr.shape == (128, 128, 48)
assert_array_almost_equal(img.affine, EXPECTED_AFFINE)

Expand Down
5 changes: 3 additions & 2 deletions nibabel/nicom/tests/test_dicomwrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -660,13 +660,14 @@ def test_data_derived_shape(self):
# Test 4D diffusion data with an additional trace volume included
# Excludes the trace volume and generates the correct shape
dw = didw.wrapper_from_file(DATA_FILE_4D_DERIVED)
assert dw.image_shape == (96, 96, 60, 33)
with pytest.warns(UserWarning, match="Derived images found and removed"):
assert dw.image_shape == (96, 96, 60, 33)

@dicom_test
@needs_nibabel_data('nitest-dicom')
def test_data_unreadable_private_headers(self):
# Test CT image with unreadable CSA tags
with pytest.warns(UserWarning):
with pytest.warns(UserWarning, match="Error while attempting to read CSA header"):
dw = didw.wrapper_from_file(DATA_FILE_CT)
assert dw.image_shape == (512, 571)

Expand Down
2 changes: 1 addition & 1 deletion nibabel/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def smooth_image(img,
fwhm = np.zeros((n_dim,))
fwhm[:3] = fwhm_scalar
# Voxel sizes
RZS = img.affine[:-1, :n_dim]
RZS = img.affine[:, :n_dim]
vox = np.sqrt(np.sum(RZS ** 2, 0))
# Smoothing in terms of voxels
vox_fwhm = fwhm / vox
Expand Down
7 changes: 6 additions & 1 deletion nibabel/streamlines/tests/test_array_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,18 @@ 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.deprecated_call(match="from version: 3.0"):
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)
seq_with_buffer = ArraySequence(gen_2, buffer_size=256)

# Check buffer size effect
assert seq_with_buffer.data.shape == seq.data.shape
assert seq_with_buffer.get_data().shape == seq.get_data().shape
assert seq_with_buffer._buffer_size > seq._buffer_size

# Check generator result
Expand Down
Loading