blob: ad60f32f7e7a627ecdf5472c1b31fc271ef4f96b [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
Petr Viktorin57aaaa82020-11-03 22:27:12 +0100124static PyModuleDef def_meth_state_access;
125
Petr Viktorine1becf42020-05-07 15:39:59 +0200126/*[clinic input]
127_testmultiphase.StateAccessType.get_defining_module
128
129 cls: defining_class
130
131Return the module of the defining class.
Petr Viktorin57aaaa82020-11-03 22:27:12 +0100132
133Also tests that result of _PyType_GetModuleByDef matches defining_class's
134module.
Petr Viktorine1becf42020-05-07 15:39:59 +0200135[clinic start generated code]*/
136
137static PyObject *
138_testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject *self,
139 PyTypeObject *cls)
Petr Viktorin57aaaa82020-11-03 22:27:12 +0100140/*[clinic end generated code: output=ba2a14284a5d0921 input=356f999fc16e0933]*/
Petr Viktorine1becf42020-05-07 15:39:59 +0200141{
142 PyObject *retval;
143 retval = PyType_GetModule(cls);
144 if (retval == NULL) {
145 return NULL;
146 }
Petr Viktorin57aaaa82020-11-03 22:27:12 +0100147 assert(_PyType_GetModuleByDef(Py_TYPE(self), &def_meth_state_access) == retval);
Petr Viktorine1becf42020-05-07 15:39:59 +0200148 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
161Add 'n' from the module-state counter.
162
163Pass 'twice' to double that amount.
164
165This tests Argument Clinic support for defining_class.
166[clinic start generated code]*/
167
168static PyObject *
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
183PyDoc_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
192static PyObject *
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
234Return the value of the module-state counter.
235[clinic start generated code]*/
236
237static PyObject *
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
246static 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
259static 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
265static 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
Nick Coghland5cacbb2015-05-23 22:24:10 +1000273/* Function of two integers returning integer */
274
275PyDoc_STRVAR(testexport_foo_doc,
276"foo(i,j)\n\
277\n\
278Return the sum of i and j.");
279
280static PyObject *
281testexport_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
293PyDoc_STRVAR(call_state_registration_func_doc,
294"register_state(0): call PyState_FindModule()\n\
295register_state(1): call PyState_AddModule()\n\
296register_state(2): call PyState_RemoveModule()");
297
298static PyObject *
299call_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
332static PyType_Slot Str_Type_slots[] = {
333 {Py_tp_base, NULL}, /* filled out in module exec function */
334 {0, 0},
335};
336
337static 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
345static 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
353static 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);
Petr Viktorine1becf42020-05-07 15:39:59 +0200364 if (temp == NULL) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000365 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200366 }
367 if (PyModule_AddObject(m, "Example", temp) != 0) {
Dong-hee Na8a9463f2020-10-22 18:44:18 +0900368 Py_DECREF(temp);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000369 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200370 }
371
Nick Coghland5cacbb2015-05-23 22:24:10 +1000372
373 /* Add an exception type */
374 temp = PyErr_NewException("_testimportexec.error", NULL, NULL);
Petr Viktorine1becf42020-05-07 15:39:59 +0200375 if (temp == NULL) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000376 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200377 }
378 if (PyModule_AddObject(m, "error", temp) != 0) {
Dong-hee Na8a9463f2020-10-22 18:44:18 +0900379 Py_DECREF(temp);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000380 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200381 }
Nick Coghland5cacbb2015-05-23 22:24:10 +1000382
383 /* Add Str */
384 temp = PyType_FromSpec(&Str_Type_spec);
Petr Viktorine1becf42020-05-07 15:39:59 +0200385 if (temp == NULL) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000386 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200387 }
388 if (PyModule_AddObject(m, "Str", temp) != 0) {
Dong-hee Na8a9463f2020-10-22 18:44:18 +0900389 Py_DECREF(temp);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000390 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200391 }
Nick Coghland5cacbb2015-05-23 22:24:10 +1000392
Petr Viktorine1becf42020-05-07 15:39:59 +0200393 if (PyModule_AddIntConstant(m, "int_const", 1969) != 0) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000394 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200395 }
Nick Coghland5cacbb2015-05-23 22:24:10 +1000396
Petr Viktorine1becf42020-05-07 15:39:59 +0200397 if (PyModule_AddStringConstant(m, "str_const", "something different") != 0) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000398 goto fail;
Petr Viktorine1becf42020-05-07 15:39:59 +0200399 }
Nick Coghland5cacbb2015-05-23 22:24:10 +1000400
401 return 0;
402 fail:
403 return -1;
404}
405
406/* Helper for module definitions; there'll be a lot of them */
Marcel Plchc2b0b122018-03-17 06:41:20 +0100407
Victor Stinner5b1ef202020-03-17 18:09:46 +0100408#define TEST_MODULE_DEF(name, slots, methods) { \
Nick Coghland5cacbb2015-05-23 22:24:10 +1000409 PyModuleDef_HEAD_INIT, /* m_base */ \
410 name, /* m_name */ \
411 PyDoc_STR("Test module " name), /* m_doc */ \
Victor Stinner5b1ef202020-03-17 18:09:46 +0100412 0, /* m_size */ \
Nick Coghland5cacbb2015-05-23 22:24:10 +1000413 methods, /* m_methods */ \
414 slots, /* m_slots */ \
Victor Stinner5b1ef202020-03-17 18:09:46 +0100415 NULL, /* m_traverse */ \
Nick Coghland5cacbb2015-05-23 22:24:10 +1000416 NULL, /* m_clear */ \
417 NULL, /* m_free */ \
418}
419
Benjamin Petersoncb4bae72018-07-06 21:05:51 -0700420static PyModuleDef_Slot main_slots[] = {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000421 {Py_mod_exec, execfunc},
422 {0, NULL},
423};
424
425static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
426
427PyMODINIT_FUNC
428PyInit__testmultiphase(PyObject *spec)
429{
430 return PyModuleDef_Init(&main_def);
431}
432
433
434/**** Importing a non-module object ****/
435
436static PyModuleDef def_nonmodule;
Nick Coghlan8682f572016-08-21 17:41:56 +1000437static PyModuleDef def_nonmodule_with_methods;
Nick Coghland5cacbb2015-05-23 22:24:10 +1000438
439/* Create a SimpleNamespace(three=3) */
440static PyObject*
441createfunc_nonmodule(PyObject *spec, PyModuleDef *def)
442{
443 PyObject *dct, *ns, *three;
444
Nick Coghlan8682f572016-08-21 17:41:56 +1000445 if (def != &def_nonmodule && def != &def_nonmodule_with_methods) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000446 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);
Nick Coghlana48db2b2015-05-24 01:03:46 +1000460 Py_DECREF(three);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000461
462 ns = _PyNamespace_New(dct);
463 Py_DECREF(dct);
464 return ns;
465}
466
467static PyModuleDef_Slot slots_create_nonmodule[] = {
468 {Py_mod_create, createfunc_nonmodule},
469 {0, NULL},
470};
471
472static PyModuleDef def_nonmodule = TEST_MODULE_DEF(
473 "_testmultiphase_nonmodule", slots_create_nonmodule, NULL);
474
475PyMODINIT_FUNC
476PyInit__testmultiphase_nonmodule(PyObject *spec)
477{
478 return PyModuleDef_Init(&def_nonmodule);
479}
480
Nick Coghlan8682f572016-08-21 17:41:56 +1000481PyDoc_STRVAR(nonmodule_bar_doc,
482"bar(i,j)\n\
483\n\
484Return the difference of i - j.");
485
486static PyObject *
487nonmodule_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
497static PyMethodDef nonmodule_methods[] = {
498 {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc},
499 {NULL, NULL} /* sentinel */
500};
501
502static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF(
503 "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods);
504
505PyMODINIT_FUNC
506PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec)
507{
508 return PyModuleDef_Init(&def_nonmodule_with_methods);
509}
510
Nick Coghland5cacbb2015-05-23 22:24:10 +1000511/**** Non-ASCII-named modules ****/
512
513static 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
525PyMODINIT_FUNC
526PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec)
527{
528 return PyModuleDef_Init(&def_nonascii_latin);
529}
530
531static 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
543PyMODINIT_FUNC
544PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec)
545{
546 return PyModuleDef_Init(&def_nonascii_kana);
547}
548
Benjamin Petersone20056c2015-05-29 17:10:30 -0500549/*** Module with a single-character name ***/
550
551PyMODINIT_FUNC
552PyInit_x(PyObject *spec)
553{
554 return PyModuleDef_Init(&main_def);
555}
556
Nick Coghland5cacbb2015-05-23 22:24:10 +1000557/**** Testing NULL slots ****/
558
559static PyModuleDef null_slots_def = TEST_MODULE_DEF(
560 "_testmultiphase_null_slots", NULL, NULL);
561
562PyMODINIT_FUNC
563PyInit__testmultiphase_null_slots(PyObject *spec)
564{
565 return PyModuleDef_Init(&null_slots_def);
566}
567
568/**** Problematic modules ****/
569
570static PyModuleDef_Slot slots_bad_large[] = {
571 {_Py_mod_LAST_SLOT + 1, NULL},
572 {0, NULL},
573};
574
575static PyModuleDef def_bad_large = TEST_MODULE_DEF(
576 "_testmultiphase_bad_slot_large", slots_bad_large, NULL);
577
578PyMODINIT_FUNC
579PyInit__testmultiphase_bad_slot_large(PyObject *spec)
580{
581 return PyModuleDef_Init(&def_bad_large);
582}
583
584static PyModuleDef_Slot slots_bad_negative[] = {
585 {-1, NULL},
586 {0, NULL},
587};
588
589static PyModuleDef def_bad_negative = TEST_MODULE_DEF(
590 "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL);
591
592PyMODINIT_FUNC
593PyInit__testmultiphase_bad_slot_negative(PyObject *spec)
594{
595 return PyModuleDef_Init(&def_bad_negative);
596}
597
598static 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
610PyMODINIT_FUNC
611PyInit__testmultiphase_create_int_with_state(PyObject *spec)
612{
613 return PyModuleDef_Init(&def_create_int_with_state);
614}
615
616
617static 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
629PyMODINIT_FUNC
630PyInit__testmultiphase_negative_size(PyObject *spec)
631{
632 return PyModuleDef_Init(&def_negative_size);
633}
634
635
636static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
637
638PyMODINIT_FUNC
639PyInit__testmultiphase_export_uninitialized(PyObject *spec)
640{
641 return (PyObject*) &uninitialized_def;
642}
643
644PyMODINIT_FUNC
645PyInit__testmultiphase_export_null(PyObject *spec)
646{
647 return NULL;
648}
649
650PyMODINIT_FUNC
651PyInit__testmultiphase_export_raise(PyObject *spec)
652{
653 PyErr_SetString(PyExc_SystemError, "bad export function");
654 return NULL;
655}
656
657PyMODINIT_FUNC
658PyInit__testmultiphase_export_unreported_exception(PyObject *spec)
659{
660 PyErr_SetString(PyExc_SystemError, "bad export function");
661 return PyModuleDef_Init(&main_def);
662}
663
664static PyObject*
665createfunc_null(PyObject *spec, PyModuleDef *def)
666{
667 return NULL;
668}
669
Benjamin Petersoncb4bae72018-07-06 21:05:51 -0700670static PyModuleDef_Slot slots_create_null[] = {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000671 {Py_mod_create, createfunc_null},
672 {0, NULL},
673};
674
675static PyModuleDef def_create_null = TEST_MODULE_DEF(
676 "_testmultiphase_create_null", slots_create_null, NULL);
677
678PyMODINIT_FUNC
679PyInit__testmultiphase_create_null(PyObject *spec)
680{
681 return PyModuleDef_Init(&def_create_null);
682}
683
684static PyObject*
685createfunc_raise(PyObject *spec, PyModuleDef *def)
686{
687 PyErr_SetString(PyExc_SystemError, "bad create function");
688 return NULL;
689}
690
691static PyModuleDef_Slot slots_create_raise[] = {
692 {Py_mod_create, createfunc_raise},
693 {0, NULL},
694};
695
696static PyModuleDef def_create_raise = TEST_MODULE_DEF(
697 "_testmultiphase_create_null", slots_create_raise, NULL);
698
699PyMODINIT_FUNC
700PyInit__testmultiphase_create_raise(PyObject *spec)
701{
702 return PyModuleDef_Init(&def_create_raise);
703}
704
705static PyObject*
706createfunc_unreported_exception(PyObject *spec, PyModuleDef *def)
707{
708 PyErr_SetString(PyExc_SystemError, "bad create function");
709 return PyModule_New("foo");
710}
711
712static PyModuleDef_Slot slots_create_unreported_exception[] = {
713 {Py_mod_create, createfunc_unreported_exception},
714 {0, NULL},
715};
716
717static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF(
718 "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL);
719
720PyMODINIT_FUNC
721PyInit__testmultiphase_create_unreported_exception(PyObject *spec)
722{
723 return PyModuleDef_Init(&def_create_unreported_exception);
724}
725
726static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = {
727 {Py_mod_create, createfunc_nonmodule},
728 {Py_mod_exec, execfunc},
729 {0, NULL},
730};
731
732static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF(
733 "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL);
734
735PyMODINIT_FUNC
736PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec)
737{
738 return PyModuleDef_Init(&def_nonmodule_with_exec_slots);
739}
740
741static int
742execfunc_err(PyObject *mod)
743{
744 return -1;
745}
746
747static PyModuleDef_Slot slots_exec_err[] = {
748 {Py_mod_exec, execfunc_err},
749 {0, NULL},
750};
751
752static PyModuleDef def_exec_err = TEST_MODULE_DEF(
753 "_testmultiphase_exec_err", slots_exec_err, NULL);
754
755PyMODINIT_FUNC
756PyInit__testmultiphase_exec_err(PyObject *spec)
757{
758 return PyModuleDef_Init(&def_exec_err);
759}
760
761static int
762execfunc_raise(PyObject *spec)
763{
764 PyErr_SetString(PyExc_SystemError, "bad exec function");
765 return -1;
766}
767
768static PyModuleDef_Slot slots_exec_raise[] = {
769 {Py_mod_exec, execfunc_raise},
770 {0, NULL},
771};
772
773static PyModuleDef def_exec_raise = TEST_MODULE_DEF(
774 "_testmultiphase_exec_raise", slots_exec_raise, NULL);
775
776PyMODINIT_FUNC
777PyInit__testmultiphase_exec_raise(PyObject *mod)
778{
779 return PyModuleDef_Init(&def_exec_raise);
780}
781
782static int
783execfunc_unreported_exception(PyObject *mod)
784{
785 PyErr_SetString(PyExc_SystemError, "bad exec function");
786 return 0;
787}
788
789static PyModuleDef_Slot slots_exec_unreported_exception[] = {
790 {Py_mod_exec, execfunc_unreported_exception},
791 {0, NULL},
792};
793
794static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF(
795 "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL);
796
797PyMODINIT_FUNC
798PyInit__testmultiphase_exec_unreported_exception(PyObject *spec)
799{
800 return PyModuleDef_Init(&def_exec_unreported_exception);
801}
Nick Coghlan9d3c61c2015-09-05 21:05:05 +1000802
Petr Viktorine1becf42020-05-07 15:39:59 +0200803static int
804meth_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) {
Dong-hee Na8a9463f2020-10-22 18:44:18 +0900819 Py_DECREF(temp);
Petr Viktorine1becf42020-05-07 15:39:59 +0200820 return -1;
821 }
822
823
824 return 0;
825}
826
827static PyModuleDef_Slot meth_state_access_slots[] = {
828 {Py_mod_exec, meth_state_access_exec},
829 {0, NULL}
830};
831
832static PyModuleDef def_meth_state_access = {
Hai Shic068b532020-05-08 01:16:01 +0800833 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,
Petr Viktorine1becf42020-05-07 15:39:59 +0200839};
840
841PyMODINIT_FUNC
842PyInit__testmultiphase_meth_state_access(PyObject *spec)
843{
844 return PyModuleDef_Init(&def_meth_state_access);
845}
846
847
Nick Coghlan9d3c61c2015-09-05 21:05:05 +1000848/*** Helper for imp test ***/
849
850static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods);
851
852PyMODINIT_FUNC
853PyInit_imp_dummy(PyObject *spec)
854{
855 return PyModuleDef_Init(&imp_dummy_def);
856}
Marcel Plchc2b0b122018-03-17 06:41:20 +0100857