1 #include <Python.h> 2 #include "structmember.h" 3 4 typedef struct { 5 PyObject_HEAD 6 PyObject *first; /* first name */ 7 PyObject *last; /* last name */ 8 int number; 9 } Noddy; 10 11 static void 12 Noddy_dealloc(Noddy* self) 13 { 14 Py_XDECREF(self->first); 15 Py_XDECREF(self->last); 16 self->ob_type->tp_free((PyObject*)self); 17 } 18 19 static PyObject * 20 Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 21 { 22 Noddy *self; 23 24 self = (Noddy *)type->tp_alloc(type, 0); 25 if (self != NULL) { 26 self->first = PyString_FromString(""); 27 if (self->first == NULL) 28 { 29 Py_DECREF(self); 30 return NULL; 31 } 32 33 self->last = PyString_FromString(""); 34 if (self->last == NULL) 35 { 36 Py_DECREF(self); 37 return NULL; 38 } 39 40 self->number = 0; 41 } 42 43 return (PyObject *)self; 44 } 45 46 static int 47 Noddy_init(Noddy *self, PyObject *args, PyObject *kwds) 48 { 49 PyObject *first=NULL, *last=NULL, *tmp; 50 51 static char *kwlist[] = {"first", "last", "number", NULL}; 52 53 if (! PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, 54 &first, &last, 55 &self->number)) 56 return -1; 57 58 if (first) { 59 tmp = self->first; 60 Py_INCREF(first); 61 self->first = first; 62 Py_XDECREF(tmp); 63 } 64 65 if (last) { 66 tmp = self->last; 67 Py_INCREF(last); 68 self->last = last; 69 Py_XDECREF(tmp); 70 } 71 72 return 0; 73 } 74 75 76 static PyMemberDef Noddy_members[] = { 77 {"first", T_OBJECT_EX, offsetof(Noddy, first), 0, 78 "first name"}, 79 {"last", T_OBJECT_EX, offsetof(Noddy, last), 0, 80 "last name"}, 81 {"number", T_INT, offsetof(Noddy, number), 0, 82 "noddy number"}, 83 {NULL} /* Sentinel */ 84 }; 85 86 static PyObject * 87 Noddy_name(Noddy* self) 88 { 89 static PyObject *format = NULL; 90 PyObject *args, *result; 91 92 if (format == NULL) { 93 format = PyString_FromString("%s %s"); 94 if (format == NULL) 95 return NULL; 96 } 97 98 if (self->first == NULL) { 99 PyErr_SetString(PyExc_AttributeError, "first"); 100 return NULL; 101 } 102 103 if (self->last == NULL) { 104 PyErr_SetString(PyExc_AttributeError, "last"); 105 return NULL; 106 } 107 108 args = Py_BuildValue("OO", self->first, self->last); 109 if (args == NULL) 110 return NULL; 111 112 result = PyString_Format(format, args); 113 Py_DECREF(args); 114 115 return result; 116 } 117 118 static PyMethodDef Noddy_methods[] = { 119 {"name", (PyCFunction)Noddy_name, METH_NOARGS, 120 "Return the name, combining the first and last name" 121 }, 122 {NULL} /* Sentinel */ 123 }; 124 125 static PyTypeObject NoddyType = { 126 PyObject_HEAD_INIT(NULL) 127 0, /*ob_size*/ 128 "noddy.Noddy", /*tp_name*/ 129 sizeof(Noddy), /*tp_basicsize*/ 130 0, /*tp_itemsize*/ 131 (destructor)Noddy_dealloc, /*tp_dealloc*/ 132 0, /*tp_print*/ 133 0, /*tp_getattr*/ 134 0, /*tp_setattr*/ 135 0, /*tp_compare*/ 136 0, /*tp_repr*/ 137 0, /*tp_as_number*/ 138 0, /*tp_as_sequence*/ 139 0, /*tp_as_mapping*/ 140 0, /*tp_hash */ 141 0, /*tp_call*/ 142 0, /*tp_str*/ 143 0, /*tp_getattro*/ 144 0, /*tp_setattro*/ 145 0, /*tp_as_buffer*/ 146 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ 147 "Noddy objects", /* tp_doc */ 148 0, /* tp_traverse */ 149 0, /* tp_clear */ 150 0, /* tp_richcompare */ 151 0, /* tp_weaklistoffset */ 152 0, /* tp_iter */ 153 0, /* tp_iternext */ 154 Noddy_methods, /* tp_methods */ 155 Noddy_members, /* tp_members */ 156 0, /* tp_getset */ 157 0, /* tp_base */ 158 0, /* tp_dict */ 159 0, /* tp_descr_get */ 160 0, /* tp_descr_set */ 161 0, /* tp_dictoffset */ 162 (initproc)Noddy_init, /* tp_init */ 163 0, /* tp_alloc */ 164 Noddy_new, /* tp_new */ 165 }; 166 167 static PyMethodDef module_methods[] = { 168 {NULL} /* Sentinel */ 169 }; 170 171 #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */ 172 #define PyMODINIT_FUNC void 173 #endif 174 PyMODINIT_FUNC 175 initnoddy2(void) 176 { 177 PyObject* m; 178 179 if (PyType_Ready(&NoddyType) < 0) 180 return; 181 182 m = Py_InitModule3("noddy2", module_methods, 183 "Example module that creates an extension type."); 184 185 if (m == NULL) 186 return; 187 188 Py_INCREF(&NoddyType); 189 PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType); 190 } 191