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