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