Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
GH-134160: Prefer multi-phase initialisation in docs#134764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -137,9 +137,15 @@ | ||
(where the initialization function is added using :c:func:`PyImport_AppendInittab`). | ||
See :ref:`building` or :ref:`extending-with-embedding` for details. | ||
To perform ':ref:`multi-phase initialization <multi-phase-initialization>`' | ||
(:pep:`489`), the initialization function must return a pointer to the | ||
:c:type:`module definition struct <PyModuleDef>`. | ||
This allows Python to determine which capabilities the module supports *before* | ||
it is executed, as creation and initialization are split, | ||
similarly to the :py:meth:`!__new__` and :py:meth:`!__init__` on classes. | ||
The legacy method (prior to Python 3.5) to specify an extension module is | ||
':ref:`single-phase initialization <single-phase-initialization>`'. | ||
.. c:type:: PyModuleDef | ||
@@ -189,7 +195,7 @@ | ||
An array of slot definitions for multi-phase initialization, terminated by | ||
a ``{0, NULL}`` entry. | ||
When usinglegacysingle-phase initialization, *m_slots* must be ``NULL``. | ||
.. versionchanged:: 3.5 | ||
@@ -249,52 +255,22 @@ | ||
.. versionchanged:: 3.9 | ||
No longer called before the module state is allocated. | ||
.. _multi-phase-initialization: | ||
Multi-phase initialization | ||
.......................... | ||
The preferred method 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:`!__new__` and :py:meth:`!__init__` methods | ||
of classes. | ||
Unlike modules created usingthe legacysingle-phase initialization mechanism, | ||
these modules are notsingletons: if the *sys.modules* entry is removed and | ||
the module is re-imported,a new module object is created, and the old module | ||
is subject to normal garbagecollection -- as with Python modules. | ||
Comment on lines -287 to +273 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I think this shouldn't be a comparison. If we're calling single-phase “legacy” (which finallyseems to be the cunsensus), then this section should describe what modulesare, and the single-phase section should describe the eldritch weirdness of that method. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. There is existing mention of single-phase as 'legacy', though admittedly in a niche location:https://docs.python.org/3/c-api/init.html#c.PyInterpreterConfig.check_multi_interp_extensions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more.
@encukou feel free to push to this branch. | ||
By default, multiple modules created from the same definition should be | ||
independent: changes to one should not affect the others. | ||
This means that all state should be specific to the module object (using e.g. | ||
@@ -320,7 +296,12 @@ | ||
.. versionadded:: 3.5 | ||
The *m_slots* member of the module definition must point to an array of | ||
:c:type:`PyModuleDef_Slot` structures, terminated by a slot with id 0. | ||
See :PEP:`489` for more details on multi-phase initialization. | ||
Module slots | ||
............ | ||
.. c:type:: PyModuleDef_Slot | ||
@@ -334,8 +315,6 @@ | ||
.. versionadded:: 3.5 | ||
The available slot types are: | ||
.. c:macro:: Py_mod_create | ||
@@ -446,7 +425,43 @@ | ||
.. versionadded:: 3.13 | ||
.. _single-phase-initialization: | ||
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. | ||
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, returning the resulting | ||
module object: | ||
.. 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`. | ||
Low-level module creation functions | ||
................................... | ||
@@ -677,8 +692,8 @@ | ||
.. versionadded:: 3.13 | ||
Module lookup (single-phase initialization) | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Single-phase initialization creates singleton modules that can be looked up | ||
in the context of the current interpreter. This allows the module object to be | ||
Uh oh!
There was an error while loading.Please reload this page.