blob: 4daa34e106146a519cc8532594154b7918e0803b [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
7/* Example objects */
8typedef struct {
9 PyObject_HEAD
10 PyObject *x_attr; /* Attributes dictionary */
11} ExampleObject;
12
13/* Example methods */
14
Nick Coghlan53f95022015-06-04 21:52:57 +100015static int
16Example_traverse(ExampleObject *self, visitproc visit, void *arg)
Nick Coghland5cacbb2015-05-23 22:24:10 +100017{
Nick Coghlan53f95022015-06-04 21:52:57 +100018 Py_VISIT(self->x_attr);
19 return 0;
20}
21
22static int
23Example_finalize(ExampleObject *self)
24{
25 Py_CLEAR(self->x_attr);
26 return 0;
Nick Coghland5cacbb2015-05-23 22:24:10 +100027}
28
29static PyObject *
30Example_demo(ExampleObject *self, PyObject *args)
31{
32 PyObject *o = NULL;
33 if (!PyArg_ParseTuple(args, "|O:demo", &o))
34 return NULL;
35 if (o != NULL && PyUnicode_Check(o)) {
36 Py_INCREF(o);
37 return o;
38 }
39 Py_INCREF(Py_None);
40 return Py_None;
41}
42
43
44static PyMethodDef Example_methods[] = {
45 {"demo", (PyCFunction)Example_demo, METH_VARARGS,
46 PyDoc_STR("demo() -> None")},
47 {NULL, NULL} /* sentinel */
48};
49
50static PyObject *
51Example_getattro(ExampleObject *self, PyObject *name)
52{
53 if (self->x_attr != NULL) {
54 PyObject *v = PyDict_GetItem(self->x_attr, name);
55 if (v != NULL) {
56 Py_INCREF(v);
57 return v;
58 }
59 }
60 return PyObject_GenericGetAttr((PyObject *)self, name);
61}
62
63static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020064Example_setattr(ExampleObject *self, const char *name, PyObject *v)
Nick Coghland5cacbb2015-05-23 22:24:10 +100065{
66 if (self->x_attr == NULL) {
67 self->x_attr = PyDict_New();
68 if (self->x_attr == NULL)
69 return -1;
70 }
71 if (v == NULL) {
72 int rv = PyDict_DelItemString(self->x_attr, name);
73 if (rv < 0)
74 PyErr_SetString(PyExc_AttributeError,
75 "delete non-existing Example attribute");
76 return rv;
77 }
78 else
79 return PyDict_SetItemString(self->x_attr, name, v);
80}
81
82static PyType_Slot Example_Type_slots[] = {
83 {Py_tp_doc, "The Example type"},
Nick Coghlan53f95022015-06-04 21:52:57 +100084 {Py_tp_finalize, Example_finalize},
85 {Py_tp_traverse, Example_traverse},
Nick Coghland5cacbb2015-05-23 22:24:10 +100086 {Py_tp_getattro, Example_getattro},
87 {Py_tp_setattr, Example_setattr},
88 {Py_tp_methods, Example_methods},
89 {0, 0},
90};
91
92static PyType_Spec Example_Type_spec = {
93 "_testimportexec.Example",
94 sizeof(ExampleObject),
95 0,
Nick Coghlan53f95022015-06-04 21:52:57 +100096 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE,
Nick Coghland5cacbb2015-05-23 22:24:10 +100097 Example_Type_slots
98};
99
100/* Function of two integers returning integer */
101
102PyDoc_STRVAR(testexport_foo_doc,
103"foo(i,j)\n\
104\n\
105Return the sum of i and j.");
106
107static PyObject *
108testexport_foo(PyObject *self, PyObject *args)
109{
110 long i, j;
111 long res;
112 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
113 return NULL;
114 res = i + j;
115 return PyLong_FromLong(res);
116}
117
118/* Test that PyState registration fails */
119
120PyDoc_STRVAR(call_state_registration_func_doc,
121"register_state(0): call PyState_FindModule()\n\
122register_state(1): call PyState_AddModule()\n\
123register_state(2): call PyState_RemoveModule()");
124
125static PyObject *
126call_state_registration_func(PyObject *mod, PyObject *args)
127{
128 int i, ret;
129 PyModuleDef *def = PyModule_GetDef(mod);
130 if (def == NULL) {
131 return NULL;
132 }
133 if (!PyArg_ParseTuple(args, "i:call_state_registration_func", &i))
134 return NULL;
135 switch (i) {
136 case 0:
137 mod = PyState_FindModule(def);
138 if (mod == NULL) {
139 Py_RETURN_NONE;
140 }
141 return mod;
142 case 1:
143 ret = PyState_AddModule(mod, def);
144 if (ret != 0) {
145 return NULL;
146 }
147 break;
148 case 2:
149 ret = PyState_RemoveModule(def);
150 if (ret != 0) {
151 return NULL;
152 }
153 break;
154 }
155 Py_RETURN_NONE;
156}
157
158
159static PyType_Slot Str_Type_slots[] = {
160 {Py_tp_base, NULL}, /* filled out in module exec function */
161 {0, 0},
162};
163
164static PyType_Spec Str_Type_spec = {
165 "_testimportexec.Str",
166 0,
167 0,
168 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
169 Str_Type_slots
170};
171
172static PyMethodDef testexport_methods[] = {
173 {"foo", testexport_foo, METH_VARARGS,
174 testexport_foo_doc},
175 {"call_state_registration_func", call_state_registration_func,
176 METH_VARARGS, call_state_registration_func_doc},
177 {NULL, NULL} /* sentinel */
178};
179
180static int execfunc(PyObject *m)
181{
182 PyObject *temp = NULL;
183
184 /* Due to cross platform compiler issues the slots must be filled
185 * here. It's required for portability to Windows without requiring
186 * C++. */
187 Str_Type_slots[0].pfunc = &PyUnicode_Type;
188
189 /* Add a custom type */
190 temp = PyType_FromSpec(&Example_Type_spec);
191 if (temp == NULL)
192 goto fail;
193 if (PyModule_AddObject(m, "Example", temp) != 0)
194 goto fail;
195
196 /* Add an exception type */
197 temp = PyErr_NewException("_testimportexec.error", NULL, NULL);
198 if (temp == NULL)
199 goto fail;
200 if (PyModule_AddObject(m, "error", temp) != 0)
201 goto fail;
202
203 /* Add Str */
204 temp = PyType_FromSpec(&Str_Type_spec);
205 if (temp == NULL)
206 goto fail;
207 if (PyModule_AddObject(m, "Str", temp) != 0)
208 goto fail;
209
210 if (PyModule_AddIntConstant(m, "int_const", 1969) != 0)
211 goto fail;
212
213 if (PyModule_AddStringConstant(m, "str_const", "something different") != 0)
214 goto fail;
215
216 return 0;
217 fail:
218 return -1;
219}
220
221/* Helper for module definitions; there'll be a lot of them */
222#define TEST_MODULE_DEF(name, slots, methods) { \
223 PyModuleDef_HEAD_INIT, /* m_base */ \
224 name, /* m_name */ \
225 PyDoc_STR("Test module " name), /* m_doc */ \
226 0, /* m_size */ \
227 methods, /* m_methods */ \
228 slots, /* m_slots */ \
229 NULL, /* m_traverse */ \
230 NULL, /* m_clear */ \
231 NULL, /* m_free */ \
232}
233
234PyModuleDef_Slot main_slots[] = {
235 {Py_mod_exec, execfunc},
236 {0, NULL},
237};
238
239static PyModuleDef main_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
240
241PyMODINIT_FUNC
242PyInit__testmultiphase(PyObject *spec)
243{
244 return PyModuleDef_Init(&main_def);
245}
246
247
248/**** Importing a non-module object ****/
249
250static PyModuleDef def_nonmodule;
Nick Coghlan8682f572016-08-21 17:41:56 +1000251static PyModuleDef def_nonmodule_with_methods;
Nick Coghland5cacbb2015-05-23 22:24:10 +1000252
253/* Create a SimpleNamespace(three=3) */
254static PyObject*
255createfunc_nonmodule(PyObject *spec, PyModuleDef *def)
256{
257 PyObject *dct, *ns, *three;
258
Nick Coghlan8682f572016-08-21 17:41:56 +1000259 if (def != &def_nonmodule && def != &def_nonmodule_with_methods) {
Nick Coghland5cacbb2015-05-23 22:24:10 +1000260 PyErr_SetString(PyExc_SystemError, "def does not match");
261 return NULL;
262 }
263
264 dct = PyDict_New();
265 if (dct == NULL)
266 return NULL;
267
268 three = PyLong_FromLong(3);
269 if (three == NULL) {
270 Py_DECREF(dct);
271 return NULL;
272 }
273 PyDict_SetItemString(dct, "three", three);
Nick Coghlana48db2b2015-05-24 01:03:46 +1000274 Py_DECREF(three);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000275
276 ns = _PyNamespace_New(dct);
277 Py_DECREF(dct);
278 return ns;
279}
280
281static PyModuleDef_Slot slots_create_nonmodule[] = {
282 {Py_mod_create, createfunc_nonmodule},
283 {0, NULL},
284};
285
286static PyModuleDef def_nonmodule = TEST_MODULE_DEF(
287 "_testmultiphase_nonmodule", slots_create_nonmodule, NULL);
288
289PyMODINIT_FUNC
290PyInit__testmultiphase_nonmodule(PyObject *spec)
291{
292 return PyModuleDef_Init(&def_nonmodule);
293}
294
Nick Coghlan8682f572016-08-21 17:41:56 +1000295PyDoc_STRVAR(nonmodule_bar_doc,
296"bar(i,j)\n\
297\n\
298Return the difference of i - j.");
299
300static PyObject *
301nonmodule_bar(PyObject *self, PyObject *args)
302{
303 long i, j;
304 long res;
305 if (!PyArg_ParseTuple(args, "ll:bar", &i, &j))
306 return NULL;
307 res = i - j;
308 return PyLong_FromLong(res);
309}
310
311static PyMethodDef nonmodule_methods[] = {
312 {"bar", nonmodule_bar, METH_VARARGS, nonmodule_bar_doc},
313 {NULL, NULL} /* sentinel */
314};
315
316static PyModuleDef def_nonmodule_with_methods = TEST_MODULE_DEF(
317 "_testmultiphase_nonmodule_with_methods", slots_create_nonmodule, nonmodule_methods);
318
319PyMODINIT_FUNC
320PyInit__testmultiphase_nonmodule_with_methods(PyObject *spec)
321{
322 return PyModuleDef_Init(&def_nonmodule_with_methods);
323}
324
Nick Coghland5cacbb2015-05-23 22:24:10 +1000325/**** Non-ASCII-named modules ****/
326
327static PyModuleDef def_nonascii_latin = { \
328 PyModuleDef_HEAD_INIT, /* m_base */
329 "_testmultiphase_nonascii_latin", /* m_name */
330 PyDoc_STR("Module named in Czech"), /* m_doc */
331 0, /* m_size */
332 NULL, /* m_methods */
333 NULL, /* m_slots */
334 NULL, /* m_traverse */
335 NULL, /* m_clear */
336 NULL, /* m_free */
337};
338
339PyMODINIT_FUNC
340PyInitU__testmultiphase_zkouka_naten_evc07gi8e(PyObject *spec)
341{
342 return PyModuleDef_Init(&def_nonascii_latin);
343}
344
345static PyModuleDef def_nonascii_kana = { \
346 PyModuleDef_HEAD_INIT, /* m_base */
347 "_testmultiphase_nonascii_kana", /* m_name */
348 PyDoc_STR("Module named in Japanese"), /* m_doc */
349 0, /* m_size */
350 NULL, /* m_methods */
351 NULL, /* m_slots */
352 NULL, /* m_traverse */
353 NULL, /* m_clear */
354 NULL, /* m_free */
355};
356
357PyMODINIT_FUNC
358PyInitU_eckzbwbhc6jpgzcx415x(PyObject *spec)
359{
360 return PyModuleDef_Init(&def_nonascii_kana);
361}
362
Benjamin Petersone20056c2015-05-29 17:10:30 -0500363/*** Module with a single-character name ***/
364
365PyMODINIT_FUNC
366PyInit_x(PyObject *spec)
367{
368 return PyModuleDef_Init(&main_def);
369}
370
Nick Coghland5cacbb2015-05-23 22:24:10 +1000371/**** Testing NULL slots ****/
372
373static PyModuleDef null_slots_def = TEST_MODULE_DEF(
374 "_testmultiphase_null_slots", NULL, NULL);
375
376PyMODINIT_FUNC
377PyInit__testmultiphase_null_slots(PyObject *spec)
378{
379 return PyModuleDef_Init(&null_slots_def);
380}
381
382/**** Problematic modules ****/
383
384static PyModuleDef_Slot slots_bad_large[] = {
385 {_Py_mod_LAST_SLOT + 1, NULL},
386 {0, NULL},
387};
388
389static PyModuleDef def_bad_large = TEST_MODULE_DEF(
390 "_testmultiphase_bad_slot_large", slots_bad_large, NULL);
391
392PyMODINIT_FUNC
393PyInit__testmultiphase_bad_slot_large(PyObject *spec)
394{
395 return PyModuleDef_Init(&def_bad_large);
396}
397
398static PyModuleDef_Slot slots_bad_negative[] = {
399 {-1, NULL},
400 {0, NULL},
401};
402
403static PyModuleDef def_bad_negative = TEST_MODULE_DEF(
404 "_testmultiphase_bad_slot_negative", slots_bad_negative, NULL);
405
406PyMODINIT_FUNC
407PyInit__testmultiphase_bad_slot_negative(PyObject *spec)
408{
409 return PyModuleDef_Init(&def_bad_negative);
410}
411
412static PyModuleDef def_create_int_with_state = { \
413 PyModuleDef_HEAD_INIT, /* m_base */
414 "create_with_state", /* m_name */
415 PyDoc_STR("Not a PyModuleObject object, but requests per-module state"),
416 10, /* m_size */
417 NULL, /* m_methods */
418 slots_create_nonmodule, /* m_slots */
419 NULL, /* m_traverse */
420 NULL, /* m_clear */
421 NULL, /* m_free */
422};
423
424PyMODINIT_FUNC
425PyInit__testmultiphase_create_int_with_state(PyObject *spec)
426{
427 return PyModuleDef_Init(&def_create_int_with_state);
428}
429
430
431static PyModuleDef def_negative_size = { \
432 PyModuleDef_HEAD_INIT, /* m_base */
433 "negative_size", /* m_name */
434 PyDoc_STR("PyModuleDef with negative m_size"),
435 -1, /* m_size */
436 NULL, /* m_methods */
437 slots_create_nonmodule, /* m_slots */
438 NULL, /* m_traverse */
439 NULL, /* m_clear */
440 NULL, /* m_free */
441};
442
443PyMODINIT_FUNC
444PyInit__testmultiphase_negative_size(PyObject *spec)
445{
446 return PyModuleDef_Init(&def_negative_size);
447}
448
449
450static PyModuleDef uninitialized_def = TEST_MODULE_DEF("main", main_slots, testexport_methods);
451
452PyMODINIT_FUNC
453PyInit__testmultiphase_export_uninitialized(PyObject *spec)
454{
455 return (PyObject*) &uninitialized_def;
456}
457
458PyMODINIT_FUNC
459PyInit__testmultiphase_export_null(PyObject *spec)
460{
461 return NULL;
462}
463
464PyMODINIT_FUNC
465PyInit__testmultiphase_export_raise(PyObject *spec)
466{
467 PyErr_SetString(PyExc_SystemError, "bad export function");
468 return NULL;
469}
470
471PyMODINIT_FUNC
472PyInit__testmultiphase_export_unreported_exception(PyObject *spec)
473{
474 PyErr_SetString(PyExc_SystemError, "bad export function");
475 return PyModuleDef_Init(&main_def);
476}
477
478static PyObject*
479createfunc_null(PyObject *spec, PyModuleDef *def)
480{
481 return NULL;
482}
483
484PyModuleDef_Slot slots_create_null[] = {
485 {Py_mod_create, createfunc_null},
486 {0, NULL},
487};
488
489static PyModuleDef def_create_null = TEST_MODULE_DEF(
490 "_testmultiphase_create_null", slots_create_null, NULL);
491
492PyMODINIT_FUNC
493PyInit__testmultiphase_create_null(PyObject *spec)
494{
495 return PyModuleDef_Init(&def_create_null);
496}
497
498static PyObject*
499createfunc_raise(PyObject *spec, PyModuleDef *def)
500{
501 PyErr_SetString(PyExc_SystemError, "bad create function");
502 return NULL;
503}
504
505static PyModuleDef_Slot slots_create_raise[] = {
506 {Py_mod_create, createfunc_raise},
507 {0, NULL},
508};
509
510static PyModuleDef def_create_raise = TEST_MODULE_DEF(
511 "_testmultiphase_create_null", slots_create_raise, NULL);
512
513PyMODINIT_FUNC
514PyInit__testmultiphase_create_raise(PyObject *spec)
515{
516 return PyModuleDef_Init(&def_create_raise);
517}
518
519static PyObject*
520createfunc_unreported_exception(PyObject *spec, PyModuleDef *def)
521{
522 PyErr_SetString(PyExc_SystemError, "bad create function");
523 return PyModule_New("foo");
524}
525
526static PyModuleDef_Slot slots_create_unreported_exception[] = {
527 {Py_mod_create, createfunc_unreported_exception},
528 {0, NULL},
529};
530
531static PyModuleDef def_create_unreported_exception = TEST_MODULE_DEF(
532 "_testmultiphase_create_unreported_exception", slots_create_unreported_exception, NULL);
533
534PyMODINIT_FUNC
535PyInit__testmultiphase_create_unreported_exception(PyObject *spec)
536{
537 return PyModuleDef_Init(&def_create_unreported_exception);
538}
539
540static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = {
541 {Py_mod_create, createfunc_nonmodule},
542 {Py_mod_exec, execfunc},
543 {0, NULL},
544};
545
546static PyModuleDef def_nonmodule_with_exec_slots = TEST_MODULE_DEF(
547 "_testmultiphase_nonmodule_with_exec_slots", slots_nonmodule_with_exec_slots, NULL);
548
549PyMODINIT_FUNC
550PyInit__testmultiphase_nonmodule_with_exec_slots(PyObject *spec)
551{
552 return PyModuleDef_Init(&def_nonmodule_with_exec_slots);
553}
554
555static int
556execfunc_err(PyObject *mod)
557{
558 return -1;
559}
560
561static PyModuleDef_Slot slots_exec_err[] = {
562 {Py_mod_exec, execfunc_err},
563 {0, NULL},
564};
565
566static PyModuleDef def_exec_err = TEST_MODULE_DEF(
567 "_testmultiphase_exec_err", slots_exec_err, NULL);
568
569PyMODINIT_FUNC
570PyInit__testmultiphase_exec_err(PyObject *spec)
571{
572 return PyModuleDef_Init(&def_exec_err);
573}
574
575static int
576execfunc_raise(PyObject *spec)
577{
578 PyErr_SetString(PyExc_SystemError, "bad exec function");
579 return -1;
580}
581
582static PyModuleDef_Slot slots_exec_raise[] = {
583 {Py_mod_exec, execfunc_raise},
584 {0, NULL},
585};
586
587static PyModuleDef def_exec_raise = TEST_MODULE_DEF(
588 "_testmultiphase_exec_raise", slots_exec_raise, NULL);
589
590PyMODINIT_FUNC
591PyInit__testmultiphase_exec_raise(PyObject *mod)
592{
593 return PyModuleDef_Init(&def_exec_raise);
594}
595
596static int
597execfunc_unreported_exception(PyObject *mod)
598{
599 PyErr_SetString(PyExc_SystemError, "bad exec function");
600 return 0;
601}
602
603static PyModuleDef_Slot slots_exec_unreported_exception[] = {
604 {Py_mod_exec, execfunc_unreported_exception},
605 {0, NULL},
606};
607
608static PyModuleDef def_exec_unreported_exception = TEST_MODULE_DEF(
609 "_testmultiphase_exec_unreported_exception", slots_exec_unreported_exception, NULL);
610
611PyMODINIT_FUNC
612PyInit__testmultiphase_exec_unreported_exception(PyObject *spec)
613{
614 return PyModuleDef_Init(&def_exec_unreported_exception);
615}
Nick Coghlan9d3c61c2015-09-05 21:05:05 +1000616
617/*** Helper for imp test ***/
618
619static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods);
620
621PyMODINIT_FUNC
622PyInit_imp_dummy(PyObject *spec)
623{
624 return PyModuleDef_Init(&imp_dummy_def);
625}