ยปCore Development>Code coverage>Modules/_testmultiphase.c

Python code coverage for Modules/_testmultiphase.c

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