blob: 58024d11b04fb3ed3fba5ed2c68dee3f8a97fe44 [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
Tim Peters65760b22001-12-10 22:53:30 +00004static char xxsubtype__doc__[] =
5"xxsubtype is an example module showing how to subtype builtin types from C.\n"
6"test_descr.py in the standard test suite requires it in order to complete.\n"
7"If you don't care about the examples, and don't intend to run the Python\n"
8"test suite, you can recompile Python without Modules/xxsubtype.c.";
Tim Peters6d6c1a32001-08-02 04:15:00 +00009
10/* spamlist -- a list subtype */
11
12typedef struct {
13 PyListObject list;
14 int state;
15} spamlistobject;
16
17static PyObject *
18spamlist_getstate(spamlistobject *self, PyObject *args)
19{
20 if (!PyArg_ParseTuple(args, ":getstate"))
21 return NULL;
22 return PyInt_FromLong(self->state);
23}
24
25static PyObject *
26spamlist_setstate(spamlistobject *self, PyObject *args)
27{
28 int state;
29
30 if (!PyArg_ParseTuple(args, "i:setstate", &state))
31 return NULL;
32 self->state = state;
33 Py_INCREF(Py_None);
34 return Py_None;
35}
36
37static PyMethodDef spamlist_methods[] = {
38 {"getstate", (PyCFunction)spamlist_getstate, METH_VARARGS,
39 "getstate() -> state"},
40 {"setstate", (PyCFunction)spamlist_setstate, METH_VARARGS,
41 "setstate(state)"},
42 {NULL, NULL},
43};
44
45staticforward PyTypeObject spamlist_type;
46
47static int
48spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
49{
50 if (PyList_Type.tp_init((PyObject *)self, args, kwds) < 0)
51 return -1;
52 self->state = 0;
53 return 0;
54}
55
Guido van Rossum88dcf032001-08-15 18:18:58 +000056static PyObject *
57spamlist_state_get(spamlistobject *self)
58{
59 return PyInt_FromLong(self->state);
60}
61
Guido van Rossum32d34c82001-09-20 21:45:26 +000062static PyGetSetDef spamlist_getsets[] = {
63 {"state", (getter)spamlist_state_get, NULL,
64 "an int variable for demonstration purposes"},
Guido van Rossum88dcf032001-08-15 18:18:58 +000065 {0}
66};
67
Tim Peters6d6c1a32001-08-02 04:15:00 +000068static PyTypeObject spamlist_type = {
69 PyObject_HEAD_INIT(&PyType_Type)
70 0,
Guido van Rossum83f56cb2001-08-16 09:10:42 +000071 "xxsubtype.spamlist",
Tim Peters6d6c1a32001-08-02 04:15:00 +000072 sizeof(spamlistobject),
73 0,
74 0, /* tp_dealloc */
75 0, /* tp_print */
76 0, /* tp_getattr */
77 0, /* tp_setattr */
78 0, /* tp_compare */
79 0, /* tp_repr */
80 0, /* tp_as_number */
81 0, /* tp_as_sequence */
82 0, /* tp_as_mapping */
83 0, /* tp_hash */
84 0, /* tp_call */
85 0, /* tp_str */
86 0, /* tp_getattro */
87 0, /* tp_setattro */
88 0, /* tp_as_buffer */
89 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
90 0, /* tp_doc */
91 0, /* tp_traverse */
92 0, /* tp_clear */
93 0, /* tp_richcompare */
94 0, /* tp_weaklistoffset */
95 0, /* tp_iter */
96 0, /* tp_iternext */
97 spamlist_methods, /* tp_methods */
98 0, /* tp_members */
Guido van Rossum88dcf032001-08-15 18:18:58 +000099 spamlist_getsets, /* tp_getset */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000100 &PyList_Type, /* tp_base */
101 0, /* tp_dict */
102 0, /* tp_descr_get */
103 0, /* tp_descr_set */
104 0, /* tp_dictoffset */
105 (initproc)spamlist_init, /* tp_init */
106 0, /* tp_alloc */
107 0, /* tp_new */
108};
109
110/* spamdict -- a dict subtype */
111
112typedef struct {
113 PyDictObject dict;
114 int state;
115} spamdictobject;
116
117static PyObject *
118spamdict_getstate(spamdictobject *self, PyObject *args)
119{
120 if (!PyArg_ParseTuple(args, ":getstate"))
121 return NULL;
122 return PyInt_FromLong(self->state);
123}
124
125static PyObject *
126spamdict_setstate(spamdictobject *self, PyObject *args)
127{
128 int state;
129
130 if (!PyArg_ParseTuple(args, "i:setstate", &state))
131 return NULL;
132 self->state = state;
133 Py_INCREF(Py_None);
134 return Py_None;
135}
136
137static PyMethodDef spamdict_methods[] = {
138 {"getstate", (PyCFunction)spamdict_getstate, METH_VARARGS,
139 "getstate() -> state"},
140 {"setstate", (PyCFunction)spamdict_setstate, METH_VARARGS,
141 "setstate(state)"},
142 {NULL, NULL},
143};
144
145staticforward PyTypeObject spamdict_type;
146
147static int
148spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
149{
150 if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
151 return -1;
152 self->state = 0;
153 return 0;
154}
155
Guido van Rossum6f799372001-09-20 20:46:19 +0000156static PyMemberDef spamdict_members[] = {
157 {"state", T_INT, offsetof(spamdictobject, state), READONLY,
158 "an int variable for demonstration purposes"},
Guido van Rossume6b90ea2001-08-15 18:09:11 +0000159 {0}
160};
161
Tim Peters6d6c1a32001-08-02 04:15:00 +0000162static PyTypeObject spamdict_type = {
163 PyObject_HEAD_INIT(&PyType_Type)
164 0,
Guido van Rossum83f56cb2001-08-16 09:10:42 +0000165 "xxsubtype.spamdict",
Tim Peters6d6c1a32001-08-02 04:15:00 +0000166 sizeof(spamdictobject),
167 0,
168 0, /* tp_dealloc */
169 0, /* tp_print */
170 0, /* tp_getattr */
171 0, /* tp_setattr */
172 0, /* tp_compare */
173 0, /* tp_repr */
174 0, /* tp_as_number */
175 0, /* tp_as_sequence */
176 0, /* tp_as_mapping */
177 0, /* tp_hash */
178 0, /* tp_call */
179 0, /* tp_str */
180 0, /* tp_getattro */
181 0, /* tp_setattro */
182 0, /* tp_as_buffer */
183 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
184 0, /* tp_doc */
185 0, /* tp_traverse */
186 0, /* tp_clear */
187 0, /* tp_richcompare */
188 0, /* tp_weaklistoffset */
189 0, /* tp_iter */
190 0, /* tp_iternext */
191 spamdict_methods, /* tp_methods */
Guido van Rossume6b90ea2001-08-15 18:09:11 +0000192 spamdict_members, /* tp_members */
Tim Peters6d6c1a32001-08-02 04:15:00 +0000193 0, /* tp_getset */
194 &PyDict_Type, /* tp_base */
195 0, /* tp_dict */
196 0, /* tp_descr_get */
197 0, /* tp_descr_set */
198 0, /* tp_dictoffset */
199 (initproc)spamdict_init, /* tp_init */
200 0, /* tp_alloc */
201 0, /* tp_new */
202};
203
Neil Schemenauer26775122001-10-21 22:26:43 +0000204static PyObject *
Tim Peters6d6c1a32001-08-02 04:15:00 +0000205spam_bench(PyObject *self, PyObject *args)
206{
207 PyObject *obj, *name, *res;
208 int n = 1000;
209 time_t t0, t1;
210
211 if (!PyArg_ParseTuple(args, "OS|i", &obj, &name, &n))
212 return NULL;
213 t0 = clock();
214 while (--n >= 0) {
215 res = PyObject_GetAttr(obj, name);
216 if (res == NULL)
217 return NULL;
218 Py_DECREF(res);
219 }
220 t1 = clock();
221 return PyFloat_FromDouble((double)(t1-t0) / CLOCKS_PER_SEC);
222}
223
224static PyMethodDef xxsubtype_functions[] = {
225 {"bench", spam_bench, METH_VARARGS},
226 {NULL, NULL} /* sentinel */
227};
228
229DL_EXPORT(void)
230initxxsubtype(void)
231{
232 PyObject *m, *d;
233
Tim Peters65760b22001-12-10 22:53:30 +0000234 m = Py_InitModule3("xxsubtype",
235 xxsubtype_functions,
236 xxsubtype__doc__);
Tim Peters6d6c1a32001-08-02 04:15:00 +0000237 if (m == NULL)
238 return;
239
Guido van Rossum528b7eb2001-08-07 17:24:28 +0000240 if (PyType_Ready(&spamlist_type) < 0)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000241 return;
Guido van Rossum528b7eb2001-08-07 17:24:28 +0000242 if (PyType_Ready(&spamdict_type) < 0)
Tim Peters6d6c1a32001-08-02 04:15:00 +0000243 return;
244
245 d = PyModule_GetDict(m);
246 if (d == NULL)
247 return;
248
249 Py_INCREF(&spamlist_type);
250 if (PyDict_SetItemString(d, "spamlist",
251 (PyObject *) &spamlist_type) < 0)
252 return;
253
254 Py_INCREF(&spamdict_type);
255 if (PyDict_SetItemString(d, "spamdict",
256 (PyObject *) &spamdict_type) < 0)
257 return;
258}