diff Lib/importlib/_bootstrap.py @ 78758:ca4bf8e10bc0

Issue #15316: Let exceptions raised during imports triggered by the fromlist of __import__ propagate. The problem previously was that if something listed in fromlist didn't exist then that's okay. The fix for that was too broad in terms of catching ImportError. The trick with the solution to this issue is that the proper refactoring of import thanks to importlib doesn't allow for a way to distinguish (portably) between an ImportError because finders couldn't find a loader, or a loader raised the exception. In Python 3.4 the hope is to introduce a new exception (e.g. ModuleNotFound) to make it clean to differentiate why ImportError was raised.
author Brett Cannon <brett@python.org>
date Fri, 24 Aug 2012 18:25:59 -0400
parents 0c661c5632e0
children 7fa6336e9864
line wrap: on
line diff
--- a/Lib/importlib/_bootstrap.py	Fri Aug 24 20:32:24 2012 +0100
+++ b/Lib/importlib/_bootstrap.py	Fri Aug 24 18:25:59 2012 -0400
@@ -1513,7 +1513,11 @@
             raise ImportError(msg, name=name)
     loader = _find_module(name, path)
     if loader is None:
-        raise ImportError(_ERR_MSG.format(name), name=name)
+        exc = ImportError(_ERR_MSG.format(name), name=name)
+        # TODO(brett): switch to a proper ModuleNotFound exception in Python
+        # 3.4.
+        exc._not_found = True
+        raise exc
     elif name not in sys.modules:
         # The parent import may have already imported this module.
         loader.load_module(name)
@@ -1599,10 +1603,16 @@
                 try:
                     _call_with_frames_removed(import_,
                                       '{}.{}'.format(module.__name__, x))
-                except ImportError:
+                except ImportError as exc:
                     # Backwards-compatibility dictates we ignore failed
-                    # imports triggered by fromlist.
-                    pass
+                    # imports triggered by fromlist for modules that don't
+                    # exist.
+                    # TODO(brett): In Python 3.4, have import raise
+                    #   ModuleNotFound and catch that.
+                    if hasattr(exc, '_not_found') and exc._not_found:
+                        pass
+                    else:
+                        raise
     return module