2
/* Use this file as a template to start implementing a module that
3
also declares object types. All occurrences of 'Xxo' should be changed
4
to something reasonable for your objects. After that, all other
5
occurrences of 'xx' should be changed to something reasonable for your
6
module. If your module is named foo your sourcefile should be named
9
You will probably want to delete all references to 'x_attr' and add
10
your own types of attributes instead. Maybe you want to name your
11
local variables other than 'self'. If your object type is needed in
12
other files, you'll have to create a file "foobarobject.h"; see
13
intobject.h for an example. */
19
static PyObject *ErrorObject;
23
PyObject *x_attr; /* Attributes dictionary */
26
static PyTypeObject Xxo_Type;
28
#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type)
31
newXxoObject(PyObject *arg)
34
self = PyObject_New(XxoObject, &Xxo_Type);
44
Xxo_dealloc(XxoObject *self)
46
Py_XDECREF(self->x_attr);
51
Xxo_demo(XxoObject *self, PyObject *args)
53
if (!PyArg_ParseTuple(args, ":demo"))
59
static PyMethodDef Xxo_methods[] = {
60
{"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
61
PyDoc_STR("demo() -> None")},
62
{NULL, NULL} /* sentinel */
66
Xxo_getattro(XxoObject *self, PyObject *name)
68
if (self->x_attr != NULL) {
69
PyObject *v = PyDict_GetItem(self->x_attr, name);
75
return PyObject_GenericGetAttr((PyObject *)self, name);
79
Xxo_setattr(XxoObject *self, char *name, PyObject *v)
81
if (self->x_attr == NULL) {
82
self->x_attr = PyDict_New();
83
if (self->x_attr == NULL)
87
int rv = PyDict_DelItemString(self->x_attr, name);
89
PyErr_SetString(PyExc_AttributeError,
90
"delete non-existing Xxo attribute");
94
return PyDict_SetItemString(self->x_attr, name, v);
97
static PyTypeObject Xxo_Type = {
98
/* The ob_type field must be initialized in the module init function
99
* to be portable to Windows without using C++. */
100
PyVarObject_HEAD_INIT(NULL, 0)
101
"xxmodule.Xxo", /*tp_name*/
102
sizeof(XxoObject), /*tp_basicsize*/
105
(destructor)Xxo_dealloc, /*tp_dealloc*/
107
(getattrfunc)0, /*tp_getattr*/
108
(setattrfunc)Xxo_setattr, /*tp_setattr*/
112
0, /*tp_as_sequence*/
117
(getattrofunc)Xxo_getattro, /*tp_getattro*/
120
Py_TPFLAGS_DEFAULT, /*tp_flags*/
124
0, /*tp_richcompare*/
125
0, /*tp_weaklistoffset*/
128
Xxo_methods, /*tp_methods*/
142
/* --------------------------------------------------------------------- */
144
/* Function of two integers returning integer */
146
PyDoc_STRVAR(xx_foo_doc,
149
Return the sum of i and j.");
152
xx_foo(PyObject *self, PyObject *args)
156
if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
158
res = i+j; /* XXX Do something here */
159
return PyLong_FromLong(res);
163
/* Function of no arguments returning new Xxo object */
166
xx_new(PyObject *self, PyObject *args)
170
if (!PyArg_ParseTuple(args, ":new"))
172
rv = newXxoObject(args);
175
return (PyObject *)rv;
178
/* Example with subtle bug from extensions manual ("Thin Ice"). */
181
xx_bug(PyObject *self, PyObject *args)
183
PyObject *list, *item;
185
if (!PyArg_ParseTuple(args, "O:bug", &list))
188
item = PyList_GetItem(list, 0);
189
/* Py_INCREF(item); */
190
PyList_SetItem(list, 1, PyLong_FromLong(0L));
191
PyObject_Print(item, stdout, 0);
193
/* Py_DECREF(item); */
199
/* Test bad format character */
202
xx_roj(PyObject *self, PyObject *args)
206
if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
215
static PyTypeObject Str_Type = {
216
/* The ob_type field must be initialized in the module init function
217
* to be portable to Windows without using C++. */
218
PyVarObject_HEAD_INIT(NULL, 0)
219
"xxmodule.Str", /*tp_name*/
230
0, /*tp_as_sequence*/
238
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
242
0, /*tp_richcompare*/
243
0, /*tp_weaklistoffset*/
249
0, /* see PyInit_xx */ /*tp_base*/
264
null_richcompare(PyObject *self, PyObject *other, int op)
266
Py_INCREF(Py_NotImplemented);
267
return Py_NotImplemented;
270
static PyTypeObject Null_Type = {
271
/* The ob_type field must be initialized in the module init function
272
* to be portable to Windows without using C++. */
273
PyVarObject_HEAD_INIT(NULL, 0)
274
"xxmodule.Null", /*tp_name*/
285
0, /*tp_as_sequence*/
293
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
297
null_richcompare, /*tp_richcompare*/
298
0, /*tp_weaklistoffset*/
304
0, /* see PyInit_xx */ /*tp_base*/
311
0, /* see PyInit_xx */ /*tp_new*/
320
/* List of functions defined in the module */
322
static PyMethodDef xx_methods[] = {
323
{"roj", xx_roj, METH_VARARGS,
324
PyDoc_STR("roj(a,b) -> None")},
325
{"foo", xx_foo, METH_VARARGS,
327
{"new", xx_new, METH_VARARGS,
328
PyDoc_STR("new() -> new Xx object")},
329
{"bug", xx_bug, METH_VARARGS,
330
PyDoc_STR("bug(o) -> None")},
331
{NULL, NULL} /* sentinel */
334
PyDoc_STRVAR(module_doc,
335
"This is a template module just for instruction.");
337
/* Initialization function for the module (*must* be called PyInit_xx) */
340
static struct PyModuleDef xxmodule = {
341
PyModuleDef_HEAD_INIT,
357
/* Due to cross platform compiler issues the slots must be filled
358
* here. It's required for portability to Windows without requiring
360
Null_Type.tp_base = &PyBaseObject_Type;
361
Null_Type.tp_new = PyType_GenericNew;
362
Str_Type.tp_base = &PyUnicode_Type;
364
/* Finalize the type object including setting type of the new type
365
* object; doing it here is required for portability, too. */
366
if (PyType_Ready(&Xxo_Type) < 0)
369
/* Create the module and add the functions */
370
m = PyModule_Create(&xxmodule);
374
/* Add some symbolic constants to the module */
375
if (ErrorObject == NULL) {
376
ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
377
if (ErrorObject == NULL)
380
Py_INCREF(ErrorObject);
381
PyModule_AddObject(m, "error", ErrorObject);
384
if (PyType_Ready(&Str_Type) < 0)
386
PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
389
if (PyType_Ready(&Null_Type) < 0)
391
PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);