diff Lib/importlib/_bootstrap.py @ 78344:62033490ca0f

Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
author Nick Coghlan <ncoghlan@gmail.com>
date Tue, 31 Jul 2012 21:14:18 +1000
parents 75a30a478dc7
children a1ac1e13c5a0
line wrap: on
line diff
--- a/Lib/importlib/_bootstrap.py	Tue Jul 31 06:14:59 2012 +0300
+++ b/Lib/importlib/_bootstrap.py	Tue Jul 31 21:14:18 2012 +1000
@@ -297,8 +297,20 @@
     else:
         lock.release()
 
+# Frame stripping magic ###############################################
 
-# Finder/loader utility code ##################################################
+def _call_with_frames_removed(f, *args, **kwds):
+    """remove_importlib_frames in import.c will always remove sequences
+    of importlib frames that end with a call to this function
+
+    Use it instead of a normal call in places where including the importlib
+    frames introduces unwanted noise into the traceback (e.g. when executing
+    module code)
+    """
+    return f(*args, **kwds)
+
+
+# Finder/loader utility code ###############################################
 
 """Magic word to reject .pyc files generated by other Python versions.
 It should change for each incompatible change to the bytecode.
@@ -629,20 +641,13 @@
         """Load a built-in module."""
         is_reload = fullname in sys.modules
         try:
-            return cls._exec_module(fullname)
+            return _call_with_frames_removed(_imp.init_builtin, fullname)
         except:
             if not is_reload and fullname in sys.modules:
                 del sys.modules[fullname]
             raise
 
     @classmethod
-    def _exec_module(cls, fullname):
-        """Helper for load_module, allowing to isolate easily (when
-        looking at a traceback) whether an error comes from executing
-        an imported module's code."""
-        return _imp.init_builtin(fullname)
-
-    @classmethod
     @_requires_builtin
     def get_code(cls, fullname):
         """Return None as built-in modules do not have code objects."""
@@ -687,7 +692,7 @@
         """Load a frozen module."""
         is_reload = fullname in sys.modules
         try:
-            m = cls._exec_module(fullname)
+            m = _call_with_frames_removed(_imp.init_frozen, fullname)
             # Let our own module_repr() method produce a suitable repr.
             del m.__file__
             return m
@@ -714,13 +719,6 @@
         """Return if the frozen module is a package."""
         return _imp.is_frozen_package(fullname)
 
-    @classmethod
-    def _exec_module(cls, fullname):
-        """Helper for load_module, allowing to isolate easily (when
-        looking at a traceback) whether an error comes from executing
-        an imported module's code."""
-        return _imp.init_frozen(fullname)
-
 
 class WindowsRegistryImporter:
 
@@ -850,15 +848,9 @@
         else:
             module.__package__ = module.__package__.rpartition('.')[0]
         module.__loader__ = self
-        self._exec_module(code_object, module.__dict__)
+        _call_with_frames_removed(exec, code_object, module.__dict__)
         return module
 
-    def _exec_module(self, code_object, module_dict):
-        """Helper for _load_module, allowing to isolate easily (when
-        looking at a traceback) whether an error comes from executing
-        an imported module's code."""
-        exec(code_object, module_dict)
-
 
 class SourceLoader(_LoaderBasics):
 
@@ -956,8 +948,9 @@
                             raise ImportError(msg.format(bytecode_path),
                                               name=fullname, path=bytecode_path)
         source_bytes = self.get_data(source_path)
-        code_object = compile(source_bytes, source_path, 'exec',
-                                dont_inherit=True)
+        code_object = _call_with_frames_removed(compile,
+                          source_bytes, source_path, 'exec',
+                          dont_inherit=True)
         _verbose_message('code object from {}', source_path)
         if (not sys.dont_write_bytecode and bytecode_path is not None and
             source_mtime is not None):
@@ -1093,7 +1086,8 @@
         """Load an extension module."""
         is_reload = fullname in sys.modules
         try:
-            module = self._exec_module(fullname, self.path)
+            module = _call_with_frames_removed(_imp.load_dynamic,
+                                               fullname, self.path)
             _verbose_message('extension module loaded from {!r}', self.path)
             return module
         except:
@@ -1113,12 +1107,6 @@
         """Return None as extension modules have no source code."""
         return None
 
-    def _exec_module(self, fullname, path):
-        """Helper for load_module, allowing to isolate easily (when
-        looking at a traceback) whether an error comes from executing
-        an imported module's code."""
-        return _imp.load_dynamic(fullname, path)
-
 
 class _NamespacePath:
     """Represents a namespace package's path.  It uses the module name
@@ -1472,7 +1460,7 @@
     parent = name.rpartition('.')[0]
     if parent:
         if parent not in sys.modules:
-            _recursive_import(import_, parent)
+            _call_with_frames_removed(import_, parent)
         # Crazy side-effects!
         if name in sys.modules:
             return sys.modules[name]
@@ -1550,13 +1538,6 @@
     _lock_unlock_module(name)
     return module
 
-def _recursive_import(import_, name):
-    """Common exit point for recursive calls to the import machinery
-
-    This simplifies the process of stripping importlib from tracebacks
-    """
-    return import_(name)
-
 def _handle_fromlist(module, fromlist, import_):
     """Figure out what __import__ should return.
 
@@ -1575,7 +1556,7 @@
                 fromlist.extend(module.__all__)
         for x in fromlist:
             if not hasattr(module, x):
-                _recursive_import(import_,
+                _call_with_frames_removed(import_,
                                   '{}.{}'.format(module.__name__, x))
     return module