.. highlight:: c

.. _importing:

Importing Modules
=================


.. c:function:: PyObject* PyImport_ImportModule(const char *name)

   .. index::
      single: package variable; __all__
      single: __all__ (package variable)
      single: modules (in module sys)

   This is a simplified interface to :c:func:`PyImport_ImportModuleEx` below,
   leaving the *globals* and *locals* arguments set to ``NULL`` and *level* set
   to 0.  When the *name*
   argument contains a dot (when it specifies a submodule of a package), the
   *fromlist* argument is set to the list ``['*']`` so that the return value is the
   named module rather than the top-level package containing it as would otherwise
   be the case.  (Unfortunately, this has an additional side effect when *name* in
   fact specifies a subpackage instead of a submodule: the submodules specified in
   the package's ``__all__`` variable are  loaded.)  Return a new reference to the
   imported module, or ``NULL`` with an exception set on failure.  A failing
   import of a module doesn't leave the module in :data:`sys.modules`.

   This function always uses absolute imports.


.. c:function:: PyObject* PyImport_ImportModuleNoBlock(const char *name)

   This function is a deprecated alias of :c:func:`PyImport_ImportModule`.

   .. versionchanged:: 3.3
      This function used to fail immediately when the import lock was held
      by another thread.  In Python 3.3 though, the locking scheme switched
      to per-module locks for most purposes, so this function's special
      behaviour isn't needed anymore.

   .. deprecated-removed:: 3.13 3.15
      Use :c:func:`PyImport_ImportModule` instead.


.. c:function:: PyObject* PyImport_ImportModuleEx(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)

   .. index:: pair: built-in function; __import__

   Import a module.  This is best described by referring to the built-in Python
   function :func:`__import__`.

   The return value is a new reference to the imported module or top-level
   package, or ``NULL`` with an exception set on failure.  Like for
   :func:`__import__`, the return value when a submodule of a package was
   requested is normally the top-level package, unless a non-empty *fromlist*
   was given.

   Failing imports remove incomplete module objects, like with
   :c:func:`PyImport_ImportModule`.


.. c:function:: PyObject* PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)

   Import a module.  This is best described by referring to the built-in Python
   function :func:`__import__`, as the standard :func:`__import__` function calls
   this function directly.

   The return value is a new reference to the imported module or top-level package,
   or ``NULL`` with an exception set on failure.  Like for :func:`__import__`,
   the return value when a submodule of a package was requested is normally the
   top-level package, unless a non-empty *fromlist* was given.

   .. versionadded:: 3.3


.. c:function:: PyObject* PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)

   Similar to :c:func:`PyImport_ImportModuleLevelObject`, but the name is a
   UTF-8 encoded string instead of a Unicode object.

   .. versionchanged:: 3.3
         Negative values for *level* are no longer accepted.

.. c:function:: PyObject* PyImport_Import(PyObject *name)

   This is a higher-level interface that calls the current "import hook
   function" (with an explicit *level* of 0, meaning absolute import).  It
   invokes the :func:`__import__` function from the ``__builtins__`` of the
   current globals.  This means that the import is done using whatever import
   hooks are installed in the current environment.

   This function always uses absolute imports.


.. c:function:: PyObject* PyImport_ReloadModule(PyObject *m)

   Reload a module.  Return a new reference to the reloaded module, or ``NULL`` with
   an exception set on failure (the module still exists in this case).


.. c:function:: PyObject* PyImport_AddModuleRef(const char *name)

   Return the module object corresponding to a module name.

   The *name* argument may be of the form ``package.module``. First check the
   modules dictionary if there's one there, and if not, create a new one and
   insert it in the modules dictionary.

   Return a :term:`strong reference` to the module on success. Return ``NULL``
   with an exception set on failure.

   The module name *name* is decoded from UTF-8.

   This function does not load or import the module; if the module wasn't
   already loaded, you will get an empty module object. Use
   :c:func:`PyImport_ImportModule` or one of its variants to import a module.
   Package structures implied by a dotted name for *name* are not created if
   not already present.

   .. versionadded:: 3.13


.. c:function:: PyObject* PyImport_AddModuleObject(PyObject *name)

   Similar to :c:func:`PyImport_AddModuleRef`, but return a :term:`borrowed
   reference` and *name* is a Python :class:`str` object.

   .. versionadded:: 3.3


.. c:function:: PyObject* PyImport_AddModule(const char *name)

   Similar to :c:func:`PyImport_AddModuleRef`, but return a :term:`borrowed
   reference`.


.. c:function:: PyObject* PyImport_ExecCodeModule(const char *name, PyObject *co)

   .. index:: pair: built-in function; compile

   Given a module name (possibly of the form ``package.module``) and a code object
   read from a Python bytecode file or obtained from the built-in function
   :func:`compile`, load the module.  Return a new reference to the module object,
   or ``NULL`` with an exception set if an error occurred.  *name*
   is removed from :data:`sys.modules` in error cases, even if *name* was already
   in :data:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`.  Leaving
   incompletely initialized modules in :data:`sys.modules` is dangerous, as imports of
   such modules have no way to know that the module object is an unknown (and
   probably damaged with respect to the module author's intents) state.

   The module's :attr:`__spec__` and :attr:`__loader__` will be set, if
   not set already, with the appropriate values.  The spec's loader will
   be set to the module's ``__loader__`` (if set) and to an instance of
   :class:`~importlib.machinery.SourceFileLoader` otherwise.

   The module's :attr:`__file__` attribute will be set to the code object's
   :attr:`!co_filename`.  If applicable, :attr:`__cached__` will also
   be set.

   This function will reload the module if it was already imported.  See
   :c:func:`PyImport_ReloadModule` for the intended way to reload a module.

   If *name* points to a dotted name of the form ``package.module``, any package
   structures not already created will still not be created.

   See also :c:func:`PyImport_ExecCodeModuleEx` and
   :c:func:`PyImport_ExecCodeModuleWithPathnames`.

   .. versionchanged:: 3.12
      The setting of :attr:`__cached__` and :attr:`__loader__` is
      deprecated. See :class:`~importlib.machinery.ModuleSpec` for
      alternatives.


.. c:function:: PyObject* PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname)

   Like :c:func:`PyImport_ExecCodeModule`, but the :attr:`__file__` attribute of
   the module object is set to *pathname* if it is non-``NULL``.

   See also :c:func:`PyImport_ExecCodeModuleWithPathnames`.


.. c:function:: PyObject* PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, PyObject *cpathname)

   Like :c:func:`PyImport_ExecCodeModuleEx`, but the :attr:`__cached__`
   attribute of the module object is set to *cpathname* if it is
   non-``NULL``.  Of the three functions, this is the preferred one to use.

   .. versionadded:: 3.3

   .. versionchanged:: 3.12
      Setting :attr:`__cached__` is deprecated. See
      :class:`~importlib.machinery.ModuleSpec` for alternatives.


.. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *pathname, const char *cpathname)

   Like :c:func:`PyImport_ExecCodeModuleObject`, but *name*, *pathname* and
   *cpathname* are UTF-8 encoded strings. Attempts are also made to figure out
   what the value for *pathname* should be from *cpathname* if the former is
   set to ``NULL``.

   .. versionadded:: 3.2
   .. versionchanged:: 3.3
      Uses :func:`!imp.source_from_cache()` in calculating the source path if
      only the bytecode path is provided.
   .. versionchanged:: 3.12
      No longer uses the removed :mod:`!imp` module.


.. c:function:: long PyImport_GetMagicNumber()

   Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` file).
   The magic number should be present in the first four bytes of the bytecode
   file, in little-endian byte order. Returns ``-1`` on error.

   .. versionchanged:: 3.3
      Return value of ``-1`` upon failure.


.. c:function:: const char * PyImport_GetMagicTag()

   Return the magic tag string for :pep:`3147` format Python bytecode file
   names.  Keep in mind that the value at ``sys.implementation.cache_tag`` is
   authoritative and should be used instead of this function.

   .. versionadded:: 3.2

