2 #include "structmember.h"
4 PyDoc_STRVAR(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.");
10 /* We link this module statically for convenience. If compiled as a shared
11 library instead, some compilers don't allow addresses of Python objects
12 defined in other libraries to be used in static initializers here. The
13 DEFERRED_ADDRESS macro is used to tag the slots where such addresses
14 appear; the module init function must fill in the tagged slots at runtime.
15 The argument is for documentation -- the macro ignores it.
17 #define DEFERRED_ADDRESS(ADDR) 0
19 /* spamlist -- a list subtype */
27 spamlist_getstate(spamlistobject
*self
, PyObject
*args
)
29 if (!PyArg_ParseTuple(args
, ":getstate"))
31 return PyInt_FromLong(self
->state
);
35 spamlist_setstate(spamlistobject
*self
, PyObject
*args
)
39 if (!PyArg_ParseTuple(args
, "i:setstate", &state
))
47 spamlist_specialmeth(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
49 PyObject
*result
= PyTuple_New(3);
57 PyTuple_SET_ITEM(result
, 0, self
);
59 PyTuple_SET_ITEM(result
, 1, args
);
61 PyTuple_SET_ITEM(result
, 2, kw
);
66 static PyMethodDef spamlist_methods
[] = {
67 {"getstate", (PyCFunction
)spamlist_getstate
, METH_VARARGS
,
68 PyDoc_STR("getstate() -> state")},
69 {"setstate", (PyCFunction
)spamlist_setstate
, METH_VARARGS
,
70 PyDoc_STR("setstate(state)")},
71 /* These entries differ only in the flags; they are used by the tests
72 in test.test_descr. */
73 {"classmeth", (PyCFunction
)spamlist_specialmeth
,
74 METH_VARARGS
| METH_KEYWORDS
| METH_CLASS
,
75 PyDoc_STR("classmeth(*args, **kw)")},
76 {"staticmeth", (PyCFunction
)spamlist_specialmeth
,
77 METH_VARARGS
| METH_KEYWORDS
| METH_STATIC
,
78 PyDoc_STR("staticmeth(*args, **kw)")},
83 spamlist_init(spamlistobject
*self
, PyObject
*args
, PyObject
*kwds
)
85 if (PyList_Type
.tp_init((PyObject
*)self
, args
, kwds
) < 0)
92 spamlist_state_get(spamlistobject
*self
)
94 return PyInt_FromLong(self
->state
);
97 static PyGetSetDef spamlist_getsets
[] = {
98 {"state", (getter
)spamlist_state_get
, NULL
,
99 PyDoc_STR("an int variable for demonstration purposes")},
103 static PyTypeObject spamlist_type
= {
104 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
), 0)
105 "xxsubtype.spamlist",
106 sizeof(spamlistobject
),
114 0, /* tp_as_number */
115 0, /* tp_as_sequence */
116 0, /* tp_as_mapping */
122 0, /* tp_as_buffer */
123 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
127 0, /* tp_richcompare */
128 0, /* tp_weaklistoffset */
131 spamlist_methods
, /* tp_methods */
133 spamlist_getsets
, /* tp_getset */
134 DEFERRED_ADDRESS(&PyList_Type
), /* tp_base */
136 0, /* tp_descr_get */
137 0, /* tp_descr_set */
138 0, /* tp_dictoffset */
139 (initproc
)spamlist_init
, /* tp_init */
144 /* spamdict -- a dict subtype */
152 spamdict_getstate(spamdictobject
*self
, PyObject
*args
)
154 if (!PyArg_ParseTuple(args
, ":getstate"))
156 return PyInt_FromLong(self
->state
);
160 spamdict_setstate(spamdictobject
*self
, PyObject
*args
)
164 if (!PyArg_ParseTuple(args
, "i:setstate", &state
))
171 static PyMethodDef spamdict_methods
[] = {
172 {"getstate", (PyCFunction
)spamdict_getstate
, METH_VARARGS
,
173 PyDoc_STR("getstate() -> state")},
174 {"setstate", (PyCFunction
)spamdict_setstate
, METH_VARARGS
,
175 PyDoc_STR("setstate(state)")},
180 spamdict_init(spamdictobject
*self
, PyObject
*args
, PyObject
*kwds
)
182 if (PyDict_Type
.tp_init((PyObject
*)self
, args
, kwds
) < 0)
188 static PyMemberDef spamdict_members
[] = {
189 {"state", T_INT
, offsetof(spamdictobject
, state
), READONLY
,
190 PyDoc_STR("an int variable for demonstration purposes")},
194 static PyTypeObject spamdict_type
= {
195 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
), 0)
196 "xxsubtype.spamdict",
197 sizeof(spamdictobject
),
205 0, /* tp_as_number */
206 0, /* tp_as_sequence */
207 0, /* tp_as_mapping */
213 0, /* tp_as_buffer */
214 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
218 0, /* tp_richcompare */
219 0, /* tp_weaklistoffset */
222 spamdict_methods
, /* tp_methods */
223 spamdict_members
, /* tp_members */
225 DEFERRED_ADDRESS(&PyDict_Type
), /* tp_base */
227 0, /* tp_descr_get */
228 0, /* tp_descr_set */
229 0, /* tp_dictoffset */
230 (initproc
)spamdict_init
, /* tp_init */
236 spam_bench(PyObject
*self
, PyObject
*args
)
238 PyObject
*obj
, *name
, *res
;
242 if (!PyArg_ParseTuple(args
, "OS|i", &obj
, &name
, &n
))
246 res
= PyObject_GetAttr(obj
, name
);
252 return PyFloat_FromDouble((double)(t1
-t0
) / CLOCKS_PER_SEC
);
255 static PyMethodDef xxsubtype_functions
[] = {
256 {"bench", spam_bench
, METH_VARARGS
},
257 {NULL
, NULL
} /* sentinel */
265 /* Fill in deferred data addresses. This must be done before
266 PyType_Ready() is called. Note that PyType_Ready() automatically
267 initializes the ob.ob_type field to &PyType_Type if it's NULL,
268 so it's not necessary to fill in ob_type first. */
269 spamdict_type
.tp_base
= &PyDict_Type
;
270 if (PyType_Ready(&spamdict_type
) < 0)
273 spamlist_type
.tp_base
= &PyList_Type
;
274 if (PyType_Ready(&spamlist_type
) < 0)
277 m
= Py_InitModule3("xxsubtype",
283 if (PyType_Ready(&spamlist_type
) < 0)
285 if (PyType_Ready(&spamdict_type
) < 0)
288 Py_INCREF(&spamlist_type
);
289 if (PyModule_AddObject(m
, "spamlist",
290 (PyObject
*) &spamlist_type
) < 0)
293 Py_INCREF(&spamdict_type
);
294 if (PyModule_AddObject(m
, "spamdict",
295 (PyObject
*) &spamdict_type
) < 0)