.. highlight:: c

.. _isolating-extensions-howto:

***************************
Isolating Extension Modules
***************************

.. topic:: Abstract

    Traditionally, state belonging to Python extension modules was kept in C
    ``static`` variables, which have process-wide scope. This document
    describes problems of such per-process state and shows a safer way:
    per-module state.

    The document also describes how to switch to per-module state where
    possible. This transition involves allocating space for that state, potentially
    switching from static types to heap types, and—perhaps most
    importantly—accessing per-module state from code.


Who should read this
====================

This guide is written for maintainers of :ref:`C-API <c-api-index>` extensions
who would like to make that extension safer to use in applications where
Python itself is used as a library.


Background
==========

An *interpreter* is the context in which Python code runs. It contains
configuration (e.g. the import path) and runtime state (e.g. the set of
imported modules).

Python supports running multiple interpreters in one process. There are
two cases to think about—users may run interpreters:

-  in sequence, with several :c:func:`Py_InitializeEx`/:c:func:`Py_FinalizeEx`
   cycles, and
-  in parallel, managing "sub-interpreters" using
   :c:func:`Py_NewInterpreter`/:c:func:`Py_EndInterpreter`.

Both cases (and combinations of them) would be most useful when
embedding Python within a library. Libraries generally shouldn't make
assumptions about the application that uses them, which include
assuming a process-wide "main Python interpreter".

Historically, Python extension modules don't handle this use case well.
Many extension modules (and even some stdlib modules) use *per-process*
global state, because C ``static`` variables are extremely easy to use.
Thus, data that should be specific to an interpreter ends up being shared
between interpreters. Unless the extension developer is careful, it is very
easy to introduce edge cases that lead to crashes when a module is loaded in
more than one interpreter in the same process.

Unfortunately, *per-interpreter* state is not easy to achieve. Extension
authors tend to not keep multiple interpreters in mind when developing,
and it is currently cumbersome to test the behavior.

Enter Per-Module State
----------------------

Instead of focusing on per-interpreter state, Python's C API is evolving
to better support the more granular *per-module* state.
This means that C-level data should be attached to a *module object*.
Each interpreter creates its own module object, keeping the data separate.
For testing the isolation, multiple module objects corresponding to a single
extension can even be loaded in a single interpreter.

Per-module state provides an easy way to think about lifetime and
resource ownership: the extension module will initialize when a
module object is created, and clean up when it's freed. In this regard,
a module is just like any other :c:expr:`PyObject *`; there are no "on
interpreter shutdown" hooks to think—or forget—about.

Note that there are use cases for different kinds of "globals":
per-process, per-interpreter, per-thread or per-task state.
With per-module state as the default, these are still possible,
but you should treat them as exceptional cases:
if you need them, you should give them additional care and testing.
(Note that this guide does not cover them.)


Isolated Module Objects
-----------------------

The key point to keep in mind when developing an extension module is
that several module objects can be created from a single shared library.
For example:

.. code-block:: pycon

   >>> import sys
   >>> import binascii
   >>> old_binascii = binascii
   >>> del sys.modules['binascii']
   >>> import binascii  # create a new module object
   >>> old_binascii == binascii
   False

As a rule of thumb, the two modules should be completely independent.
All objects and state specific to the module should be encapsulated
within the module object, not shared with other module objects, and
cleaned up when the module object is deallocated.
Since this just is a rule of thumb, exceptions are possible
(see `Managing Global State`_), but they will need more
thought and attention to edge cases.

While some modules could do with less stringent restrictions, isolated
modules make it easier to set clear expectations and guidelines that
work across a variety of use cases.


Surprising Edge Cases
---------------------

Note that isolated modules do create some surprising edge cases. Most
notably, each module object will typically not share its classes and
exceptions with other similar modules. Continuing from the
`example above <Isolated Module Objects_>`__,
note that ``old_binascii.Error`` and ``binascii.Error`` are
separate objects. In the following code, the exception is *not* caught:

.. code-block:: pycon

   >>> old_binascii.Error == binascii.Error
   False
   >>> try:
   ...     old_binascii.unhexlify(b'qwertyuiop')
   ... except binascii.Error:
   ...     print('boo')
   ...
   Traceback (most recent call last):
     File "<stdin>", line 2, in <module>
   binascii.Error: Non-hexadecimal digit found

This is expected. Notice that pure-Python modules behave the same way:
it is a part of how Python works.

The goal is to make extension modules safe at the C level, not to make
hacks behave intuitively. Mutating ``sys.modules`` "manually" counts
as a hack.


Making Modules Safe with Multiple Interpreters
==============================================


Managing Global State
---------------------

Sometimes, the state associated with a Python module is not specific to that module, but
to the entire process (or something else "more global" than a module).
For example:

-  The ``readline`` module manages *the* terminal.
-  A module running on a circuit board wants to control *the* on-board
   LED.

In these cases, the Python module should provide *access* to the global
state, rather than *own* it. If possible, write the module so that
multiple copies of it can access the state independently (along with
other libraries, whether for Python or other languages). If that is not
possible, consider explicit locking.

If it is necessary to use process-global state, the simplest way to
avoid issues with multiple interpreters is to explicitly prevent a
module from being loaded more than once per process—see
:ref:`isolating-extensions-optout`.


Managing Per-Module State
-------------------------

To use per-module state, use
:ref:`multi-phase extension module initialization <multi-phase-initialization>`.
This signals that your module supports multiple interpreters correctly.

