1
2 /* Testing module for multi-phase initialization of extension modules (PEP 489)
3 */
4 #ifndef Py_BUILD_CORE_BUILTIN
5 # define Py_BUILD_CORE_MODULE 1
6 #endif
7
8 #include "Python.h"
9 #include "pycore_modsupport.h" // _PyArg_CheckPositional()
10 #include "pycore_namespace.h" // _PyNamespace_New()
11
12 /* State for testing module state access from methods */
13
14 typedef struct {
15 int counter;
16 } meth_state;
17
18 /*[clinic input]
19 module _testmultiphase
20
21 class _testmultiphase.StateAccessType "StateAccessTypeObject *" "!StateAccessType"
22 [clinic start generated code]*/
23 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=bab9f2fe3bd312ff]*/
24
25 /* Example objects */
26 typedef struct {
27 PyObject_HEAD
28 PyObject *x_attr; /* Attributes dictionary */
29 } ExampleObject;
30
31 typedef struct {
32 PyObject *integer;
33 } testmultiphase_state;
34
35 typedef struct {
36 PyObject_HEAD
37 } StateAccessTypeObject;
38
39 /* Example methods */
40
41 static int
Example_traverse(ExampleObject * self,visitproc visit,void * arg)42 Example_traverse(ExampleObject *self, visitproc visit, void *arg)
43 {
44 Py_VISIT(self->x_attr);
45 return 0;
46 }
47
48 static void
Example_finalize(ExampleObject * self)49 Example_finalize(ExampleObject *self)
50 {
51 Py_CLEAR(self->x_attr);
52 }
53
54 static PyObject *
Example_demo(ExampleObject * self,PyObject * args)55 Example_demo(ExampleObject *self, PyObject *args)
56 {
57 PyObject *o = NULL;
58 if (!PyArg_ParseTuple(args, "|O:demo", &o))
59 return NULL;
60 if (o != NULL && PyUnicode_Check(o)) {
61 return Py_NewRef(o);
62 }
63 Py_RETURN_NONE;
64 }
65
66 #include "clinic/_testmultiphase.c.h"
67
68 static PyMethodDef Example_methods[] = {
69 {"demo", (PyCFunction)Example_demo, METH_VARARGS,
70 PyDoc_STR("demo() -> None")},
71 {NULL, NULL} /* sentinel */
72 };
73
74 static PyObject *
Example_getattro(ExampleObject * self,PyObject * name)75 Example_getattro(ExampleObject *self, PyObject *name)
76 {
77 if (self->x_attr != NULL) {
78 PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
79 if (v != NULL) {
80 return Py_NewRef(v);
81 }
82 else if (PyErr_Occurred()) {
83 return NULL;
84 }
85 }
86 return PyObject_GenericGetAttr((PyObject *)self, name);
87 }
88
89 static int
Example_setattr(ExampleObject * self,const char * name,PyObject * v)90 Example_setattr(ExampleObject *self, const char *name, PyObject *v)
91 {
92 if (self->x_attr == NULL) {
93 self->x_attr = PyDict_New();
94 if (self->x_attr == NULL)
95 return -1;
96 }
97 if (v == NULL) {
98 int rv = PyDict_DelItemString(self->x_attr, name);
99 if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
100 PyErr_SetString(PyExc_AttributeError,
101 "delete non-existing Example attribute");
102 return rv;
103 }
104 else
105 return PyDict_SetItemString(self->x_attr, name, v);
106 }
107
108 static PyType_Slot Example_Type_slots[] = {
109 {Py_tp_doc, "The Example type"},
110 {Py_tp_finalize, Example_finalize},
111 {Py_tp_traverse, Example_traverse},
112 {Py_tp_getattro, Example_getattro},
113 {Py_tp_setattr, Example_setattr},
114 {Py_tp_methods, Example_methods},
115 {0, 0},
116 };
117
118 static PyType_Spec Example_Type_spec = {
119 "_testimportexec.Example",
120 sizeof(ExampleObject),
121 0,
122 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
123 Example_Type_slots
124 };
125
126
127 static PyModuleDef def_meth_state_access;
128 static PyModuleDef def_nonmodule;
129 static PyModuleDef def_nonmodule_with_methods;
130
131 /*[clinic input]
132 _testmultiphase.StateAccessType.get_defining_module
133
134 cls: defining_class
135
136 Return the module of the defining class.
137
138 Also tests that result of PyType_GetModuleByDef matches defining_class's
139 module.
140 [clinic start generated code]*/
141
142 static PyObject *
_testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject * self,PyTypeObject * cls)143 _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject *self,
144 PyTypeObject *cls)
145 /*[clinic end generated code: output=ba2a14284a5d0921 input=d2c7245c8a9d06f8]*/
146 {
147 PyObject *retval;
148 retval = PyType_GetModule(cls);
149 if (retval == NULL) {
150 return NULL;
151 }
152 assert(PyType_GetModuleByDef(Py_TYPE(self), &def_meth_state_access) == retval);
153 return Py_NewRef(retval);
154 }
155
156 /*[clinic input]
157 _testmultiphase.StateAccessType.getmodulebydef_bad_def
158
159 cls: defining_class
160
161 Test that result of PyType_GetModuleByDef with a bad def is NULL.
162 [clinic start generated code]*/
163
164 static PyObject *
_testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(StateAccessTypeObject * self,PyTypeObject * cls)165 _testmultiphase_StateAccessType_getmodulebydef_bad_def_impl(StateAccessTypeObject *self,
166 PyTypeObject *cls)
167 /*[clinic end generated code: output=64509074dfcdbd31 input=edaff09aa4788204]*/
168 {
169 PyType_GetModuleByDef(Py_TYPE(self), &def_nonmodule); // should raise
170 assert(PyErr_Occurred());
171 return NULL;
172 }
173
174 /*[clinic input]
175 _testmultiphase.StateAccessType.increment_count_clinic
176
177 cls: defining_class
178 /
179 n: int = 1
180 *
181 twice: bool = False
182
183 Add 'n' from the module-state counter.
184
185 Pass 'twice' to double that amount.
186
187 This tests Argument Clinic support for defining_class.
188 [clinic start generated code]*/
189
190 static PyObject *
_testmultiphase_StateAccessType_increment_count_clinic_impl(StateAccessTypeObject * self,PyTypeObject * cls,int n,int twice)191 _testmultiphase_StateAccessType_increment_count_clinic_impl(StateAccessTypeObject *self,
192 PyTypeObject *cls,
193 int n, int twice)
194 /*[clinic end generated code: output=3b34f86bc5473204 input=551d482e1fe0b8f5]*/
195 {
196 meth_state *m_state = PyType_GetModuleState(cls);
197 if (twice) {
198 n *= 2;
199 }
200 m_state->counter += n;
201
202 Py_RETURN_NONE;
203 }
204
205 PyDoc_STRVAR(_StateAccessType_decrement_count__doc__,
206 "decrement_count($self, /, n=1, *, twice=None)\n"
207 "--\n"
208 "\n"
209 "Add 'n' from the module-state counter.\n"
210 "Pass 'twice' to double that amount.\n"
211 "(This is to test both positional and keyword arguments.");
212
213 // Intentionally does not use Argument Clinic
214 static PyObject *
_StateAccessType_increment_count_noclinic(StateAccessTypeObject * self,PyTypeObject * defining_class,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)215 _StateAccessType_increment_count_noclinic(StateAccessTypeObject *self,
216 PyTypeObject *defining_class,
217 PyObject *const *args,
218 Py_ssize_t nargs,
219 PyObject *kwnames)
220 {
221 if (!_PyArg_CheckPositional("StateAccessTypeObject.decrement_count", nargs, 0, 1)) {
222 return NULL;
223 }
224 long n = 1;
225 if (nargs) {
226 n = PyLong_AsLong(args[0]);
227 if (PyErr_Occurred()) {
228 return NULL;
229 }
230 }
231 if (kwnames && PyTuple_Check(kwnames)) {
232 if (PyTuple_GET_SIZE(kwnames) > 1 ||
233 PyUnicode_CompareWithASCIIString(
234 PyTuple_GET_ITEM(kwnames, 0),
235 "twice"
236 )) {
237 PyErr_SetString(
238 PyExc_TypeError,
239 "decrement_count only takes 'twice' keyword argument"
240 );
241 return NULL;
242 }
243 n *= 2;
244 }
245 meth_state *m_state = PyType_GetModuleState(defining_class);
246 m_state->counter += n;
247
248 Py_RETURN_NONE;
249 }
250
251 /*[clinic input]
252 _testmultiphase.StateAccessType.get_count
253
254 cls: defining_class
255
256 Return the value of the module-state counter.
257 [clinic start generated code]*/
258
259 static PyObject *
_testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject * self,PyTypeObject * cls)260 _testmultiphase_StateAccessType_get_count_impl(StateAccessTypeObject *self,
261 PyTypeObject *cls)
262 /*[clinic end generated code: output=64600f95b499a319 input=d5d181f12384849f]*/
263 {
264 meth_state *m_state = PyType_GetModuleState(cls);
265 return PyLong_FromLong(m_state->counter);
266 }
267
268 static PyMethodDef StateAccessType_methods[] = {
269 _TESTMULTIPHASE_STATEACCESSTYPE_GET_DEFINING_MODULE_METHODDEF
270 _TESTMULTIPHASE_STATEACCESSTYPE_GETMODULEBYDEF_BAD_DEF_METHODDEF
271 _TESTMULTIPHASE_STATEACCESSTYPE_GET_COUNT_METHODDEF
272 _TESTMULTIPHASE_STATEACCESSTYPE_INCREMENT_COUNT_CLINIC_METHODDEF
273 {
274 "increment_count_noclinic",
275 _PyCFunction_CAST(_StateAccessType_increment_count_noclinic),
276 METH_METHOD|METH_FASTCALL|METH_KEYWORDS,
277 _StateAccessType_decrement_count__doc__
278 },
279 {NULL, NULL} /* sentinel */
280 };
281
282 static PyType_Slot StateAccessType_Type_slots[] = {
283 {Py_tp_doc, "Type for testing per-module state access from methods."},
284 {Py_tp_methods, StateAccessType_methods},
285 {0, NULL}
286 };
287
288 static PyType_Spec StateAccessType_spec = {
289 "_testimportexec.StateAccessType",
290 sizeof(StateAccessTypeObject),
291 0,
292 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE | Py_TPFLAGS_BASETYPE,
293 StateAccessType_Type_slots
294 };
295
296 /* Function of two integers returning integer */
297
298 PyDoc_STRVAR(testexport_foo_doc,
299 "foo(i,j)\n\
300 \n\
301 Return the sum of i and j.");
302
303 static PyObject *
testexport_foo(PyObject * self,PyObject * args)304 testexport_foo(PyObject *self, PyObject *args)
305 {
306 long i, j;
307 long res;
308 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
309 return NULL;
310 res = i + j;
311 return PyLong_FromLong(res);
312 }
313
314 /* Test that PyState registration fails */
315
316 PyDoc_STRVAR(call_state_registration_func_doc,
317 "register_state(0): call PyState_FindModule()\n\
318 register_state(1): call PyState_AddModule()\n\
319 register_state(2): call PyState_RemoveModule()");
320
321 static PyObject *
call_state_registration_func(PyObject * mod,PyObject * args)322 call_state_registration_func(PyObject *mod, PyObject *args)
323 {
324 int i, ret;
325 PyModuleDef *def = PyModule_GetDef(mod);
326 if (def == NULL) {
327 return NULL;
328 }
329 if (!PyArg_ParseTuple(args, "i:call_state_registration_func", &i))
330 return NULL;
331 switch (i) {
332 case 0:
333 mod = PyState_FindModule(def);
334 if (mod == NULL) {
335 Py_RETURN_NONE;
336 }
337 return mod;
338 case 1:
339 ret = PyState_AddModule(mod, def);
340 if (ret != 0) {
341 return NULL;
342 }
343 break;
344 case 2:
345 ret = PyState_RemoveModule(def);
346 if (ret != 0) {
347 return NULL;
348 }
349 break;
350 }
351 Py_RETURN_NONE;
352 }
353
354
355 static PyType_Slot Str_Type_slots[] = {
356 {Py_tp_base, NULL}, /* filled out in module exec function */
357 {0, 0},
358 };
359
360 static PyType_Spec Str_Type_spec = {
361 "_testimportexec.Str",
362 0,
363 0,
364 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
365 Str_Type_slots
366 };
367
368 static PyMethodDef testexport_methods[] = {
369 {"foo", testexport_foo, METH_VARARGS,
370 testexport_foo_doc},
371 {"call_state_registration_func", call_state_registration_func,
372 METH_VARARGS, call_state_registration_func_doc},
373 {NULL, NULL} /* sentinel */
374 };
375
execfunc(PyObject * m)376 static int execfunc(PyObject *m)
377 {
378 PyObject *temp = NULL;
379
380 /* Due to cross platform compiler issues the slots must be filled
381 * here. It's required for portability to Windows without requiring
382 * C++. */
383 Str_Type_slots[0].pfunc = &PyUnicode_Type;
384
385 /* Add a custom type */
386 temp = PyType_FromSpec(&Example_Type_spec);
387 if (PyModule_Add(m, "Example", temp) != 0) {
388 goto fail;
389 }
390
391
392 /* Add an exception type */
393 temp = PyErr_NewException("_testimportexec.error", NULL, NULL);
394 if (PyModule_Add(m, "error", temp) != 0) {
395 goto fail;
396 }
397
398 /* Add Str */
399 temp = PyType_FromSpec(&Str_Type_spec);
400 if (PyModule_Add(m, "Str", temp) != 0) {
401 goto fail;
402 }
403
404 if (PyModule_AddIntConstant(m, "int_const", 1969) != 0) {
405 goto fail;
406 }
407
408 if (PyModule_AddStringConstant(m, "str_const", "something different") != 0) {
409 goto fail;
410 }
411
412 return 0;
413 fail:
414 return -1;
415 }
416
417 /* Helper for module definitions; there'll be a lot of them */
418
419 #define TEST_MODULE_DEF(name, slots, methods) { \
420 PyModuleDef_HEAD_INIT, /* m_base */ \
421 name, /* m_name */ \
422 PyDoc_STR("Test module " name), /* m_doc */ \
423 0, /* m_size */ \
424 methods, /* m_methods */ \
425 slots, /* m_slots */ \
426 NULL, /* m_traverse */ \
427 NULL, /* m_clear */ \
428 NULL, /* m_free */ \
429 }
430
431 static PyModuleDef_Slot main_slots[] = {
432 {Py_mod_exec, execfunc},
433 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
434 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
435 {0, NULL},
436 };
437
438 static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
439
440 PyMODINIT_FUNC
PyInit__testmultiphase(void)441 PyInit__testmultiphase(void)
442 {
443 return PyModuleDef_Init(&main_def);
444 }
445
446
447 /**** Importing a non-module object ****/
448
449 /* Create a SimpleNamespace(three=3) */
450 static PyObject*
createfunc_nonmodule(PyObject * spec,PyModuleDef * def)451 createfunc_nonmodule(PyObject *spec, PyModuleDef *def)
452 {
453 PyObject *dct, *ns, *three;
454
455 if (def != &def_nonmodule && def != &def_nonmodule_with_methods) {
456 PyErr_SetString(PyExc_SystemError, "def does not match");
457 return NULL;
458 }
459
460 dct = PyDict_New();
461 if (dct == NULL)
462 return NULL;
463
464 three = PyLong_FromLong(3);
465 if (three == NULL) {
466 Py_DECREF(dct);
467 return NULL;
468 }
469 PyDict_SetItemString(dct, "three", three);
470 Py_DECREF(three);
471
472 ns = _PyNamespace_New(dct);
473 Py_DECREF(dct);
474 return ns;
475 }
476
477 static PyModuleDef_Slot slots_create_nonmodule[] = {
478 {Py_mod_create, createfunc_nonmodule},
479 {0, NULL},
480 };
481
482 static PyModuleDef def_nonmodule = TEST_MODULE_DEF(
483 "_testmultiphase_nonmodule", slots_create_nonmodule, NULL);
484
485 PyMODINIT_FUNC
PyInit__testmultiphase_nonmodule(void)486 PyInit__testmultiphase_nonmodule(void)
487 {
488 return PyModuleDef_Init(&def_nonmodule);
489 }
490
491 PyDoc_STRVAR(nonmodule_bar_doc,
492 "bar(i,j)\n\
493 \n\
494 Return the difference of i - j.");
495
496 static PyObject *
nonmodule_bar(PyObject * self,PyObject * args)497 nonmodule_bar(PyObject *self, PyObject *args)
498 {
499 long i, j;
500 long res;
501 if (!PyArg_ParseTuple(args, "ll:bar", &i, &j))
502 return NULL;
503 res = i - j;
504 return PyLong_FromLong(res);
505 }
506
507 static PyMethodDef nonmodule_methods[] = {
508 {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc},
509 {NULL, NULL} /* sentinel */
510 };
511
512 static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF(
513 "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods);
514
515 PyMODINIT_FUNC
PyInit__testmultiphase_nonmodule_with_methods(void)516 PyInit__testmultiphase_nonmodule_with_methods(void)
517 {
518 return PyModuleDef_Init(&def_nonmodule_with_methods);
519 }
520
521 /**** Non-ASCII-named modules ****/
522
523 static PyModuleDef_Slot nonascii_slots[] = {
524 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
525 {0, NULL},
526 };
527
528 static PyModuleDef def_nonascii_latin = { \
529 PyModuleDef_HEAD_INIT, /* m_base */
530 "_testmultiphase_nonascii_latin", /* m_name */
531 PyDoc_STR("Module named in Czech"), /* m_doc */
532 0, /* m_size */
533 NULL, /* m_methods */
534 nonascii_slots, /* m_slots */
535 NULL, /* m_traverse */
536 NULL, /* m_clear */
537 NULL, /* m_free */
538 };
539
540 PyMODINIT_FUNC
PyInitU__testmultiphase_zkouka_naten_evc07gi8e(void)541 PyInitU__testmultiphase_zkouka_naten_evc07gi8e(void)
542 {
543 return PyModuleDef_Init(&def_nonascii_latin);
544 }
545
546 static PyModuleDef def_nonascii_kana = { \
547 PyModuleDef_HEAD_INIT, /* m_base */
548 "_testmultiphase_nonascii_kana", /* m_name */
549 PyDoc_STR("Module named in Japanese"), /* m_doc */
550 0, /* m_size */
551 NULL, /* m_methods */
552 nonascii_slots, /* m_slots */
553 NULL, /* m_traverse */
554 NULL, /* m_clear */
555 NULL, /* m_free */
556 };
557
558 PyMODINIT_FUNC
PyInitU_eckzbwbhc6jpgzcx415x(void)559 PyInitU_eckzbwbhc6jpgzcx415x(void)
560 {
561 return PyModuleDef_Init(&def_nonascii_kana);
562 }
563
564 /*** Module with a single-character name ***/
565
566 PyMODINIT_FUNC
PyInit_x(void)567 PyInit_x(void)
568 {
569 return PyModuleDef_Init(&main_def);
570 }
571
572 /**** Testing NULL slots ****/
573
574 static PyModuleDef null_slots_def = TEST_MODULE_DEF(
575 "_testmultiphase_null_slots", NULL, NULL);
576
577 PyMODINIT_FUNC
PyInit__testmultiphase_null_slots(void)578 PyInit__testmultiphase_null_slots(void)
579 {
580 return PyModuleDef_Init(&null_slots_def);
581 }
582
583 /**** Problematic modules ****/
584
585 static PyModuleDef_Slot slots_bad_large[] = {
586 {_Py_mod_LAST_SLOT + 1, NULL},
587 {0, NULL},
588 };
589
590 static PyModuleDef def_bad_large = TEST_MODULE_DEF(
591 "_testmultiphase_bad_slot_large", slots_bad_large, NULL);
592
593 PyMODINIT_FUNC
PyInit__testmultiphase_bad_slot_large(void)594 PyInit__testmultiphase_bad_slot_large(void)
595 {
596 return PyModuleDef_Init(&def_bad_large);
597 }
598
599 static PyModuleDef_Slot slots_bad_negative[] = {
600 {-1, NULL},
601 {0, NULL},
602 };
603
604 static PyModuleDef def_bad_negative = TEST_MODULE_DEF(
605 "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL);
606
607 PyMODINIT_FUNC
PyInit__testmultiphase_bad_slot_negative(void)608 PyInit__testmultiphase_bad_slot_negative(void)
609 {
610 return PyModuleDef_Init(&def_bad_negative);
611 }
612
613 static PyModuleDef def_create_int_with_state = { \
614 PyModuleDef_HEAD_INIT, /* m_base */
615 "create_with_state", /* m_name */
616 PyDoc_STR("Not a PyModuleObject object, but requests per-module state"),
617 10, /* m_size */
618 NULL, /* m_methods */
619 slots_create_nonmodule, /* m_slots */
620 NULL, /* m_traverse */
621 NULL, /* m_clear */
622 NULL, /* m_free */
623 };
624
625 PyMODINIT_FUNC
PyInit__testmultiphase_create_int_with_state(void)626 PyInit__testmultiphase_create_int_with_state(void)
627 {
628 return PyModuleDef_Init(&def_create_int_with_state);
629 }
630
631
632 static PyModuleDef def_negative_size = { \
633 PyModuleDef_HEAD_INIT, /* m_base */
634 "negative_size", /* m_name */
635 PyDoc_STR("PyModuleDef with negative m_size"),
636 -1, /* m_size */
637 NULL, /* m_methods */
638 slots_create_nonmodule, /* m_slots */
639 NULL, /* m_traverse */
640 NULL, /* m_clear */
641 NULL, /* m_free */
642 };
643
644 PyMODINIT_FUNC
PyInit__testmultiphase_negative_size(void)645 PyInit__testmultiphase_negative_size(void)
646 {
647 return PyModuleDef_Init(&def_negative_size);
648 }
649
650
651 static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
652
653 PyMODINIT_FUNC
PyInit__testmultiphase_export_uninitialized(void)654 PyInit__testmultiphase_export_uninitialized(void)
655 {
656 return (PyObject*) &uninitialized_def;
657 }
658
659 PyMODINIT_FUNC
PyInit__testmultiphase_export_null(void)660 PyInit__testmultiphase_export_null(void)
661 {
662 return NULL;
663 }
664
665 PyMODINIT_FUNC
PyInit__testmultiphase_export_raise(void)666 PyInit__testmultiphase_export_raise(void)
667 {
668 PyErr_SetString(PyExc_SystemError, "bad export function");
669 return NULL;
670 }
671
672 PyMODINIT_FUNC
PyInit__testmultiphase_export_unreported_exception(void)673 PyInit__testmultiphase_export_unreported_exception(void)
674 {
675 PyErr_SetString(PyExc_SystemError, "bad export function");
676 return PyModuleDef_Init(&main_def);
677 }
678
679 static PyObject*
createfunc_noop(PyObject * spec,PyModuleDef * def)680 createfunc_noop(PyObject *spec, PyModuleDef *def)
681 {
682 return PyModule_New("spam");
683 }
684
685 static PyModuleDef_Slot slots_multiple_create_slots[] = {
686 {Py_mod_create, createfunc_noop},
687 {Py_mod_create, createfunc_noop},
688 {0, NULL},
689 };
690
691 static PyModuleDef def_multiple_create_slots = TEST_MODULE_DEF(
692 "_testmultiphase_multiple_create_slots", slots_multiple_create_slots, NULL);
693
694 PyMODINIT_FUNC
PyInit__testmultiphase_multiple_create_slots(void)695 PyInit__testmultiphase_multiple_create_slots(void)
696 {
697 return PyModuleDef_Init(&def_multiple_create_slots);
698 }
699
700 static PyObject*
createfunc_null(PyObject * spec,PyModuleDef * def)701 createfunc_null(PyObject *spec, PyModuleDef *def)
702 {
703 return NULL;
704 }
705
706 static PyModuleDef_Slot slots_create_null[] = {
707 {Py_mod_create, createfunc_null},
708 {0, NULL},
709 };
710
711 static PyModuleDef def_create_null = TEST_MODULE_DEF(
712 "_testmultiphase_create_null", slots_create_null, NULL);
713
714 PyMODINIT_FUNC
PyInit__testmultiphase_create_null(void)715 PyInit__testmultiphase_create_null(void)
716 {
717 return PyModuleDef_Init(&def_create_null);
718 }
719
720 static PyObject*
createfunc_raise(PyObject * spec,PyModuleDef * def)721 createfunc_raise(PyObject *spec, PyModuleDef *def)
722 {
723 PyErr_SetString(PyExc_SystemError, "bad create function");
724 return NULL;
725 }
726
727 static PyModuleDef_Slot slots_create_raise[] = {
728 {Py_mod_create, createfunc_raise},
729 {0, NULL},
730 };
731
732 static PyModuleDef def_create_raise = TEST_MODULE_DEF(
733 "_testmultiphase_create_null", slots_create_raise, NULL);
734
735 PyMODINIT_FUNC
PyInit__testmultiphase_create_raise(void)736 PyInit__testmultiphase_create_raise(void)
737 {
738 return PyModuleDef_Init(&def_create_raise);
739 }
740
741 static PyObject*
createfunc_unreported_exception(PyObject * spec,PyModuleDef * def)742 createfunc_unreported_exception(PyObject *spec, PyModuleDef *def)
743 {
744 PyErr_SetString(PyExc_SystemError, "bad create function");
745 return PyModule_New("foo");
746 }
747
748 static PyModuleDef_Slot slots_create_unreported_exception[] = {
749 {Py_mod_create, createfunc_unreported_exception},
750 {0, NULL},
751 };
752
753 static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF(
754 "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL);
755
756 PyMODINIT_FUNC
PyInit__testmultiphase_create_unreported_exception(void)757 PyInit__testmultiphase_create_unreported_exception(void)
758 {
759 return PyModuleDef_Init(&def_create_unreported_exception);
760 }
761
762 static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = {
763 {Py_mod_create, createfunc_nonmodule},
764 {Py_mod_exec, execfunc},
765 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
766 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
767 {0, NULL},
768 };
769
770 static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF(
771 "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL);
772
773 PyMODINIT_FUNC
PyInit__testmultiphase_nonmodule_with_exec_slots(void)774 PyInit__testmultiphase_nonmodule_with_exec_slots(void)
775 {
776 return PyModuleDef_Init(&def_nonmodule_with_exec_slots);
777 }
778
779 static int
execfunc_err(PyObject * mod)780 execfunc_err(PyObject *mod)
781 {
782 return -1;
783 }
784
785 static PyModuleDef_Slot slots_exec_err[] = {
786 {Py_mod_exec, execfunc_err},
787 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
788 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
789 {0, NULL},
790 };
791
792 static PyModuleDef def_exec_err = TEST_MODULE_DEF(
793 "_testmultiphase_exec_err", slots_exec_err, NULL);
794
795 PyMODINIT_FUNC
PyInit__testmultiphase_exec_err(void)796 PyInit__testmultiphase_exec_err(void)
797 {
798 return PyModuleDef_Init(&def_exec_err);
799 }
800
801 static int
execfunc_raise(PyObject * spec)802 execfunc_raise(PyObject *spec)
803 {
804 PyErr_SetString(PyExc_SystemError, "bad exec function");
805 return -1;
806 }
807
808 static PyModuleDef_Slot slots_exec_raise[] = {
809 {Py_mod_exec, execfunc_raise},
810 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
811 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
812 {0, NULL},
813 };
814
815 static PyModuleDef def_exec_raise = TEST_MODULE_DEF(
816 "_testmultiphase_exec_raise", slots_exec_raise, NULL);
817
818 PyMODINIT_FUNC
PyInit__testmultiphase_exec_raise(void)819 PyInit__testmultiphase_exec_raise(void)
820 {
821 return PyModuleDef_Init(&def_exec_raise);
822 }
823
824 static int
execfunc_unreported_exception(PyObject * mod)825 execfunc_unreported_exception(PyObject *mod)
826 {
827 PyErr_SetString(PyExc_SystemError, "bad exec function");
828 return 0;
829 }
830
831 static PyModuleDef_Slot slots_exec_unreported_exception[] = {
832 {Py_mod_exec, execfunc_unreported_exception},
833 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
834 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
835 {0, NULL},
836 };
837
838 static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF(
839 "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL);
840
841 PyMODINIT_FUNC
PyInit__testmultiphase_exec_unreported_exception(void)842 PyInit__testmultiphase_exec_unreported_exception(void)
843 {
844 return PyModuleDef_Init(&def_exec_unreported_exception);
845 }
846
847 static int
meth_state_access_exec(PyObject * m)848 meth_state_access_exec(PyObject *m)
849 {
850 PyObject *temp;
851 meth_state *m_state;
852
853 m_state = PyModule_GetState(m);
854 if (m_state == NULL) {
855 return -1;
856 }
857
858 temp = PyType_FromModuleAndSpec(m, &StateAccessType_spec, NULL);
859 if (PyModule_Add(m, "StateAccessType", temp) != 0) {
860 return -1;
861 }
862
863
864 return 0;
865 }
866
867 static PyModuleDef_Slot meth_state_access_slots[] = {
868 {Py_mod_exec, meth_state_access_exec},
869 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
870 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
871 {0, NULL}
872 };
873
874 static PyModuleDef def_meth_state_access = {
875 PyModuleDef_HEAD_INIT,
876 .m_name = "_testmultiphase_meth_state_access",
877 .m_doc = PyDoc_STR("Module testing access"
878 " to state from methods."),
879 .m_size = sizeof(meth_state),
880 .m_slots = meth_state_access_slots,
881 };
882
883 PyMODINIT_FUNC
PyInit__testmultiphase_meth_state_access(void)884 PyInit__testmultiphase_meth_state_access(void)
885 {
886 return PyModuleDef_Init(&def_meth_state_access);
887 }
888
889 static PyModuleDef def_module_state_shared = {
890 PyModuleDef_HEAD_INIT,
891 .m_name = "_test_module_state_shared",
892 .m_doc = PyDoc_STR("Regression Test module for single-phase init."),
893 .m_size = -1,
894 };
895
896 PyMODINIT_FUNC
PyInit__test_module_state_shared(void)897 PyInit__test_module_state_shared(void)
898 {
899 PyObject *module = PyModule_Create(&def_module_state_shared);
900 if (module == NULL) {
901 return NULL;
902 }
903 #ifdef Py_GIL_DISABLED
904 PyUnstable_Module_SetGIL(module, Py_MOD_GIL_NOT_USED);
905 #endif
906
907 if (PyModule_AddObjectRef(module, "Error", PyExc_Exception) < 0) {
908 Py_DECREF(module);
909 return NULL;
910 }
911 return module;
912 }
913
914
915 /* multiple interpreters support */
916
917 static PyModuleDef_Slot slots_multiple_multiple_interpreters_slots[] = {
918 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
919 {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
920 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
921 {0, NULL},
922 };
923
924 static PyModuleDef def_multiple_multiple_interpreters_slots = TEST_MODULE_DEF(
925 "_testmultiphase_multiple_multiple_interpreters_slots",
926 slots_multiple_multiple_interpreters_slots,
927 NULL);
928
929 PyMODINIT_FUNC
PyInit__testmultiphase_multiple_multiple_interpreters_slots(void)930 PyInit__testmultiphase_multiple_multiple_interpreters_slots(void)
931 {
932 return PyModuleDef_Init(&def_multiple_multiple_interpreters_slots);
933 }
934
935 static PyModuleDef_Slot non_isolated_slots[] = {
936 {Py_mod_exec, execfunc},
937 {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
938 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
939 {0, NULL},
940 };
941
942 static PyModuleDef non_isolated_def = TEST_MODULE_DEF("_test_non_isolated",
943 non_isolated_slots,
944 testexport_methods);
945
946 PyMODINIT_FUNC
PyInit__test_non_isolated(void)947 PyInit__test_non_isolated(void)
948 {
949 return PyModuleDef_Init(&non_isolated_def);
950 }
951
952
953 static PyModuleDef_Slot shared_gil_only_slots[] = {
954 {Py_mod_exec, execfunc},
955 /* Note that Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED is the default.
956 We put it here explicitly to draw attention to the contrast
957 with Py_MOD_PER_INTERPRETER_GIL_SUPPORTED. */
958 {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED},
959 {Py_mod_gil, Py_MOD_GIL_NOT_USED},
960 {0, NULL},
961 };
962
963 static PyModuleDef shared_gil_only_def = TEST_MODULE_DEF("_test_shared_gil_only",
964 shared_gil_only_slots,
965 testexport_methods);
966
967 PyMODINIT_FUNC
PyInit__test_shared_gil_only(void)968 PyInit__test_shared_gil_only(void)
969 {
970 return PyModuleDef_Init(&shared_gil_only_def);
971 }
972