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