@@ -26,6 +26,10 @@ To make this viable, we also specify new module slot types to replace
2626
2727We also add an API for defining modules from slots dynamically.
2828
29+ The existing API (``PyInit_* ``) is soft-deprecated.
30+ (That is: it will continue to work without warnings, and it'll fe fully
31+ documented and supported, but we plan to not add any new features to it.)
32+
2933
3034Background & Motivation
3135=======================
@@ -147,6 +151,27 @@ Unlike types, the import mechanism often has a pointer that's known to be
147151suitable as a token value; in these cases it can provide a default token.
148152Thus, module tokens do not need a variant of the inelegant ``Py_TP_USE_SPEC ``.
149153
154+ To help extensions that straddle Python versions, ``PyModuleDef `` addresses
155+ are used as default tokens, and where it's reasonable, they are made
156+ interchangeable with tokens.
157+
158+
159+ Soft-deprecating the existing export hook
160+ -----------------------------------------
161+
162+ The only reason for authors of *existing * extensions to switch to the
163+ API proposed here is that it allows a single module for both free-threaded
164+ and non-free-threaded builds.
165+ It is important that Python *allows * that, but for many existing modules,
166+ it is nowhere near worth losing compatibility with 3.14 and lower versions.
167+
168+ It is much too early to plan deprecation of the old API.
169+
170+ Instead, this PEP proposes to stop adding new features to the ``PyInit_* ``
171+ scheme.
172+ After all, the perfect time for extension authors to switch is when they want
173+ to modify module initialization anyway.
174+
150175
151176Specification
152177=============
@@ -264,6 +289,10 @@ If specified, using a new ``Py_mod_token`` slot, the module token must:
264289
265290(Typically, it should point to a static constant.)
266291
292+ When the address of a ``PyModuleDef `` is used as as a module's token,
293+ the module should behave as if it was created from that ``PyModuleDef ``.
294+ In particular, the module state must have matching layout and semantics.
295+
267296Modules created using the ``PyModule_FromSlotsAndSpec `` or the
268297``PyModExport_<NAME> `` export hook can use a new ``Py_mod_token `` slot
269298to set the token.
@@ -288,8 +317,15 @@ will return 0 on success and -1 on failure:
288317 int PyModule_GetToken(PyObject *, void **token_p)
289318
290319 A new ``PyType_GetModuleByToken `` function will be added, with a signature
291- like ``PyType_GetModuleByDef `` but a ``void *token `` argument,
292- and the same behaviour except matching tokens, rather than only defs.
320+ like the existing ``PyType_GetModuleByDef `` but a ``void *token `` argument,
321+ and the same behaviour except matching tokens rather than only defs.
322+
323+ For easier backwards compatibility, the existing ``PyType_GetModuleByDef ``
324+ will be changed to work exactly like ``PyType_GetModuleByToken `` -- that is,
325+ it will allow a token (cast to a ``PyModuleDef * `` pointer) as the
326+ *def * argument.
327+ (The ``PyModule_GetDef `` function will not get a similar change, as users may
328+ access members of its result.)
293329
294330
295331New slots
@@ -333,6 +369,14 @@ via a pointer; the function will return 0 on success and -1 on failure:
333369 int PyModule_GetStateSize(PyObject *, Py_ssize_t *result);
334370
335371
372+ Soft-deprecating the existing export hook
373+ -----------------------------------------
374+
375+ The ``PyInit_* `` export hook will be
376+ :ref: `soft-deprecated <pep387-soft-deprecation >`.
377+
378+
379+
336380.. _pep793-api-summary :
337381
338382New API summary
@@ -383,9 +427,14 @@ If an existing module is ported to use the new mechanism, then
383427We claim that how a module was defined is an implementation detail of that
384428module, so this should not be considered a breaking change.
385429
386- Similarly, ``PyType_GetModuleByDef `` will not match modules that are not
387- defined using a *def *.
388- The new ``PyType_GetModuleByToken `` function may be used instead.
430+ Similarly, the ``PyType_GetModuleByDef `` function may stop matching modules
431+ whose definition changed. Module authors may avoid this by explicitly
432+ explicitly setting a *def * as the *token *.
433+
434+ ``PyType_GetModuleByDef `` will now accept a module token as the *def * argument.
435+ We specify a suitable restriction on using ``PyModuleDef `` addresses as tokens,
436+ and non-``PyModuleDef `` pointers were previously invalid input,
437+ so this is not a backwards-compatibility issue.
389438
390439The ``Py_mod_create `` function may now be called with ``NULL `` for the second
391440argument.
@@ -428,11 +477,15 @@ wrappers, the :ref:`pep793-shim` below may be more useful.
428477 Later in this guide, you'll set the token to *be * the existing
429478 ``PyModuleDef `` structure.
430479
431- #. Scan your code for uses of ``PyType_GetModuleByDef ``, and replace them by
432- ``PyType_GetModuleByToken ``.
480+ #. Optionally, scan your code for uses of ``PyType_GetModuleByDef ``,
481+ and replace them by ``PyType_GetModuleByToken ``.
433482 Later in this guide, you'll set the token to *be * the existing
434483 ``PyModuleDef `` structure.
435484
485+ (You may skip this step if targetting Python versions that don't expose
486+ ``PyType_GetModuleByToken ``, since ``PyType_GetModuleByDef `` is
487+ backwards-compatible. )
488+
436489#. Look at the function identified by ``Py_mod_create ``, if any.
437490 Make sure that it does not use its second argument (``PyModuleDef ``),
438491 as it will be called with ``NULL ``.
@@ -467,18 +520,17 @@ wrappers, the :ref:`pep793-shim` below may be more useful.
467520 };
468521
469522 #. If you switched from ``PyModule_GetDef `` to ``PyModule_GetToken ``,
470- and/or from ``PyType_GetModuleByDef `` to ``PyType_GetModuleByToken ``,
523+ and/or if you use ``PyType_GetModuleByDef `` or ``PyType_GetModuleByToken ``,
471524 add a ``Py_mod_token `` slot pointing to the existing ``PyModuleDef `` struct:
472525
473526 .. code-block :: c
474527
475528 static PyModuleDef_Slot module_slots[] = {
476529 // ... (keep existing slots here)
477- {Py_mod_token, your_module_def},
530+ {Py_mod_token, & your_module_def},
478531 {0}
479532 };
480533
481-
482534 #. Add a new export hook.
483535
484536 .. code-block :: c
@@ -492,31 +544,43 @@ wrappers, the :ref:`pep793-shim` below may be more useful.
492544 }
493545
494546 The new export hook will be used on Python 3.15 and above.
495- Once your module no longer supports lower versions, delete the ``PyInit_ ``
496- function and any unused data.
547+ Once your module no longer supports lower versions:
497548
549+ #. Delete the ``PyInit_ `` function.
550+
551+ #. If the existing ``PyModuleDef `` struct is used *only * for ``Py_mod_token ``
552+ and/or ``PyType_GetModuleByToken ``, you may remove the ``Py_mod_token ``
553+ line and replace ``&your_module_def `` by ``module_slots `` everywhere else.
554+
555+ #. Delete any unused data.
556+ The ``PyModuleDef `` struct and the original slots array are likely to be
557+ unused.
558+
559+
560+ .. _pep793-shim :
498561
499562Backwards compatibility shim
500563----------------------------
501564
502- It is possible to write generic function that implements the existing export
565+ It is possible to write generic function that implements the “old” export
503566hook (``PyInit_ ``) in terms of the API proposed here.
504567
505- The following implemntation can be copy-pasted; only the names
506- ``PyInit_examplemodule `` (twice) and ``PyModExport_examplemodule `` need adjusting.
568+ The following implementation can be copied and pasted to a project; only the
569+ names ``PyInit_examplemodule `` (twice) and ``PyModExport_examplemodule `` should
570+ need adjusting.
507571
508572When added to the :ref: `pep793-example ` below and compiled with a
509573non-free-threaded build of this PEP's reference implementation, the resulting
510- extension is compatible with regular builds 3.9+ in addition to a
574+ extension is compatible with non-free-threading 3.9+ builds, in addition to a
511575free-threading build of the reference implementation.
512576(The module must be named without a version tag, e.g. ``examplemodule.so ``,
513577and be placed on ``sys.path ``.)
514578
515579Full support for creating such modules will require backports of some new
516580API, and support in build/install tools. This is out of scope of this PEP.
517- (In particular, the demo “cheats” uses a subset Limited API 3.15 that
518- *happens to work * on 3.9; it * should * use Limited API 3.9 with backport
519- shims for new API like ``Py_mod_name ``.)
581+ (In particular, the demo “cheats” by using a subset of Limited API 3.15 that
582+ *happens to work * on 3.9; a proper implementation would use Limited API 3.9
583+ with backport shims for new API like ``Py_mod_name ``.)
520584
521585This implementation places a few additional requirements on the slots array:
522586
@@ -589,6 +653,7 @@ Possible Future Directions
589653
590654These ideas are out of scope for *this * proposal.
591655
656+
592657Improving slots in general
593658--------------------------
594659
0 commit comments