.. c:function:: PyObject* PyImport_GetModuleDict()

   Return the dictionary used for the module administration (a.k.a.
   ``sys.modules``).  Note that this is a per-interpreter variable.

.. c:function:: PyObject* PyImport_GetModule(PyObject *name)

   Return the already imported module with the given name.  If the
   module has not been imported yet then returns ``NULL`` but does not set
   an error.  Returns ``NULL`` and sets an error if the lookup failed.

   .. versionadded:: 3.7

.. c:function:: PyObject* PyImport_GetImporter(PyObject *path)

   Return a finder object for a :data:`sys.path`/:attr:`!pkg.__path__` item
   *path*, possibly by fetching it from the :data:`sys.path_importer_cache`
   dict.  If it wasn't yet cached, traverse :data:`sys.path_hooks` until a hook
   is found that can handle the path item.  Return ``None`` if no hook could;
   this tells our caller that the :term:`path based finder` could not find a
   finder for this path item. Cache the result in :data:`sys.path_importer_cache`.
   Return a new reference to the finder object.


.. c:function:: int PyImport_ImportFrozenModuleObject(PyObject *name)

   Load a frozen module named *name*.  Return ``1`` for success, ``0`` if the
   module is not found, and ``-1`` with an exception set if the initialization
   failed.  To access the imported module on a successful load, use
   :c:func:`PyImport_ImportModule`.  (Note the misnomer --- this function would
   reload the module if it was already imported.)

   .. versionadded:: 3.3

   .. versionchanged:: 3.4
      The ``__file__`` attribute is no longer set on the module.


.. c:function:: int PyImport_ImportFrozenModule(const char *name)

   Similar to :c:func:`PyImport_ImportFrozenModuleObject`, but the name is a
   UTF-8 encoded string instead of a Unicode object.


.. c:struct:: _frozen

   .. index:: single: freeze utility

   This is the structure type definition for frozen module descriptors, as
   generated by the :program:`freeze` utility (see :file:`Tools/freeze/` in the
   Python source distribution).  Its definition, found in :file:`Include/import.h`,
   is::

      struct _frozen {
          const char *name;
          const unsigned char *code;
          int size;
          bool is_package;
      };

   .. versionchanged:: 3.11
      The new ``is_package`` field indicates whether the module is a package or not.
      This replaces setting the ``size`` field to a negative value.

.. c:var:: const struct _frozen* PyImport_FrozenModules

   This pointer is initialized to point to an array of :c:struct:`_frozen`
   records, terminated by one whose members are all ``NULL`` or zero.  When a frozen
   module is imported, it is searched in this table.  Third-party code could play
   tricks with this to provide a dynamically created collection of frozen modules.


.. c:function:: int PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))

   Add a single module to the existing table of built-in modules.  This is a
   convenience wrapper around :c:func:`PyImport_ExtendInittab`, returning ``-1`` if
   the table could not be extended.  The new module can be imported by the name
   *name*, and uses the function *initfunc* as the initialization function called
   on the first attempted import.  This should be called before
   :c:func:`Py_Initialize`.


.. c:struct:: _inittab

   Structure describing a single entry in the list of built-in modules.
   Programs which
   embed Python may use an array of these structures in conjunction with
   :c:func:`PyImport_ExtendInittab` to provide additional built-in modules.
   The structure consists of two members:

   .. c:member:: const char *name

      The module name, as an ASCII encoded string.

   .. c: member:: PyObject* (*initfunc)(void)

      Initialization function for a module built into the interpreter.


.. c:function:: int PyImport_ExtendInittab(struct _inittab *newtab)

   Add a collection of modules to the table of built-in modules.  The *newtab*
   array must end with a sentinel entry which contains ``NULL`` for the :c:member:`~_inittab.name`
   field; failure to provide the sentinel value can result in a memory fault.
   Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to
   extend the internal table.  In the event of failure, no modules are added to the
   internal table.  This must be called before :c:func:`Py_Initialize`.

   If Python is initialized multiple times, :c:func:`PyImport_AppendInittab` or
   :c:func:`PyImport_ExtendInittab` must be called before each Python
   initialization.
