Skip to content

detecting if the input is empty early on! #611

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 10 commits into from
Mar 22, 2018
Merged
10 changes: 7 additions & 3 deletions nibabel/loadsave.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# module imports
""" Utilities to load and save image objects """

import os.path as op
import os
import numpy as np

from .filename_parser import splitext_addext
Expand All @@ -36,8 +36,12 @@ def load(filename, **kwargs):
img : ``SpatialImage``
Image of guessed type
'''
if not op.exists(filename):
raise FileNotFoundError("No such file: '%s'" % filename)
try:
stat_result = os.stat(filename)
except OSError:
raise FileNotFoundError("No such file or no access: '%s'" % filename)
if stat_result.st_size <= 0:
raise ImageFileError("Empty file: '%s'" % filename)
sniff = None
for image_klass in all_image_classes:
is_valid, sniff = image_klass.path_maybe_image(filename, sniff)
Expand Down
8 changes: 8 additions & 0 deletions nibabel/tests/test_loadsave.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ def test_file_not_found():
assert_raises(FileNotFoundError, load, 'does_not_exist.nii.gz')


def test_load_empty_image():
with InTemporaryDirectory():
open('empty.nii', 'w').close()
with assert_raises(ImageFileError) as err:
load('empty.nii')
Copy link
Member

Choose a reason for hiding this comment

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

I'm surprised this works on Python 3 - I thought that the err variable went out of scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to work - didn’t dig into why

Copy link
Member

Choose a reason for hiding this comment

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

From the docs:

Signature: unittest.TestCase.assertRaises(self, expected_exception, *args, **kwargs)
Docstring:
Fail unless an exception of class expected_exception is raised
by the callable when invoked with specified positional and
keyword arguments. If a different type of exception is
raised, it will not be caught, and the test case will be
deemed to have suffered an error, exactly as for an
unexpected exception.

If called with the callable and arguments omitted, will return a
context object used like this::

     with self.assertRaises(SomeException):
         do_something()

An optional keyword argument 'msg' can be provided when assertRaises
is used as a context object.

The context manager keeps a reference to the exception as
the 'exception' attribute. This allows you to inspect the
exception after the assertion::

    with self.assertRaises(SomeException) as cm:
        do_something()
    the_exception = cm.exception
    self.assertEqual(the_exception.error_code, 3)
File:      /anaconda3/lib/python3.6/unittest/case.py
Type:      function

assert_true(err.exception.args[0].startswith('Empty file: '))


def test_read_img_data_nifti():
shape = (2, 3, 4)
data = np.random.normal(size=shape)
Expand Down