@@ -203,24 +203,32 @@ function usually raises :c:data:`PyExc_TypeError`. If you have an argument whos
203203value must be in a particular range or must satisfy other conditions,
204204:c:data: `PyExc_ValueError ` is appropriate.
205205
206- You can also define a new exception that is unique to your module. For this, you
207- usually declare a static object variable at the beginning of your file ::
206+ You can also define a new exception that is unique to your module.
207+ For this, you usually declare an object variable at in the module state ::
208208
209- static PyObject *SpamError;
209+ typedef struct {
210+ // ...
211+ PyObject *SpamError;
212+ // ...
213+ } spam_state;
210214
211215and initialize it in the module's :c:data: `Py_mod_exec ` function
212- (:c:func: `!spam_module_exec `)
213-
214- with an exception object::
216+ (:c:func: `!spam_module_exec `) with an exception object::
215217
216218 static int
217219 spam_module_exec(PyObject *m)
218220 {
219- SpamError = PyErr_NewException("spam.error", NULL, NULL);
220- if (PyModule_AddObjectRef(m, "SpamError", SpamError) < 0) {
221+ spam_state *state = PyModule_GetState(m);
222+ if (state == NULL) {
223+ return -1;
224+ }
225+ state->SpamError = PyErr_NewException("spam.error", NULL, NULL);
226+ if (state->SpamError == NULL) {
227+ return -1;
228+ }
229+ if (PyModule_AddType(m, (PyTypeObject *)state->SpamError) < 0) {
221230 return -1;
222231 }
223-
224232 return 0;
225233 }
226234
@@ -232,7 +240,7 @@ with an exception object::
232240 static struct PyModuleDef spam_module = {
233241 .m_base = PyModuleDef_HEAD_INIT,
234242 .m_name = "spam",
235- .m_size = 0, // non-negative
243+ .m_size = sizeof(spam_state),
236244 .m_slots = spam_module_slots,
237245 };
238246
@@ -436,18 +444,20 @@ optionally followed by an import of the module::
436444
437445.. note ::
438446
439- If you declare a global variable or a local static one, the module can
440- cause the same problems as the legacy single-phase initialization when
447+ If you declare a global variable or a local static one, the module may
448+ experience unintended side-effects on re-initialisation, for example when
441449 removing entries from ``sys.modules `` or importing compiled modules into
442- multiple interpreters within a process (or following a :c:func: `fork ` without an
443- intervening :c:func: `exec `). In this case, at least the module should
444- stop supporting subinterpreters through a :c:type: `PyModuleDef_Slot `
445- (:c:data: `Py_mod_multiple_interpreters `).
450+ multiple interpreters within a process
451+ (or following a :c:func: `fork ` without an intervening :c:func: `exec `).
452+ If module state is not yet fully :ref: `isolated <isolating-extensions-howto >`,
453+ authors should consider marking the module as having no support for subinterpreters
454+ (via :c:macro: `Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED `).
446455
447456A more substantial example module is included in the Python source distribution
448457as :file: `Modules/xxlimited.c `. This file may be used as a template or simply
449458read as an example.
450459
460+
451461.. _compilation :
452462
453463Compilation and Linkage
@@ -1068,8 +1078,9 @@ why his :meth:`!__del__` methods would fail...
10681078
10691079The second case of problems with a borrowed reference is a variant involving
10701080threads. Normally, multiple threads in the Python interpreter can't get in each
1071- other's way, because there is a global lock protecting Python's entire object
1072- space. However, it is possible to temporarily release this lock using the macro
1081+ other's way, because there is a :term: `global lock <global interpreter lock> `
1082+ protecting Python's entire object space.
1083+ However, it is possible to temporarily release this lock using the macro
10731084:c:macro: `Py_BEGIN_ALLOW_THREADS `, and to re-acquire it using
10741085:c:macro: `Py_END_ALLOW_THREADS `. This is common around blocking I/O calls, to
10751086let other threads use the processor while waiting for the I/O to complete.
@@ -1255,8 +1266,8 @@ two more lines must be added::
12551266 #include "spammodule.h"
12561267
12571268The ``#define `` is used to tell the header file that it is being included in the
1258- exporting module, not a client module. Finally, the module's initialization
1259- function must take care of initializing the C API pointer array::
1269+ exporting module, not a client module. Finally, the module's :c:data: ` mod_exec
1270+ <Py_mod_exec> ` function must take care of initializing the C API pointer array::
12601271
12611272 static int
12621273 spam_module_exec(PyObject *m)
@@ -1277,24 +1288,6 @@ function must take care of initializing the C API pointer array::
12771288 return 0;
12781289 }
12791290
1280- static PyModuleDef_Slot spam_module_slots[] = {
1281- {Py_mod_exec, spam_module_exec},
1282- {0, NULL}
1283- };
1284-
1285- static struct PyModuleDef spam_module = {
1286- .m_base = PyModuleDef_HEAD_INIT,
1287- .m_name = "spam",
1288- .m_size = 0,
1289- .m_slots = spam_module_slots,
1290- };
1291-
1292- PyMODINIT_FUNC
1293- PyInit_spam(void)
1294- {
1295- return PyModuleDef_Init(&spam_module);
1296- }
1297-
12981291Note that ``PySpam_API `` is declared ``static ``; otherwise the pointer
12991292array would disappear when :c:func: `!PyInit_spam ` terminates!
13001293
@@ -1351,7 +1344,7 @@ like this::
13511344
13521345All that a client module must do in order to have access to the function
13531346:c:func: `!PySpam_System ` is to call the function (or rather macro)
1354- :c:func: `!import_spam ` in its initialization function::
1347+ :c:func: `!import_spam ` in its :c:data: ` mod_exec <Py_mod_exec> ` function::
13551348
13561349 static int
13571350 client_module_exec(PyObject *m)
@@ -1362,24 +1355,6 @@ All that a client module must do in order to have access to the function
13621355 return 0;
13631356 }
13641357
1365- static PyModuleDef_Slot client_module_slots[] = {
1366- {Py_mod_exec, client_module_exec},
1367- {0, NULL}
1368- };
1369-
1370- static struct PyModuleDef client_module = {
1371- .m_base = PyModuleDef_HEAD_INIT,
1372- .m_name = "client",
1373- .m_size = 0,
1374- .m_slots = client_module_slots,
1375- };
1376-
1377- PyMODINIT_FUNC
1378- PyInit_client(void)
1379- {
1380- return PyModuleDef_Init(&client_module);
1381- }
1382-
13831358The main disadvantage of this approach is that the file :file: `spammodule.h ` is
13841359rather complicated. However, the basic structure is the same for each function
13851360that is exported, so it has to be learned only once.
0 commit comments