Set ``PyModuleDef.m_size`` to a positive number to request that many
bytes of storage local to the module. Usually, this will be set to the
size of some module-specific ``struct``, which can store all of the
module's C-level state. In particular, it is where you should put
pointers to classes (including exceptions, but excluding static types)
and settings (e.g. ``csv``'s :py:data:`~csv.field_size_limit`)
which the C code needs to function.

.. note::
   Another option is to store state in the module's ``__dict__``,
   but you must avoid crashing when users modify ``__dict__`` from
   Python code. This usually means error- and type-checking at the C level,
   which is easy to get wrong and hard to test sufficiently.

   However, if module state is not needed in C code, storing it in
   ``__dict__`` only is a good idea.

If the module state includes ``PyObject`` pointers, the module object
must hold references to those objects and implement the module-level hooks
``m_traverse``, ``m_clear`` and ``m_free``. These work like
``tp_traverse``, ``tp_clear`` and ``tp_free`` of a class. Adding them will
require some work and make the code longer; this is the price for
modules which can be unloaded cleanly.

An example of a module with per-module state is currently available as
`xxlimited <https://github.com/python/cpython/blob/master/Modules/xxlimited.c>`__;
example module initialization shown at the bottom of the file.


.. _isolating-extensions-optout:

Opt-Out: Limiting to One Module Object per Process
--------------------------------------------------

A non-negative ``PyModuleDef.m_size`` signals that a module supports
multiple interpreters correctly. If this is not yet the case for your
module, you can explicitly make your module loadable only once per
process. For example::

   // A process-wide flag
   static int loaded = 0;

   // Mutex to provide thread safety (only needed for free-threaded Python)
   static PyMutex modinit_mutex = {0};

   static int
   exec_module(PyObject* module)
   {
       PyMutex_Lock(&modinit_mutex);
       if (loaded) {
           PyMutex_Unlock(&modinit_mutex);
           PyErr_SetString(PyExc_ImportError,
                           "cannot load module more than once per process");
           return -1;
       }
       loaded = 1;
       PyMutex_Unlock(&modinit_mutex);
       // ... rest of initialization
   }


If your module's :c:member:`PyModuleDef.m_clear` function is able to prepare
for future re-initialization, it should clear the ``loaded`` flag.
In this case, your module won't support multiple instances existing
*concurrently*, but it will, for example, support being loaded after
Python runtime shutdown (:c:func:`Py_FinalizeEx`) and re-initialization
(:c:func:`Py_Initialize`).


Module State Access from Functions
----------------------------------

Accessing the state from module-level functions is straightforward.
Functions get the module object as their first argument; for extracting
the state, you can use ``PyModule_GetState``::

   static PyObject *
   func(PyObject *module, PyObject *args)
   {
       my_struct *state = (my_struct*)PyModule_GetState(module);
       if (state == NULL) {
           return NULL;
       }
       // ... rest of logic
   }

.. note::
   ``PyModule_GetState`` may return ``NULL`` without setting an
   exception if there is no module state, i.e. ``PyModuleDef.m_size`` was
   zero. In your own module, you're in control of ``m_size``, so this is
   easy to prevent.


Heap Types
==========

Traditionally, types defined in C code are *static*; that is,
``static PyTypeObject`` structures defined directly in code and
initialized using ``PyType_Ready()``.

Such types are necessarily shared across the process. Sharing them
between module objects requires paying attention to any state they own
or access. To limit the possible issues, static types are immutable at
the Python level: for example, you can't set ``str.myattribute = 123``.

.. impl-detail::
   Sharing truly immutable objects between interpreters is fine,
   as long as they don't provide access to mutable objects.
   However, in CPython, every Python object has a mutable implementation
   detail: the reference count. Changes to the refcount are guarded by the GIL.
   Thus, code that shares any Python objects across interpreters implicitly
   depends on CPython's current, process-wide GIL.

Because they are immutable and process-global, static types cannot access
"their" module state.
If any method of such a type requires access to module state,
the type must be converted to a *heap-allocated type*, or *heap type*
for short. These correspond more closely to classes created by Python's
``class`` statement.

For new modules, using heap types by default is a good rule of thumb.


Changing Static Types to Heap Types
-----------------------------------

Static types can be converted to heap types, but note that
the heap type API was not designed for "lossless" conversion
from static types—that is, creating a type that works exactly like a given
static type.
So, when rewriting the class definition in a new API,
you are likely to unintentionally change a few details (e.g. pickleability
or inherited slots).
Always test the details that are important to you.

Watch out for the following two points in particular (but note that this is not
a comprehensive list):

* Unlike static types, heap type objects are mutable by default.
  Use the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability.
* Heap types inherit :c:member:`~PyTypeObject.tp_new` by default,
  so it may become possible to instantiate them from Python code.
  You can prevent this with the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag.


Defining Heap Types
-------------------

Heap types can be created by filling a :c:struct:`PyType_Spec` structure, a
description or "blueprint" of a class, and calling
:c:func:`PyType_FromModuleAndSpec` to construct a new class object.

.. note::
   Other functions, like :c:func:`PyType_FromSpec`, can also create
   heap types, but :c:func:`PyType_FromModuleAndSpec` associates the module
   with the class, allowing access to the module state from methods.

The class should generally be stored in *both* the module state (for
safe access from C) and the module's ``__dict__`` (for access from
Python code).


Garbage-Collection Protocol
---------------------------

Instances of heap types hold a reference to their type.
This ensures that the type isn't destroyed before all its instances are,
but may result in reference cycles that need to be broken by the
garbage collector.

To avoid memory leaks, instances of heap types must implement the
garbage collection protocol.
That is, heap types should:

- Have the :c:macro:`Py_TPFLAGS_HAVE_GC` flag.
- Define a traverse function using :c:data:`Py_tp_traverse`, which
  visits the type (e.g. using ``Py_VISIT(Py_TYPE(self))``).

