diff options
author | Brett Cannon <brett@python.org> | 2013-05-31 22:56:47 (GMT) |
---|---|---|
committer | Brett Cannon <brett@python.org> | 2013-05-31 22:56:47 (GMT) |
commit | 0dbb4c7f1338d1391e7214b564ef4638bc257347 (patch) | |
tree | d9bd89758691c3b739c68e7eb50b444b15186bd1 /Lib/importlib/abc.py | |
parent | f1d7b11db905db5b40e2d97fa21af06871cf89ff (diff) | |
download | cpython-0dbb4c7f1338d1391e7214b564ef4638bc257347.zip cpython-0dbb4c7f1338d1391e7214b564ef4638bc257347.tar.gz cpython-0dbb4c7f1338d1391e7214b564ef4638bc257347.tar.bz2 |
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.py | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 897f343..417fe41 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): |