Skip to content

Commit

Permalink
Catch exceptions from opening invalid files
Browse files Browse the repository at this point in the history
This ensures very badly invalid files are still recorded as such,
while allowing further files to be processed.
  • Loading branch information
colinpalmer committed Jul 12, 2022
1 parent 620044e commit 0bbfded
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Version 1.4.1 (2022-07-12)

* Add file names to mrcfile-header output
* Add file names and a success message for valid files to the output of the
validation functions (mrcfile-validate command and the validate() method)
validation functions (mrcfile-validate command and the mrcfile.validate()
function)
* Add support for numpy 1.23 and Python 3.10 and 3.11

Version 1.4.0 (2022-07-02)
Expand Down
15 changes: 10 additions & 5 deletions mrcfile/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import argparse
import sys
import traceback

from . import load_functions

Expand Down Expand Up @@ -155,11 +156,15 @@ def validate(name, print_file=None):
is not the same size as expected from the header.
"""
print("Checking if {} is a valid MRC2014 file...".format(name), file=print_file)
with load_functions.open(name, permissive=True) as mrc:
result = mrc.validate(print_file=print_file)
if result:
print("File appears to be valid.", file=print_file)
return result
try:
with load_functions.open(name, permissive=True) as mrc:
result = mrc.validate(print_file=print_file)
except Exception:
result = False
traceback.print_exc(file=print_file)
if result:
print("File appears to be valid.", file=print_file)
return result


if __name__ == '__main__':
Expand Down
24 changes: 20 additions & 4 deletions tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@
from __future__ import (absolute_import, division, print_function,
unicode_literals)

import io
import os
import shutil
import sys
import tempfile
import unittest
import warnings

# Avoid str/unicode issues when traceback.print_exc tries to write to StringIO
# (see https://stackoverflow.com/a/34872005)
try:
# Python 2
from cStringIO import StringIO
except ImportError:
# Python 3
from io import StringIO

import numpy as np

import mrcfile
Expand All @@ -43,15 +51,16 @@ def setUp(self):
self.ext_header_mrc_name = os.path.join(self.test_data, 'EMD-3001.map')
self.fei1_ext_header_mrc_name = os.path.join(self.test_data, 'fei-extended.mrc')
self.fei2_ext_header_mrc_name = os.path.join(self.test_data, 'epu2.9_example.mrc')
self.not_an_mrc_name = os.path.join(self.test_data, 'README.txt')

# Set up stream to catch print output from validate()
self.print_stream = io.StringIO()
self.print_stream = StringIO()

# Replace stdout and stderr to capture output for checking
self.orig_stdout = sys.stdout
self.orig_stderr = sys.stderr
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
sys.stdout = StringIO()
sys.stderr = StringIO()

def tearDown(self):
# Restore stdout and stderr
Expand Down Expand Up @@ -562,6 +571,7 @@ def test_validate_good_files(self):

def test_validate_bad_files(self):
bad_files = [
self.not_an_mrc_name,
self.example_mrc_name,
self.ext_header_mrc_name,
self.gzip_mrc_name
Expand All @@ -570,11 +580,17 @@ def test_validate_bad_files(self):
assert result == False
print_output = self.print_stream.getvalue()
assert len(print_output) > 0
assert "Checking if " + bad_files[0] + " is a valid MRC2014 file..." in print_output
assert "Checking if " + bad_files[1] + " is a valid MRC2014 file..." in print_output
assert "Checking if " + bad_files[2] + " is a valid MRC2014 file..." in print_output
assert "Checking if " + bad_files[3] + " is a valid MRC2014 file..." in print_output
assert "ValueError:" in print_output
assert len(sys.stdout.getvalue()) == 0
assert len(sys.stderr.getvalue()) == 0

def test_validate_good_and_bad_files(self):
files = self.create_good_files() + [
self.not_an_mrc_name,
self.example_mrc_name,
self.ext_header_mrc_name,
self.gzip_mrc_name
Expand Down

0 comments on commit 0bbfded

Please sign in to comment.