.. highlight:: c

.. _moduleobjects:

Module Objects
==============

.. index:: pair: object; module

.. c:var:: PyTypeObject PyModule_Type

   .. index:: single: ModuleType (in module types)

   This instance of :c:type:`PyTypeObject` represents the Python module type.  This
   is exposed to Python programs as :py:class:`types.ModuleType`.


.. c:function:: int PyModule_Check(PyObject *p)

   Return true if *p* is a module object, or a subtype of a module object.
   This function always succeeds.


.. c:function:: int PyModule_CheckExact(PyObject *p)

   Return true if *p* is a module object, but not a subtype of
   :c:data:`PyModule_Type`.  This function always succeeds.


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

   .. index::
      single: __name__ (module attribute)
      single: __doc__ (module attribute)
      single: __file__ (module attribute)
      single: __package__ (module attribute)
      single: __loader__ (module attribute)

   Return a new module object with :attr:`module.__name__` set to *name*.
   The module's :attr:`!__name__`, :attr:`~module.__doc__`,
   :attr:`~module.__package__` and :attr:`~module.__loader__` attributes are
   filled in (all but :attr:`!__name__` are set to ``None``). The caller is
   responsible for setting a :attr:`~module.__file__` attribute.

   Return ``NULL`` with an exception set on error.

   .. versionadded:: 3.3

   .. versionchanged:: 3.4
      :attr:`~module.__package__` and :attr:`~module.__loader__` are now set to
      ``None``.


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

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


.. c:function:: PyObject* PyModule_GetDict(PyObject *module)

   .. index:: single: __dict__ (module attribute)

   Return the dictionary object that implements *module*'s namespace; this object
   is the same as the :attr:`~object.__dict__` attribute of the module object.
   If *module* is not a module object (or a subtype of a module object),
   :exc:`SystemError` is raised and ``NULL`` is returned.

   It is recommended extensions use other ``PyModule_*`` and
   ``PyObject_*`` functions rather than directly manipulate a module's
   :attr:`~object.__dict__`.

   The returned reference is borrowed from the module; it is valid until
   the module is destroyed.


.. c:function:: PyObject* PyModule_GetNameObject(PyObject *module)

   .. index::
      single: __name__ (module attribute)
      single: SystemError (built-in exception)

   Return *module*'s :attr:`~module.__name__` value.  If the module does not
   provide one, or if it is not a string, :exc:`SystemError` is raised and
   ``NULL`` is returned.

   .. versionadded:: 3.3


.. c:function:: const char* PyModule_GetName(PyObject *module)

   Similar to :c:func:`PyModule_GetNameObject` but return the name encoded to
   ``'utf-8'``.

   The returned buffer is only valid until the module is renamed or destroyed.
   Note that Python code may rename a module by setting its :py:attr:`~module.__name__`
   attribute.

.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module)

   Return a pointer to the :c:type:`PyModuleDef` struct from which the module was
   created, or ``NULL`` if the module wasn't created from a definition.

   On error, return ``NULL`` with an exception set.
   Use :c:func:`PyErr_Occurred` to tell this case apart from a missing
   :c:type:`!PyModuleDef`.


.. c:function:: PyObject* PyModule_GetFilenameObject(PyObject *module)

   .. index::
      single: __file__ (module attribute)
      single: SystemError (built-in exception)

   Return the name of the file from which *module* was loaded using *module*'s
   :attr:`~module.__file__` attribute.  If this is not defined, or if it is not a
   string, raise :exc:`SystemError` and return ``NULL``; otherwise return
   a reference to a Unicode object.

   .. versionadded:: 3.2


.. c:function:: const char* PyModule_GetFilename(PyObject *module)

   Similar to :c:func:`PyModule_GetFilenameObject` but return the filename
   encoded to 'utf-8'.

   The returned buffer is only valid until the module's :py:attr:`~module.__file__` attribute
   is reassigned or the module is destroyed.

   .. deprecated:: 3.2
      :c:func:`PyModule_GetFilename` raises :exc:`UnicodeEncodeError` on
      unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead.


.. _pymoduledef_slot:

Module definition
-----------------

Modules created using the C API are typically defined using an
array of :dfn:`slots`.
The slots provide a "description" of how a module should be created.

.. versionchanged:: 3.15

   Previously, a :c:type:`PyModuleDef` struct was necessary to define modules.
   The older way of defining modules is still available: consult either the
   :ref:`pymoduledef` section or earlier versions of this documentation
   if you plan to support earlier Python versions.

