[3.14] gh-134160: Split extension module init from PyModule docs; emphasize multi-phase init (GH-135126) (#135470)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2025-06-16 17:01:09 +02:00 committed by GitHub
parent 941011374a
commit 0e0ad7b8ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 387 additions and 210 deletions

View file

@ -0,0 +1,247 @@
.. highlight:: c
.. _extension-modules:
Defining extension modules
--------------------------
A C extension for CPython is a shared library (for example, a ``.so`` file
on Linux, ``.pyd`` DLL on Windows), which is loadable into the Python process
(for example, it is compiled with compatible compiler settings), and which
exports an :ref:`initialization function <extension-export-hook>`.
To be importable by default (that is, by
:py:class:`importlib.machinery.ExtensionFileLoader`),
the shared library must be available on :py:attr:`sys.path`,
and must be named after the module name plus an extension listed in
:py:attr:`importlib.machinery.EXTENSION_SUFFIXES`.
.. note::
Building, packaging and distributing extension modules is best done with
third-party tools, and is out of scope of this document.
One suitable tool is Setuptools, whose documentation can be found at
https://setuptools.pypa.io/en/latest/setuptools.html.
Normally, the initialization function returns a module definition initialized
using :c:func:`PyModuleDef_Init`.
This allows splitting the creation process into several phases:
- Before any substantial code is executed, Python can determine which
capabilities the module supports, and it can adjust the environment or
refuse loading an incompatible extension.
- By default, Python itself creates the module object -- that is, it does
the equivalent of :py:meth:`object.__new__` for classes.
It also sets initial attributes like :attr:`~module.__package__` and
:attr:`~module.__loader__`.
- Afterwards, the module object is initialized using extension-specific
code -- the equivalent of :py:meth:`~object.__init__` on classes.
This is called *multi-phase initialization* to distinguish it from the legacy
(but still supported) *single-phase initialization* scheme,
where the initialization function returns a fully constructed module.
See the :ref:`single-phase-initialization section below <single-phase-initialization>`
for details.
.. versionchanged:: 3.5
Added support for multi-phase initialization (:pep:`489`).
Multiple module instances
.........................
By default, extension modules are not singletons.
For example, if the :py:attr:`sys.modules` entry is removed and the module
is re-imported, a new module object is created, and typically populated with
fresh method and type objects.
The old module is subject to normal garbage collection.
This mirrors the behavior of pure-Python modules.
Additional module instances may be created in
:ref:`sub-interpreters <sub-interpreter-support>`
or after Python runtime reinitialization
(:c:func:`Py_Finalize` and :c:func:`Py_Initialize`).
In these cases, sharing Python objects between module instances would likely
cause crashes or undefined behavior.
To avoid such issues, each instance of an extension module should
be *isolated*: changes to one instance should not implicitly affect the others,
and all state owned by the module, including references to Python objects,
should be specific to a particular module instance.
See :ref:`isolating-extensions-howto` for more details and a practical guide.
A simpler way to avoid these issues is
:ref:`raising an error on repeated initialization <isolating-extensions-optout>`.
All modules are expected to support
:ref:`sub-interpreters <sub-interpreter-support>`, or otherwise explicitly
signal a lack of support.
This is usually achieved by isolation or blocking repeated initialization,
as above.
A module may also be limited to the main interpreter using
the :c:data:`Py_mod_multiple_interpreters` slot.
.. _extension-export-hook:
Initialization function
.......................
The initialization function defined by an extension module has the
following signature:
.. c:function:: PyObject* PyInit_modulename(void)
Its name should be :samp:`PyInit_{<name>}`, with ``<name>`` replaced by the
name of the module.
For modules with ASCII-only names, the function must instead be named
:samp:`PyInit_{<name>}`, with ``<name>`` replaced by the name of the module.
When using :ref:`multi-phase-initialization`, non-ASCII module names
are allowed. In this case, the initialization function name is
:samp:`PyInitU_{<name>}`, with ``<name>`` encoded using Python's
*punycode* encoding with hyphens replaced by underscores. In Python:
.. code-block:: python
def initfunc_name(name):
try:
suffix = b'_' + name.encode('ascii')
except UnicodeEncodeError:
suffix = b'U_' + name.encode('punycode').replace(b'-', b'_')
return b'PyInit' + suffix
It is recommended to define the initialization function using a helper macro:
.. c:macro:: PyMODINIT_FUNC
Declare an extension module initialization function.
This macro:
* specifies the :c:expr:`PyObject*` return type,
* adds any special linkage declarations required by the platform, and
* for C++, declares the function as ``extern "C"``.
For example, a module called ``spam`` would be defined like this::
static struct PyModuleDef spam_module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "spam",
...
};
PyMODINIT_FUNC
PyInit_spam(void)
{
return PyModuleDef_Init(&spam_module);
}
It is possible to export multiple modules from a single shared library by
defining multiple initialization functions. However, importing them requires
using symbolic links or a custom importer, because by default only the
function corresponding to the filename is found.
See the `Multiple modules in one library <https://peps.python.org/pep-0489/#multiple-modules-in-one-library>`__
section in :pep:`489` for details.
The initialization function is typically the only non-\ ``static``
item defined in the module's C source.
.. _multi-phase-initialization:
Multi-phase initialization
..........................
Normally, the :ref:`initialization function <extension-export-hook>`
(``PyInit_modulename``) returns a :c:type:`PyModuleDef` instance with
non-``NULL`` :c:member:`~PyModuleDef.m_slots`.
Before it is returned, the ``PyModuleDef`` instance must be initialized
using the following function:
.. c:function:: PyObject* PyModuleDef_Init(PyModuleDef *def)
Ensure a module definition is a properly initialized Python object that
correctly reports its type and a reference count.
Return *def* cast to ``PyObject*``, or ``NULL`` if an error occurred.
Calling this function is required for :ref:`multi-phase-initialization`.
It should not be used in other contexts.
Note that Python assumes that ``PyModuleDef`` structures are statically
allocated.
This function may return either a new reference or a borrowed one;
this reference must not be released.
.. versionadded:: 3.5
.. _single-phase-initialization:
Legacy single-phase initialization
..................................
.. attention::
Single-phase initialization is a legacy mechanism to initialize extension
modules, with known drawbacks and design flaws. Extension module authors
are encouraged to use multi-phase initialization instead.
In single-phase initialization, the
:ref:`initialization function <extension-export-hook>` (``PyInit_modulename``)
should create, populate and return a module object.
This is typically done using :c:func:`PyModule_Create` and functions like
:c:func:`PyModule_AddObjectRef`.
Single-phase initialization differs from the :ref:`default <multi-phase-initialization>`
in the following ways:
* Single-phase modules are, or rather *contain*, “singletons”.
When the module is first initialized, Python saves the contents of
the module's ``__dict__`` (that is, typically, the module's functions and
types).
For subsequent imports, Python does not call the initialization function
again.
Instead, it creates a new module object with a new ``__dict__``, and copies
the saved contents to it.
For example, given a single-phase module ``_testsinglephase``
[#testsinglephase]_ that defines a function ``sum`` and an exception class
``error``:
.. code-block:: python
>>> import sys
>>> import _testsinglephase as one
>>> del sys.modules['_testsinglephase']
>>> import _testsinglephase as two
>>> one is two
False
>>> one.__dict__ is two.__dict__
False
>>> one.sum is two.sum
True
>>> one.error is two.error
True
The exact behavior should be considered a CPython implementation detail.
* To work around the fact that ``PyInit_modulename`` does not take a *spec*
argument, some state of the import machinery is saved and applied to the
first suitable module created during the ``PyInit_modulename`` call.
Specifically, when a sub-module is imported, this mechanism prepends the
parent package name to the name of the module.
A single-phase ``PyInit_modulename`` function should create “its” module
object as soon as possible, before any other module objects can be created.
* Non-ASCII module names (``PyInitU_modulename``) are not supported.
* Single-phase modules support module lookup functions like
:c:func:`PyState_FindModule`.
.. [#testsinglephase] ``_testsinglephase`` is an internal module used \
in CPython's self-test suite; your installation may or may not \
include it.

View file

@ -17,6 +17,7 @@ document the API functions in detail.
veryhigh.rst
refcounting.rst
exceptions.rst
extension-modules.rst
utilities.rst
abstract.rst
concrete.rst

View file

@ -111,33 +111,11 @@ Useful macros
=============
Several useful macros are defined in the Python header files. Many are
defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`).
defined closer to where they are useful (for example, :c:macro:`Py_RETURN_NONE`,
:c:macro:`PyMODINIT_FUNC`).
Others of a more general utility are defined here. This is not necessarily a
complete listing.
.. c:macro:: PyMODINIT_FUNC
Declare an extension module ``PyInit`` initialization function. The function
return type is :c:expr:`PyObject*`. The macro declares any special linkage
declarations required by the platform, and for C++ declares the function as
``extern "C"``.
The initialization function must be named :samp:`PyInit_{name}`, where
*name* is the name of the module, and should be the only non-\ ``static``
item defined in the module file. Example::
static struct PyModuleDef spam_module = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "spam",
...
};
PyMODINIT_FUNC
PyInit_spam(void)
{
return PyModuleDef_Init(&spam_module);
}
.. c:macro:: Py_ABS(x)

View file

@ -127,25 +127,36 @@ Module Objects
unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead.
.. _initializing-modules:
.. _pymoduledef:
Initializing C modules
^^^^^^^^^^^^^^^^^^^^^^
Module definitions
------------------
Modules objects are usually created from extension modules (shared libraries
which export an initialization function), or compiled-in modules
(where the initialization function is added using :c:func:`PyImport_AppendInittab`).
See :ref:`building` or :ref:`extending-with-embedding` for details.
The functions in the previous section work on any module object, including
modules imported from Python code.
The initialization function can either pass a module definition instance
to :c:func:`PyModule_Create`, and return the resulting module object,
or request "multi-phase initialization" by returning the definition struct itself.
Modules defined using the C API typically use a *module definition*,
:c:type:`PyModuleDef` -- a statically allocated, constant “description" of
how a module should be created.
The definition is usually used to define an extension's “main” module object
(see :ref:`extension-modules` for details).
It is also used to
:ref:`create extension modules dynamically <moduledef-dynamic>`.
Unlike :c:func:`PyModule_New`, the definition allows management of
*module state* -- a piece of memory that is allocated and cleared together
with the module object.
Unlike the module's Python attributes, Python code cannot replace or delete
data stored in module state.
.. c:type:: PyModuleDef
The module definition struct, which holds all information needed to create
a module object. There is usually only one statically initialized variable
of this type for each module.
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.
.. c:member:: PyModuleDef_Base m_base
@ -170,13 +181,15 @@ or request "multi-phase initialization" by returning the definition struct itsel
and freed when the module object is deallocated, after the
:c:member:`~PyModuleDef.m_free` function has been called, if present.
Setting ``m_size`` to ``-1`` means that the module does not support
sub-interpreters, because it has global state.
Setting it 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. Non-negative ``m_size`` is required for multi-phase
initialization.
for its state.
Setting ``m_size`` to ``-1`` means that the module does not support
sub-interpreters, because it has global state.
Negative ``m_size`` is only allowed when using
:ref:`legacy single-phase initialization <single-phase-initialization>`
or when :ref:`creating modules dynamically <moduledef-dynamic>`.
See :PEP:`3121` for more details.
@ -189,7 +202,7 @@ or request "multi-phase initialization" by returning the definition struct itsel
An array of slot definitions for multi-phase initialization, terminated by
a ``{0, NULL}`` entry.
When using single-phase initialization, *m_slots* must be ``NULL``.
When using legacy single-phase initialization, *m_slots* must be ``NULL``.
.. versionchanged:: 3.5
@ -249,96 +262,9 @@ or request "multi-phase initialization" by returning the definition struct itsel
.. versionchanged:: 3.9
No longer called before the module state is allocated.
Single-phase initialization
...........................
The module initialization function may create and return the module object
directly. This is referred to as "single-phase initialization", and uses one
of the following two module creation functions:
.. c:function:: PyObject* PyModule_Create(PyModuleDef *def)
Create a new module object, given the definition in *def*. This behaves
like :c:func:`PyModule_Create2` with *module_api_version* set to
:c:macro:`PYTHON_API_VERSION`.
.. 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.
.. note::
Most uses of this function should be using :c:func:`PyModule_Create`
instead; only use this if you are sure you need it.
Before it is returned from in the initialization function, the resulting module
object is typically populated using functions like :c:func:`PyModule_AddObjectRef`.
.. _multi-phase-initialization:
Multi-phase initialization
..........................
An alternate way to specify extensions is to request "multi-phase initialization".
Extension modules created this way behave more like Python modules: the
initialization is split between the *creation phase*, when the module object
is created, and the *execution phase*, when it is populated.
The distinction is similar to the :py:meth:`~object.__new__` and
:py:meth:`~object.__init__` methods of classes.
Unlike modules created using single-phase initialization, these modules are not
singletons.
For example, if the :py:attr:`sys.modules` entry is removed and the module
is re-imported, a new module object is created, and typically populated with
fresh method and type objects.
The old module is subject to normal garbage collection.
This mirrors the behavior of pure-Python modules.
Additional module instances may be created in
:ref:`sub-interpreters <sub-interpreter-support>`
or after after Python runtime reinitialization
(:c:func:`Py_Finalize` and :c:func:`Py_Initialize`).
In these cases, sharing Python objects between module instances would likely
cause crashes or undefined behavior.
To avoid such issues, each instance of an extension module should
be *isolated*: changes to one instance should not implicitly affect the others,
and all state, including references to Python objects, should be specific to
a particular module instance.
See :ref:`isolating-extensions-howto` for more details and a practical guide.
A simpler way to avoid these issues is
:ref:`raising an error on repeated initialization <isolating-extensions-optout>`.
All modules created using multi-phase initialization are expected to support
:ref:`sub-interpreters <sub-interpreter-support>`, or otherwise explicitly
signal a lack of support.
This is usually achieved by isolation or blocking repeated initialization,
as above.
A module may also be limited to the main interpreter using
the :c:data:`Py_mod_multiple_interpreters` slot.
To request multi-phase initialization, the initialization function
(PyInit_modulename) returns a :c:type:`PyModuleDef` instance with non-empty
:c:member:`~PyModuleDef.m_slots`. Before it is returned, the ``PyModuleDef``
instance must be initialized with the following function:
.. c:function:: PyObject* PyModuleDef_Init(PyModuleDef *def)
Ensures a module definition is a properly initialized Python object that
correctly reports its type and reference count.
Returns *def* cast to ``PyObject*``, or ``NULL`` if an error occurred.
.. versionadded:: 3.5
The *m_slots* member of the module definition must point to an array of
``PyModuleDef_Slot`` structures:
Module slots
............
.. c:type:: PyModuleDef_Slot
@ -352,8 +278,6 @@ The *m_slots* member of the module definition must point to an array of
.. versionadded:: 3.5
The *m_slots* array must be terminated by a slot with id 0.
The available slot types are:
.. c:macro:: Py_mod_create
@ -464,21 +388,48 @@ The available slot types are:
.. versionadded:: 3.13
See :PEP:`489` for more details on multi-phase initialization.
Low-level module creation functions
...................................
.. _moduledef-dynamic:
The following functions are called under the hood when using multi-phase
initialization. They can be used directly, for example when creating module
objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
``PyModule_ExecDef`` must be called to fully initialize a module.
Creating extension modules dynamically
--------------------------------------
The following functions may be used to create a module outside of an
extension's :ref:`initialization function <extension-export-hook>`.
They are also used in
:ref:`single-phase initialization <single-phase-initialization>`.
.. 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)
Create a new module object, given the definition in *def* and the
ModuleSpec *spec*. This behaves like :c:func:`PyModule_FromDefAndSpec2`
with *module_api_version* set to :c:macro:`PYTHON_API_VERSION`.
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
@ -491,6 +442,10 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
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`
@ -504,35 +459,29 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and
.. versionadded:: 3.5
.. c:function:: int PyModule_SetDocString(PyObject *module, const char *docstring)
.. c:macro:: PYTHON_API_VERSION
Set the docstring for *module* to *docstring*.
This function is called automatically when creating a module from
``PyModuleDef``, using either ``PyModule_Create`` or
``PyModule_FromDefAndSpec``.
The C API version. Defined for backwards compatibility.
.. versionadded:: 3.5
Currently, this constant is not updated in new Python versions, and is not
useful for versioning. This may change in the future.
.. c:function:: int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions)
.. c:macro:: PYTHON_ABI_VERSION
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``, using either ``PyModule_Create`` or
``PyModule_FromDefAndSpec``.
Defined as ``3`` 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.
.. versionadded:: 3.5
Support functions
.................
-----------------
The module initialization function (if using single phase initialization) or
a function called from a module execution slot (if using multi-phase
initialization), can use the following functions to help initialize the module
state:
The following functions are provided to help initialize a module
state.
They are intended for a module's execution slots (: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)
@ -681,12 +630,39 @@ state:
.. 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.
.. 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``).
.. 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. If this function is not called during module initialization, the
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`.
@ -695,10 +671,11 @@ state:
.. versionadded:: 3.13
Module lookup
^^^^^^^^^^^^^
Module lookup (single-phase initialization)
...........................................
Single-phase initialization creates singleton modules that can be looked up
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.
@ -719,7 +696,8 @@ since multiple such modules can be created from a single definition.
Only effective on modules created using single-phase initialization.
Python calls ``PyState_AddModule`` automatically after importing a module,
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``.
@ -727,6 +705,9 @@ since multiple such modules can be created from a single definition.
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.

View file

@ -1492,9 +1492,6 @@ PyModule_SetDocString:int:::
PyModule_SetDocString:PyObject*:module:0:
PyModule_SetDocString:const char*:docstring::
PyModuleDef_Init:PyObject*::0:
PyModuleDef_Init:PyModuleDef*:def::
PyNumber_Absolute:PyObject*::+1:
PyNumber_Absolute:PyObject*:o:0:

View file

@ -6,41 +6,10 @@
Building C and C++ Extensions
*****************************
A C extension for CPython is a shared library (e.g. a ``.so`` file on Linux,
``.pyd`` on Windows), which exports an *initialization function*.
A C extension for CPython is a shared library (for example, a ``.so`` file on
Linux, ``.pyd`` on Windows), which exports an *initialization function*.
To be importable, the shared library must be available on :envvar:`PYTHONPATH`,
and must be named after the module name, with an appropriate extension.
When using setuptools, the correct filename is generated automatically.
The initialization function has the signature:
.. c:function:: PyObject* PyInit_modulename(void)
It returns either a fully initialized module, or a :c:type:`PyModuleDef`
instance. See :ref:`initializing-modules` for details.
.. highlight:: python
For modules with ASCII-only names, the function must be named
:samp:`PyInit_{<name>}`, with ``<name>`` replaced by the name of the module.
When using :ref:`multi-phase-initialization`, non-ASCII module names
are allowed. In this case, the initialization function name is
:samp:`PyInitU_{<name>}`, with ``<name>`` encoded using Python's
*punycode* encoding with hyphens replaced by underscores. In Python::
def initfunc_name(name):
try:
suffix = b'_' + name.encode('ascii')
except UnicodeEncodeError:
suffix = b'U_' + name.encode('punycode').replace(b'-', b'_')
return b'PyInit' + suffix
It is possible to export multiple modules from a single shared library by
defining multiple initialization functions. However, importing them requires
using symbolic links or a custom importer, because by default only the
function corresponding to the filename is found.
See the *"Multiple modules in one library"* section in :pep:`489` for details.
See :ref:`extension-modules` for details.
.. highlight:: c
@ -51,7 +20,11 @@ See the *"Multiple modules in one library"* section in :pep:`489` for details.
Building C and C++ Extensions with setuptools
=============================================
Python 3.12 and newer no longer come with distutils. Please refer to the
``setuptools`` documentation at
https://setuptools.readthedocs.io/en/latest/setuptools.html
to learn more about how build and distribute C/C++ extensions with setuptools.
Building, packaging and distributing extension modules is best done with
third-party tools, and is out of scope of this document.
One suitable tool is Setuptools, whose documentation can be found at
https://setuptools.pypa.io/en/latest/setuptools.html.
The :mod:`distutils` module, which was included in the standard library
until Python 3.12, is now maintained as part of Setuptools.