[Python-checkins] bpo-46109: Separate out files relating to importlib.resources (GH-30160)

jaraco webhook-mailer at python.org
Thu Dec 30 21:17:19 EST 2021


https://github.com/python/cpython/commit/99945c6b5cf280bd90075cffae942af44941abcc
commit: 99945c6b5cf280bd90075cffae942af44941abcc
branch: main
author: Jason R. Coombs <jaraco at jaraco.com>
committer: jaraco <jaraco at jaraco.com>
date: 2021-12-30T21:17:05-05:00
summary:

bpo-46109: Separate out files relating to importlib.resources (GH-30160)

* Separate out files relating to importlib.resources

* Update Introduction to direct readers to the submodule documentation.

* Create separate file for abcs relating to resources.

* Move abc docs back to where they were.

files:
A Doc/library/importlib.resources.abc.rst
A Doc/library/importlib.resources.rst
A Misc/NEWS.d/next/Documentation/2021-12-16-21-13-55.bpo-46109.0-RNzu.rst
M Doc/library/importlib.rst
M Doc/library/modules.rst

diff --git a/Doc/library/importlib.resources.abc.rst b/Doc/library/importlib.resources.abc.rst
new file mode 100644
index 0000000000000..6b0e1e04c8852
--- /dev/null
+++ b/Doc/library/importlib.resources.abc.rst
@@ -0,0 +1,385 @@
+.. class:: ResourceReader
+
+    *Superseded by TraversableResources*
+
+    An :term:`abstract base class` to provide the ability to read
+    *resources*.
+
+    From the perspective of this ABC, a *resource* is a binary
+    artifact that is shipped within a package. Typically this is
+    something like a data file that lives next to the ``__init__.py``
+    file of the package. The purpose of this class is to help abstract
+    out the accessing of such data files so that it does not matter if
+    the package and its data file(s) are stored in a e.g. zip file
+    versus on the file system.
+
+    For any of methods of this class, a *resource* argument is
+    expected to be a :term:`path-like object` which represents
+    conceptually just a file name. This means that no subdirectory
+    paths should be included in the *resource* argument. This is
+    because the location of the package the reader is for, acts as the
+    "directory". Hence the metaphor for directories and file
+    names is packages and resources, respectively. This is also why
+    instances of this class are expected to directly correlate to
+    a specific package (instead of potentially representing multiple
+    packages or a module).
+
+    Loaders that wish to support resource reading are expected to
+    provide a method called ``get_resource_reader(fullname)`` which
+    returns an object implementing this ABC's interface. If the module
+    specified by fullname is not a package, this method should return
+    :const:`None`. An object compatible with this ABC should only be
+    returned when the specified module is a package.
+
+    .. versionadded:: 3.7
+
+    .. abstractmethod:: open_resource(resource)
+
+        Returns an opened, :term:`file-like object` for binary reading
+        of the *resource*.
+
+        If the resource cannot be found, :exc:`FileNotFoundError` is
+        raised.
+
+    .. abstractmethod:: resource_path(resource)
+
+        Returns the file system path to the *resource*.
+
+        If the resource does not concretely exist on the file system,
+        raise :exc:`FileNotFoundError`.
+
+    .. abstractmethod:: is_resource(name)
+
+        Returns ``True`` if the named *name* is considered a resource.
+        :exc:`FileNotFoundError` is raised if *name* does not exist.
+
+    .. abstractmethod:: contents()
+
+        Returns an :term:`iterable` of strings over the contents of
+        the package. Do note that it is not required that all names
+        returned by the iterator be actual resources, e.g. it is
+        acceptable to return names for which :meth:`is_resource` would
+        be false.
+
+        Allowing non-resource names to be returned is to allow for
+        situations where how a package and its resources are stored
+        are known a priori and the non-resource names would be useful.
+        For instance, returning subdirectory names is allowed so that
+        when it is known that the package and resources are stored on
+        the file system then those subdirectory names can be used
+        directly.
+
+        The abstract method returns an iterable of no items.
+
+
+.. class:: ResourceLoader
+
+    An abstract base class for a :term:`loader` which implements the optional
+    :pep:`302` protocol for loading arbitrary resources from the storage
+    back-end.
+
+    .. deprecated:: 3.7
+       This ABC is deprecated in favour of supporting resource loading
+       through :class:`importlib.abc.ResourceReader`.
+
+    .. abstractmethod:: get_data(path)
+
+        An abstract method to return the bytes for the data located at *path*.
+        Loaders that have a file-like storage back-end
+        that allows storing arbitrary data
+        can implement this abstract method to give direct access
+        to the data stored. :exc:`OSError` is to be raised if the *path* cannot
+        be found. The *path* is expected to be constructed using a module's
+        :attr:`__file__` attribute or an item from a package's :attr:`__path__`.
+
+        .. versionchanged:: 3.4
+           Raises :exc:`OSError` instead of :exc:`NotImplementedError`.
+
+
+.. class:: InspectLoader
+
+    An abstract base class for a :term:`loader` which implements the optional
+    :pep:`302` protocol for loaders that inspect modules.
+
+    .. method:: get_code(fullname)
+
+        Return the code object for a module, or ``None`` if the module does not
+        have a code object (as would be the case, for example, for a built-in
+        module).  Raise an :exc:`ImportError` if loader cannot find the
+        requested module.
+
+        .. note::
+           While the method has a default implementation, it is suggested that
+           it be overridden if possible for performance.
+
+        .. index::
+           single: universal newlines; importlib.abc.InspectLoader.get_source method
+
+        .. versionchanged:: 3.4
+           No longer abstract and a concrete implementation is provided.
+
+    .. abstractmethod:: get_source(fullname)
+
+        An abstract method to return the source of a module. It is returned as
+        a text string using :term:`universal newlines`, translating all
+        recognized line separators into ``'\n'`` characters.  Returns ``None``
+        if no source is available (e.g. a built-in module). Raises
+        :exc:`ImportError` if the loader cannot find the module specified.
+
+        .. versionchanged:: 3.4
+           Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
+
+    .. method:: is_package(fullname)
+
+        An optional method to return a true value if the module is a package, a
+        false value otherwise. :exc:`ImportError` is raised if the
+        :term:`loader` cannot find the module.
+
+        .. versionchanged:: 3.4
+           Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
+
+    .. staticmethod:: source_to_code(data, path='<string>')
+
+        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).
+
+        With the subsequent code object one can execute it in a module by
+        running ``exec(code, module.__dict__)``.
+
+        .. versionadded:: 3.4
+
+        .. versionchanged:: 3.5
+           Made the method static.
+
+    .. method:: exec_module(module)
+
+       Implementation of :meth:`Loader.exec_module`.
+
+       .. versionadded:: 3.4
+
+    .. method:: load_module(fullname)
+
+       Implementation of :meth:`Loader.load_module`.
+
+       .. deprecated:: 3.4
+          use :meth:`exec_module` instead.
+
+
+.. class:: ExecutionLoader
+
+    An abstract base class which inherits from :class:`InspectLoader` that,
+    when implemented, helps a module to be executed as a script. The ABC
+    represents an optional :pep:`302` protocol.
+
+    .. abstractmethod:: get_filename(fullname)
+
+        An abstract method that is to return the value of :attr:`__file__` for
+        the specified module. If no path is available, :exc:`ImportError` is
+        raised.
+
+        If source code is available, then the method should return the path to
+        the source file, regardless of whether a bytecode was used to load the
+        module.
+
+        .. versionchanged:: 3.4
+           Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
+
+
+.. class:: FileLoader(fullname, path)
+
+   An abstract base class which inherits from :class:`ResourceLoader` and
+   :class:`ExecutionLoader`, providing concrete implementations of
+   :meth:`ResourceLoader.get_data` and :meth:`ExecutionLoader.get_filename`.
+
+   The *fullname* argument is a fully resolved name of the module the loader is
+   to handle. The *path* argument is the path to the file for the module.
+
+   .. versionadded:: 3.3
+
+   .. attribute:: name
+
+      The name of the module the loader can handle.
+
+   .. attribute:: path
+
+      Path to the file of the module.
+
+   .. method:: load_module(fullname)
+
+      Calls super's ``load_module()``.
+
+      .. deprecated:: 3.4
+         Use :meth:`Loader.exec_module` instead.
+
+   .. abstractmethod:: get_filename(fullname)
+
+      Returns :attr:`path`.
+
+   .. abstractmethod:: get_data(path)
+
+      Reads *path* as a binary file and returns the bytes from it.
+
+
+.. class:: SourceLoader
+
+    An abstract base class for implementing source (and optionally bytecode)
+    file loading. The class inherits from both :class:`ResourceLoader` and
+    :class:`ExecutionLoader`, requiring the implementation of:
+
+    * :meth:`ResourceLoader.get_data`
+    * :meth:`ExecutionLoader.get_filename`
+          Should only return the path to the source file; sourceless
+          loading is not supported.
+
+    The abstract methods defined by this class are to add optional bytecode
+    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
+    optimization to speed up loading by removing the parsing step of Python's
+    compiler, and so no bytecode-specific API is exposed.
+
+    .. method:: path_stats(path)
+
+        Optional abstract method which returns a :class:`dict` containing
+        metadata about the specified path.  Supported dictionary keys are:
+
+        - ``'mtime'`` (mandatory): an integer or floating-point number
+          representing the modification time of the source code;
+        - ``'size'`` (optional): the size in bytes of the source code.
+
+        Any other keys in the dictionary are ignored, to allow for future
+        extensions. If the path cannot be handled, :exc:`OSError` is raised.
+
+        .. versionadded:: 3.3
+
+        .. versionchanged:: 3.4
+           Raise :exc:`OSError` instead of :exc:`NotImplementedError`.
+
+    .. method:: path_mtime(path)
+
+        Optional abstract method which returns the modification time for the
+        specified path.
+
+        .. deprecated:: 3.3
+           This method is deprecated in favour of :meth:`path_stats`.  You don't
+           have to implement it, but it is still available for compatibility
+           purposes. Raise :exc:`OSError` if the path cannot be handled.
+
+        .. versionchanged:: 3.4
+           Raise :exc:`OSError` instead of :exc:`NotImplementedError`.
+
+    .. method:: set_data(path, data)
+
+        Optional abstract method which writes the specified bytes to a file
+        path. Any intermediate directories which do not exist are to be created
+        automatically.
+
+        When writing to the path fails because the path is read-only
+        (:attr:`errno.EACCES`/:exc:`PermissionError`), do not propagate the
+        exception.
+
+        .. versionchanged:: 3.4
+           No longer raises :exc:`NotImplementedError` when called.
+
+    .. method:: get_code(fullname)
+
+        Concrete implementation of :meth:`InspectLoader.get_code`.
+
+    .. method:: exec_module(module)
+
+       Concrete implementation of :meth:`Loader.exec_module`.
+
+       .. versionadded:: 3.4
+
+    .. method:: load_module(fullname)
+
+       Concrete implementation of :meth:`Loader.load_module`.
+
+       .. deprecated:: 3.4
+          Use :meth:`exec_module` instead.
+
+    .. method:: get_source(fullname)
+
+        Concrete implementation of :meth:`InspectLoader.get_source`.
+
+    .. method:: is_package(fullname)
+
+        Concrete implementation of :meth:`InspectLoader.is_package`. A module
+        is determined to be a package if its file path (as provided by
+        :meth:`ExecutionLoader.get_filename`) is a file named
+        ``__init__`` when the file extension is removed **and** the module name
+        itself does not end in ``__init__``.
+
+
+.. class:: Traversable
+
+    An object with a subset of pathlib.Path methods suitable for
+    traversing directories and opening files.
+
+    .. versionadded:: 3.9
+
+    .. attribute:: name
+
+       Abstract. The base name of this object without any parent references.
+
+    .. abstractmethod:: iterdir()
+
+       Yield Traversable objects in self.
+
+    .. abstractmethod:: is_dir()
+
+       Return True if self is a directory.
+
+    .. abstractmethod:: is_file()
+
+       Return True if self is a file.
+
+    .. abstractmethod:: joinpath(child)
+
+       Return Traversable child in self.
+
+    .. abstractmethod:: __truediv__(child)
+
+       Return Traversable child in self.
+
+    .. abstractmethod:: open(mode='r', *args, **kwargs)
+
+       *mode* may be 'r' or 'rb' to open as text or binary. Return a handle
+       suitable for reading (same as :attr:`pathlib.Path.open`).
+
+       When opening as text, accepts encoding parameters such as those
+       accepted by :attr:`io.TextIOWrapper`.
+
+    .. method:: read_bytes()
+
+       Read contents of self as bytes.
+
+    .. method:: read_text(encoding=None)
+
+       Read contents of self as text.
+
+
+.. class:: TraversableResources
+
+    An abstract base class for resource readers capable of serving
+    the :meth:`importlib.resources.files` interface. Subclasses
+    :class:`importlib.abc.ResourceReader` and provides
+    concrete implementations of the :class:`importlib.abc.ResourceReader`'s
+    abstract methods. Therefore, any loader supplying
+    :class:`importlib.abc.TraversableReader` also supplies ResourceReader.
+
+    Loaders that wish to support resource reading are expected to
+    implement this interface.
+
+    .. versionadded:: 3.9
+
+    .. abstractmethod:: files()
+
+       Returns a :class:`importlib.abc.Traversable` object for the loaded
+       package.
diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst
new file mode 100644
index 0000000000000..f62d15dd6fdc9
--- /dev/null
+++ b/Doc/library/importlib.resources.rst
@@ -0,0 +1,185 @@
+:mod:`importlib.resources` -- Resources
+---------------------------------------
+
+.. module:: importlib.resources
+    :synopsis: Package resource reading, opening, and access
+
+**Source code:** :source:`Lib/importlib/resources.py`
+
+--------------
+
+.. versionadded:: 3.7
+
+This module leverages Python's import system to provide access to *resources*
+within *packages*.  If you can import a package, you can access resources
+within that package.  Resources can be opened or read, in either binary or
+text mode.
+
+Resources are roughly akin to files inside directories, though it's important
+to keep in mind that this is just a metaphor.  Resources and packages **do
+not** have to exist as physical files and directories on the file system.
+
+.. note::
+
+   This module provides functionality similar to `pkg_resources
+   <https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_ `Basic
+   Resource Access
+   <http://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access>`_
+   without the performance overhead of that package.  This makes reading
+   resources included in packages easier, with more stable and consistent
+   semantics.
+
+   The standalone backport of this module provides more information
+   on `using importlib.resources
+   <http://importlib-resources.readthedocs.io/en/latest/using.html>`_ and
+   `migrating from pkg_resources to importlib.resources
+   <http://importlib-resources.readthedocs.io/en/latest/migration.html>`_
+   and
+   `migrating legacy usage <https://importlib-resources.readthedocs.io/en/latest/using.html#migrating-from-legacy>`_.
+
+Loaders that wish to support resource reading should implement a
+``get_resource_reader(fullname)`` method as specified by
+:class:`importlib.abc.ResourceReader`.
+
+The following types are defined.
+
+.. data:: Package
+
+    The ``Package`` type is defined as ``Union[str, ModuleType]``.  This means
+    that where the function describes accepting a ``Package``, you can pass in
+    either a string or a module.  Module objects must have a resolvable
+    ``__spec__.submodule_search_locations`` that is not ``None``.
+
+.. data:: Resource
+
+    This type describes the resource names passed into the various functions
+    in this package.  This is defined as ``Union[str, os.PathLike]``.
+
+
+The following functions are available.
+
+
+.. function:: files(package)
+
+    Returns an :class:`importlib.resources.abc.Traversable` object
+    representing the resource container for the package (think directory)
+    and its resources (think files). A Traversable may contain other
+    containers (think subdirectories).
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.
+
+    .. versionadded:: 3.9
+
+.. function:: as_file(traversable)
+
+    Given a :class:`importlib.resources.abc.Traversable` object representing
+    a file, typically from :func:`importlib.resources.files`, return
+    a context manager for use in a :keyword:`with` statement.
+    The context manager provides a :class:`pathlib.Path` object.
+
+    Exiting the context manager cleans up any temporary file created when the
+    resource was extracted from e.g. a zip file.
+
+    Use ``as_file`` when the Traversable methods
+    (``read_text``, etc) are insufficient and an actual file on
+    the file system is required.
+
+    .. versionadded:: 3.9
+
+.. function:: open_binary(package, resource)
+
+    Open for binary reading the *resource* within *package*.
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.  *resource* is the name of the resource to open
+    within *package*; it may not contain path separators and it may not have
+    sub-resources (i.e. it cannot be a directory).  This function returns a
+    ``typing.BinaryIO`` instance, a binary I/O stream open for reading.
+
+   .. deprecated:: 3.11
+
+
+.. function:: open_text(package, resource, encoding='utf-8', errors='strict')
+
+    Open for text reading the *resource* within *package*.  By default, the
+    resource is opened for reading as UTF-8.
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.  *resource* is the name of the resource to open
+    within *package*; it may not contain path separators and it may not have
+    sub-resources (i.e. it cannot be a directory).  *encoding* and *errors*
+    have the same meaning as with built-in :func:`open`.
+
+    This function returns a ``typing.TextIO`` instance, a text I/O stream open
+    for reading.
+
+   .. deprecated:: 3.11
+
+
+.. function:: read_binary(package, resource)
+
+    Read and return the contents of the *resource* within *package* as
+    ``bytes``.
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.  *resource* is the name of the resource to open
+    within *package*; it may not contain path separators and it may not have
+    sub-resources (i.e. it cannot be a directory).  This function returns the
+    contents of the resource as :class:`bytes`.
+
+   .. deprecated:: 3.11
+
+
+.. function:: read_text(package, resource, encoding='utf-8', errors='strict')
+
+    Read and return the contents of *resource* within *package* as a ``str``.
+    By default, the contents are read as strict UTF-8.
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.  *resource* is the name of the resource to open
+    within *package*; it may not contain path separators and it may not have
+    sub-resources (i.e. it cannot be a directory).  *encoding* and *errors*
+    have the same meaning as with built-in :func:`open`.  This function
+    returns the contents of the resource as :class:`str`.
+
+   .. deprecated:: 3.11
+
+
+.. function:: path(package, resource)
+
+    Return the path to the *resource* as an actual file system path.  This
+    function returns a context manager for use in a :keyword:`with` statement.
+    The context manager provides a :class:`pathlib.Path` object.
+
+    Exiting the context manager cleans up any temporary file created when the
+    resource needs to be extracted from e.g. a zip file.
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.  *resource* is the name of the resource to open
+    within *package*; it may not contain path separators and it may not have
+    sub-resources (i.e. it cannot be a directory).
+
+   .. deprecated:: 3.11
+
+
+.. function:: is_resource(package, name)
+
+    Return ``True`` if there is a resource named *name* in the package,
+    otherwise ``False``.  Remember that directories are *not* resources!
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.
+
+   .. deprecated:: 3.11
+
+
+.. function:: contents(package)
+
+    Return an iterable over the named items within the package.  The iterable
+    returns :class:`str` resources (e.g. files) and non-resources
+    (e.g. directories).  The iterable does not recurse into subdirectories.
+
+    *package* is either a name or a module object which conforms to the
+    ``Package`` requirements.
+
+   .. deprecated:: 3.11
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst
index 347e08e4a2846..23d908196669f 100644
--- a/Doc/library/importlib.rst
+++ b/Doc/library/importlib.rst
@@ -13,10 +13,13 @@
 
 --------------
 
+
 Introduction
 ------------
 
-The purpose of the :mod:`importlib` package is two-fold. One is to provide the
+The purpose of the :mod:`importlib` package is three-fold.
+
+One is to provide the
 implementation of the :keyword:`import` statement (and thus, by extension, the
 :func:`__import__` function) in Python source code. This provides an
 implementation of :keyword:`!import` which is portable to any Python
@@ -27,6 +30,14 @@ Two, the components to implement :keyword:`import` are exposed in this
 package, making it easier for users to create their own custom objects (known
 generically as an :term:`importer`) to participate in the import process.
 
+Three, the package contains modules exposing additional functionality for
+managing aspects of Python packages:
+
+* :mod:`importlib.metadata` presents access to metadata from third-party
+  distributions.
+* :mod:`importlib.resources` provides routines for accessing non-code
+  "resources" from Python packages.
+
 .. seealso::
 
     :ref:`import`
@@ -495,578 +506,7 @@ ABC hierarchy::
            The import machinery now takes care of this automatically.
 
 
-.. class:: ResourceReader
-
-    *Superseded by TraversableResources*
-
-    An :term:`abstract base class` to provide the ability to read
-    *resources*.
-
-    From the perspective of this ABC, a *resource* is a binary
-    artifact that is shipped within a package. Typically this is
-    something like a data file that lives next to the ``__init__.py``
-    file of the package. The purpose of this class is to help abstract
-    out the accessing of such data files so that it does not matter if
-    the package and its data file(s) are stored in a e.g. zip file
-    versus on the file system.
-
-    For any of methods of this class, a *resource* argument is
-    expected to be a :term:`path-like object` which represents
-    conceptually just a file name. This means that no subdirectory
-    paths should be included in the *resource* argument. This is
-    because the location of the package the reader is for, acts as the
-    "directory". Hence the metaphor for directories and file
-    names is packages and resources, respectively. This is also why
-    instances of this class are expected to directly correlate to
-    a specific package (instead of potentially representing multiple
-    packages or a module).
-
-    Loaders that wish to support resource reading are expected to
-    provide a method called ``get_resource_reader(fullname)`` which
-    returns an object implementing this ABC's interface. If the module
-    specified by fullname is not a package, this method should return
-    :const:`None`. An object compatible with this ABC should only be
-    returned when the specified module is a package.
-
-    .. versionadded:: 3.7
-
-    .. abstractmethod:: open_resource(resource)
-
-        Returns an opened, :term:`file-like object` for binary reading
-        of the *resource*.
-
-        If the resource cannot be found, :exc:`FileNotFoundError` is
-        raised.
-
-    .. abstractmethod:: resource_path(resource)
-
-        Returns the file system path to the *resource*.
-
-        If the resource does not concretely exist on the file system,
-        raise :exc:`FileNotFoundError`.
-
-    .. abstractmethod:: is_resource(name)
-
-        Returns ``True`` if the named *name* is considered a resource.
-        :exc:`FileNotFoundError` is raised if *name* does not exist.
-
-    .. abstractmethod:: contents()
-
-        Returns an :term:`iterable` of strings over the contents of
-        the package. Do note that it is not required that all names
-        returned by the iterator be actual resources, e.g. it is
-        acceptable to return names for which :meth:`is_resource` would
-        be false.
-
-        Allowing non-resource names to be returned is to allow for
-        situations where how a package and its resources are stored
-        are known a priori and the non-resource names would be useful.
-        For instance, returning subdirectory names is allowed so that
-        when it is known that the package and resources are stored on
-        the file system then those subdirectory names can be used
-        directly.
-
-        The abstract method returns an iterable of no items.
-
-
-.. class:: ResourceLoader
-
-    An abstract base class for a :term:`loader` which implements the optional
-    :pep:`302` protocol for loading arbitrary resources from the storage
-    back-end.
-
-    .. deprecated:: 3.7
-       This ABC is deprecated in favour of supporting resource loading
-       through :class:`importlib.abc.ResourceReader`.
-
-    .. abstractmethod:: get_data(path)
-
-        An abstract method to return the bytes for the data located at *path*.
-        Loaders that have a file-like storage back-end
-        that allows storing arbitrary data
-        can implement this abstract method to give direct access
-        to the data stored. :exc:`OSError` is to be raised if the *path* cannot
-        be found. The *path* is expected to be constructed using a module's
-        :attr:`__file__` attribute or an item from a package's :attr:`__path__`.
-
-        .. versionchanged:: 3.4
-           Raises :exc:`OSError` instead of :exc:`NotImplementedError`.
-
-
-.. class:: InspectLoader
-
-    An abstract base class for a :term:`loader` which implements the optional
-    :pep:`302` protocol for loaders that inspect modules.
-
-    .. method:: get_code(fullname)
-
-        Return the code object for a module, or ``None`` if the module does not
-        have a code object (as would be the case, for example, for a built-in
-        module).  Raise an :exc:`ImportError` if loader cannot find the
-        requested module.
-
-        .. note::
-           While the method has a default implementation, it is suggested that
-           it be overridden if possible for performance.
-
-        .. index::
-           single: universal newlines; importlib.abc.InspectLoader.get_source method
-
-        .. versionchanged:: 3.4
-           No longer abstract and a concrete implementation is provided.
-
-    .. abstractmethod:: get_source(fullname)
-
-        An abstract method to return the source of a module. It is returned as
-        a text string using :term:`universal newlines`, translating all
-        recognized line separators into ``'\n'`` characters.  Returns ``None``
-        if no source is available (e.g. a built-in module). Raises
-        :exc:`ImportError` if the loader cannot find the module specified.
-
-        .. versionchanged:: 3.4
-           Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
-
-    .. method:: is_package(fullname)
-
-        An optional method to return a true value if the module is a package, a
-        false value otherwise. :exc:`ImportError` is raised if the
-        :term:`loader` cannot find the module.
-
-        .. versionchanged:: 3.4
-           Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
-
-    .. staticmethod:: source_to_code(data, path='<string>')
-
-        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).
-
-        With the subsequent code object one can execute it in a module by
-        running ``exec(code, module.__dict__)``.
-
-        .. versionadded:: 3.4
-
-        .. versionchanged:: 3.5
-           Made the method static.
-
-    .. method:: exec_module(module)
-
-       Implementation of :meth:`Loader.exec_module`.
-
-       .. versionadded:: 3.4
-
-    .. method:: load_module(fullname)
-
-       Implementation of :meth:`Loader.load_module`.
-
-       .. deprecated:: 3.4
-          use :meth:`exec_module` instead.
-
-
-.. class:: ExecutionLoader
-
-    An abstract base class which inherits from :class:`InspectLoader` that,
-    when implemented, helps a module to be executed as a script. The ABC
-    represents an optional :pep:`302` protocol.
-
-    .. abstractmethod:: get_filename(fullname)
-
-        An abstract method that is to return the value of :attr:`__file__` for
-        the specified module. If no path is available, :exc:`ImportError` is
-        raised.
-
-        If source code is available, then the method should return the path to
-        the source file, regardless of whether a bytecode was used to load the
-        module.
-
-        .. versionchanged:: 3.4
-           Raises :exc:`ImportError` instead of :exc:`NotImplementedError`.
-
-
-.. class:: FileLoader(fullname, path)
-
-   An abstract base class which inherits from :class:`ResourceLoader` and
-   :class:`ExecutionLoader`, providing concrete implementations of
-   :meth:`ResourceLoader.get_data` and :meth:`ExecutionLoader.get_filename`.
-
-   The *fullname* argument is a fully resolved name of the module the loader is
-   to handle. The *path* argument is the path to the file for the module.
-
-   .. versionadded:: 3.3
-
-   .. attribute:: name
-
-      The name of the module the loader can handle.
-
-   .. attribute:: path
-
-      Path to the file of the module.
-
-   .. method:: load_module(fullname)
-
-      Calls super's ``load_module()``.
-
-      .. deprecated:: 3.4
-         Use :meth:`Loader.exec_module` instead.
-
-   .. abstractmethod:: get_filename(fullname)
-
-      Returns :attr:`path`.
-
-   .. abstractmethod:: get_data(path)
-
-      Reads *path* as a binary file and returns the bytes from it.
-
-
-.. class:: SourceLoader
-
-    An abstract base class for implementing source (and optionally bytecode)
-    file loading. The class inherits from both :class:`ResourceLoader` and
-    :class:`ExecutionLoader`, requiring the implementation of:
-
-    * :meth:`ResourceLoader.get_data`
-    * :meth:`ExecutionLoader.get_filename`
-          Should only return the path to the source file; sourceless
-          loading is not supported.
-
-    The abstract methods defined by this class are to add optional bytecode
-    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
-    optimization to speed up loading by removing the parsing step of Python's
-    compiler, and so no bytecode-specific API is exposed.
-
-    .. method:: path_stats(path)
-
-        Optional abstract method which returns a :class:`dict` containing
-        metadata about the specified path.  Supported dictionary keys are:
-
-        - ``'mtime'`` (mandatory): an integer or floating-point number
-          representing the modification time of the source code;
-        - ``'size'`` (optional): the size in bytes of the source code.
-
-        Any other keys in the dictionary are ignored, to allow for future
-        extensions. If the path cannot be handled, :exc:`OSError` is raised.
-
-        .. versionadded:: 3.3
-
-        .. versionchanged:: 3.4
-           Raise :exc:`OSError` instead of :exc:`NotImplementedError`.
-
-    .. method:: path_mtime(path)
-
-        Optional abstract method which returns the modification time for the
-        specified path.
-
-        .. deprecated:: 3.3
-           This method is deprecated in favour of :meth:`path_stats`.  You don't
-           have to implement it, but it is still available for compatibility
-           purposes. Raise :exc:`OSError` if the path cannot be handled.
-
-        .. versionchanged:: 3.4
-           Raise :exc:`OSError` instead of :exc:`NotImplementedError`.
-
-    .. method:: set_data(path, data)
-
-        Optional abstract method which writes the specified bytes to a file
-        path. Any intermediate directories which do not exist are to be created
-        automatically.
-
-        When writing to the path fails because the path is read-only
-        (:attr:`errno.EACCES`/:exc:`PermissionError`), do not propagate the
-        exception.
-
-        .. versionchanged:: 3.4
-           No longer raises :exc:`NotImplementedError` when called.
-
-    .. method:: get_code(fullname)
-
-        Concrete implementation of :meth:`InspectLoader.get_code`.
-
-    .. method:: exec_module(module)
-
-       Concrete implementation of :meth:`Loader.exec_module`.
-
-       .. versionadded:: 3.4
-
-    .. method:: load_module(fullname)
-
-       Concrete implementation of :meth:`Loader.load_module`.
-
-       .. deprecated:: 3.4
-          Use :meth:`exec_module` instead.
-
-    .. method:: get_source(fullname)
-
-        Concrete implementation of :meth:`InspectLoader.get_source`.
-
-    .. method:: is_package(fullname)
-
-        Concrete implementation of :meth:`InspectLoader.is_package`. A module
-        is determined to be a package if its file path (as provided by
-        :meth:`ExecutionLoader.get_filename`) is a file named
-        ``__init__`` when the file extension is removed **and** the module name
-        itself does not end in ``__init__``.
-
-
-.. class:: Traversable
-
-    An object with a subset of pathlib.Path methods suitable for
-    traversing directories and opening files.
-
-    .. versionadded:: 3.9
-
-    .. attribute:: name
-
-       Abstract. The base name of this object without any parent references.
-
-    .. abstractmethod:: iterdir()
-
-       Yield Traversable objects in self.
-
-    .. abstractmethod:: is_dir()
-
-       Return True if self is a directory.
-
-    .. abstractmethod:: is_file()
-
-       Return True if self is a file.
-
-    .. abstractmethod:: joinpath(child)
-
-       Return Traversable child in self.
-
-    .. abstractmethod:: __truediv__(child)
-
-       Return Traversable child in self.
-
-    .. abstractmethod:: open(mode='r', *args, **kwargs)
-
-       *mode* may be 'r' or 'rb' to open as text or binary. Return a handle
-       suitable for reading (same as :attr:`pathlib.Path.open`).
-
-       When opening as text, accepts encoding parameters such as those
-       accepted by :attr:`io.TextIOWrapper`.
-
-    .. method:: read_bytes()
-
-       Read contents of self as bytes.
-
-    .. method:: read_text(encoding=None)
-
-       Read contents of self as text.
-
-
-.. class:: TraversableResources
-
-    An abstract base class for resource readers capable of serving
-    the :meth:`importlib.resources.files` interface. Subclasses
-    :class:`importlib.abc.ResourceReader` and provides
-    concrete implementations of the :class:`importlib.abc.ResourceReader`'s
-    abstract methods. Therefore, any loader supplying
-    :class:`importlib.abc.TraversableReader` also supplies ResourceReader.
-
-    Loaders that wish to support resource reading are expected to
-    implement this interface.
-
-    .. versionadded:: 3.9
-
-    .. abstractmethod:: files()
-
-       Returns a :class:`importlib.abc.Traversable` object for the loaded
-       package.
-
-
-:mod:`importlib.resources` -- Resources
----------------------------------------
-
-.. module:: importlib.resources
-    :synopsis: Package resource reading, opening, and access
-
-**Source code:** :source:`Lib/importlib/resources.py`
-
---------------
-
-.. versionadded:: 3.7
-
-This module leverages Python's import system to provide access to *resources*
-within *packages*.  If you can import a package, you can access resources
-within that package.  Resources can be opened or read, in either binary or
-text mode.
-
-Resources are roughly akin to files inside directories, though it's important
-to keep in mind that this is just a metaphor.  Resources and packages **do
-not** have to exist as physical files and directories on the file system.
-
-.. note::
-
-   This module provides functionality similar to `pkg_resources
-   <https://setuptools.readthedocs.io/en/latest/pkg_resources.html>`_ `Basic
-   Resource Access
-   <http://setuptools.readthedocs.io/en/latest/pkg_resources.html#basic-resource-access>`_
-   without the performance overhead of that package.  This makes reading
-   resources included in packages easier, with more stable and consistent
-   semantics.
-
-   The standalone backport of this module provides more information
-   on `using importlib.resources
-   <http://importlib-resources.readthedocs.io/en/latest/using.html>`_ and
-   `migrating from pkg_resources to importlib.resources
-   <http://importlib-resources.readthedocs.io/en/latest/migration.html>`_
-   and
-   `migrating legacy usage <https://importlib-resources.readthedocs.io/en/latest/using.html#migrating-from-legacy>`_.
-
-Loaders that wish to support resource reading should implement a
-``get_resource_reader(fullname)`` method as specified by
-:class:`importlib.abc.ResourceReader`.
-
-The following types are defined.
-
-.. data:: Package
-
-    The ``Package`` type is defined as ``Union[str, ModuleType]``.  This means
-    that where the function describes accepting a ``Package``, you can pass in
-    either a string or a module.  Module objects must have a resolvable
-    ``__spec__.submodule_search_locations`` that is not ``None``.
-
-.. data:: Resource
-
-    This type describes the resource names passed into the various functions
-    in this package.  This is defined as ``Union[str, os.PathLike]``.
-
-
-The following functions are available.
-
-
-.. function:: files(package)
-
-    Returns an :class:`importlib.resources.abc.Traversable` object
-    representing the resource container for the package (think directory)
-    and its resources (think files). A Traversable may contain other
-    containers (think subdirectories).
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.
-
-    .. versionadded:: 3.9
-
-.. function:: as_file(traversable)
-
-    Given a :class:`importlib.resources.abc.Traversable` object representing
-    a file, typically from :func:`importlib.resources.files`, return
-    a context manager for use in a :keyword:`with` statement.
-    The context manager provides a :class:`pathlib.Path` object.
-
-    Exiting the context manager cleans up any temporary file created when the
-    resource was extracted from e.g. a zip file.
-
-    Use ``as_file`` when the Traversable methods
-    (``read_text``, etc) are insufficient and an actual file on
-    the file system is required.
-
-    .. versionadded:: 3.9
-
-.. function:: open_binary(package, resource)
-
-    Open for binary reading the *resource* within *package*.
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.  *resource* is the name of the resource to open
-    within *package*; it may not contain path separators and it may not have
-    sub-resources (i.e. it cannot be a directory).  This function returns a
-    ``typing.BinaryIO`` instance, a binary I/O stream open for reading.
-
-   .. deprecated:: 3.11
-
-
-.. function:: open_text(package, resource, encoding='utf-8', errors='strict')
-
-    Open for text reading the *resource* within *package*.  By default, the
-    resource is opened for reading as UTF-8.
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.  *resource* is the name of the resource to open
-    within *package*; it may not contain path separators and it may not have
-    sub-resources (i.e. it cannot be a directory).  *encoding* and *errors*
-    have the same meaning as with built-in :func:`open`.
-
-    This function returns a ``typing.TextIO`` instance, a text I/O stream open
-    for reading.
-
-   .. deprecated:: 3.11
-
-
-.. function:: read_binary(package, resource)
-
-    Read and return the contents of the *resource* within *package* as
-    ``bytes``.
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.  *resource* is the name of the resource to open
-    within *package*; it may not contain path separators and it may not have
-    sub-resources (i.e. it cannot be a directory).  This function returns the
-    contents of the resource as :class:`bytes`.
-
-   .. deprecated:: 3.11
-
-
-.. function:: read_text(package, resource, encoding='utf-8', errors='strict')
-
-    Read and return the contents of *resource* within *package* as a ``str``.
-    By default, the contents are read as strict UTF-8.
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.  *resource* is the name of the resource to open
-    within *package*; it may not contain path separators and it may not have
-    sub-resources (i.e. it cannot be a directory).  *encoding* and *errors*
-    have the same meaning as with built-in :func:`open`.  This function
-    returns the contents of the resource as :class:`str`.
-
-   .. deprecated:: 3.11
-
-
-.. function:: path(package, resource)
-
-    Return the path to the *resource* as an actual file system path.  This
-    function returns a context manager for use in a :keyword:`with` statement.
-    The context manager provides a :class:`pathlib.Path` object.
-
-    Exiting the context manager cleans up any temporary file created when the
-    resource needs to be extracted from e.g. a zip file.
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.  *resource* is the name of the resource to open
-    within *package*; it may not contain path separators and it may not have
-    sub-resources (i.e. it cannot be a directory).
-
-   .. deprecated:: 3.11
-
-
-.. function:: is_resource(package, name)
-
-    Return ``True`` if there is a resource named *name* in the package,
-    otherwise ``False``.  Remember that directories are *not* resources!
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.
-
-   .. deprecated:: 3.11
-
-
-.. function:: contents(package)
-
-    Return an iterable over the named items within the package.  The iterable
-    returns :class:`str` resources (e.g. files) and non-resources
-    (e.g. directories).  The iterable does not recurse into subdirectories.
-
-    *package* is either a name or a module object which conforms to the
-    ``Package`` requirements.
-
-   .. deprecated:: 3.11
+.. include:: importlib.resources.abc.rst
 
 
 :mod:`importlib.machinery` -- Importers and path hooks
diff --git a/Doc/library/modules.rst b/Doc/library/modules.rst
index 565ce0525c2c9..131dfca9576a3 100644
--- a/Doc/library/modules.rst
+++ b/Doc/library/modules.rst
@@ -17,4 +17,5 @@ The full list of modules described in this chapter is:
    modulefinder.rst
    runpy.rst
    importlib.rst
+   importlib.resources.rst
    importlib.metadata.rst
diff --git a/Misc/NEWS.d/next/Documentation/2021-12-16-21-13-55.bpo-46109.0-RNzu.rst b/Misc/NEWS.d/next/Documentation/2021-12-16-21-13-55.bpo-46109.0-RNzu.rst
new file mode 100644
index 0000000000000..78d5149c80022
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2021-12-16-21-13-55.bpo-46109.0-RNzu.rst
@@ -0,0 +1,2 @@
+Extracted ``importlib.resources`` and ``importlib.resources.abc`` documentation into
+separate files.



More information about the Python-checkins mailing list