Please refer to the documentation of
:c:macro:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse`
for additional considerations.

The API for defining heap types grew organically, leaving it
somewhat awkward to use in its current state.
The following sections will guide you through common issues.


``tp_traverse`` in Python 3.8 and lower
.......................................

The requirement to visit the type from ``tp_traverse`` was added in Python 3.9.
If you support Python 3.8 and lower, the traverse function must *not*
visit the type, so it must be more complicated::

   static int my_traverse(PyObject *self, visitproc visit, void *arg)
   {
       if (Py_Version >= 0x03090000) {
           Py_VISIT(Py_TYPE(self));
       }
       return 0;
   }

Unfortunately, :c:data:`Py_Version` was only added in Python 3.11.
As a replacement, use:

* :c:macro:`PY_VERSION_HEX`, if not using the stable ABI, or
* :py:data:`sys.version_info` (via :c:func:`PySys_GetObject` and
  :c:func:`PyArg_ParseTuple`).


Delegating ``tp_traverse``
..........................

If your traverse function delegates to the :c:member:`~PyTypeObject.tp_traverse`
of its base class (or another type), ensure that ``Py_TYPE(self)`` is visited
only once.
Note that only heap type are expected to visit the type in ``tp_traverse``.

For example, if your traverse function includes::

   base->tp_traverse(self, visit, arg)

...and ``base`` may be a static type, then it should also include::

    if (base->tp_flags & Py_TPFLAGS_HEAPTYPE) {
        // a heap type's tp_traverse already visited Py_TYPE(self)
    } else {
        if (Py_Version >= 0x03090000) {
            Py_VISIT(Py_TYPE(self));
        }
    }

It is not necessary to handle the type's reference count in
:c:member:`~PyTypeObject.tp_new` and :c:member:`~PyTypeObject.tp_clear`.


Defining ``tp_dealloc``
.......................

If your type has a custom :c:member:`~PyTypeObject.tp_dealloc` function,
it needs to:

- call :c:func:`PyObject_GC_UnTrack` before any fields are invalidated, and
- decrement the reference count of the type.

To keep the type valid while ``tp_free`` is called, the type's refcount needs
to be decremented *after* the instance is deallocated. For example::

   static void my_dealloc(PyObject *self)
   {
       PyObject_GC_UnTrack(self);
       ...
       PyTypeObject *type = Py_TYPE(self);
       type->tp_free(self);
       Py_DECREF(type);
   }

The default ``tp_dealloc`` function does this, so
if your type does *not* override
``tp_dealloc`` you don't need to add it.


Not overriding ``tp_free``
..........................

The :c:member:`~PyTypeObject.tp_free` slot of a heap type must be set to
:c:func:`PyObject_GC_Del`.
This is the default; do not override it.


Avoiding ``PyObject_New``
.........................

GC-tracked objects need to be allocated using GC-aware functions.

If you use :c:func:`PyObject_New` or :c:func:`PyObject_NewVar`:

- Get and call type's :c:member:`~PyTypeObject.tp_alloc` slot, if possible.
  That is, replace ``TYPE *o = PyObject_New(TYPE, typeobj)`` with::

      TYPE *o = typeobj->tp_alloc(typeobj, 0);

  Replace ``o = PyObject_NewVar(TYPE, typeobj, size)`` with the same,
  but use size instead of the 0.

- If the above is not possible (e.g. inside a custom ``tp_alloc``),
  call :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`::

      TYPE *o = PyObject_GC_New(TYPE, typeobj);

      TYPE *o = PyObject_GC_NewVar(TYPE, typeobj, size);


Module State Access from Classes
--------------------------------

If you have a type object defined with :c:func:`PyType_FromModuleAndSpec`,
you can call :c:func:`PyType_GetModule` to get the associated module, and then
:c:func:`PyModule_GetState` to get the module's state.

To save a some tedious error-handling boilerplate code, you can combine
these two steps with :c:func:`PyType_GetModuleState`, resulting in::

   my_struct *state = (my_struct*)PyType_GetModuleState(type);
   if (state == NULL) {
       return NULL;
   }


Module State Access from Regular Methods
----------------------------------------

Accessing the module-level state from methods of a class is somewhat more
complicated, but is possible thanks to API introduced in Python 3.9.
To get the state, you need to first get the *defining class*, and then
get the module state from it.

The largest roadblock is getting *the class a method was defined in*, or
that method's "defining class" for short. The defining class can have a
reference to the module it is part of.

Do not confuse the defining class with ``Py_TYPE(self)``. If the method
is called on a *subclass* of your type, ``Py_TYPE(self)`` will refer to
that subclass, which may be defined in different module than yours.

