#include #include "structmember.h" typedef struct { PyObject_HEAD PyObject *first; PyObject *last; int number; } Noddy; static void Noddy_dealloc(Noddy* self) { Py_XDECREF(self->first); Py_XDECREF(self->last); Py_TYPE(self)->tp_free((PyObject*)self); } static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { Noddy *self; self = (Noddy *)type->tp_alloc(type, 0); if (self != NULL) { self->first = PyUnicode_FromString(""); if (self->first == NULL) { Py_DECREF(self); return NULL; } self->last = PyUnicode_FromString(""); if (self->last == NULL) { Py_DECREF(self); return NULL; } self->number = 0; } return (PyObject *)self; } static int Noddy_init(Noddy *self, PyObject *args, PyObject *kwds) { PyObject *first=NULL, *last=NULL, *tmp; static char *kwlist[] = {"first", "last", "number", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, &first, &last, &self->number)) return -1; if (first) { tmp = self->first; Py_INCREF(first); self->first = first; Py_DECREF(tmp); } if (last) { tmp = self->last; Py_INCREF(last); self->last = last; Py_DECREF(tmp); } return 0; } static PyMemberDef Noddy_members[] = { {"number", T_INT, offsetof(Noddy, number), 0, "noddy number"}, {NULL} /* Sentinel */ }; static PyObject * Noddy_getfirst(Noddy *self, void *closure) { Py_INCREF(self->first); return self->first; } static int Noddy_setfirst(Noddy *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute"); return -1; } if (! PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "The first attribute value must be a string"); return -1; } Py_DECREF(self->first); Py_INCREF(value); self->first = value; return 0; } static PyObject * Noddy_getlast(Noddy *self, void *closure) { Py_INCREF(self->last); return self->last; } static int Noddy_setlast(Noddy *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute"); return -1; } if (! PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "The last attribute value must be a string"); return -1; } Py_DECREF(self->last); Py_INCREF(value); self->last = value; return 0; } static PyGetSetDef Noddy_getseters[] = { {"first", (getter)Noddy_getfirst, (setter)Noddy_setfirst, "first name", NULL}, {"last", (getter)Noddy_getlast, (setter)Noddy_setlast, "last name", NULL}, {NULL} /* Sentinel */ }; static PyObject * Noddy_name(Noddy* self) { static PyObject *format = NULL; PyObject *args, *result; if (format == NULL) { format = PyUnicode_FromString("%s %s"); if (format == NULL) return NULL; } args = Py_BuildValue("OO", self->first, self->last); if (args == NULL) return NULL; result = PyUnicode_Format(format, args); Py_DECREF(args); return result; } static PyMethodDef Noddy_methods[] = { {"name", (PyCFunction)Noddy_name, METH_NOARGS, "Return the name, combining the first and last name" }, {NULL} /* Sentinel */ }; static PyTypeObject NoddyType = { PyVarObject_HEAD_INIT(NULL, 0) "noddy.Noddy", /* tp_name */ sizeof(Noddy), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)Noddy_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ "Noddy objects", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ Noddy_methods, /* tp_methods */ Noddy_members, /* tp_members */ Noddy_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)Noddy_init, /* tp_init */ 0, /* tp_alloc */ Noddy_new, /* tp_new */ }; static PyModuleDef noddy3module = { PyModuleDef_HEAD_INIT, "noddy3", "Example module that creates an extension type.", -1, NULL, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit_noddy3(void) { PyObject* m; if (PyType_Ready(&NoddyType) < 0) return NULL; m = PyModule_Create(&noddy3module); if (m == NULL) return NULL; Py_INCREF(&NoddyType); PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType); return m; }