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