• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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