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
9typedef struct {
10 int counter;
11} meth_state;
12
13/*[clinic input]
14module _testmultiphase
15
16class _testmultiphase.StateAccessType "StateAccessTypeObject *" "!StateAccessType"
17[clinic start generated code]*/
18/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bab9f2fe3bd312ff]*/
19
20/* Example objects */
21typedef struct {
22 PyObject_HEAD
23 PyObject *x_attr; /* Attributes dictionary */
24} ExampleObject;
25
26typedef struct {
27 PyObject *integer;
28} testmultiphase_state;
29
30typedef struct {
31 PyObject_HEAD
32} StateAccessTypeObject;
33
34/* Example methods */
35
36static int
37Example_traverse(ExampleObject *self, visitproc visit, void *arg)
38{
39 Py_VISIT(self->x_attr);
40 return 0;
41}
42
43static void
44Example_finalize(ExampleObject *self)
45{
46 Py_CLEAR(self->x_attr);
47}
48
49static PyObject *
50Example_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
64static PyMethodDef Example_methods[] = {
65 {"demo", (PyCFunction)Example_demo, METH_VARARGS,
66 PyDoc_STR("demo() -> None")},
67 {NULL, NULL} /* sentinel */
68};
69
70static PyObject *
71Example_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
86static int
87Example_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
105static 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
115static 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
124static PyModuleDef def_meth_state_access;
125static PyModuleDef def_nonmodule;
126static PyModuleDef def_nonmodule_with_methods;
127
128/*[clinic input]
129_testmultiphase.StateAccessType.get_defining_module
130
131 cls: defining_class
132
133Return the module of the defining class.
134
135Also tests that result of _PyType_GetModuleByDef matches defining_class's
136module.
137[clinic start generated code]*/
138
139static PyObject *
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
159Test that result of _PyType_GetModuleByDef with a bad def is NULL.
160[clinic start generated code]*/
161
162static PyObject *
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
181Add 'n' from the module-state counter.
182
183Pass 'twice' to double that amount.
184
185This tests Argument Clinic support for defining_class.
186[clinic start generated code]*/
187
188static PyObject *
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
203PyDoc_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
212static PyObject *
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
254Return the value of the module-state counter.
255[clinic start generated code]*/
256
257static PyObject *
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
266static 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
280static 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
286static 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
296PyDoc_STRVAR(testexport_foo_doc,
297"foo(i,j)\n\
298\n\
299Return the sum of i and j.");
300
301static PyObject *
302testexport_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
314PyDoc_STRVAR(call_state_registration_func_doc,
315"register_state(0): call PyState_FindModule()\n\
316register_state(1): call PyState_AddModule()\n\
317register_state(2): call PyState_RemoveModule()");
318
319static PyObject *
320call_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
353static PyType_Slot Str_Type_slots[] = {
354 {Py_tp_base, NULL}, /* filled out in module exec function */
355 {0, 0},
356};
357
358static 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
366static 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
374static 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
441static PyModuleDef_Slot main_slots[] = {
442 {Py_mod_exec, execfunc},
443 {0, NULL},
444};
445
446static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
447
448PyMODINIT_FUNC
449PyInit__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) */
458static PyObject*
459createfunc_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
485static PyModuleDef_Slot slots_create_nonmodule[] = {
486 {Py_mod_create, createfunc_nonmodule},
487 {0, NULL},
488};
489
490static PyModuleDef def_nonmodule = TEST_MODULE_DEF(
491 "_testmultiphase_nonmodule", slots_create_nonmodule, NULL);
492
493PyMODINIT_FUNC
494PyInit__testmultiphase_nonmodule(PyObject *spec)
495{
496 return PyModuleDef_Init(&def_nonmodule);
497}
498
499PyDoc_STRVAR(nonmodule_bar_doc,
500"bar(i,j)\n\
501\n\
502Return the difference of i - j.");
503
504static PyObject *
505nonmodule_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
515static PyMethodDef nonmodule_methods[] = {
516 {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc},
517 {NULL, NULL} /* sentinel */
518};
519
520static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF(
521 "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods);
522
523PyMODINIT_FUNC
524PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec)
525{
526 return PyModuleDef_Init(&def_nonmodule_with_methods);
527}
528
529/**** Non-ASCII-named modules ****/
530
531static 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
543PyMODINIT_FUNC
544PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec)
545{
546 return PyModuleDef_Init(&def_nonascii_latin);
547}
548
549static 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
561PyMODINIT_FUNC
562PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec)
563{
564 return PyModuleDef_Init(&def_nonascii_kana);
565}
566
567/*** Module with a single-character name ***/
568
569PyMODINIT_FUNC
570PyInit_x(PyObject *spec)
571{
572 return PyModuleDef_Init(&main_def);
573}
574
575/**** Testing NULL slots ****/
576
577static PyModuleDef null_slots_def = TEST_MODULE_DEF(
578 "_testmultiphase_null_slots", NULL, NULL);
579
580PyMODINIT_FUNC
581PyInit__testmultiphase_null_slots(PyObject *spec)
582{
583 return PyModuleDef_Init(&null_slots_def);
584}
585
586/**** Problematic modules ****/
587
588static PyModuleDef_Slot slots_bad_large[] = {
589 {_Py_mod_LAST_SLOT + 1, NULL},
590 {0, NULL},
591};
592
593static PyModuleDef def_bad_large = TEST_MODULE_DEF(
594 "_testmultiphase_bad_slot_large", slots_bad_large, NULL);
595
596PyMODINIT_FUNC
597PyInit__testmultiphase_bad_slot_large(PyObject *spec)
598{
599 return PyModuleDef_Init(&def_bad_large);
600}
601
602static PyModuleDef_Slot slots_bad_negative[] = {
603 {-1, NULL},
604 {0, NULL},
605};
606
607static PyModuleDef def_bad_negative = TEST_MODULE_DEF(
608 "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL);
609
610PyMODINIT_FUNC
611PyInit__testmultiphase_bad_slot_negative(PyObject *spec)
612{
613 return PyModuleDef_Init(&def_bad_negative);
614}
615
616static 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
628PyMODINIT_FUNC
629PyInit__testmultiphase_create_int_with_state(PyObject *spec)
630{
631 return PyModuleDef_Init(&def_create_int_with_state);
632}
633
634
635static 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
647PyMODINIT_FUNC
648PyInit__testmultiphase_negative_size(PyObject *spec)
649{
650 return PyModuleDef_Init(&def_negative_size);
651}
652
653
654static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
655
656PyMODINIT_FUNC
657PyInit__testmultiphase_export_uninitialized(PyObject *spec)
658{
659 return (PyObject*) &uninitialized_def;
660}
661
662PyMODINIT_FUNC
663PyInit__testmultiphase_export_null(PyObject *spec)
664{
665 return NULL;
666}
667
668PyMODINIT_FUNC
669PyInit__testmultiphase_export_raise(PyObject *spec)
670{
671 PyErr_SetString(PyExc_SystemError, "bad export function");
672 return NULL;
673}
674
675PyMODINIT_FUNC
676PyInit__testmultiphase_export_unreported_exception(PyObject *spec)
677{
678 PyErr_SetString(PyExc_SystemError, "bad export function");
679 return PyModuleDef_Init(&main_def);
680}
681
682static PyObject*
683createfunc_null(PyObject *spec, PyModuleDef *def)
684{
685 return NULL;
686}
687
688static PyModuleDef_Slot slots_create_null[] = {
689 {Py_mod_create, createfunc_null},
690 {0, NULL},
691};
692
693static PyModuleDef def_create_null = TEST_MODULE_DEF(
694 "_testmultiphase_create_null", slots_create_null, NULL);
695
696PyMODINIT_FUNC
697PyInit__testmultiphase_create_null(PyObject *spec)
698{
699 return PyModuleDef_Init(&def_create_null);
700}
701
702static PyObject*
703createfunc_raise(PyObject *spec, PyModuleDef *def)
704{
705 PyErr_SetString(PyExc_SystemError, "bad create function");
706 return NULL;
707}
708
709static PyModuleDef_Slot slots_create_raise[] = {
710 {Py_mod_create, createfunc_raise},
711 {0, NULL},
712};
713
714static PyModuleDef def_create_raise = TEST_MODULE_DEF(
715 "_testmultiphase_create_null", slots_create_raise, NULL);
716
717PyMODINIT_FUNC
718PyInit__testmultiphase_create_raise(PyObject *spec)
719{
720 return PyModuleDef_Init(&def_create_raise);
721}
722
723static PyObject*
724createfunc_unreported_exception(PyObject *spec, PyModuleDef *def)
725{
726 PyErr_SetString(PyExc_SystemError, "bad create function");
727 return PyModule_New("foo");
728}
729
730static PyModuleDef_Slot slots_create_unreported_exception[] = {
731 {Py_mod_create, createfunc_unreported_exception},
732 {0, NULL},
733};
734
735static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF(
736 "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL);
737
738PyMODINIT_FUNC
739PyInit__testmultiphase_create_unreported_exception(PyObject *spec)
740{
741 return PyModuleDef_Init(&def_create_unreported_exception);
742}
743
744static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = {
745 {Py_mod_create, createfunc_nonmodule},
746 {Py_mod_exec, execfunc},
747 {0, NULL},
748};
749
750static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF(
751 "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL);
752
753PyMODINIT_FUNC
754PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec)
755{
756 return PyModuleDef_Init(&def_nonmodule_with_exec_slots);
757}
758
759static int
760execfunc_err(PyObject *mod)
761{
762 return -1;
763}
764
765static PyModuleDef_Slot slots_exec_err[] = {
766 {Py_mod_exec, execfunc_err},
767 {0, NULL},
768};
769
770static PyModuleDef def_exec_err = TEST_MODULE_DEF(
771 "_testmultiphase_exec_err", slots_exec_err, NULL);
772
773PyMODINIT_FUNC
774PyInit__testmultiphase_exec_err(PyObject *spec)
775{
776 return PyModuleDef_Init(&def_exec_err);
777}
778
779static int
780execfunc_raise(PyObject *spec)
781{
782 PyErr_SetString(PyExc_SystemError, "bad exec function");
783 return -1;
784}
785
786static PyModuleDef_Slot slots_exec_raise[] = {
787 {Py_mod_exec, execfunc_raise},
788 {0, NULL},
789};
790
791static PyModuleDef def_exec_raise = TEST_MODULE_DEF(
792 "_testmultiphase_exec_raise", slots_exec_raise, NULL);
793
794PyMODINIT_FUNC
795PyInit__testmultiphase_exec_raise(PyObject *mod)
796{
797 return PyModuleDef_Init(&def_exec_raise);
798}
799
800static int
801execfunc_unreported_exception(PyObject *mod)
802{
803 PyErr_SetString(PyExc_SystemError, "bad exec function");
804 return 0;
805}
806
807static PyModuleDef_Slot slots_exec_unreported_exception[] = {
808 {Py_mod_exec, execfunc_unreported_exception},
809 {0, NULL},
810};
811
812static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF(
813 "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL);
814
815PyMODINIT_FUNC
816PyInit__testmultiphase_exec_unreported_exception(PyObject *spec)
817{
818 return PyModuleDef_Init(&def_exec_unreported_exception);
819}
820
821static int
822meth_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
845static PyModuleDef_Slot meth_state_access_slots[] = {
846 {Py_mod_exec, meth_state_access_exec},
847 {0, NULL}
848};
849
850static 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
859PyMODINIT_FUNC
860PyInit__testmultiphase_meth_state_access(PyObject *spec)
861{
862 return PyModuleDef_Init(&def_meth_state_access);
863}
864
865static 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
872PyMODINIT_FUNC
873PyInit__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
890static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods);
891
892PyMODINIT_FUNC
893PyInit_imp_dummy(PyObject *spec)
894{
895 return PyModuleDef_Init(&imp_dummy_def);
896}
897
898