1
1
PEP: 793
2
2
Title: PyModExport: A new entry point for C extension modules
3
3
Author: Petr Viktorin <encukou@gmail.com>
4
- Discussions-To: https://discuss.python.org/t/84498
4
+ Discussions-To: Pending
5
5
Status: Draft
6
6
Type: Standards Track
7
7
Created: 23-May-2025
8
8
Python-Version: 3.15
9
- Post-History: 23-May -2025
9
+ Post-History: ` 14-Mar -2025 < https://discuss.python.org/t/84498/ >`__,
10
10
11
11
12
12
Abstract
@@ -23,7 +23,7 @@ To make this viable, we also specify new module slot types to replace
23
23
``PyModuleDef ``'s fields, and to allow adding a *token * similar to the
24
24
``Py_tp_token `` used for type objects.
25
25
26
- We also add API for defining modules from slots dynamically.
26
+ We also add an API for defining modules from slots dynamically.
27
27
28
28
29
29
Background & Motivation
@@ -36,7 +36,7 @@ the current ``PyObject`` memory layout. To stay compatible with existing ABI
36
36
(and API), it cannot support statically allocated Python objects.
37
37
38
38
There is one type of object that is needed in most extension modules
39
- and is allocated statically in virtually cases: the ``PyModuleDef `` returned
39
+ and is allocated statically in virtually all cases: the ``PyModuleDef `` returned
40
40
from the module export hooks (that is, ``PyInit_* `` functions).
41
41
42
42
Module export hooks (``PyInit_* `` functions) can return two kinds of objects:
@@ -48,12 +48,12 @@ Module export hooks (``PyInit_*`` functions) can return two kinds of objects:
48
48
(Specifically, the *contents * of such a module's ``__dict__ `` are shared
49
49
across all instances of the module object.)
50
50
51
- The modules to return is typically created using the ``PyModule_Create ``
51
+ The module returned is typically created using the ``PyModule_Create ``
52
52
function, which requires a statically allocated (or at least long-lived)
53
53
``PyModuleDef `` struct.
54
54
55
55
It is possible to bypass this using the lower-level ``PyModule_New* `` API.
56
- This does not need ``PyModuleDef ``, but offers much less functionality.
56
+ This avoids the need for ``PyModuleDef ``, but offers much less functionality.
57
57
58
58
2. A ``PyModuleDef `` object containing a description of how to create a module
59
59
object. This option, *multi-phase initialization *, was introduced in
@@ -118,13 +118,13 @@ Python can check whether the module is compatible.
118
118
Using slots without a wrapper struct
119
119
------------------------------------
120
120
121
- The existing ``PyModuleDef `` is struct with some fixed fields and
121
+ The existing ``PyModuleDef `` is a struct with some fixed fields and
122
122
a “slots” array.
123
123
Unlike slots, the fixed fields cannot be individually deprecated and replaced.
124
124
This proposal does away with fixed fields and proposes using a slots array
125
125
directly, without a wrapper struct.
126
126
127
- The ``PyModuleDef_Slot `` struct does have some downsides to fixed fields.
127
+ The ``PyModuleDef_Slot `` struct does have some downsides compared to fixed fields.
128
128
We believe these are fixable, but leave that out of scope of this PEP
129
129
(see “Improving slots in general” in the Possible Future Directions section).
130
130
@@ -144,14 +144,14 @@ This proposal adds the same mechanism to modules.
144
144
145
145
Unlike types, the import mechanism often has a pointer that's known to be
146
146
suitable as a token value; in these cases it can provide a default token.
147
- Thus, module tokens do not need a varaint of the inelegant ``Py_TP_USE_SPEC ``.
147
+ Thus, module tokens do not need a variant of the inelegant ``Py_TP_USE_SPEC ``.
148
148
149
149
150
150
Specification
151
151
=============
152
152
153
153
154
- When importing an extension module, Python will newly look for an export hook
154
+ When importing an extension module, Python will now first look for an export hook
155
155
like this:
156
156
157
157
.. code-block :: c
@@ -201,9 +201,8 @@ A new function will be added to create a module from an array of slots:
201
201
202
202
The *slots * argument must point to an array of ``PyModuleDef_Slot `` structures,
203
203
terminated by a slot with ``slot=0 `` (typically written as ``{0} `` in C).
204
- There are no required slots.
205
- (So, the minimal input contains only the terminator; *slots * may not be
206
- ``NULL ``.)
204
+ There are no required slots, though *slots * must not be ``NULL ``.
205
+ It follows that minimal input contains only the terminator slot.
207
206
208
207
The *spec * argument is a duck-typed ModuleSpec-like object, meaning that any
209
208
attributes defined for ``importlib.machinery.ModuleSpec `` have matching
@@ -230,9 +229,9 @@ As an exception, any ``PyMethodDef`` array given by ``Py_mod_methods``
230
229
must be statically allocated (or be otherwise guaranteed to outlive the
231
230
objects created from it). This limitation may be lifted in the future.
232
231
233
- A new function will be added to run the ``exec `` slot(s) for a module -- like
234
- ``PyModule_ExecDef ``, but supporting modules created using slots,
235
- and not taking an explicit *def *:
232
+ A new function, `` PyModule_Exec ``, will be added to run the ``exec `` slot(s) for a module.
233
+ This acts like ``PyModule_ExecDef ``, but supports modules created using slots,
234
+ and does not take an explicit *def *:
236
235
237
236
.. code-block :: c
238
237
@@ -254,15 +253,16 @@ similar to ``Py_tp_token`` for types.
254
253
255
254
If specified, using a new ``Py_mod_token `` slot, the module token must:
256
255
257
- - outlive the module, so it’ s not reused for something else while the module
256
+ - outlive the module, so it' s not reused for something else while the module
258
257
exists; and
259
- - “ belong” to the extension module where the module lives, so it will not
260
- clash with other extensions .
258
+ - " belong" to the extension module where the module lives, so it will not
259
+ clash with other extension modules .
261
260
262
261
(Typically, it should point to a static constant.)
263
262
264
- Modules created using the new ``PyModule_FromSlotsAndSpec `` or the new
265
- export hook can use a slot with a new ID, ``Py_mod_token ``, to set the token.
263
+ Modules created using the ``PyModule_FromSlotsAndSpec `` or the
264
+ ``PyModExport_<NAME> `` export hook can use a new ``Py_mod_token `` slot
265
+ to set the token.
266
266
267
267
Modules created from a ``PyModuleDef `` will have the token set to that
268
268
definition. An explicit ``Py_mod_token `` slot will we rejected for these.
@@ -435,7 +435,7 @@ Improving slots in general
435
435
Slots -- and specifically the existing ``PyModuleDef_Slot `` -- do have a few
436
436
shortcomings. The most important are:
437
437
438
- - Type safety: ``void * `` is used for data poiners , function pointers
438
+ - Type safety: ``void * `` is used for data pointers , function pointers
439
439
and small integers, requiring casting that is technically undefined
440
440
behaviour in C -- but works in practice on all relevant architectures.
441
441
(For example: ``Py_tp_doc `` marks a string; ``Py_mod_gil `` an integer.)
@@ -468,7 +468,6 @@ The inittab is used for embedding, where a common/stable ABI is not that
468
468
important. So, it might be OK to leave this to a later change.
469
469
470
470
471
-
472
471
Copyright
473
472
=========
474
473
0 commit comments