The slots array is usually used to define an extension module's “main”
module object (see :ref:`extension-modules` for details).
It can also be used to
:ref:`create extension modules dynamically <module-from-slots>`.

Unless specified otherwise, the same slot ID may not be repeated
in an array of slots.


.. c:type:: PyModuleDef_Slot

   .. c:member:: int slot

      A slot ID, chosen from the available ``Py_mod_*`` values explained below.

      An ID of 0 marks the end of a :c:type:`!PyModuleDef_Slot` array.

   .. c:member:: void* value

      Value of the slot, whose meaning depends on the slot ID.

      The value may not be NULL.
      To leave a slot out, omit the :c:type:`PyModuleDef_Slot` entry entirely.

   .. versionadded:: 3.5


Metadata slots
..............

.. c:macro:: Py_mod_name

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for the name of the new module,
   as a NUL-terminated UTF8-encoded ``const char *``.

   Note that modules are typically created using a
   :py:class:`~importlib.machinery.ModuleSpec`, and when they are, the
   name from the spec will be used instead of :c:data:`!Py_mod_name`.
   However, it is still recommended to include this slot for introspection
   and debugging purposes.

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_name` instead to support previous versions.

.. c:macro:: Py_mod_doc

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for the docstring of the new
   module, as a NUL-terminated UTF8-encoded ``const char *``.

   Usually it is set to a variable created with :c:macro:`PyDoc_STRVAR`.

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_doc` instead to support previous versions.


Feature slots
.............

.. c:macro:: Py_mod_abi

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` whose value points to
   a :c:struct:`PyABIInfo` structure describing the ABI that
   the extension is using.

   A suitable :c:struct:`!PyABIInfo` variable can be defined using the
   :c:macro:`PyABIInfo_VAR` macro, as in:

   .. code-block:: c

      PyABIInfo_VAR(abi_info);

      static PyModuleDef_Slot mymodule_slots[] = {
         {Py_mod_abi, &abi_info},
         ...
      };

   When creating a module, Python checks the value of this slot
   using :c:func:`PyABIInfo_Check`.

   .. versionadded:: 3.15

.. c:macro:: Py_mod_multiple_interpreters

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` whose value is one of:

   .. c:namespace:: NULL

   .. c:macro:: Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED

      The module does not support being imported in subinterpreters.

   .. c:macro:: Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED

      The module supports being imported in subinterpreters,
      but only when they share the main interpreter's GIL.
      (See :ref:`isolating-extensions-howto`.)

   .. c:macro:: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED

      The module supports being imported in subinterpreters,
      even when they have their own GIL.
      (See :ref:`isolating-extensions-howto`.)

   This slot determines whether or not importing this module
   in a subinterpreter will fail.

   If ``Py_mod_multiple_interpreters`` is not specified, the import
   machinery defaults to ``Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED``.

   .. versionadded:: 3.12

