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

Conversation

raamana
Copy link
Contributor

@raamana raamana commented Mar 19, 2018

Apparently no one needed it so far ;)

Not sure where to write tests for it, so wanna check with you guys before taking appropriate action.

@coveralls
Copy link

coveralls commented Mar 19, 2018

Coverage Status

Coverage increased (+0.002%) to 93.962% when pulling a974b70 on raamana:empty_files into 1140e18 on nipy:master.

Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

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

If I understand the paths here correctly, we should get fall-through behavior here and you should be seeing an ImageFileError with message "Cannot work out file type ...".

Is this what you're seeing? I agree that it could be more informative. (If it's not, could you copy in what you are seeing?)


if op.getsize(filename) <= 0:
raise FileEmptyError("Given file is empty: '%s'" % filename)

Copy link
Member

Choose a reason for hiding this comment

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

PEP8 is complaining about whitespace on this line.

@@ -38,6 +38,10 @@ def load(filename, **kwargs):
'''
if not op.exists(filename):
raise FileNotFoundError("No such file: '%s'" % filename)

if op.getsize(filename) <= 0:
raise FileEmptyError("Given file is empty: '%s'" % filename)
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps we can use ImageFileError here, rather than defining a new exception? And I think the message could be shortened to "Empty file: '%s'" % filename.

@raamana
Copy link
Contributor Author

raamana commented Mar 19, 2018

I get the following, which talks about Cannot work out file type which makes me think about incorrect header, not empty file.

nibabel.filebasedimages.ImageFileError: Cannot work out file type of "/home/praamana/dev/visualqc/example_datasets/empty.nii"

@codecov-io
Copy link

codecov-io commented Mar 19, 2018

Codecov Report

Merging #611 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #611      +/-   ##
==========================================
+ Coverage   90.91%   90.91%   +<.01%     
==========================================
  Files          84       84              
  Lines       10661    10665       +4     
  Branches     1764     1764              
==========================================
+ Hits         9692     9696       +4     
  Misses        644      644              
  Partials      325      325
Impacted Files Coverage Δ
nibabel/loadsave.py 85.71% <100%> (+0.56%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1140e18...a974b70. Read the comment docs.

@effigies
Copy link
Member

This looks reasonable to me. I think you could quickly add a test in test_loadsave.py. The following would exercise the new code and verify that you're getting a useful error message:

def test_empty_load():
    with InTemporaryDirectory():
        open('empty.nii', 'w').close()
        with assert_raises(ImageFileError) as cm:
            load('empty.nii')
    assert_true(cm.exception.args[0].startswith('Empty file: '))

Copy link
Member

@matthew-brett matthew-brett left a comment

Choose a reason for hiding this comment

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

Seems fine to me - one small question.

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

Copy link
Member

@effigies effigies left a comment

Choose a reason for hiding this comment

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

LGTM.

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.

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

@effigies
Copy link
Member

@matthew-brett Okay to merge?

@matthew-brett
Copy link
Member

Yes, looks good - merging - thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants