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.
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 35336b1..d9e4273 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -246,7 +246,7 @@
 
         The loader should set several attributes on the module.
         (Note that some of these attributes can change when a module is
-        reloaded.)
+        reloaded; see :meth:`init_module_attrs`):
 
         - :attr:`__name__`
             The name of the module.
@@ -289,6 +289,17 @@
         .. versionchanged:: 3.4
            Made optional instead of an abstractmethod.
 
+    .. method:: init_module_attrs(module)
+
+        Set the :attr:`__loader__` attribute on the module.
+
+        Subclasses overriding this method should set whatever appropriate
+        attributes it can, getting the module's name from :attr:`__name__` when
+        needed. All values should also be overridden so that reloading works as
+        expected.
+
+        .. versionadded:: 3.4
+
 
 .. class:: ResourceLoader
 
@@ -363,6 +374,18 @@
 
         .. versionadded:: 3.4
 
+    .. method:: init_module_attrs(module)
+
+        Set the :attr:`__package__` attribute and :attr:`__path__` attribute to
+        the empty list if appropriate along with what
+        :meth:`importlib.abc.Loader.init_module_attrs` sets.
+
+        .. versionadded:: 3.4
+
+    .. method:: load_module(fullname)
+
+        Implementation of :meth:`Loader.load_module`.
+
 
 .. class:: ExecutionLoader
 
@@ -383,6 +406,15 @@
         .. versionchanged:: 3.4
            Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
 
+    .. method:: init_module_attrs(module)
+
+        Set :attr:`__file__` and if initializing a package then set
+        :attr:`__path__` to ``[os.path.dirname(__file__)]`` along with
+        all attributes set by
+        :meth:`importlib.abc.InspectLoader.init_module_attrs`.
+
+        .. versionadded:: 3.4
+
 
 .. class:: FileLoader(fullname, path)
 
@@ -500,6 +532,14 @@
         ``__init__`` when the file extension is removed **and** the module name
         itself does not end in ``__init__``.
 
+    .. method:: init_module_attr(module)
+
+        Set :attr:`__cached__` using :func:`imp.cache_from_source`. Other
+        attributes set by
+        :meth:`importlib.abc.ExecutionLoader.init_module_attrs`.
+
+        .. versionadded:: 3.4
+
 
 :mod:`importlib.machinery` -- Importers and path hooks
 ------------------------------------------------------
@@ -826,17 +866,18 @@
     module from being in left in :data:`sys.modules`. If the module was already
     in :data:`sys.modules` then it is left alone.
 
-    .. note::
-       :func:`module_to_load` subsumes the module management aspect of this
-       decorator.
-
     .. versionchanged:: 3.3
        :attr:`__loader__` and :attr:`__package__` are automatically set
        (when possible).
 
     .. versionchanged:: 3.4
-       Set :attr:`__loader__` :attr:`__package__` unconditionally to support
-       reloading.
+       Set :attr:`__name__`, :attr:`__loader__` :attr:`__package__`
+       unconditionally to support reloading.
+
+    .. deprecated:: 3.4
+        For the benefit of :term:`loader` subclasses, please use
+        :func:`module_to_load` and
+        :meth:`importlib.abc.Loader.init_module_attrs` instead.
 
 .. decorator:: set_loader
 
@@ -849,7 +890,8 @@
 
    .. note::
       As this decorator sets :attr:`__loader__` after loading the module, it is
-      recommended to use :func:`module_for_loader` instead when appropriate.
+      recommended to use :meth:`importlib.abc.Loader.init_module_attrs` instead
+      when appropriate.
 
    .. versionchanged:: 3.4
       Set ``__loader__`` if set to ``None``, as if the attribute does not
@@ -862,4 +904,5 @@
 
    .. note::
       As this decorator sets :attr:`__package__` after loading the module, it is
-      recommended to use :func:`module_for_loader` instead when appropriate.
+      recommended to use :meth:`importlib.abc.Loader.init_module_attrs` instead
+      when appropriate.