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