No longer swallow important import errors.

This implements a simple but elegant method to find out if an import
error can be swallowed to try the next module or if the import error is
important and must be reraised.
This commit is contained in:
Armin Ronacher 2011-09-21 03:47:36 +02:00
parent 4573715195
commit 9a70e62b8d
2 changed files with 35 additions and 3 deletions

View File

@ -47,7 +47,7 @@ class _ExtensionImporter(object):
return self
def load_module(self, fullname):
from sys import modules
from sys import modules, exc_info
if fullname in modules:
return modules[fullname]
modname = fullname.split('.', self.prefix_cutoff)[self.prefix_cutoff]
@ -56,12 +56,28 @@ class _ExtensionImporter(object):
try:
__import__(realname)
except ImportError:
exc_type, exc_value, tb = exc_info()
if self.is_important_traceback(realname, tb):
raise exc_type, exc_value, tb
continue
module = modules[fullname] = modules[realname]
if '.' not in modname:
setattr(modules[__name__], modname, module)
return module
raise ImportError(fullname)
raise ImportError('No module named %s' % fullname)
def is_important_traceback(self, important_module, tb):
"""Walks a traceback's frames and checks if any of the frames
originated in the given important module. If that is the case
then we were able to import the module itself but apparently
something went wrong when the module was imported. (Eg: import
of an import failed).
"""
while tb is not None:
if tb.tb_frame.f_globals.get('__name__') == important_module:
return True
tb = tb.tb_next
return False
_ExtensionImporter()

View File

@ -44,12 +44,28 @@ class _ExtensionImporter(object):
try:
__import__(realname)
except ImportError:
exc_type, exc_value, tb = sys.exc_info()
if self.is_important_traceback(realname, tb):
raise exc_type, exc_value, tb
continue
module = sys.modules[fullname] = sys.modules[realname]
if '.' not in modname:
setattr(ext_module, modname, module)
return module
raise ImportError(fullname)
raise ImportError('No module named %s' % fullname)
def is_important_traceback(self, important_module, tb):
"""Walks a traceback's frames and checks if any of the frames
originated in the given important module. If that is the case
then we were able to import the module itself but apparently
something went wrong when the module was imported. (Eg: import
of an import failed).
"""
while tb is not None:
if tb.tb_frame.f_globals.get('__name__') == important_module:
return True
tb = tb.tb_next
return False
def activate():