[Python-checkins] cpython: Issue #15627: Add the compile_source() method to

brett.cannon python-checkins at python.org
Sun Nov 18 16:03:47 CET 2012


http://hg.python.org/cpython/rev/e30bcce5c634
changeset:   80507:e30bcce5c634
user:        Brett Cannon <brett at python.org>
date:        Sun Nov 18 10:03:31 2012 -0500
summary:
  Issue #15627: Add the compile_source() method to
importlib.abc.SourceLoader.

This provides an easy hook into the import system to allow for source
transformations, AST optimizations, etc.

files:
  Doc/library/importlib.rst                         |    17 +-
  Lib/importlib/_bootstrap.py                       |    12 +-
  Lib/test/test_importlib/source/test_abc_loader.py |    15 +-
  Misc/NEWS                                         |     2 +
  Python/importlib.h                                |  4718 +++++----
  5 files changed, 2404 insertions(+), 2360 deletions(-)


diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -364,10 +364,12 @@
     * :meth:`ResourceLoader.get_data`
     * :meth:`ExecutionLoader.get_filename`
           Should only return the path to the source file; sourceless
-          loading is not supported.
+          loading is not supported (see :class:`SourcelessLoader` if that
+          functionality is required)
 
     The abstract methods defined by this class are to add optional bytecode
-    file support. Not implementing these optional methods causes the loader to
+    file support. Not implementing these optional methods (or causing them to
+    raise :exc:`NotImplementedError`) causes the loader to
     only work with source code. Implementing the methods allows the loader to
     work with source *and* bytecode files; it does not allow for *sourceless*
     loading where only bytecode is provided.  Bytecode files are an
@@ -407,6 +409,17 @@
         When writing to the path fails because the path is read-only
         (:attr:`errno.EACCES`), do not propagate the exception.
 
+    .. method:: compile_source(data, path)
+
+        Create a code object from Python source.
+
+        The *data* argument can be whatever the :func:`compile` function
+        supports (i.e. string or bytes). The *path* argument should be
+        the "path" to where the source code originated from, which can be an
+        abstract concept (e.g. location in a zip file).
+
+        .. versionadded:: 3.4
+
     .. method:: get_code(fullname)
 
         Concrete implementation of :meth:`InspectLoader.get_code`.
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -931,6 +931,14 @@
             raise ImportError("Failed to decode source file",
                               name=fullname) from exc
 
+    def compile_source(self, data, path):
+        """Return the code object compiled from source.
+
+        The 'data' argument can be any object type that compile() supports.
+        """
+        return _call_with_frames_removed(compile, data, path, 'exec',
+                                        dont_inherit=True)
+
     def get_code(self, fullname):
         """Concrete implementation of InspectLoader.get_code.
 
@@ -976,9 +984,7 @@
                             raise ImportError(msg.format(bytecode_path),
                                               name=fullname, path=bytecode_path)
         source_bytes = self.get_data(source_path)
-        code_object = _call_with_frames_removed(compile,
-                          source_bytes, source_path, 'exec',
-                          dont_inherit=True)
+        code_object = self.compile_source(source_bytes, source_path)
         _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):
diff --git a/Lib/test/test_importlib/source/test_abc_loader.py b/Lib/test/test_importlib/source/test_abc_loader.py
--- a/Lib/test/test_importlib/source/test_abc_loader.py
+++ b/Lib/test/test_importlib/source/test_abc_loader.py
@@ -148,6 +148,11 @@
         code_object = self.loader.get_code(self.name)
         self.verify_code(code_object)
 
+    def test_compile_source(self):
+        # Verify the compiled code object.
+        code = self.loader.compile_source(self.loader.source, self.path)
+        self.verify_code(code)
+
     def test_load_module(self):
         # Loading a module should set __name__, __loader__, __package__,
         # __path__ (for packages), __file__, and __cached__.
@@ -395,12 +400,10 @@
 
 def test_main():
     from test.support import run_unittest
-    run_unittest(SkipWritingBytecodeTests, RegeneratedBytecodeTests,
-                    BadBytecodeFailureTests, MissingPathsTests,
-                    SourceOnlyLoaderTests,
-                    SourceLoaderBytecodeTests,
-                    SourceLoaderGetSourceTests,
-                    AbstractMethodImplTests)
+    run_unittest(SourceOnlyLoaderTests,
+                 SourceLoaderBytecodeTests,
+                 SourceLoaderGetSourceTests,
+                 AbstractMethodImplTests)
 
 
 if __name__ == '__main__':
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -133,6 +133,8 @@
 Library
 -------
 
+- Issue #15627: Add the importlib.abc.SourceLoader.compile_source() method.
+
 - Issue #16408: Fix file descriptors not being closed in error conditions
   in the zipfile module.  Patch by Serhiy Storchaka.
 
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list