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

Python code coverage for Modules/xxmodule.c

#countcontent
1n/a
2n/a/* Use this file as a template to start implementing a module that
3n/a also declares object types. All occurrences of 'Xxo' should be changed
4n/a to something reasonable for your objects. After that, all other
5n/a occurrences of 'xx' should be changed to something reasonable for your
6n/a module. If your module is named foo your sourcefile should be named
7n/a foomodule.c.
8n/a
9n/a You will probably want to delete all references to 'x_attr' and add
10n/a your own types of attributes instead. Maybe you want to name your
11n/a local variables other than 'self'. If your object type is needed in
12n/a other files, you'll have to create a file "foobarobject.h"; see
13n/a floatobject.h for an example. */
14n/a
15n/a/* Xxo objects */
16n/a
17n/a#include "Python.h"
18n/a
19n/astatic PyObject *ErrorObject;
20n/a
21n/atypedef struct {
22n/a PyObject_HEAD
23n/a PyObject *x_attr; /* Attributes dictionary */
24n/a} XxoObject;
25n/a
26n/astatic PyTypeObject Xxo_Type;
27n/a
28n/a#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type)
29n/a
30n/astatic XxoObject *
31n/anewXxoObject(PyObject *arg)
32n/a{
33n/a XxoObject *self;
34n/a self = PyObject_New(XxoObject, &Xxo_Type);
35n/a if (self == NULL)
36n/a return NULL;
37n/a self->x_attr = NULL;
38n/a return self;
39n/a}
40n/a
41n/a/* Xxo methods */
42n/a
43n/astatic void
44n/aXxo_dealloc(XxoObject *self)
45n/a{
46n/a Py_XDECREF(self->x_attr);
47n/a PyObject_Del(self);
48n/a}
49n/a
50n/astatic PyObject *
51n/aXxo_demo(XxoObject *self, PyObject *args)
52n/a{
53n/a if (!PyArg_ParseTuple(args, ":demo"))
54n/a return NULL;
55n/a Py_INCREF(Py_None);
56n/a return Py_None;
57n/a}
58n/a
59n/astatic PyMethodDef Xxo_methods[] = {
60n/a {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
61n/a PyDoc_STR("demo() -> None")},
62n/a {NULL, NULL} /* sentinel */
63n/a};
64n/a
65n/astatic PyObject *
66n/aXxo_getattro(XxoObject *self, PyObject *name)
67n/a{
68n/a if (self->x_attr != NULL) {
69n/a PyObject *v = PyDict_GetItem(self->x_attr, name);
70n/a if (v != NULL) {
71n/a Py_INCREF(v);
72n/a return v;
73n/a }
74n/a }
75n/a return PyObject_GenericGetAttr((PyObject *)self, name);
76n/a}
77n/a
78n/astatic int
79n/aXxo_setattr(XxoObject *self, const char *name, PyObject *v)
80n/a{
81n/a if (self->x_attr == NULL) {
82n/a self->x_attr = PyDict_New();
83n/a if (self->x_attr == NULL)
84n/a return -1;
85n/a }
86n/a if (v == NULL) {
87n/a int rv = PyDict_DelItemString(self->x_attr, name);
88n/a if (rv < 0)
89n/a PyErr_SetString(PyExc_AttributeError,
90n/a "delete non-existing Xxo attribute");
91n/a return rv;
92n/a }
93n/a else
94n/a return PyDict_SetItemString(self->x_attr, name, v);
95n/a}
96n/a
97n/astatic PyTypeObject Xxo_Type = {
98n/a /* The ob_type field must be initialized in the module init function
99n/a * to be portable to Windows without using C++. */
100n/a PyVarObject_HEAD_INIT(NULL, 0)
101n/a "xxmodule.Xxo", /*tp_name*/
102n/a sizeof(XxoObject), /*tp_basicsize*/
103n/a 0, /*tp_itemsize*/
104n/a /* methods */
105n/a (destructor)Xxo_dealloc, /*tp_dealloc*/
106n/a 0, /*tp_print*/
107n/a (getattrfunc)0, /*tp_getattr*/
108n/a (setattrfunc)Xxo_setattr, /*tp_setattr*/
109n/a 0, /*tp_reserved*/
110n/a 0, /*tp_repr*/
111n/a 0, /*tp_as_number*/
112n/a 0, /*tp_as_sequence*/
113n/a 0, /*tp_as_mapping*/
114n/a 0, /*tp_hash*/
115n/a 0, /*tp_call*/
116n/a 0, /*tp_str*/
117n/a (getattrofunc)Xxo_getattro, /*tp_getattro*/
118n/a 0, /*tp_setattro*/
119n/a 0, /*tp_as_buffer*/
120n/a Py_TPFLAGS_DEFAULT, /*tp_flags*/
121n/a 0, /*tp_doc*/
122n/a 0, /*tp_traverse*/
123n/a 0, /*tp_clear*/
124n/a 0, /*tp_richcompare*/
125n/a 0, /*tp_weaklistoffset*/
126n/a 0, /*tp_iter*/
127n/a 0, /*tp_iternext*/
128n/a Xxo_methods, /*tp_methods*/
129n/a 0, /*tp_members*/
130n/a 0, /*tp_getset*/
131n/a 0, /*tp_base*/
132n/a 0, /*tp_dict*/
133n/a 0, /*tp_descr_get*/
134n/a 0, /*tp_descr_set*/
135n/a 0, /*tp_dictoffset*/
136n/a 0, /*tp_init*/
137n/a 0, /*tp_alloc*/
138n/a 0, /*tp_new*/
139n/a 0, /*tp_free*/
140n/a 0, /*tp_is_gc*/
141n/a};
142n/a/* --------------------------------------------------------------------- */
143n/a
144n/a/* Function of two integers returning integer */
145n/a
146n/aPyDoc_STRVAR(xx_foo_doc,
147n/a"foo(i,j)\n\
148n/a\n\
149n/aReturn the sum of i and j.");
150n/a
151n/astatic PyObject *
152n/axx_foo(PyObject *self, PyObject *args)
153n/a{
154n/a long i, j;
155n/a long res;
156n/a if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
157n/a return NULL;
158n/a res = i+j; /* XXX Do something here */
159n/a return PyLong_FromLong(res);
160n/a}
161n/a
162n/a
163n/a/* Function of no arguments returning new Xxo object */
164n/a
165n/astatic PyObject *
166n/axx_new(PyObject *self, PyObject *args)
167n/a{
168n/a XxoObject *rv;
169n/a
170n/a if (!PyArg_ParseTuple(args, ":new"))
171n/a return NULL;
172n/a rv = newXxoObject(args);
173n/a if (rv == NULL)
174n/a return NULL;
175n/a return (PyObject *)rv;
176n/a}
177n/a
178n/a/* Example with subtle bug from extensions manual ("Thin Ice"). */
179n/a
180n/astatic PyObject *
181n/axx_bug(PyObject *self, PyObject *args)
182n/a{
183n/a PyObject *list, *item;
184n/a
185n/a if (!PyArg_ParseTuple(args, "O:bug", &list))
186n/a return NULL;
187n/a
188n/a item = PyList_GetItem(list, 0);
189n/a /* Py_INCREF(item); */
190n/a PyList_SetItem(list, 1, PyLong_FromLong(0L));
191n/a PyObject_Print(item, stdout, 0);
192n/a printf("\n");
193n/a /* Py_DECREF(item); */
194n/a
195n/a Py_INCREF(Py_None);
196n/a return Py_None;
197n/a}
198n/a
199n/a/* Test bad format character */
200n/a
201n/astatic PyObject *
202n/axx_roj(PyObject *self, PyObject *args)
203n/a{
204n/a PyObject *a;
205n/a long b;
206n/a if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
207n/a return NULL;
208n/a Py_INCREF(Py_None);
209n/a return Py_None;
210n/a}
211n/a
212n/a
213n/a/* ---------- */
214n/a
215n/astatic PyTypeObject Str_Type = {
216n/a /* The ob_type field must be initialized in the module init function
217n/a * to be portable to Windows without using C++. */
218n/a PyVarObject_HEAD_INIT(NULL, 0)
219n/a "xxmodule.Str", /*tp_name*/
220n/a 0, /*tp_basicsize*/
221n/a 0, /*tp_itemsize*/
222n/a /* methods */
223n/a 0, /*tp_dealloc*/
224n/a 0, /*tp_print*/
225n/a 0, /*tp_getattr*/
226n/a 0, /*tp_setattr*/
227n/a 0, /*tp_reserved*/
228n/a 0, /*tp_repr*/
229n/a 0, /*tp_as_number*/
230n/a 0, /*tp_as_sequence*/
231n/a 0, /*tp_as_mapping*/
232n/a 0, /*tp_hash*/
233n/a 0, /*tp_call*/
234n/a 0, /*tp_str*/
235n/a 0, /*tp_getattro*/
236n/a 0, /*tp_setattro*/
237n/a 0, /*tp_as_buffer*/
238n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
239n/a 0, /*tp_doc*/
240n/a 0, /*tp_traverse*/
241n/a 0, /*tp_clear*/
242n/a 0, /*tp_richcompare*/
243n/a 0, /*tp_weaklistoffset*/
244n/a 0, /*tp_iter*/
245n/a 0, /*tp_iternext*/
246n/a 0, /*tp_methods*/
247n/a 0, /*tp_members*/
248n/a 0, /*tp_getset*/
249n/a 0, /* see PyInit_xx */ /*tp_base*/
250n/a 0, /*tp_dict*/
251n/a 0, /*tp_descr_get*/
252n/a 0, /*tp_descr_set*/
253n/a 0, /*tp_dictoffset*/
254n/a 0, /*tp_init*/
255n/a 0, /*tp_alloc*/
256n/a 0, /*tp_new*/
257n/a 0, /*tp_free*/
258n/a 0, /*tp_is_gc*/
259n/a};
260n/a
261n/a/* ---------- */
262n/a
263n/astatic PyObject *
264n/anull_richcompare(PyObject *self, PyObject *other, int op)
265n/a{
266n/a Py_INCREF(Py_NotImplemented);
267n/a return Py_NotImplemented;
268n/a}
269n/a
270n/astatic PyTypeObject Null_Type = {
271n/a /* The ob_type field must be initialized in the module init function
272n/a * to be portable to Windows without using C++. */
273n/a PyVarObject_HEAD_INIT(NULL, 0)
274n/a "xxmodule.Null", /*tp_name*/
275n/a 0, /*tp_basicsize*/
276n/a 0, /*tp_itemsize*/
277n/a /* methods */
278n/a 0, /*tp_dealloc*/
279n/a 0, /*tp_print*/
280n/a 0, /*tp_getattr*/
281n/a 0, /*tp_setattr*/
282n/a 0, /*tp_reserved*/
283n/a 0, /*tp_repr*/
284n/a 0, /*tp_as_number*/
285n/a 0, /*tp_as_sequence*/
286n/a 0, /*tp_as_mapping*/
287n/a 0, /*tp_hash*/
288n/a 0, /*tp_call*/
289n/a 0, /*tp_str*/
290n/a 0, /*tp_getattro*/
291n/a 0, /*tp_setattro*/
292n/a 0, /*tp_as_buffer*/
293n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
294n/a 0, /*tp_doc*/
295n/a 0, /*tp_traverse*/
296n/a 0, /*tp_clear*/
297n/a null_richcompare, /*tp_richcompare*/
298n/a 0, /*tp_weaklistoffset*/
299n/a 0, /*tp_iter*/
300n/a 0, /*tp_iternext*/
301n/a 0, /*tp_methods*/
302n/a 0, /*tp_members*/
303n/a 0, /*tp_getset*/
304n/a 0, /* see PyInit_xx */ /*tp_base*/
305n/a 0, /*tp_dict*/
306n/a 0, /*tp_descr_get*/
307n/a 0, /*tp_descr_set*/
308n/a 0, /*tp_dictoffset*/
309n/a 0, /*tp_init*/
310n/a 0, /*tp_alloc*/
311n/a 0, /* see PyInit_xx */ /*tp_new*/
312n/a 0, /*tp_free*/
313n/a 0, /*tp_is_gc*/
314n/a};
315n/a
316n/a
317n/a/* ---------- */
318n/a
319n/a
320n/a/* List of functions defined in the module */
321n/a
322n/astatic PyMethodDef xx_methods[] = {
323n/a {"roj", xx_roj, METH_VARARGS,
324n/a PyDoc_STR("roj(a,b) -> None")},
325n/a {"foo", xx_foo, METH_VARARGS,
326n/a xx_foo_doc},
327n/a {"new", xx_new, METH_VARARGS,
328n/a PyDoc_STR("new() -> new Xx object")},
329n/a {"bug", xx_bug, METH_VARARGS,
330n/a PyDoc_STR("bug(o) -> None")},
331n/a {NULL, NULL} /* sentinel */
332n/a};
333n/a
334n/aPyDoc_STRVAR(module_doc,
335n/a"This is a template module just for instruction.");
336n/a
337n/a
338n/astatic int
339n/axx_exec(PyObject *m)
340n/a{
341n/a /* Due to cross platform compiler issues the slots must be filled
342n/a * here. It's required for portability to Windows without requiring
343n/a * C++. */
344n/a Null_Type.tp_base = &PyBaseObject_Type;
345n/a Null_Type.tp_new = PyType_GenericNew;
346n/a Str_Type.tp_base = &PyUnicode_Type;
347n/a
348n/a /* Finalize the type object including setting type of the new type
349n/a * object; doing it here is required for portability, too. */
350n/a if (PyType_Ready(&Xxo_Type) < 0)
351n/a goto fail;
352n/a
353n/a /* Add some symbolic constants to the module */
354n/a if (ErrorObject == NULL) {
355n/a ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
356n/a if (ErrorObject == NULL)
357n/a goto fail;
358n/a }
359n/a Py_INCREF(ErrorObject);
360n/a PyModule_AddObject(m, "error", ErrorObject);
361n/a
362n/a /* Add Str */
363n/a if (PyType_Ready(&Str_Type) < 0)
364n/a goto fail;
365n/a PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
366n/a
367n/a /* Add Null */
368n/a if (PyType_Ready(&Null_Type) < 0)
369n/a goto fail;
370n/a PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
371n/a return 0;
372n/a fail:
373n/a Py_XDECREF(m);
374n/a return -1;
375n/a}
376n/a
377n/astatic struct PyModuleDef_Slot xx_slots[] = {
378n/a {Py_mod_exec, xx_exec},
379n/a {0, NULL},
380n/a};
381n/a
382n/astatic struct PyModuleDef xxmodule = {
383n/a PyModuleDef_HEAD_INIT,
384n/a "xx",
385n/a module_doc,
386n/a 0,
387n/a xx_methods,
388n/a xx_slots,
389n/a NULL,
390n/a NULL,
391n/a NULL
392n/a};
393n/a
394n/a/* Export function for the module (*must* be called PyInit_xx) */
395n/a
396n/aPyMODINIT_FUNC
397n/aPyInit_xx(void)
398n/a{
399n/a return PyModuleDef_Init(&xxmodule);
400n/a}