.. c:macro:: Py_mod_gil

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` whose value is one of:

   .. c:namespace:: NULL

   .. c:macro:: Py_MOD_GIL_USED

      The module depends on the presence of the global interpreter lock (GIL),
      and may access global state without synchronization.

   .. c:macro:: Py_MOD_GIL_NOT_USED

      The module is safe to run without an active GIL.

   This slot is ignored by Python builds not configured with
   :option:`--disable-gil`.  Otherwise, it determines whether or not importing
   this module will cause the GIL to be automatically enabled. See
   :ref:`whatsnew313-free-threaded-cpython` for more detail.

   If ``Py_mod_gil`` is not specified, the import machinery defaults to
   ``Py_MOD_GIL_USED``.

   .. versionadded:: 3.13


Creation and initialization slots
.................................

.. c:macro:: Py_mod_create

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for a function that creates
   the module object itself.
   The function must have the signature:

   .. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def)
      :no-index-entry:
      :no-contents-entry:

   The function will be called with:

   - *spec*: a ``ModuleSpec``-like object, meaning that any attributes defined
     for :py:class:`importlib.machinery.ModuleSpec` have matching semantics.
     However, any of the attributes may be missing.
   - *def*: ``NULL``, or the module definition if the module is created from one.

   The function should return a new module object, or set an error
   and return ``NULL``.

   This function should be kept minimal. In particular, it should not
   call arbitrary Python code, as trying to import the same module again may
   result in an infinite loop.

   If ``Py_mod_create`` is not specified, the import machinery will create
   a normal module object using :c:func:`PyModule_New`. The name is taken from
   *spec*, not the definition, to allow extension modules to dynamically adjust
   to their place in the module hierarchy and be imported under different
   names through symlinks, all while sharing a single module definition.

   There is no requirement for the returned object to be an instance of
   :c:type:`PyModule_Type`.
   However, some slots may only be used with
   :c:type:`!PyModule_Type` instances; in particular:

   - :c:macro:`Py_mod_exec`,
   - :ref:`module state slots <ext-module-state-slots>` (``Py_mod_state_*``),
   - :c:macro:`Py_mod_token`.

   .. versionadded:: 3.5

   .. versionchanged:: 3.15

      The *slots* argument may be a ``ModuleSpec``-like object, rather than
      a true :py:class:`~importlib.machinery.ModuleSpec` instance.
      Note that previous versions of CPython did not enforce this.

      The *def* argument may now be ``NULL``, since modules are not necessarily
      made from definitions.

.. c:macro:: Py_mod_exec

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for a function that will
   :dfn:`execute`, or initialize, the module.
   This function does the equivalent to executing the code of a Python module:
   typically, it adds classes and constants to the module.
   The signature of the function is:

   .. c:function:: int exec_module(PyObject* module)
      :no-index-entry:
      :no-contents-entry:

   See the :ref:`capi-module-support-functions` section for some useful
   functions to call.

   For backwards compatibility, the :c:type:`PyModuleDef.m_slots` array may
   contain multiple :c:macro:`!Py_mod_exec` slots; these are processed in the
   order they appear in the array.
   Elsewhere (that is, in arguments to :c:func:`PyModule_FromSlotsAndSpec`
   and in return values of :samp:`PyModExport_{<name>}`), repeating the slot
   is not allowed.

   .. versionadded:: 3.5

   .. versionchanged:: 3.15

      Repeated ``Py_mod_exec`` slots are disallowed, except in
      :c:type:`PyModuleDef.m_slots`.

.. c:macro:: Py_mod_methods

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for a table of module-level
   functions, as an array of :c:type:`PyMethodDef` values suitable as the
   *functions* argument to :c:func:`PyModule_AddFunctions`.

   Like other slot IDs, a slots array may only contain one
   :c:macro:`!Py_mod_methods` entry.
   To add functions from multiple :c:type:`PyMethodDef` arrays, call
   :c:func:`PyModule_AddFunctions` in the :c:macro:`Py_mod_exec` function.

   The table must be statically allocated (or otherwise guaranteed to outlive
   the module object).

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_methods` instead to support previous versions.

.. _ext-module-state:

Module state
------------

Extension modules can have *module state* -- a
piece of memory that is allocated on module creation,
and freed when the module object is deallocated.
The module state is specified using :ref:`dedicated slots <ext-module-state-slots>`.

A typical use of module state is storing an exception type -- or indeed *any*
type object defined by the module --

Unlike the module's Python attributes, Python code cannot replace or delete
data stored in module state.

Keeping per-module information in attributes and module state, rather than in
static globals, makes module objects *isolated* and safer for use in
multiple sub-interpreters.
It also helps Python do an orderly clean-up when it shuts down.

Extensions that keep references to Python objects as part of module state must
implement :c:macro:`Py_mod_state_traverse` and :c:macro:`Py_mod_state_clear`
functions to avoid reference leaks.

To retrieve the state from a given module, use the following functions:

.. c:function:: void* PyModule_GetState(PyObject *module)

   Return the "state" of the module, that is, a pointer to the block of memory
   allocated at module creation time, or ``NULL``.  See
   :c:macro:`Py_mod_state_size`.

   On error, return ``NULL`` with an exception set.
   Use :c:func:`PyErr_Occurred` to tell this case apart from missing
   module state.


.. c:function:: int PyModule_GetStateSize(PyObject *module, Py_ssize_t *result)

   Set *\*result* to the size of *module*'s state, as specified
   using :c:macro:`Py_mod_state_size` (or :c:member:`PyModuleDef.m_size`),
   and return 0.

   On error, set *\*result* to -1, and return -1 with an exception set.

   .. versionadded:: 3.15



.. _ext-module-state-slots:

Slots for defining module state
...............................

The following :c:member:`PyModuleDef_Slot.slot` IDs are available for
defining the module state.

.. c:macro:: Py_mod_state_size

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for the size of the module state,
   in bytes.

   Setting the value to a non-negative value means that the module can be
   re-initialized and specifies the additional amount of memory it requires
   for its state.

   See :PEP:`3121` for more details.

   Use :c:func:`PyModule_GetStateSize` to retrieve the size of a given module.

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_size` instead to support previous versions.

.. c:macro:: Py_mod_state_traverse

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for a traversal function to call
   during GC traversal of the module object.

   The signature of the function, and meanings of the arguments,
   is similar as for :c:member:`PyTypeObject.tp_traverse`:

   .. c:function:: int traverse_module_state(PyObject *module, visitproc visit, void *arg)
      :no-index-entry:
      :no-contents-entry:

   This function is not called if the module state was requested but is not
   allocated yet. This is the case immediately after the module is created
   and before the module is executed (:c:data:`Py_mod_exec` function). More
   precisely, this function is not called if the state size
   (:c:data:`Py_mod_state_size`) is greater than 0 and the module state
   (as returned by :c:func:`PyModule_GetState`) is ``NULL``.

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_size` instead to support previous versions.

.. c:macro:: Py_mod_state_clear

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for a clear function to call
   during GC clearing of the module object.

   The signature of the function is:

   .. c:function:: int clear_module_state(PyObject* module)
      :no-index-entry:
      :no-contents-entry:

   This function is not called if the module state was requested but is not
   allocated yet. This is the case immediately after the module is created
   and before the module is executed (:c:data:`Py_mod_exec` function). More
   precisely, this function is not called if the state size
   (:c:data:`Py_mod_state_size`) is greater than 0 and the module state
   (as returned by :c:func:`PyModule_GetState`) is ``NULL``.

   Like :c:member:`PyTypeObject.tp_clear`, this function is not *always*
   called before a module is deallocated. For example, when reference
   counting is enough to determine that an object is no longer used,
   the cyclic garbage collector is not involved and
   the :c:macro:`Py_mod_state_free` function is called directly.

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_clear` instead to support previous versions.

.. c:macro:: Py_mod_state_free

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for a function to call during
   deallocation of the module object.

   The signature of the function is:

   .. c:function:: int free_module_state(PyObject* module)
      :no-index-entry:
      :no-contents-entry:

   This function is not called if the module state was requested but is not
   allocated yet. This is the case immediately after the module is created
   and before the module is executed (:c:data:`Py_mod_exec` function). More
   precisely, this function is not called if the state size
   (:c:data:`Py_mod_state_size`) is greater than 0 and the module state
   (as returned by :c:func:`PyModule_GetState`) is ``NULL``.

   .. versionadded:: 3.15

      Use :c:member:`PyModuleDef.m_free` instead to support previous versions.


.. _ext-module-token:

Module token
............

Each module may have an associated *token*: a pointer-sized value intended to
identify of the module state's memory layout.
This means that if you have a module object, but you are not sure if it
“belongs” to your extension, you can check using code like this:

.. code-block:: c

   PyObject *module = <the module in question>

   void *module_token;
   if (PyModule_GetToken(module, &module_token) < 0) {
       return NULL;
   }
   if (module_token != your_token) {
       PyErr_SetString(PyExc_ValueError, "unexpected module")
       return NULL;
   }

   // This module's state has the expected memory layout; it's safe to cast
   struct my_state state = (struct my_state*)PyModule_GetState(module)

A module's token -- and the *your_token* value to use in the above code -- is:

- For modules created with :c:type:`PyModuleDef`: the address of that
  :c:type:`PyModuleDef`;
- For modules defined with the :c:macro:`Py_mod_token` slot: the value
  of that slot;
- For modules created from an ``PyModExport_*``
  :ref:`export hook <extension-export-hook>`: the slots array that the export
  hook returned (unless overridden with :c:macro:`Py_mod_token`).

.. c:macro:: Py_mod_token

   :c:type:`Slot ID <PyModuleDef_Slot.slot>` for the module token.

   If you use this slot to set the module token (rather than rely on the
   default), you must ensure that:

   * The pointer outlives the class, so it's not reused for something else
     while the class exists.
   * It "belongs" to the extension module where the class lives, so it will not
     clash with other extensions.
   * If the token points to a :c:type:`PyModuleDef` struct, the module should
     behave as if it was created from that :c:type:`PyModuleDef`.
     In particular, the module state must have matching layout and semantics.

   Modules created from :c:type:`PyModuleDef` always use the address of
   the :c:type:`PyModuleDef` as the token.
   This means that :c:macro:`!Py_mod_token` cannot be used in
   :c:member:`PyModuleDef.m_slots`.

   .. versionadded:: 3.15

.. c:function:: int PyModule_GetToken(PyObject *module, void** result)

   Set *\*result* to the module token for *module* and return 0.

   On error, set *\*result* to NULL, and return -1 with an exception set.

   .. versionadded:: 3.15

See also :c:func:`PyType_GetModuleByToken`.


.. _module-from-slots:

Creating extension modules dynamically
--------------------------------------

The following functions may be used to create an extension module dynamically,
rather than from an extension's :ref:`export hook <extension-export-hook>`.

.. c:function:: PyObject *PyModule_FromSlotsAndSpec(const PyModuleDef_Slot *slots, PyObject *spec)

   Create a new module object, given an array of :ref:`slots <pymoduledef_slot>`
   and the :py:class:`~importlib.machinery.ModuleSpec` *spec*.

   The *slots* argument must point to an array of :c:type:`PyModuleDef_Slot`
   structures, terminated by an entry slot with slot ID of 0
   (typically written as ``{0}`` or ``{0, NULL}`` in C).
   The *slots* argument may not be ``NULL``.

   The *spec* argument may be any ``ModuleSpec``-like object, as described
   in :c:macro:`Py_mod_create` documentation.
   Currently, the *spec* must have a ``name`` attribute.

   On success, return the new module.
   On error, return ``NULL`` with an exception set.

   Note that this does not process the module's execution slot
   (:c:data:`Py_mod_exec`).
   Both :c:func:`!PyModule_FromSlotsAndSpec` and :c:func:`PyModule_Exec`
   must be called to fully initialize a module.
   (See also :ref:`multi-phase-initialization`.)

   The *slots* array only needs to be valid for the duration of the
   :c:func:`!PyModule_FromSlotsAndSpec` call.
   In particular, it may be heap-allocated.

   .. versionadded:: 3.15

.. c:function:: int PyModule_Exec(PyObject *module)

   Execute the :c:data:`Py_mod_exec` slot(s) of *module*.

   On success, return 0.
   On error, return -1 with an exception set.

   For clarity: If *module* has no slots, for example if it uses
   :ref:`legacy single-phase initialization <single-phase-initialization>`,
   this function does nothing and returns 0.

   .. versionadded:: 3.15



.. _pymoduledef:

Module definition struct
------------------------

Traditionally, extension modules were defined using a *module definition*
as the “description" of how a module should be created.
Rather than using an array of :ref:`slots <pymoduledef_slot>` directly,
the definition has dedicated members for most common functionality,
and allows additional slots as an extension mechanism.

This way of defining modules is still available and there are no plans to
remove it.

.. c:type:: PyModuleDef

   The module definition struct, which holds information needed to create
   a module object.

   This structure must be statically allocated (or be otherwise guaranteed
   to be valid while any modules created from it exist).
   Usually, there is only one variable of this type for each extension module
   defined this way.

   .. c:member:: PyModuleDef_Base m_base

      Always initialize this member to :c:macro:`PyModuleDef_HEAD_INIT`:

      .. c:namespace:: NULL

      .. c:type:: PyModuleDef_Base

         The type of :c:member:`!PyModuleDef.m_base`.

      .. c:macro:: PyModuleDef_HEAD_INIT

         The required initial value for :c:member:`!PyModuleDef.m_base`.

   .. c:member:: const char *m_name

      Corresponds to the :c:macro:`Py_mod_name` slot.

   .. c:member:: const char *m_doc

      These members correspond to the :c:macro:`Py_mod_doc` slot.
      Setting this to NULL is equivalent to omitting the slot.

   .. c:member:: Py_ssize_t m_size

      Corresponds to the :c:macro:`Py_mod_state_size` slot.
      Setting this to zero is equivalent to omitting the slot.

      When using :ref:`legacy single-phase initialization <single-phase-initialization>`
      or when creating modules dynamically using :c:func:`PyModule_Create`
      or :c:func:`PyModule_Create2`, :c:member:`!m_size` may be set to -1.
      This indicates that the module does not support sub-interpreters,
      because it has global state.

   .. c:member:: PyMethodDef *m_methods

      Corresponds to the :c:macro:`Py_mod_methods` slot.
      Setting this to NULL is equivalent to omitting the slot.

   .. c:member:: PyModuleDef_Slot* m_slots

      An array of additional slots, terminated by a ``{0, NULL}`` entry.

      If the array contains slots corresponding to :c:type:`PyModuleDef`
      members, the values must match.
      For example, if you use :c:macro:`Py_mod_name` in :c:member:`!m_slots`,
      :c:member:`PyModuleDef.m_name` must be set to the same pointer
      (not just an equal string).

      .. versionchanged:: 3.5

         Prior to version 3.5, this member was always set to ``NULL``,
         and was defined as:

           .. c:member:: inquiry m_reload

   .. c:member:: traverseproc m_traverse
                 inquiry m_clear
                 freefunc m_free

      These members correspond to the :c:macro:`Py_mod_state_traverse`,
      :c:macro:`Py_mod_state_clear`, and :c:macro:`Py_mod_state_free` slots,
      respectively.

      Setting these members to NULL is equivalent to omitting the
      corresponding slots.

      .. versionchanged:: 3.9

         :c:member:`m_traverse`, :c:member:`m_clear` and :c:member:`m_free`
         functions are no longer called before the module state is allocated.


.. c:var:: PyTypeObject PyModuleDef_Type

   The type of ``PyModuleDef`` objects.


.. _moduledef-dynamic:

The following API can be used to create modules from a :c:type:`!PyModuleDef`
struct:

.. c:function:: PyObject* PyModule_Create(PyModuleDef *def)

   Create a new module object, given the definition in *def*.
   This is a macro that calls :c:func:`PyModule_Create2` with
   *module_api_version* set to :c:macro:`PYTHON_API_VERSION`, or
   to :c:macro:`PYTHON_ABI_VERSION` if using the
   :ref:`limited API <limited-c-api>`.

.. c:function:: PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version)

   Create a new module object, given the definition in *def*, assuming the
   API version *module_api_version*.  If that version does not match the version
   of the running interpreter, a :exc:`RuntimeWarning` is emitted.

   Return ``NULL`` with an exception set on error.

   This function does not support slots.
   The :c:member:`~PyModuleDef.m_slots` member of *def* must be ``NULL``.


   .. note::

      Most uses of this function should be using :c:func:`PyModule_Create`
      instead; only use this if you are sure you need it.

.. c:function:: PyObject * PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec)

   This macro calls :c:func:`PyModule_FromDefAndSpec2` with
   *module_api_version* set to :c:macro:`PYTHON_API_VERSION`, or
   to :c:macro:`PYTHON_ABI_VERSION` if using the
   :ref:`limited API <limited-c-api>`.

   .. versionadded:: 3.5

.. c:function:: PyObject * PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version)

   Create a new module object, given the definition in *def* and the
   ModuleSpec *spec*, assuming the API version *module_api_version*.
   If that version does not match the version of the running interpreter,
   a :exc:`RuntimeWarning` is emitted.

   Return ``NULL`` with an exception set on error.

   Note that this does not process execution slots (:c:data:`Py_mod_exec`).
   Both ``PyModule_FromDefAndSpec`` and ``PyModule_ExecDef`` must be called
   to fully initialize a module.

   .. note::

      Most uses of this function should be using :c:func:`PyModule_FromDefAndSpec`
      instead; only use this if you are sure you need it.

   .. versionadded:: 3.5

.. c:function:: int PyModule_ExecDef(PyObject *module, PyModuleDef *def)

   Process any execution slots (:c:data:`Py_mod_exec`) given in *def*.

   .. versionadded:: 3.5

.. c:macro:: PYTHON_API_VERSION
             PYTHON_API_STRING

   The C API version, as an integer (``1013``) and string (``"1013"``), respectively.
   Defined for backwards compatibility.

   Currently, this constant is not updated in new Python versions, and is not
   useful for versioning. This may change in the future.

.. c:macro:: PYTHON_ABI_VERSION
             PYTHON_ABI_STRING

   Defined as ``3`` and ``"3"``, respectively, for backwards compatibility.

   Currently, this constant is not updated in new Python versions, and is not
   useful for versioning. This may change in the future.


.. _capi-module-support-functions:

Support functions
-----------------

The following functions are provided to help initialize a module object.
They are intended for a module's execution slot (:c:data:`Py_mod_exec`),
the initialization function for legacy :ref:`single-phase initialization <single-phase-initialization>`,
or code that creates modules dynamically.

.. c:function:: int PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value)

   Add an object to *module* as *name*.  This is a convenience function which
   can be used from the module's initialization function.

   On success, return ``0``. On error, raise an exception and return ``-1``.

   Example usage::

       static int
       add_spam(PyObject *module, int value)
       {
           PyObject *obj = PyLong_FromLong(value);
           if (obj == NULL) {
               return -1;
           }
           int res = PyModule_AddObjectRef(module, "spam", obj);
           Py_DECREF(obj);
           return res;
        }

   To be convenient, the function accepts ``NULL`` *value* with an exception
   set. In this case, return ``-1`` and just leave the raised exception
   unchanged.

   The example can also be written without checking explicitly if *obj* is
   ``NULL``::

       static int
       add_spam(PyObject *module, int value)
       {
           PyObject *obj = PyLong_FromLong(value);
           int res = PyModule_AddObjectRef(module, "spam", obj);
           Py_XDECREF(obj);
           return res;
        }

   Note that ``Py_XDECREF()`` should be used instead of ``Py_DECREF()`` in
   this case, since *obj* can be ``NULL``.

   The number of different *name* strings passed to this function
   should be kept small, usually by only using statically allocated strings
   as *name*.
   For names that aren't known at compile time, prefer calling
   :c:func:`PyUnicode_FromString` and :c:func:`PyObject_SetAttr` directly.
   For more details, see :c:func:`PyUnicode_InternFromString`, which may be
   used internally to create a key object.

   .. versionadded:: 3.10


.. c:function:: int PyModule_Add(PyObject *module, const char *name, PyObject *value)

   Similar to :c:func:`PyModule_AddObjectRef`, but "steals" a reference
   to *value*.
   It can be called with a result of function that returns a new reference
   without bothering to check its result or even saving it to a variable.

   Example usage::

        if (PyModule_Add(module, "spam", PyBytes_FromString(value)) < 0) {
            goto error;
        }

   .. versionadded:: 3.13


.. c:function:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value)

   Similar to :c:func:`PyModule_AddObjectRef`, but steals a reference to
   *value* on success (if it returns ``0``).

   The new :c:func:`PyModule_Add` or :c:func:`PyModule_AddObjectRef`
   functions are recommended, since it is
   easy to introduce reference leaks by misusing the
   :c:func:`PyModule_AddObject` function.

   .. note::

      Unlike other functions that steal references, ``PyModule_AddObject()``
      only releases the reference to *value* **on success**.

      This means that its return value must be checked, and calling code must
      :c:func:`Py_XDECREF` *value* manually on error.

   Example usage::

        PyObject *obj = PyBytes_FromString(value);
        if (PyModule_AddObject(module, "spam", obj) < 0) {
            // If 'obj' is not NULL and PyModule_AddObject() failed,
            // 'obj' strong reference must be deleted with Py_XDECREF().
            // If 'obj' is NULL, Py_XDECREF() does nothing.
            Py_XDECREF(obj);
            goto error;
        }
        // PyModule_AddObject() stole a reference to obj:
        // Py_XDECREF(obj) is not needed here.

   .. deprecated:: 3.13

      :c:func:`PyModule_AddObject` is :term:`soft deprecated`.


.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)

   Add an integer constant to *module* as *name*.  This convenience function can be
   used from the module's initialization function.
   Return ``-1`` with an exception set on error, ``0`` on success.

   This is a convenience function that calls :c:func:`PyLong_FromLong` and
   :c:func:`PyModule_AddObjectRef`; see their documentation for details.


.. c:function:: int PyModule_AddStringConstant(PyObject *module, const char *name, const char *value)

   Add a string constant to *module* as *name*.  This convenience function can be
   used from the module's initialization function.  The string *value* must be
   ``NULL``-terminated.
   Return ``-1`` with an exception set on error, ``0`` on success.

   This is a convenience function that calls
   :c:func:`PyUnicode_InternFromString` and :c:func:`PyModule_AddObjectRef`;
   see their documentation for details.


.. c:macro:: PyModule_AddIntMacro(module, macro)

   Add an int constant to *module*. The name and the value are taken from
   *macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int
   constant *AF_INET* with the value of *AF_INET* to *module*.
   Return ``-1`` with an exception set on error, ``0`` on success.


.. c:macro:: PyModule_AddStringMacro(module, macro)

   Add a string constant to *module*.

.. c:function:: int PyModule_AddType(PyObject *module, PyTypeObject *type)

   Add a type object to *module*.
   The type object is finalized by calling internally :c:func:`PyType_Ready`.
   The name of the type object is taken from the last component of
   :c:member:`~PyTypeObject.tp_name` after dot.
   Return ``-1`` with an exception set on error, ``0`` on success.

   .. versionadded:: 3.9

.. c:function:: int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)

   Add the functions from the ``NULL`` terminated *functions* array to *module*.
   Refer to the :c:type:`PyMethodDef` documentation for details on individual
   entries (due to the lack of a shared module namespace, module level
   "functions" implemented in C typically receive the module as their first
   parameter, making them similar to instance methods on Python classes).

   This function is called automatically when creating a module from
   ``PyModuleDef`` (such as when using :ref:`multi-phase-initialization`,
   ``PyModule_Create``, or ``PyModule_FromDefAndSpec``).
   Some module authors may prefer defining functions in multiple
   :c:type:`PyMethodDef` arrays; in that case they should call this function
   directly.

   The *functions* array must be statically allocated (or otherwise guaranteed
   to outlive the module object).

   .. versionadded:: 3.5

.. c:function:: int PyModule_SetDocString(PyObject *module, const char *docstring)

   Set the docstring for *module* to *docstring*.
   This function is called automatically when creating a module from
   ``PyModuleDef`` (such as when using :ref:`multi-phase-initialization`,
   ``PyModule_Create``, or ``PyModule_FromDefAndSpec``).

   Return ``0`` on success.
   Return ``-1`` with an exception set on error.

   .. versionadded:: 3.5

.. c:function:: int PyUnstable_Module_SetGIL(PyObject *module, void *gil)

   Indicate that *module* does or does not support running without the global
   interpreter lock (GIL), using one of the values from
   :c:macro:`Py_mod_gil`. It must be called during *module*'s initialization
   function when using :ref:`single-phase-initialization`.
   If this function is not called during module initialization, the
   import machinery assumes the module does not support running without the
   GIL. This function is only available in Python builds configured with
   :option:`--disable-gil`.
   Return ``-1`` with an exception set on error, ``0`` on success.

   .. versionadded:: 3.13


Module lookup (single-phase initialization)
...........................................

The legacy :ref:`single-phase initialization <single-phase-initialization>`
initialization scheme creates singleton modules that can be looked up
in the context of the current interpreter. This allows the module object to be
retrieved later with only a reference to the module definition.

These functions will not work on modules created using multi-phase initialization,
since multiple such modules can be created from a single definition.

.. c:function:: PyObject* PyState_FindModule(PyModuleDef *def)

   Returns the module object that was created from *def* for the current interpreter.
   This method requires that the module object has been attached to the interpreter state with
   :c:func:`PyState_AddModule` beforehand. In case the corresponding module object is not
   found or has not been attached to the interpreter state yet, it returns ``NULL``.

.. c:function:: int PyState_AddModule(PyObject *module, PyModuleDef *def)

   Attaches the module object passed to the function to the interpreter state. This allows
   the module object to be accessible via :c:func:`PyState_FindModule`.

   Only effective on modules created using single-phase initialization.

   Python calls ``PyState_AddModule`` automatically after importing a module
   that uses :ref:`single-phase initialization <single-phase-initialization>`,
   so it is unnecessary (but harmless) to call it from module initialization
   code. An explicit call is needed only if the module's own init code
   subsequently calls ``PyState_FindModule``.
   The function is mainly intended for implementing alternative import
   mechanisms (either by calling it directly, or by referring to its
   implementation for details of the required state updates).

   If a module was attached previously using the same *def*, it is replaced
   by the new *module*.

   The caller must have an :term:`attached thread state`.

   Return ``-1`` with an exception set on error, ``0`` on success.

   .. versionadded:: 3.3

.. c:function:: int PyState_RemoveModule(PyModuleDef *def)

   Removes the module object created from *def* from the interpreter state.
   Return ``-1`` with an exception set on error, ``0`` on success.

   The caller must have an :term:`attached thread state`.

   .. versionadded:: 3.3
