Kaydet (Commit) 5650e4f4 authored tarafından Brett Cannon's avatar Brett Cannon

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.
üst 195ad6ce
......@@ -364,10 +364,12 @@ ABC hierarchy::
* :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 @@ ABC hierarchy::
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`.
......
......@@ -931,6 +931,14 @@ class SourceLoader(_LoaderBasics):
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 @@ class SourceLoader(_LoaderBasics):
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):
......
......@@ -148,6 +148,11 @@ class SourceOnlyLoaderTests(SourceLoaderTestHarness):
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 @@ class AbstractMethodImplTests(unittest.TestCase):
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__':
......
......@@ -133,6 +133,8 @@ Core and Builtins
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.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment