:mod:`!importlib` --- The implementation of :keyword:`!import`
==============================================================

.. module:: importlib
   :synopsis: The implementation of the import machinery.

.. versionadded:: 3.1

**Source code:** :source:`Lib/importlib/__init__.py`

--------------


Introduction
------------

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
interpreter. This also provides an implementation which is easier to
comprehend than one implemented in a programming language other than Python.

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`
        The language reference for the :keyword:`import` statement.

    `Packages specification <https://www.python.org/doc/essays/packages/>`__
        Original specification of packages. Some semantics have changed since
        the writing of this document (e.g. redirecting based on ``None``
        in :data:`sys.modules`).

    The :func:`.__import__` function
        The :keyword:`import` statement is syntactic sugar for this function.

    :ref:`sys-path-init`
        The initialization of :data:`sys.path`.

    :pep:`235`
        Import on Case-Insensitive Platforms

    :pep:`263`
        Defining Python Source Code Encodings

    :pep:`302`
        New Import Hooks

    :pep:`328`
        Imports: Multi-Line and Absolute/Relative

    :pep:`366`
        Main module explicit relative imports

    :pep:`420`
        Implicit namespace packages

    :pep:`451`
        A ModuleSpec Type for the Import System

    :pep:`488`
        Elimination of PYO files

    :pep:`489`
        Multi-phase extension module initialization

    :pep:`552`
        Deterministic pycs

    :pep:`3120`
        Using UTF-8 as the Default Source Encoding

    :pep:`3147`
        PYC Repository Directories


Functions
---------

.. function:: __import__(name, globals=None, locals=None, fromlist=(), level=0)

    An implementation of the built-in :func:`__import__` function.

    .. note::
       Programmatic importing of modules should use :func:`import_module`
       instead of this function.

.. function:: import_module(name, package=None)

    Import a module. The *name* argument specifies what module to
    import in absolute or relative terms
    (e.g. either ``pkg.mod`` or ``..mod``). If the name is
    specified in relative terms, then the *package* argument must be set to
    the name of the package which is to act as the anchor for resolving the
    package name (e.g. ``import_module('..mod', 'pkg.subpkg')`` will import
    ``pkg.mod``).

    The :func:`import_module` function acts as a simplifying wrapper around
    :func:`importlib.__import__`. This means all semantics of the function are
    derived from :func:`importlib.__import__`. The most important difference
    between these two functions is that :func:`import_module` returns the
    specified package or module (e.g. ``pkg.mod``), while :func:`__import__`
    returns the top-level package or module (e.g. ``pkg``).

    If you are dynamically importing a module that was created since the
    interpreter began execution (e.g., created a Python source file), you may
    need to call :func:`invalidate_caches` in order for the new module to be
    noticed by the import system.

    If the module cannot be imported, :func:`import_module` will raise
    :exc:`ImportError` or an appropriate subclass like
    :exc:`ModuleNotFoundError`.

    .. versionchanged:: 3.3
       Parent packages are automatically imported.

.. function:: invalidate_caches()

   Invalidate the internal caches of finders stored at
   :data:`sys.meta_path`. If a finder implements ``invalidate_caches()`` then it
   will be called to perform the invalidation.  This function should be called
   if any modules are created/installed while your program is running to
   guarantee all finders will notice the new module's existence.

   .. versionadded:: 3.3

   .. versionchanged:: 3.10
      Namespace packages created/installed in a different :data:`sys.path`
      location after the same namespace was already imported are noticed.

.. function:: reload(module)

   Reload a previously imported *module*.  The argument must be a module object,
   so it must have been successfully imported before.  This is useful if you
   have edited the module source file using an external editor and want to try
   out the new version without leaving the Python interpreter.  The return value
   is the module object (which can be different if re-importing causes a
   different object to be placed in :data:`sys.modules`).

   When :func:`reload` is executed:

   * Python module's code is recompiled and the module-level code re-executed,
     defining a new set of objects which are bound to names in the module's
     dictionary by reusing the :term:`loader` which originally loaded the
     module.  The ``init`` function of extension modules is not called a second
     time.

   * As with all other objects in Python the old objects are only reclaimed
     after their reference counts drop to zero.

   * The names in the module namespace are updated to point to any new or
     changed objects.

   * Other references to the old objects (such as names external to the module) are
     not rebound to refer to the new objects and must be updated in each namespace
     where they occur if that is desired.

   There are a number of other caveats:

   When a module is reloaded, its dictionary (containing the module's global
   variables) is retained.  Redefinitions of names will override the old
   definitions, so this is generally not a problem.  If the new version of a
   module does not define a name that was defined by the old version, the old
   definition remains.  This feature can be used to the module's advantage if it
   maintains a global table or cache of objects --- with a :keyword:`try`
   statement it can test for the table's presence and skip its initialization if
   desired::

      try:
          cache
      except NameError:
          cache = {}

   It is generally not very useful to reload built-in or dynamically loaded
   modules.  Reloading :mod:`sys`, :mod:`__main__`, :mod:`builtins` and other
   key modules is not recommended.  In many cases extension modules are not
   designed to be initialized more than once, and may fail in arbitrary ways
   when reloaded.

   If a module imports objects from another module using :keyword:`from` ...
   :keyword:`import` ..., calling :func:`reload` for the other module does not
   redefine the objects imported from it --- one way around this is to
   re-execute the :keyword:`!from` statement, another is to use :keyword:`!import`
   and qualified names (*module.name*) instead.

   If a module instantiates instances of a class, reloading the module that
   defines the class does not affect the method definitions of the instances ---
   they continue to use the old class definition.  The same is true for derived
   classes.

   .. versionadded:: 3.4
   .. versionchanged:: 3.7
       :exc:`ModuleNotFoundError` is raised when the module being reloaded lacks
       a :class:`~importlib.machinery.ModuleSpec`.

   .. warning::
      This function is not thread-safe. Calling it from multiple threads can result
      in unexpected behavior. It's recommended to use the :class:`threading.Lock`
      or other synchronization primitives for thread-safe module reloading.

:mod:`!importlib.abc` -- Abstract base classes related to import
----------------------------------------------------------------

.. module:: importlib.abc
    :synopsis: Abstract base classes related to import

**Source code:** :source:`Lib/importlib/abc.py`

--------------


The :mod:`!importlib.abc` module contains all of the core abstract base classes
used by :keyword:`import`. Some subclasses of the core abstract base classes
are also provided to help in implementing the core ABCs.

ABC hierarchy::

    object
     +-- MetaPathFinder
     +-- PathEntryFinder
     +-- Loader
          +-- ResourceLoader --------+
          +-- InspectLoader          |
               +-- ExecutionLoader --+
                                     +-- FileLoader
                                     +-- SourceLoader


.. class:: MetaPathFinder

   An abstract base class representing a :term:`meta path finder`.

   .. versionadded:: 3.3

   .. versionchanged:: 3.10
      No longer a subclass of :class:`!Finder`.

   .. method:: find_spec(fullname, path, target=None)

      An abstract method for finding a :term:`spec <module spec>` for
      the specified module.  If this is a top-level import, *path* will
      be ``None``.  Otherwise, this is a search for a subpackage or
      module and *path* will be the value of :attr:`~module.__path__` from the
      parent package. If a spec cannot be found, ``None`` is returned.
      When passed in, ``target`` is a module object that the finder may
      use to make a more educated guess about what spec to return.
      :func:`importlib.util.spec_from_loader` may be useful for implementing
      concrete ``MetaPathFinders``.

      .. versionadded:: 3.4

   .. method:: invalidate_caches()

      An optional method which, when called, should invalidate any internal
      cache used by the finder. Used by :func:`importlib.invalidate_caches`
      when invalidating the caches of all finders on :data:`sys.meta_path`.

      .. versionchanged:: 3.4
         Returns ``None`` when called instead of :data:`NotImplemented`.

   .. method:: discover(parent=None)

      An optional method which searches for possible specs with given *parent*
      module spec. If *parent* is *None*, :meth:`MetaPathFinder.discover` will
      search for top-level modules.

      Returns an iterable of possible specs.

      Raises :exc:`ValueError` if *parent* is not a package module.

      .. warning::
         This method can potentially yield a very large number of objects, and
         it may carry out IO operations when computing these values.

         Because of this, it will generaly be desirable to compute the result
         values on-the-fly, as they are needed. As such, the returned object is
         only guaranteed to be an :class:`iterable <collections.abc.Iterable>`,
         instead of a :class:`list` or other
         :class:`collection <collections.abc.Collection>` type.

      .. versionadded:: 3.15


.. class:: PathEntryFinder

   An abstract base class representing a :term:`path entry finder`.  Though
   it bears some similarities to :class:`MetaPathFinder`, ``PathEntryFinder``
   is meant for use only within the path-based import subsystem provided
   by :class:`importlib.machinery.PathFinder`.

   .. versionadded:: 3.3

   .. versionchanged:: 3.10
      No longer a subclass of :class:`!Finder`.

   .. method:: find_spec(fullname, target=None)

      An abstract method for finding a :term:`spec <module spec>` for
      the specified module.  The finder will search for the module only
      within the :term:`path entry` to which it is assigned.  If a spec
      cannot be found, ``None`` is returned.  When passed in, ``target``
      is a module object that the finder may use to make a more educated
      guess about what spec to return. :func:`importlib.util.spec_from_loader`
      may be useful for implementing concrete ``PathEntryFinders``.

      .. versionadded:: 3.4

   .. method:: invalidate_caches()

      An optional method which, when called, should invalidate any internal
      cache used by the finder. Used by
      :meth:`importlib.machinery.PathFinder.invalidate_caches`
      when invalidating the caches of all cached finders.

   .. method:: discover(parent=None)

      An optional method which searches for possible specs with given *parent*
      module spec. If *parent* is *None*, :meth:`PathEntryFinder.discover` will
      search for top-level modules.

      Returns an iterable of possible specs.

      Raises :exc:`ValueError` if *parent* is not a package module.

      .. warning::
         This method can potentially yield a very large number of objects, and
         it may carry out IO operations when computing these values.

         Because of this, it will generaly be desirable to compute the result
         values on-the-fly, as they are needed. As such, the returned object is
         only guaranteed to be an :class:`iterable <collections.abc.Iterable>`,
         instead of a :class:`list` or other
         :class:`collection <collections.abc.Collection>` type.

      .. versionadded:: 3.15


.. class:: Loader

    An abstract base class for a :term:`loader`.
    See :pep:`302` for the exact definition for a loader.

    Loaders that wish to support resource reading should implement a
    :meth:`get_resource_reader` method as specified by
    :class:`importlib.resources.abc.ResourceReader`.

    .. versionchanged:: 3.7
       Introduced the optional :meth:`get_resource_reader` method.

   .. versionchanged:: 3.15
      Removed the ``load_module()`` method.

    .. method:: create_module(spec)

       A method that returns the module object to use when
       importing a module.  This method may return ``None``,
       indicating that default module creation semantics should take place.

       .. versionadded:: 3.4

       .. versionchanged:: 3.6
          This method is no longer optional when
          :meth:`exec_module` is defined.

    .. method:: exec_module(module)

       An abstract method that executes the module in its own namespace
       when a module is imported or reloaded.  The module should already
       be initialized when :meth:`exec_module` is called.  When this method exists,
       :meth:`create_module` must be defined.

       .. versionadded:: 3.4

       .. versionchanged:: 3.6
          :meth:`create_module` must also be defined.


.. class:: ResourceLoader

   *Superseded by TraversableResources*

    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.resources.abc.TraversableResources`.
       This class exists for backwards compatibility only with other ABCs in
       this module.

    .. method:: get_data(path)
       :abstractmethod:

        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:`~module.__file__` attribute or an item from a package's
        :attr:`~module.__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.

    .. method:: get_source(fullname)
       :abstractmethod:

        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>', fullname=None)

        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__)``.

        The optional argument *fullname* specifies the module name.
        It is needed to unambiguous :ref:`filter <warning-filter>` syntax
        warnings by module name.

        .. versionadded:: 3.4

        .. versionchanged:: 3.5
           Made the method static.

        .. versionadded:: 3.15
           Added the *fullname* parameter.


    .. method:: exec_module(module)

       Implementation of :meth:`Loader.exec_module`.

       .. versionadded:: 3.4


.. 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.

    .. method:: get_filename(fullname)
       :abstractmethod:

        An abstract method that is to return the value of
        :attr:`~module.__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

   .. versionchanged:: 3.15
      Removed the ``load_module()`` method.

   .. attribute:: name

      The name of the module the loader can handle.

   .. attribute:: path

      Path to the file of the module.

   .. method:: get_filename(fullname)
      :abstractmethod:

      Returns :attr:`path`.

   .. method:: get_data(path)
      :abstractmethod:

      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.

    .. versionchanged:: 3.15
       Removed the ``load_module()`` method.

    .. 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
        (:const:`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:: 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__``.


:mod:`!importlib.machinery` -- Importers and path hooks
-------------------------------------------------------

.. module:: importlib.machinery
    :synopsis: Importers and path hooks

**Source code:** :source:`Lib/importlib/machinery.py`

--------------

This module contains the various objects that help :keyword:`import`
find and load modules.

.. data:: SOURCE_SUFFIXES

   A list of strings representing the recognized file suffixes for source
   modules.

   .. versionadded:: 3.3

.. data:: DEBUG_BYTECODE_SUFFIXES

   A list of strings representing the file suffixes for non-optimized bytecode
   modules.

   .. versionadded:: 3.3

   .. deprecated:: 3.5
      Use :const:`BYTECODE_SUFFIXES` instead.

.. data:: OPTIMIZED_BYTECODE_SUFFIXES

   A list of strings representing the file suffixes for optimized bytecode
   modules.

   .. versionadded:: 3.3

   .. deprecated:: 3.5
      Use :const:`BYTECODE_SUFFIXES` instead.

.. data:: BYTECODE_SUFFIXES

   A list of strings representing the recognized file suffixes for bytecode
   modules (including the leading dot).

   .. versionadded:: 3.3

   .. versionchanged:: 3.5
      The value is no longer dependent on ``__debug__``.

.. data:: EXTENSION_SUFFIXES

   A list of strings representing the recognized file suffixes for
   extension modules.

   .. versionadded:: 3.3

.. function:: all_suffixes()

   Returns a combined list of strings representing all file suffixes for
   modules recognized by the standard import machinery. This is a
   helper for code which simply needs to know if a filesystem path
   potentially refers to a module without needing any details on the kind
   of module (for example, :func:`inspect.getmodulename`).

   .. versionadded:: 3.3


.. class:: BuiltinImporter

    An :term:`importer` for built-in modules. All known built-in modules are
    listed in :data:`sys.builtin_module_names`. This class implements the
    :class:`importlib.abc.MetaPathFinder` and
    :class:`importlib.abc.InspectLoader` ABCs.

    Only class methods are defined by this class to alleviate the need for
    instantiation.

    .. versionchanged:: 3.5
       As part of :pep:`489`, the builtin importer now implements
       :meth:`Loader.create_module` and :meth:`Loader.exec_module`


.. class:: FrozenImporter

    An :term:`importer` for frozen modules. This class implements the
    :class:`importlib.abc.MetaPathFinder` and
    :class:`importlib.abc.InspectLoader` ABCs.

    Only class methods are defined by this class to alleviate the need for
    instantiation.

    .. versionchanged:: 3.4
       Gained :meth:`~Loader.create_module` and :meth:`~Loader.exec_module`
       methods.


.. class:: WindowsRegistryFinder

   :term:`Finder <finder>` for modules declared in the Windows registry.  This class
   implements the :class:`importlib.abc.MetaPathFinder` ABC.

   Only class methods are defined by this class to alleviate the need for
   instantiation.

   .. versionadded:: 3.3

   .. deprecated:: 3.6
      Use :mod:`site` configuration instead. Future versions of Python may
      not enable this finder by default.


.. class:: PathFinder

   A :term:`Finder <finder>` for :data:`sys.path` and package ``__path__`` attributes.
   This class implements the :class:`importlib.abc.MetaPathFinder` ABC.

   Only class methods are defined by this class to alleviate the need for
   instantiation.

   .. classmethod:: find_spec(fullname, path=None, target=None)

      Class method that attempts to find a :term:`spec <module spec>`
      for the module specified by *fullname* on :data:`sys.path` or, if
      defined, on *path*. For each path entry that is searched,
      :data:`sys.path_importer_cache` is checked. If a non-false object
      is found then it is used as the :term:`path entry finder` to look
      for the module being searched for. If no entry is found in
      :data:`sys.path_importer_cache`, then :data:`sys.path_hooks` is
      searched for a finder for the path entry and, if found, is stored
      in :data:`sys.path_importer_cache` along with being queried about
      the module. If no finder is ever found then ``None`` is both
      stored in the cache and returned.

      .. versionadded:: 3.4

      .. versionchanged:: 3.5
         If the current working directory -- represented by an empty string --
         is no longer valid then ``None`` is returned but no value is cached
         in :data:`sys.path_importer_cache`.

   .. classmethod:: invalidate_caches()

      Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all
      finders stored in :data:`sys.path_importer_cache` that define the method.
      Otherwise entries in :data:`sys.path_importer_cache` set to ``None`` are
      deleted.

      .. versionchanged:: 3.7
         Entries of ``None`` in :data:`sys.path_importer_cache` are deleted.

   .. versionchanged:: 3.4
      Calls objects in :data:`sys.path_hooks` with the current working
      directory for ``''`` (i.e. the empty string).


.. class:: FileFinder(path, *loader_details)

   A concrete implementation of :class:`importlib.abc.PathEntryFinder` which
   caches results from the file system.

   The *path* argument is the directory for which the finder is in charge of
   searching.

   The *loader_details* argument is a variable number of 2-item tuples each
   containing a loader and a sequence of file suffixes the loader recognizes.
   The loaders are expected to be callables which accept two arguments of
   the module's name and the path to the file found.

   The finder will cache the directory contents as necessary, making stat calls
   for each module search to verify the cache is not outdated. Because cache
   staleness relies upon the granularity of the operating system's state
   information of the file system, there is a potential race condition of
   searching for a module, creating a new file, and then searching for the
   module the new file represents. If the operations happen fast enough to fit
   within the granularity of stat calls, then the module search will fail. To
   prevent this from happening, when you create a module dynamically, make sure
   to call :func:`importlib.invalidate_caches`.

   .. versionadded:: 3.3

   .. attribute:: path

      The path the finder will search in.

   .. method:: find_spec(fullname, target=None)

      Attempt to find the spec to handle *fullname* within :attr:`path`.

      .. versionadded:: 3.4

   .. method:: invalidate_caches()

      Clear out the internal cache.

   .. classmethod:: path_hook(*loader_details)

      A class method which returns a closure for use on :data:`sys.path_hooks`.
      An instance of :class:`FileFinder` is returned by the closure using the
      path argument given to the closure directly and *loader_details*
      indirectly.

      If the argument to the closure is not an existing directory,
      :exc:`ImportError` is raised.


.. class:: NamespacePath(name, path, path_finder)

   Represents a :term:`namespace package`'s path (:attr:`module.__path__`).

   When its ``__path__`` value is accessed it will be recomputed if necessary.
   This keeps it in-sync with the global state (:attr:`sys.modules`).

   The *name* argument is the name of the namespace module.

   The *path* argument is the initial path value.

   The *path_finder* argument is the callable used to recompute the path value.
   The callable has the same signature as :meth:`importlib.abc.MetaPathFinder.find_spec`.

   When the parent's :attr:`module.__path__` attribute is updated, the path
   value is recomputed.

   If the parent module is missing from :data:`sys.modules`, then
   :exc:`ModuleNotFoundError` will be raised.

   For top-level modules, the parent module's path is :data:`sys.path`.

   .. note::

      :meth:`PathFinder.invalidate_caches` invalidates :class:`NamespacePath`,
      forcing the path value to be recomputed next time it is accessed.

   .. versionadded:: 3.15


.. class:: SourceFileLoader(fullname, path)

   A concrete implementation of :class:`importlib.abc.SourceLoader` by
   subclassing :class:`importlib.abc.FileLoader` and providing some concrete
   implementations of other methods.

   .. versionadded:: 3.3

   .. versionchanged:: 3.15
      Removed the ``load_module()`` method.

   .. attribute:: name

      The name of the module that this loader will handle.

   .. attribute:: path

      The path to the source file.

   .. method:: is_package(fullname)

      Return ``True`` if :attr:`path` appears to be for a package.

   .. method:: path_stats(path)

      Concrete implementation of :meth:`importlib.abc.SourceLoader.path_stats`.

   .. method:: set_data(path, data)

      Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`.


.. class:: SourcelessFileLoader(fullname, path)

   A concrete implementation of :class:`importlib.abc.FileLoader` which can
   import bytecode files (i.e. no source code files exist).

   Please note that direct use of bytecode files (and thus not source code
   files) inhibits your modules from being usable by all Python
   implementations or new versions of Python which change the bytecode
   format.

   .. versionadded:: 3.3

   .. versionchanged:: 3.15
      Removed the ``load_module()`` method.

   .. attribute:: name

      The name of the module the loader will handle.

   .. attribute:: path

      The path to the bytecode file.

   .. method:: is_package(fullname)

      Determines if the module is a package based on :attr:`path`.

   .. method:: get_code(fullname)

      Returns the code object for :attr:`name` created from :attr:`path`.

   .. method:: get_source(fullname)

      Returns ``None`` as bytecode files have no source when this loader is
      used.


.. class:: ExtensionFileLoader(fullname, path)

   A concrete implementation of :class:`importlib.abc.ExecutionLoader` for
   extension modules.

   The *fullname* argument specifies the name of the module the loader is to
   support. The *path* argument is the path to the extension module's file.

   Note that, by default, importing an extension module will fail
   in subinterpreters if it doesn't implement multi-phase init
   (see :pep:`489`), even if it would otherwise import successfully.

   .. versionadded:: 3.3

   .. versionchanged:: 3.12
      Multi-phase init is now required for use in subinterpreters.

   .. attribute:: name

      Name of the module the loader supports.

   .. attribute:: path

      Path to the extension module.

   .. method:: create_module(spec)

      Creates the module object from the given specification in accordance
      with :pep:`489`.

      .. versionadded:: 3.5

   .. method:: exec_module(module)

      Initializes the given module object in accordance with :pep:`489`.

      .. versionadded:: 3.5

   .. method:: is_package(fullname)

      Returns ``True`` if the file path points to a package's ``__init__``
      module based on :const:`EXTENSION_SUFFIXES`.

   .. method:: get_code(fullname)

      Returns ``None`` as extension modules lack a code object.

   .. method:: get_source(fullname)

      Returns ``None`` as extension modules do not have source code.

   .. method:: get_filename(fullname)

      Returns :attr:`path`.

      .. versionadded:: 3.4


.. class:: NamespaceLoader(name, path, path_finder)

   A concrete implementation of :class:`importlib.abc.InspectLoader` for
   namespace packages.  This is an alias for a private class and is only made
   public for introspecting the ``__loader__`` attribute on namespace
   packages::

       >>> from importlib.machinery import NamespaceLoader
       >>> import my_namespace
       >>> isinstance(my_namespace.__loader__, NamespaceLoader)
       True
       >>> import importlib.abc
       >>> isinstance(my_namespace.__loader__, importlib.abc.Loader)
       True

   .. versionadded:: 3.11


.. class:: ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)

   A specification for a module's import-system-related state.  This is
   typically exposed as the module's :attr:`~module.__spec__` attribute.  Many
   of these attributes are also available directly on a module: for example,
   ``module.__spec__.origin == module.__file__``.  Note, however, that
   while the *values* are usually equivalent, they can differ since there is
   no synchronization between the two objects.  For example, it is possible to
   update the module's :attr:`~module.__file__` at runtime and this will not be
   automatically reflected in the module's
   :attr:`__spec__.origin <ModuleSpec.origin>`, and vice versa.

   .. versionadded:: 3.4

   .. attribute:: name

      The module's fully qualified name (see :attr:`module.__name__`).
      The :term:`finder` should always set this attribute to a non-empty string.

   .. attribute:: loader

      The :term:`loader` used to load the module (see :attr:`module.__loader__`).
      The :term:`finder` should always set this attribute.

   .. attribute:: origin

      The location the :term:`loader` should use to load the module
      (see :attr:`module.__file__`).
      For example, for modules loaded from a ``.py`` file this is the filename.
      The :term:`finder` should always set this attribute to a meaningful value
      for the :term:`loader` to use.  In the uncommon case that there is not one
      (like for namespace packages), it should be set to ``None``.

   .. attribute:: submodule_search_locations

      A (possibly empty) :term:`sequence` of strings enumerating the locations
      in which a package's submodules will be found
      (see :attr:`module.__path__`). Most of the time there will only be a
      single directory in this list.

      The :term:`finder` should set this attribute to a sequence, even an empty
      one, to indicate
      to the import system that the module is a package.  It should be set to ``None`` for
      non-package modules.  It is set automatically later to a special object for
      namespace packages.

   .. attribute:: loader_state

      The :term:`finder` may set this attribute to an object containing additional,
      module-specific data to use when loading the module.  Otherwise it should be
      set to ``None``.

   .. attribute:: cached

      The filename of a compiled version of the module's code.
      The :term:`finder` should always set this attribute but it may be ``None``
      for modules that do not need compiled code stored.

   .. attribute:: parent

      (Read-only) The fully qualified name of the package the module is in (or the
      empty string for a top-level module).
      See :attr:`module.__package__`.
      If the module is a package then this is the same as :attr:`name`.

   .. attribute:: has_location

      ``True`` if the spec's :attr:`origin` refers to a loadable location,
      ``False`` otherwise.  This value impacts how :attr:`!origin` is interpreted
      and how the module's :attr:`~module.__file__` is populated.


.. class:: AppleFrameworkLoader(name, path)

   A specialization of :class:`importlib.machinery.ExtensionFileLoader` that
   is able to load extension modules in Framework format.

   For compatibility with the iOS App Store, *all* binary modules in an iOS app
   must be dynamic libraries, contained in a framework with appropriate
   metadata, stored in the ``Frameworks`` folder of the packaged app. There can
   be only a single binary per framework, and there can be no executable binary
   material outside the Frameworks folder.

   To accommodate this requirement, when running on iOS, extension module
   binaries are *not* packaged as ``.so`` files on ``sys.path``, but as
   individual standalone frameworks. To discover those frameworks, this loader
   is registered against the ``.fwork`` file extension, with a ``.fwork``
   file acting as a placeholder in the original location of the binary on
   ``sys.path``. The ``.fwork`` file contains the path of the actual binary in
   the ``Frameworks`` folder, relative to the app bundle. To allow for
   resolving a framework-packaged binary back to the original location, the
   framework is expected to contain a ``.origin`` file that contains the
   location of the ``.fwork`` file, relative to the app bundle.

   For example, consider the case of an import ``from foo.bar import _whiz``,
   where ``_whiz`` is implemented with the binary module
   ``sources/foo/bar/_whiz.abi3.so``, with ``sources`` being the location
   registered on ``sys.path``, relative to the application bundle. This module
   *must* be distributed as
   ``Frameworks/foo.bar._whiz.framework/foo.bar._whiz`` (creating the framework
   name from the full import path of the module), with an ``Info.plist`` file
   in the ``.framework`` directory identifying the binary as a framework. The
   ``foo.bar._whiz`` module would be represented in the original location with
   a ``sources/foo/bar/_whiz.abi3.fwork`` marker file, containing the path
   ``Frameworks/foo.bar._whiz/foo.bar._whiz``. The framework would also contain
   ``Frameworks/foo.bar._whiz.framework/foo.bar._whiz.origin``, containing the
   path to the ``.fwork`` file.

   When a module is loaded with this loader, the ``__file__`` for the module
   will report as the location of the ``.fwork`` file. This allows code to use
   the ``__file__`` of a  module as an anchor for file system traversal.
   However, the spec origin will reference the location of the *actual* binary
   in the ``.framework`` folder.

   The Xcode project building the app is responsible for converting any ``.so``
   files from wherever they exist in the ``PYTHONPATH`` into frameworks in the
   ``Frameworks`` folder (including stripping extensions from the module file,
   the addition of framework metadata, and signing the resulting framework),
   and creating the ``.fwork`` and ``.origin`` files. This will usually be done
   with a build step in the Xcode project; see the iOS documentation for
   details on how to construct this build step.

   .. versionadded:: 3.13

   .. availability:: iOS.

   .. attribute:: name

      Name of the module the loader supports.

   .. attribute:: path

      Path to the ``.fwork`` file for the extension module.


:mod:`!importlib.util` -- Utility code for importers
----------------------------------------------------

.. module:: importlib.util
    :synopsis: Utility code for importers


**Source code:** :source:`Lib/importlib/util.py`

--------------

This module contains the various objects that help in the construction of
an :term:`importer`.

.. data:: MAGIC_NUMBER

   The bytes which represent the bytecode version number. If you need help with
   loading/writing bytecode then consider :class:`importlib.abc.SourceLoader`.

   .. versionadded:: 3.4

.. function:: cache_from_source(path, *, optimization=None)

   Return the :pep:`3147`/:pep:`488` path to the byte-compiled file associated
   with the source *path*.  For example, if *path* is ``/foo/bar/baz.py`` the return
   value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2.
   The ``cpython-32`` string comes from the current magic tag (see
   :func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then
   :exc:`NotImplementedError` will be raised).

   The *optimization* parameter is used to specify the optimization level of the
   bytecode file. An empty string represents no optimization, so
   ``/foo/bar/baz.py`` with an *optimization* of ``''`` will result in a
   bytecode path of ``/foo/bar/__pycache__/baz.cpython-32.pyc``. ``None`` causes
   the interpreter's optimization level to be used. Any other value's string
   representation is used, so ``/foo/bar/baz.py`` with an *optimization* of
   ``2`` will lead to the bytecode path of
   ``/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc``. The string representation
   of *optimization* can only be alphanumeric, else :exc:`ValueError` is raised.

   .. versionadded:: 3.4

   .. versionchanged:: 3.5
      The *optimization* parameter was added and the *debug_override* parameter
      was deprecated.

   .. versionchanged:: 3.6
      Accepts a :term:`path-like object`.

   .. versionchanged:: 3.15
      The *debug_override* parameter was removed.


.. function:: source_from_cache(path)

   Given the *path* to a :pep:`3147` file name, return the associated source code
   file path.  For example, if *path* is
   ``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be
   ``/foo/bar/baz.py``.  *path* need not exist, however if it does not conform
   to :pep:`3147` or :pep:`488` format, a :exc:`ValueError` is raised. If
   :attr:`sys.implementation.cache_tag` is not defined,
   :exc:`NotImplementedError` is raised.

   .. versionadded:: 3.4

   .. versionchanged:: 3.6
      Accepts a :term:`path-like object`.

.. function:: decode_source(source_bytes)

   Decode the given bytes representing source code and return it as a string
   with universal newlines (as required by
   :meth:`importlib.abc.InspectLoader.get_source`).

   .. versionadded:: 3.4

.. function:: resolve_name(name, package)

   Resolve a relative module name to an absolute one.

   If  **name** has no leading dots, then **name** is simply returned. This
   allows for usage such as
   ``importlib.util.resolve_name('sys', __spec__.parent)`` without doing a
   check to see if the **package** argument is needed.

   :exc:`ImportError` is raised if **name** is a relative module name but
   **package** is a false value (e.g. ``None`` or the empty string).
   :exc:`ImportError` is also raised if a relative name would escape its
   containing package (e.g. requesting ``..bacon`` from within the ``spam``
   package).

   .. versionadded:: 3.3

   .. versionchanged:: 3.9
      To improve consistency with import statements, raise
      :exc:`ImportError` instead of :exc:`ValueError` for invalid relative
      import attempts.

.. function:: find_spec(name, package=None)

   Find the :term:`spec <module spec>` for a module, optionally relative to
   the specified **package** name. If the module is in :data:`sys.modules`,
   then ``sys.modules[name].__spec__`` is returned (unless the spec would be
   ``None`` or is not set, in which case :exc:`ValueError` is raised).
   Otherwise a search using :data:`sys.meta_path` is done. ``None`` is
   returned if no spec is found.

   If **name** is for a submodule (contains a dot), the parent module is
   automatically imported.

   **name** and **package** work the same as for :func:`import_module`.

   .. versionadded:: 3.4

   .. versionchanged:: 3.7
      Raises :exc:`ModuleNotFoundError` instead of :exc:`AttributeError` if
      **package** is in fact not a package (i.e. lacks a
      :attr:`~module.__path__` attribute).

.. function:: module_from_spec(spec)

   Create a new module based on **spec** and
   :meth:`spec.loader.create_module <importlib.abc.Loader.create_module>`.

   If :meth:`spec.loader.create_module <importlib.abc.Loader.create_module>`
   does not return ``None``, then any pre-existing attributes will not be reset.
   Also, no :exc:`AttributeError` will be raised if triggered while accessing
   **spec** or setting an attribute on the module.

   This function is preferred over using :class:`types.ModuleType` to create a
   new module as **spec** is used to set as many import-controlled attributes on
   the module as possible.

   .. versionadded:: 3.5

.. function:: spec_from_loader(name, loader, *, origin=None, is_package=None)

   A factory function for creating a :class:`~importlib.machinery.ModuleSpec`
   instance based on a loader.  The parameters have the same meaning as they do
   for ModuleSpec.  The function uses available :term:`loader` APIs, such as
   :meth:`InspectLoader.is_package`, to fill in any missing
   information on the spec.

   .. versionadded:: 3.4

.. function:: spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)

   A factory function for creating a :class:`~importlib.machinery.ModuleSpec`
   instance based on the path to a file.  Missing information will be filled in
   on the spec by making use of loader APIs and by the implication that the
   module will be file-based.

   .. versionadded:: 3.4

   .. versionchanged:: 3.6
      Accepts a :term:`path-like object`.

.. function:: source_hash(source_bytes)

   Return the hash of *source_bytes* as bytes. A hash-based ``.pyc`` file embeds
   the :func:`source_hash` of the corresponding source file's contents in its
   header.

   .. versionadded:: 3.7

.. function:: _incompatible_extension_module_restrictions(*, disable_check)

   A context manager that can temporarily skip the compatibility check
   for extension modules.  By default the check is enabled and will fail
   when a single-phase init module is imported in a subinterpreter.
   It will also fail for a multi-phase init module that doesn't
   explicitly support a per-interpreter GIL, when imported
   in an interpreter with its own GIL.

   Note that this function is meant to accommodate an unusual case;
   one which is likely to eventually go away.  There's is a pretty good
   chance this is not what you were looking for.

   You can get the same effect as this function by implementing the
   basic interface of multi-phase init (:pep:`489`) and lying about
   support for multiple interpreters (or per-interpreter GIL).

   .. warning::
      Using this function to disable the check can lead to
      unexpected behavior and even crashes.  It should only be used during
      extension module development.

   .. versionadded:: 3.12

.. class:: LazyLoader(loader)

   A class which postpones the execution of the loader of a module until the
   module has an attribute accessed.

   This class **only** works with loaders that define
   :meth:`~importlib.abc.Loader.exec_module` as control over what module type
   is used for the module is required. For those same reasons, the loader's
   :meth:`~importlib.abc.Loader.create_module` method must return ``None`` or a
   type for which its ``__class__`` attribute can be mutated along with not
   using :term:`slots <__slots__>`. Finally, modules which substitute the object
   placed into :data:`sys.modules` will not work as there is no way to properly
   replace the module references throughout the interpreter safely;
   :exc:`ValueError` is raised if such a substitution is detected.

   .. note::
      For projects where startup time is critical, this class allows for
      potentially minimizing the cost of loading a module if it is never used.
      For projects where startup time is not essential then use of this class is
      **heavily** discouraged due to error messages created during loading being
      postponed and thus occurring out of context.

   .. versionadded:: 3.5

   .. versionchanged:: 3.6
      Began calling :meth:`~importlib.abc.Loader.create_module`, removing the
      compatibility warning for :class:`importlib.machinery.BuiltinImporter` and
      :class:`importlib.machinery.ExtensionFileLoader`.

   .. classmethod:: factory(loader)

      A class method which returns a callable that creates a lazy loader. This
      is meant to be used in situations where the loader is passed by class
      instead of by instance.
      ::

        suffixes = importlib.machinery.SOURCE_SUFFIXES
        loader = importlib.machinery.SourceFileLoader
        lazy_loader = importlib.util.LazyLoader.factory(loader)
        finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))

.. _importlib-examples:

Examples
--------

Importing programmatically
''''''''''''''''''''''''''

To programmatically import a module, use :func:`importlib.import_module`.
::

  import importlib

  itertools = importlib.import_module('itertools')


Checking if a module can be imported
''''''''''''''''''''''''''''''''''''

If you need to find out if a module can be imported without actually doing the
import, then you should use :func:`importlib.util.find_spec`.

Note that if ``name`` is a submodule (contains a dot),
:func:`importlib.util.find_spec` will import the parent module.
::

  import importlib.util
  import sys

  # For illustrative purposes.
  name = 'itertools'

  if name in sys.modules:
      print(f"{name!r} already in sys.modules")
  elif (spec := importlib.util.find_spec(name)) is not None:
      # If you chose to perform the actual import ...
      module = importlib.util.module_from_spec(spec)
      sys.modules[name] = module
      spec.loader.exec_module(module)
      print(f"{name!r} has been imported")
  else:
      print(f"can't find the {name!r} module")


Importing a source file directly
''''''''''''''''''''''''''''''''

This recipe should be used with caution: it is an approximation of an import
statement where the file path is specified directly, rather than
:data:`sys.path` being searched. Alternatives should first be considered first,
such as modifying :data:`sys.path` when a proper module is required, or using
:func:`runpy.run_path` when the global namespace resulting from running a Python
file is appropriate.

To import a Python source file directly from a path, use the following recipe::

    import importlib.util
    import sys


    def import_from_path(module_name, file_path):
        spec = importlib.util.spec_from_file_location(module_name, file_path)
        module = importlib.util.module_from_spec(spec)
        sys.modules[module_name] = module
        spec.loader.exec_module(module)
        return module


    # For illustrative purposes only (use of `json` is arbitrary).
    import json
    file_path = json.__file__
    module_name = json.__name__

    # Similar outcome as `import json`.
    json = import_from_path(module_name, file_path)


Implementing lazy imports
'''''''''''''''''''''''''

The example below shows how to implement lazy imports::

    >>> import importlib.util
    >>> import sys
    >>> def lazy_import(name):
    ...     spec = importlib.util.find_spec(name)
    ...     loader = importlib.util.LazyLoader(spec.loader)
    ...     spec.loader = loader
    ...     module = importlib.util.module_from_spec(spec)
    ...     sys.modules[name] = module
    ...     loader.exec_module(module)
    ...     return module
    ...
    >>> lazy_typing = lazy_import("typing")
    >>> #lazy_typing is a real module object,
    >>> #but it is not loaded in memory yet.
    >>> lazy_typing.TYPE_CHECKING
    False


Setting up an importer
''''''''''''''''''''''

For deep customizations of import, you typically want to implement an
:term:`importer`. This means managing both the :term:`finder` and :term:`loader`
side of things. For finders there are two flavours to choose from depending on
your needs: a :term:`meta path finder` or a :term:`path entry finder`. The
former is what you would put on :data:`sys.meta_path` while the latter is what
you create using a :term:`path entry hook` on :data:`sys.path_hooks` which works
with :data:`sys.path` entries to potentially create a finder. This example will
show you how to register your own importers so that import will use them (for
creating an importer for yourself, read the documentation for the appropriate
classes defined within this package)::

  import importlib.machinery
  import sys

  # For illustrative purposes only.
  SpamMetaPathFinder = importlib.machinery.PathFinder
  SpamPathEntryFinder = importlib.machinery.FileFinder
  loader_details = (importlib.machinery.SourceFileLoader,
                    importlib.machinery.SOURCE_SUFFIXES)

  # Setting up a meta path finder.
  # Make sure to put the finder in the proper location in the list in terms of
  # priority.
  sys.meta_path.append(SpamMetaPathFinder)

  # Setting up a path entry finder.
  # Make sure to put the path hook in the proper location in the list in terms
  # of priority.
  sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))


Approximating :func:`importlib.import_module`
'''''''''''''''''''''''''''''''''''''''''''''

Import itself is implemented in Python code, making it possible to
expose most of the import machinery through importlib. The following
helps illustrate the various APIs that importlib exposes by providing an
approximate implementation of
:func:`importlib.import_module`::

  import importlib.util
  import sys

  def import_module(name, package=None):
      """An approximate implementation of import."""
      absolute_name = importlib.util.resolve_name(name, package)
      try:
          return sys.modules[absolute_name]
      except KeyError:
          pass

      path = None
      if '.' in absolute_name:
          parent_name, _, child_name = absolute_name.rpartition('.')
          parent_module = import_module(parent_name)
          path = parent_module.__spec__.submodule_search_locations
      for finder in sys.meta_path:
          spec = finder.find_spec(absolute_name, path)
          if spec is not None:
              break
      else:
          msg = f'No module named {absolute_name!r}'
          raise ModuleNotFoundError(msg, name=absolute_name)
      module = importlib.util.module_from_spec(spec)
      sys.modules[absolute_name] = module
      spec.loader.exec_module(module)
      if path is not None:
          setattr(parent_module, child_name, module)
      return module
