summaryrefslogtreecommitdiff
path: root/Lib/importlib/abc.py
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2013-05-31 18:56:47 -0400
committerBrett Cannon <brett@python.org>2013-05-31 18:56:47 -0400
commit0dbb4c7f1338d1391e7214b564ef4638bc257347 (patch)
treed9bd89758691c3b739c68e7eb50b444b15186bd1 /Lib/importlib/abc.py
parentf1d7b11db905db5b40e2d97fa21af06871cf89ff (diff)
downloadcpython-git-0dbb4c7f1338d1391e7214b564ef4638bc257347.tar.gz
Issues #18088, 18089: Introduce
importlib.abc.Loader.init_module_attrs() and implement importlib.abc.InspectLoader.load_module(). The importlib.abc.Loader.init_module_attrs() method sets the various attributes on the module being loaded. It is done unconditionally to support reloading. Typically people used importlib.util.module_for_loader, but since that's a decorator there was no way to override it's actions, so init_module_attrs() came into existence to allow for overriding. This is also why module_for_loader is now pending deprecation (having its other use replaced by importlib.util.module_to_load). All of this allowed for importlib.abc.InspectLoader.load_module() to be implemented. At this point you can now implement a loader with nothing more than get_code() (which only requires get_source(); package support requires is_package()). Thanks to init_module_attrs() the implementation of load_module() is basically a context manager containing 2 methods calls, a call to exec(), and a return statement.
Diffstat (limited to 'Lib/importlib/abc.py')
-rw-r--r--Lib/importlib/abc.py32
1 files changed, 27 insertions, 5 deletions
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py
index 897f343569..417fe413fb 100644
--- a/Lib/importlib/abc.py
+++ b/Lib/importlib/abc.py
@@ -8,11 +8,6 @@ except ImportError as exc:
raise
_frozen_importlib = None
import abc
-import imp
-import marshal
-import sys
-import tokenize
-import warnings
def _register(abstract_cls, *classes):
@@ -113,6 +108,10 @@ class Loader(metaclass=abc.ABCMeta):
"""
raise NotImplementedError
+ def init_module_attrs(self, module):
+ """Set the module's __loader__ attribute."""
+ module.__loader__ = self
+
class ResourceLoader(Loader):
@@ -177,6 +176,17 @@ class InspectLoader(Loader):
argument should be where the data was retrieved (when applicable)."""
return compile(data, path, 'exec', dont_inherit=True)
+ def init_module_attrs(self, module):
+ """Initialize the __loader__ and __package__ attributes of the module.
+
+ The name of the module is gleaned from module.__name__. The __package__
+ attribute is set based on self.is_package().
+ """
+ super().init_module_attrs(module)
+ _bootstrap._init_package_attrs(self, module)
+
+ load_module = _bootstrap._LoaderBasics.load_module
+
_register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter,
machinery.ExtensionFileLoader)
@@ -215,6 +225,18 @@ class ExecutionLoader(InspectLoader):
else:
return self.source_to_code(source, path)
+ def init_module_attrs(self, module):
+ """Initialize the module's attributes.
+
+ It is assumed that the module's name has been set on module.__name__.
+ It is also assumed that any path returned by self.get_filename() uses
+ (one of) the operating system's path separator(s) to separate filenames
+ from directories in order to set __path__ intelligently.
+ InspectLoader.init_module_attrs() sets __loader__ and __package__.
+ """
+ super().init_module_attrs(module)
+ _bootstrap._init_file_attrs(self, module)
+
class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader):