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

Python code coverage for Modules/xxsubtype.c

#countcontent
1n/a#include "Python.h"
2n/a#include "structmember.h"
3n/a
4n/aPyDoc_STRVAR(xxsubtype__doc__,
5n/a"xxsubtype is an example module showing how to subtype builtin types from C.\n"
6n/a"test_descr.py in the standard test suite requires it in order to complete.\n"
7n/a"If you don't care about the examples, and don't intend to run the Python\n"
8n/a"test suite, you can recompile Python without Modules/xxsubtype.c.");
9n/a
10n/a/* We link this module statically for convenience. If compiled as a shared
11n/a library instead, some compilers don't allow addresses of Python objects
12n/a defined in other libraries to be used in static initializers here. The
13n/a DEFERRED_ADDRESS macro is used to tag the slots where such addresses
14n/a appear; the module init function must fill in the tagged slots at runtime.
15n/a The argument is for documentation -- the macro ignores it.
16n/a*/
17n/a#define DEFERRED_ADDRESS(ADDR) 0
18n/a
19n/a/* spamlist -- a list subtype */
20n/a
21n/atypedef struct {
22n/a PyListObject list;
23n/a int state;
24n/a} spamlistobject;
25n/a
26n/astatic PyObject *
27n/aspamlist_getstate(spamlistobject *self, PyObject *args)
28n/a{
29n/a if (!PyArg_ParseTuple(args, ":getstate"))
30n/a return NULL;
31n/a return PyLong_FromLong(self->state);
32n/a}
33n/a
34n/astatic PyObject *
35n/aspamlist_setstate(spamlistobject *self, PyObject *args)
36n/a{
37n/a int state;
38n/a
39n/a if (!PyArg_ParseTuple(args, "i:setstate", &state))
40n/a return NULL;
41n/a self->state = state;
42n/a Py_INCREF(Py_None);
43n/a return Py_None;
44n/a}
45n/a
46n/astatic PyObject *
47n/aspamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw)
48n/a{
49n/a PyObject *result = PyTuple_New(3);
50n/a
51n/a if (result != NULL) {
52n/a if (self == NULL)
53n/a self = Py_None;
54n/a if (kw == NULL)
55n/a kw = Py_None;
56n/a Py_INCREF(self);
57n/a PyTuple_SET_ITEM(result, 0, self);
58n/a Py_INCREF(args);
59n/a PyTuple_SET_ITEM(result, 1, args);
60n/a Py_INCREF(kw);
61n/a PyTuple_SET_ITEM(result, 2, kw);
62n/a }
63n/a return result;
64n/a}
65n/a
66n/astatic PyMethodDef spamlist_methods[] = {
67n/a {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
68n/a PyDoc_STR("getstate() -> state")},
69n/a {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
70n/a PyDoc_STR("setstate(state)")},
71n/a /* These entries differ only in the flags; they are used by the tests
72n/a in test.test_descr. */
73n/a {"classmeth", (PyCFunction)spamlist_specialmeth,
74n/a METH_VARARGS | METH_KEYWORDS | METH_CLASS,
75n/a PyDoc_STR("classmeth(*args, **kw)")},
76n/a {"staticmeth", (PyCFunction)spamlist_specialmeth,
77n/a METH_VARARGS | METH_KEYWORDS | METH_STATIC,
78n/a PyDoc_STR("staticmeth(*args, **kw)")},
79n/a {NULL, NULL},
80n/a};
81n/a
82n/astatic int
83n/aspamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
84n/a{
85n/a if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
86n/a return -1;
87n/a self->state = 0;
88n/a return 0;
89n/a}
90n/a
91n/astatic PyObject *
92n/aspamlist_state_get(spamlistobject *self)
93n/a{
94n/a return PyLong_FromLong(self->state);
95n/a}
96n/a
97n/astatic PyGetSetDef spamlist_getsets[] = {
98n/a {"state", (getter)spamlist_state_get, NULL,
99n/a PyDoc_STR("an int variable for demonstration purposes")},
100n/a {0}
101n/a};
102n/a
103n/astatic PyTypeObject spamlist_type = {
104n/a PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
105n/a "xxsubtype.spamlist",
106n/a sizeof(spamlistobject),
107n/a 0,
108n/a 0, /* tp_dealloc */
109n/a 0, /* tp_print */
110n/a 0, /* tp_getattr */
111n/a 0, /* tp_setattr */
112n/a 0, /* tp_reserved */
113n/a 0, /* tp_repr */
114n/a 0, /* tp_as_number */
115n/a 0, /* tp_as_sequence */
116n/a 0, /* tp_as_mapping */
117n/a 0, /* tp_hash */
118n/a 0, /* tp_call */
119n/a 0, /* tp_str */
120n/a 0, /* tp_getattro */
121n/a 0, /* tp_setattro */
122n/a 0, /* tp_as_buffer */
123n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
124n/a 0, /* tp_doc */
125n/a 0, /* tp_traverse */
126n/a 0, /* tp_clear */
127n/a 0, /* tp_richcompare */
128n/a 0, /* tp_weaklistoffset */
129n/a 0, /* tp_iter */
130n/a 0, /* tp_iternext */
131n/a spamlist_methods, /* tp_methods */
132n/a 0, /* tp_members */
133n/a spamlist_getsets, /* tp_getset */
134n/a DEFERRED_ADDRESS(&PyList_Type), /* tp_base */
135n/a 0, /* tp_dict */
136n/a 0, /* tp_descr_get */
137n/a 0, /* tp_descr_set */
138n/a 0, /* tp_dictoffset */
139n/a (initproc)spamlist_init, /* tp_init */
140n/a 0, /* tp_alloc */
141n/a 0, /* tp_new */
142n/a};
143n/a
144n/a/* spamdict -- a dict subtype */
145n/a
146n/atypedef struct {
147n/a PyDictObject dict;
148n/a int state;
149n/a} spamdictobject;
150n/a
151n/astatic PyObject *
152n/aspamdict_getstate(spamdictobject *self, PyObject *args)
153n/a{
154n/a if (!PyArg_ParseTuple(args, ":getstate"))
155n/a return NULL;
156n/a return PyLong_FromLong(self->state);
157n/a}
158n/a
159n/astatic PyObject *
160n/aspamdict_setstate(spamdictobject *self, PyObject *args)
161n/a{
162n/a int state;
163n/a
164n/a if (!PyArg_ParseTuple(args, "i:setstate", &state))
165n/a return NULL;
166n/a self->state = state;
167n/a Py_INCREF(Py_None);
168n/a return Py_None;
169n/a}
170n/a
171n/astatic PyMethodDef spamdict_methods[] = {
172n/a {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
173n/a PyDoc_STR("getstate() -> state")},
174n/a {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
175n/a PyDoc_STR("setstate(state)")},
176n/a {NULL, NULL},
177n/a};
178n/a
179n/astatic int
180n/aspamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
181n/a{
182n/a if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
183n/a return -1;
184n/a self->state = 0;
185n/a return 0;
186n/a}
187n/a
188n/astatic PyMemberDef spamdict_members[] = {
189n/a {"state", T_INT, offsetof(spamdictobject, state), READONLY,
190n/a PyDoc_STR("an int variable for demonstration purposes")},
191n/a {0}
192n/a};
193n/a
194n/astatic PyTypeObject spamdict_type = {
195n/a PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
196n/a "xxsubtype.spamdict",
197n/a sizeof(spamdictobject),
198n/a 0,
199n/a 0, /* tp_dealloc */
200n/a 0, /* tp_print */
201n/a 0, /* tp_getattr */
202n/a 0, /* tp_setattr */
203n/a 0, /* tp_reserved */
204n/a 0, /* tp_repr */
205n/a 0, /* tp_as_number */
206n/a 0, /* tp_as_sequence */
207n/a 0, /* tp_as_mapping */
208n/a 0, /* tp_hash */
209n/a 0, /* tp_call */
210n/a 0, /* tp_str */
211n/a 0, /* tp_getattro */
212n/a 0, /* tp_setattro */
213n/a 0, /* tp_as_buffer */
214n/a Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
215n/a 0, /* tp_doc */
216n/a 0, /* tp_traverse */
217n/a 0, /* tp_clear */
218n/a 0, /* tp_richcompare */
219n/a 0, /* tp_weaklistoffset */
220n/a 0, /* tp_iter */
221n/a 0, /* tp_iternext */
222n/a spamdict_methods, /* tp_methods */
223n/a spamdict_members, /* tp_members */
224n/a 0, /* tp_getset */
225n/a DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
226n/a 0, /* tp_dict */
227n/a 0, /* tp_descr_get */
228n/a 0, /* tp_descr_set */
229n/a 0, /* tp_dictoffset */
230n/a (initproc)spamdict_init, /* tp_init */
231n/a 0, /* tp_alloc */
232n/a 0, /* tp_new */
233n/a};
234n/a
235n/astatic PyObject *
236n/aspam_bench(PyObject *self, PyObject *args)
237n/a{
238n/a PyObject *obj, *name, *res;
239n/a int n = 1000;
240n/a time_t t0, t1;
241n/a
242n/a if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
243n/a return NULL;
244n/a t0 = clock();
245n/a while (--n >= 0) {
246n/a res = PyObject_GetAttr(obj, name);
247n/a if (res == NULL)
248n/a return NULL;
249n/a Py_DECREF(res);
250n/a }
251n/a t1 = clock();
252n/a return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
253n/a}
254n/a
255n/astatic PyMethodDef xxsubtype_functions[] = {
256n/a {"bench", spam_bench, METH_VARARGS},
257n/a {NULL, NULL} /* sentinel */
258n/a};
259n/a
260n/astatic int
261n/axxsubtype_exec(PyObject* m)
262n/a{
263n/a /* Fill in deferred data addresses. This must be done before
264n/a PyType_Ready() is called. Note that PyType_Ready() automatically
265n/a initializes the ob.ob_type field to &PyType_Type if it's NULL,
266n/a so it's not necessary to fill in ob_type first. */
267n/a spamdict_type.tp_base = &PyDict_Type;
268n/a if (PyType_Ready(&spamdict_type) < 0)
269n/a return -1;
270n/a
271n/a spamlist_type.tp_base = &PyList_Type;
272n/a if (PyType_Ready(&spamlist_type) < 0)
273n/a return -1;
274n/a
275n/a if (PyType_Ready(&spamlist_type) < 0)
276n/a return -1;
277n/a if (PyType_Ready(&spamdict_type) < 0)
278n/a return -1;
279n/a
280n/a Py_INCREF(&spamlist_type);
281n/a if (PyModule_AddObject(m, "spamlist",
282n/a (PyObject *) &spamlist_type) < 0)
283n/a return -1;
284n/a
285n/a Py_INCREF(&spamdict_type);
286n/a if (PyModule_AddObject(m, "spamdict",
287n/a (PyObject *) &spamdict_type) < 0)
288n/a return -1;
289n/a return 0;
290n/a}
291n/a
292n/astatic struct PyModuleDef_Slot xxsubtype_slots[] = {
293n/a {Py_mod_exec, xxsubtype_exec},
294n/a {0, NULL},
295n/a};
296n/a
297n/astatic struct PyModuleDef xxsubtypemodule = {
298n/a PyModuleDef_HEAD_INIT,
299n/a "xxsubtype",
300n/a xxsubtype__doc__,
301n/a 0,
302n/a xxsubtype_functions,
303n/a xxsubtype_slots,
304n/a NULL,
305n/a NULL,
306n/a NULL
307n/a};
308n/a
309n/a
310n/aPyMODINIT_FUNC
311n/aPyInit_xxsubtype(void)
312n/a{
313n/a return PyModuleDef_Init(&xxsubtypemodule);
314n/a}