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