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