Skip to content

Commit 586c0e0

Browse files
authored
Merge pull request #618 from yarikoptic/enhs
BF: be resilient to optional module non-ImportError exceptions upon import
2 parents 949d466 + 2c51018 commit 586c0e0

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

nibabel/optpkg.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,14 @@ def optional_package(name, trip_msg=None, min_version=None):
9494
# fromlist=[''] results in submodule being returned, rather than the top
9595
# level module. See help(__import__)
9696
fromlist = [''] if '.' in name else []
97+
exc = None
9798
try:
9899
pkg = __import__(name, fromlist=fromlist)
99-
except ImportError:
100-
pass
100+
except Exception as exc_:
101+
# Could fail due to some ImportError or for some other reason
102+
# e.g. h5py might have been checking file system to support UTF-8
103+
# etc. We should not blow if they blow
104+
exc = exc_ # So it is accessible outside of the code block
101105
else: # import worked
102106
# top level module
103107
if check_version(pkg):
@@ -111,8 +115,8 @@ def optional_package(name, trip_msg=None, min_version=None):
111115
(name, min_version))
112116
if trip_msg is None:
113117
trip_msg = ('We need package %s for these functions, but '
114-
'``import %s`` raised an ImportError'
115-
% (name, name))
118+
'``import %s`` raised %s'
119+
% (name, name, exc))
116120
pkg = TripWire(trip_msg)
117121

118122
def setup_module():

nibabel/py3k.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def open_latin1(filename, mode='r'):
4141
ints2bytes = lambda seq: bytes(seq)
4242
ZEROB = bytes([0])
4343
FileNotFoundError = FileNotFoundError
44+
import builtins
4445
else:
4546
import StringIO
4647
StringIO = BytesIO = StringIO.StringIO
@@ -66,6 +67,8 @@ def open_latin1(filename, mode='r'):
6667
class FileNotFoundError(IOError):
6768
pass
6869

70+
import __builtin__ as builtins # flake8: noqa F401
71+
6972

7073
def getexception():
7174
return sys.exc_info()[1]

nibabel/tests/test_optpkg.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
""" Testing optpkg module
22
"""
33

4+
import mock
45
import types
56
import sys
67
from distutils.version import LooseVersion
@@ -10,6 +11,7 @@
1011
assert_equal)
1112

1213

14+
from nibabel.py3k import builtins
1315
from nibabel.optpkg import optional_package
1416
from nibabel.tripwire import TripWire, TripWireError
1517

@@ -36,6 +38,12 @@ def test_basic():
3638
assert_good('os.path')
3739
# We never have package _not_a_package
3840
assert_bad('_not_a_package')
41+
def raise_Exception(*args, **kwargs):
42+
raise Exception(
43+
"non ImportError could be thrown by some malfunctioning module "
44+
"upon import, and optional_package should catch it too")
45+
with mock.patch.object(builtins, '__import__', side_effect=raise_Exception):
46+
assert_bad('nottriedbefore')
3947

4048

4149
def test_versions():

0 commit comments

Comments
 (0)