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)")},
82 static PyTypeObject spamlist_type
;
85 spamlist_init(spamlistobject
*self
, PyObject
*args
, PyObject
*kwds
)
87 if (PyList_Type
.tp_init((PyObject
*)self
, args
, kwds
) < 0)
94 spamlist_state_get(spamlistobject
*self
)
96 return PyInt_FromLong(self
->state
);
99 static PyGetSetDef spamlist_getsets
[] = {
100 {"state", (getter
)spamlist_state_get
, NULL
,
101 PyDoc_STR("an int variable for demonstration purposes")},
105 static PyTypeObject spamlist_type
= {
106 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
108 "xxsubtype.spamlist",
109 sizeof(spamlistobject
),
117 0, /* tp_as_number */
118 0, /* tp_as_sequence */
119 0, /* tp_as_mapping */
125 0, /* tp_as_buffer */
126 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
130 0, /* tp_richcompare */
131 0, /* tp_weaklistoffset */
134 spamlist_methods
, /* tp_methods */
136 spamlist_getsets
, /* tp_getset */
137 DEFERRED_ADDRESS(&PyList_Type
), /* tp_base */
139 0, /* tp_descr_get */
140 0, /* tp_descr_set */
141 0, /* tp_dictoffset */
142 (initproc
)spamlist_init
, /* tp_init */
147 /* spamdict -- a dict subtype */
155 spamdict_getstate(spamdictobject
*self
, PyObject
*args
)
157 if (!PyArg_ParseTuple(args
, ":getstate"))
159 return PyInt_FromLong(self
->state
);
163 spamdict_setstate(spamdictobject
*self
, PyObject
*args
)
167 if (!PyArg_ParseTuple(args
, "i:setstate", &state
))
174 static PyMethodDef spamdict_methods
[] = {
175 {"getstate", (PyCFunction
)spamdict_getstate
, METH_VARARGS
,
176 PyDoc_STR("getstate() -> state")},
177 {"setstate", (PyCFunction
)spamdict_setstate
, METH_VARARGS
,
178 PyDoc_STR("setstate(state)")},
182 static PyTypeObject spamdict_type
;
185 spamdict_init(spamdictobject
*self
, PyObject
*args
, PyObject
*kwds
)
187 if (PyDict_Type
.tp_init((PyObject
*)self
, args
, kwds
) < 0)
193 static PyMemberDef spamdict_members
[] = {
194 {"state", T_INT
, offsetof(spamdictobject
, state
), READONLY
,
195 PyDoc_STR("an int variable for demonstration purposes")},
199 static PyTypeObject spamdict_type
= {
200 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type
))
202 "xxsubtype.spamdict",
203 sizeof(spamdictobject
),
211 0, /* tp_as_number */
212 0, /* tp_as_sequence */
213 0, /* tp_as_mapping */
219 0, /* tp_as_buffer */
220 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
224 0, /* tp_richcompare */
225 0, /* tp_weaklistoffset */
228 spamdict_methods
, /* tp_methods */
229 spamdict_members
, /* tp_members */
231 DEFERRED_ADDRESS(&PyDict_Type
), /* tp_base */
233 0, /* tp_descr_get */
234 0, /* tp_descr_set */
235 0, /* tp_dictoffset */
236 (initproc
)spamdict_init
, /* tp_init */
242 spam_bench(PyObject
*self
, PyObject
*args
)
244 PyObject
*obj
, *name
, *res
;
248 if (!PyArg_ParseTuple(args
, "OS|i", &obj
, &name
, &n
))
252 res
= PyObject_GetAttr(obj
, name
);
258 return PyFloat_FromDouble((double)(t1
-t0
) / CLOCKS_PER_SEC
);
261 static PyMethodDef xxsubtype_functions
[] = {
262 {"bench", spam_bench
, METH_VARARGS
},
263 {NULL
, NULL
} /* sentinel */
271 /* Fill in deferred data addresses. This must be done before
272 PyType_Ready() is called. Note that PyType_Ready() automatically
273 initializes the ob.ob_type field to &PyType_Type if it's NULL,
274 so it's not necessary to fill in ob_type first. */
275 spamdict_type
.tp_base
= &PyDict_Type
;
276 if (PyType_Ready(&spamdict_type
) < 0)
279 spamlist_type
.tp_base
= &PyList_Type
;
280 if (PyType_Ready(&spamlist_type
) < 0)
283 m
= Py_InitModule3("xxsubtype",
289 if (PyType_Ready(&spamlist_type
) < 0)
291 if (PyType_Ready(&spamdict_type
) < 0)
294 Py_INCREF(&spamlist_type
);
295 if (PyModule_AddObject(m
, "spamlist",
296 (PyObject
*) &spamlist_type
) < 0)
299 Py_INCREF(&spamdict_type
);
300 if (PyModule_AddObject(m
, "spamdict",
301 (PyObject
*) &spamdict_type
) < 0)