blob: bbc5ea9b77b523f089ecc449a58047098b4d49a8 [file] [log] [blame]
Tim Peters6d6c1a32001-08-02 04:15:00 +00001#include "Python.h"
Guido van Rossume6b90ea2001-08-15 18:09:11 +00002#include "structmember.h"
Tim Peters6d6c1a32001-08-02 04:15:00 +00003
4/* Examples showing how to subtype the builtin list and dict types from C. */
5
6/* spamlist -- a list subtype */
7
8typedef struct {
9 PyListObject list;
10 int state;
11} spamlistobject;
12
13static PyObject *
14spamlist_getstate(spamlistobject *self, PyObject *args)
15{
16 if (!PyArg_ParseTuple(args, ":getstate"))
17 return NULL;
18 return PyInt_FromLong(self->state);
19}
20
21static PyObject *
22spamlist_setstate(spamlistobject *self, PyObject *args)
23{
24 int state;
25
26 if (!PyArg_ParseTuple(args, "i:setstate", &state))
27 return NULL;
28 self->state = state;
29 Py_INCREF(Py_None);
30 return Py_None;
31}
32
33static PyMethodDef spamlist_methods[] = {
34 {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
35 "getstate() -> state"},
36 {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
37 "setstate(state)"},
38 {NULL, NULL},
39};
40
41staticforward PyTypeObject spamlist_type;
42
43static int
44spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
45{
46 if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
47 return -1;
48 self->state = 0;
49 return 0;
50}
51
Guido van Rossum88dcf032001-08-15 18:18:58 +000052static PyObject *
53spamlist_state_get(spamlistobject *self)
54{
55 return PyInt_FromLong(self->state);
56}
57
Guido van Rossum32d34c82001-09-20 21:45:26 +000058static PyGetSetDef spamlist_getsets[] = {
59 {"state", (getter)spamlist_state_get, NULL,
60 "an int variable for demonstration purposes"},
Guido van Rossum88dcf032001-08-15 18:18:58 +000061 {0}
62};
63
Tim Peters6d6c1a32001-08-02 04:15:00 +000064static PyTypeObject spamlist_type = {
65 PyObject_HEAD_INIT(&PyType_Type)
66 0,
Guido van Rossum83f56cb2001-08-16 09:10:42 +000067 "xxsubtype.spamlist",
Tim Peters6d6c1a32001-08-02 04:15:00 +000068 sizeof(spamlistobject),
69 0,
70 0, /* tp_dealloc */
71 0, /* tp_print */
72 0, /* tp_getattr */
73 0, /* tp_setattr */
74 0, /* tp_compare */
75 0, /* tp_repr */
76 0, /* tp_as_number */
77 0, /* tp_as_sequence */
78 0, /* tp_as_mapping */
79 0, /* tp_hash */
80 0, /* tp_call */
81 0, /* tp_str */
82 0, /* tp_getattro */
83 0, /* tp_setattro */
84 0, /* tp_as_buffer */
85 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
86 0, /* tp_doc */
87 0, /* tp_traverse */
88 0, /* tp_clear */
89 0, /* tp_richcompare */
90 0, /* tp_weaklistoffset */
91 0, /* tp_iter */
92 0, /* tp_iternext */
93 spamlist_methods, /* tp_methods */
94 0, /* tp_members */
Guido van Rossum88dcf032001-08-15 18:18:58 +000095 spamlist_getsets, /* tp_getset */
Tim Peters6d6c1a32001-08-02 04:15:00 +000096 &PyList_Type, /* tp_base */
97 0, /* tp_dict */
98 0, /* tp_descr_get */
99 0, /* tp_descr_set */
100 0, /* tp_dictoffset */
101 (initproc)spamlist_init, /* tp_init */
102 0, /* tp_alloc */
103 0, /* tp_new */
104};
105
106/* spamdict -- a dict subtype */
107
108typedef struct {
109 PyDictObject dict;
110 int state;
111} spamdictobject;
112
113static PyObject *
114spamdict_getstate(spamdictobject *self, PyObject *args)
115{
116 if (!PyArg_ParseTuple(args, ":getstate"))
117 return NULL;
118 return PyInt_FromLong(self->state);
119}
120
121static PyObject *
122spamdict_setstate(spamdictobject *self, PyObject *args)
123{
124 int state;
125
126 if (!PyArg_ParseTuple(args, "i:setstate", &state))
127 return NULL;
128 self->state = state;
129 Py_INCREF(Py_None);
130 return Py_None;
131}
132
133static PyMethodDef spamdict_methods[] = {
134 {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
135 "getstate() -> state"},
136 {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
137 "setstate(state)"},
138 {NULL, NULL},
139};
140
141staticforward PyTypeObject spamdict_type;
142
143static int
144spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
145{
146 if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
147 return -1;
148 self->state = 0;
149 return 0;
150}
151
Guido van Rossum6f799372001-09-20 20:46:19 +0000152static PyMemberDef spamdict_members[] = {
153 {"state", T_INT, offsetof(spamdictobject, state), READONLY,
154 "an int variable for demonstration purposes"},
Guido van Rossume6b90ea2001-08-15 18:09:11 +0000155 {0}
156};
157
Tim Peters6d6c1a32001-08-02 04:15:00 +0000158static PyTypeObject spamdict_type = {
159 PyObject_HEAD_INIT(&PyType_Type)
160 0,
Guido van Rossum83f56cb2001-08-16 09:10:42 +0000161 "xxsubtype.spamdict",
Tim Peters6d6c1a32001-08-02 04:15:00 +0000162 sizeof(spamdictobject),
163 0,
164 0, /* tp_dealloc */
165 0, /* tp_print */
166 0, /* tp_getattr */
167 0, /* tp_setattr */
168 0, /* tp_compare */
169 0, /* tp_repr */
170 0, /* tp_as_number */
171 0, /* tp_as_sequence */
172 0, /* tp_as_mapping */
173 0, /* tp_hash */
174 0, /* tp_call */
175 0, /* tp_str */
176 0, /* tp_getattro */
177 0, /* tp_setattro */
178 0, /* tp_as_buffer */
179 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
180 0, /* tp_doc */
181 0, /* tp_traverse */
182 0, /* tp_clear */
183 0, /* tp_richcompare */
184 0, /* tp_weaklistoffset */
185 0, /* tp_iter */
186 0, /* tp_iternext */
187 spamdict_methods, /* tp_methods */
Guido van Rossume6b90ea2001-08-15 18:09:11 +0000188 spamdict_members, /* tp_members */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000189 0, /* tp_getset */
190 &PyDict_Type, /* tp_base */
191 0, /* tp_dict */
192 0, /* tp_descr_get */
193 0, /* tp_descr_set */
194 0, /* tp_dictoffset */
195 (initproc)spamdict_init, /* tp_init */
196 0, /* tp_alloc */
197 0, /* tp_new */
198};
199
Neil Schemenauer26775122001-10-21 22:26:43 +0000200static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000201spam_bench(PyObject *self, PyObject *args)
202{
203 PyObject *obj, *name, *res;
204 int n = 1000;
205 time_t t0, t1;
206
207 if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
208 return NULL;
209 t0 = clock();
210 while (--n >= 0) {
211 res = PyObject_GetAttr(obj, name);
212 if (res == NULL)
213 return NULL;
214 Py_DECREF(res);
215 }
216 t1 = clock();
217 return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
218}
219
220static PyMethodDef xxsubtype_functions[] = {
221 {"bench", spam_bench, METH_VARARGS},
222 {NULL, NULL} /* sentinel */
223};
224
225DL_EXPORT(void)
226initxxsubtype(void)
227{
228 PyObject *m, *d;
229
230 m = Py_InitModule("xxsubtype", xxsubtype_functions);
231 if (m == NULL)
232 return;
233
Guido van Rossum528b7eb2001-08-07 17:24:28 +0000234 if (PyType_Ready(&spamlist_type) < 0)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000235 return;
Guido van Rossum528b7eb2001-08-07 17:24:28 +0000236 if (PyType_Ready(&spamdict_type) < 0)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000237 return;
238
239 d = PyModule_GetDict(m);
240 if (d == NULL)
241 return;
242
243 Py_INCREF(&spamlist_type);
244 if (PyDict_SetItemString(d, "spamlist",
245 (PyObject *) &spamlist_type) < 0)
246 return;
247
248 Py_INCREF(&spamdict_type);
249 if (PyDict_SetItemString(d, "spamdict",
250 (PyObject *) &spamdict_type) < 0)
251 return;
252}