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