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