.. note::
   The following Python code can illustrate the concept.
   ``Base.get_defining_class`` returns ``Base`` even
   if ``type(self) == Sub``:

   .. code-block:: python

      class Base:
          def get_type_of_self(self):
              return type(self)

          def get_defining_class(self):
              return __class__

      class Sub(Base):
          pass

For a method to get its "defining class", it must use the
:ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS <METH_METHOD-METH_FASTCALL-METH_KEYWORDS>`
:c:type:`calling convention <PyMethodDef>`
and the corresponding :c:type:`PyCMethod` signature::

   PyObject *PyCMethod(
       PyObject *self,               // object the method was called on
       PyTypeObject *defining_class, // defining class
       PyObject *const *args,        // C array of arguments
       Py_ssize_t nargs,             // length of "args"
       PyObject *kwnames)            // NULL, or dict of keyword arguments

Once you have the defining class, call :c:func:`PyType_GetModuleState` to get
the state of its associated module.

For example::

   static PyObject *
   example_method(PyObject *self,
           PyTypeObject *defining_class,
           PyObject *const *args,
           Py_ssize_t nargs,
           PyObject *kwnames)
   {
       my_struct *state = (my_struct*)PyType_GetModuleState(defining_class);
       if (state == NULL) {
           return NULL;
       }
       ... // rest of logic
   }

   PyDoc_STRVAR(example_method_doc, "...");

   static PyMethodDef my_methods[] = {
       {"example_method",
         (PyCFunction)(void(*)(void))example_method,
         METH_METHOD|METH_FASTCALL|METH_KEYWORDS,
         example_method_doc}
       {NULL},
   }


Module State Access from Slot Methods, Getters and Setters
----------------------------------------------------------

.. note::

   This is new in Python 3.11.

   .. After adding to limited API:

      If you use the :ref:`limited API <limited-c-api>`,
      you must update ``Py_LIMITED_API`` to ``0x030b0000``, losing ABI
      compatibility with earlier versions.

Slot methods—the fast C equivalents for special methods, such as
:c:member:`~PyNumberMethods.nb_add` for :py:attr:`~object.__add__` or
:c:member:`~PyTypeObject.tp_new` for initialization—have a very simple API that
doesn't allow passing in the defining class, unlike with :c:type:`PyCMethod`.
The same goes for getters and setters defined with
:c:type:`PyGetSetDef`.

To access the module state in these cases, use the
:c:func:`PyType_GetModuleByDef` function, and pass in the module definition.
Once you have the module, call :c:func:`PyModule_GetState`
to get the state::

    PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &module_def);
    my_struct *state = (my_struct*)PyModule_GetState(module);
    if (state == NULL) {
        return NULL;
    }

:c:func:`!PyType_GetModuleByDef` works by searching the
:term:`method resolution order` (i.e. all superclasses) for the first
superclass that has a corresponding module.

.. note::

   In very exotic cases (inheritance chains spanning multiple modules
   created from the same definition), :c:func:`!PyType_GetModuleByDef` might not
   return the module of the true defining class. However, it will always
   return a module with the same definition, ensuring a compatible
   C memory layout.


Lifetime of the Module State
----------------------------

When a module object is garbage-collected, its module state is freed.
For each pointer to (a part of) the module state, you must hold a reference
to the module object.

Usually this is not an issue, because types created with
:c:func:`PyType_FromModuleAndSpec`, and their instances, hold a reference
to the module.
However, you must be careful in reference counting when you reference
module state from other places, such as callbacks for external
libraries.


Open Issues
===========

Several issues around per-module state and heap types are still open.

Discussions about improving the situation are best held on the `discuss forum under c-api tag <https://discuss.python.org/c/core-dev/c-api/30>`__.


Per-Class Scope
---------------

It is currently (as of Python 3.11) not possible to attach state to individual
*types* without relying on CPython implementation details (which may change
in the future—perhaps, ironically, to allow a proper solution for
per-class scope).


Lossless Conversion to Heap Types
---------------------------------

The heap type API was not designed for "lossless" conversion from static types;
that is, creating a type that works exactly like a given static type.
