blob: 7b044d187d267cd06b6984beb0eefceee5e0fbc8 [file] [log] [blame]
Jim Fultonaed0a4a2003-05-07 19:48:13 +00001#include <Python.h>
2#include "structmember.h"
3
4typedef struct {
5 PyObject_HEAD
6 PyObject *first;
7 PyObject *last;
8 int number;
9} Noddy;
10
11static void
12Noddy_dealloc(Noddy* self)
13{
14 Py_XDECREF(self->first);
15 Py_XDECREF(self->last);
Jim Fulton1f325562003-05-16 13:53:43 +000016 self->ob_type->tp_free((PyObject*)self);
Jim Fultonaed0a4a2003-05-07 19:48:13 +000017}
18
19static PyObject *
20Noddy_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
46static PyObject *
47Noddy_init(Noddy *self, PyObject *args, PyObject *kwds)
48{
49 PyObject *first=NULL, *last=NULL;
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 NULL;
57
58 if (first) {
59 Py_DECREF(self->first);
60 Py_INCREF(first);
61 self->first = first;
62 }
63
64 if (last) {
65 Py_DECREF(self->last);
66 Py_INCREF(last);
67 self->last = last;
68 }
69
70 Py_INCREF(Py_None);
71 return Py_None;
72}
73
74static PyMemberDef Noddy_members[] = {
75 {"number", T_INT, offsetof(Noddy, number), 0,
76 "noddy number"},
77 {NULL} /* Sentinel */
78};
79
80static PyObject *
81Noddy_getfirst(Noddy *self, void *closure)
82{
83 Py_INCREF(self->first);
84 return self->first;
85}
86
87static int
88Noddy_setfirst(Noddy *self, PyObject *value, void *closure)
89{
90 if (value == NULL) {
91 PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute");
92 return -1;
93 }
94
95 if (! PyString_Check(value)) {
96 PyErr_SetString(PyExc_TypeError,
97 "The first attribute value must be a string");
98 return -1;
99 }
100
101 Py_DECREF(self->first);
102 Py_INCREF(value);
103 self->first = value;
104
105 return 0;
106}
107
108static PyObject *
109Noddy_getlast(Noddy *self, void *closure)
110{
111 Py_INCREF(self->last);
112 return self->last;
113}
114
115static int
116Noddy_setlast(Noddy *self, PyObject *value, void *closure)
117{
118 if (value == NULL) {
119 PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute");
120 return -1;
121 }
122
123 if (! PyString_Check(value)) {
124 PyErr_SetString(PyExc_TypeError,
125 "The last attribute value must be a string");
126 return -1;
127 }
128
129 Py_DECREF(self->last);
130 Py_INCREF(value);
131 self->last = value;
132
133 return 0;
134}
135
136static PyGetSetDef Noddy_getseters[] = {
137 {"first",
138 (getter)Noddy_getfirst, (setter)Noddy_setfirst,
139 "first name",
140 NULL},
141 {"last",
142 (getter)Noddy_getlast, (setter)Noddy_setlast,
143 "last name",
144 NULL},
145 {NULL} /* Sentinel */
146};
147
148static PyObject *
149Noddy_name(Noddy* self)
150{
151 static PyObject *format = NULL;
152 PyObject *args, *result;
153
154 if (format == NULL) {
155 format = PyString_FromString("%s %s");
156 if (format == NULL)
157 return NULL;
158 }
159
160 args = Py_BuildValue("OO", self->first, self->last);
161 if (args == NULL)
162 return NULL;
163
164 result = PyString_Format(format, args);
165 Py_DECREF(args);
166
167 return result;
168}
169
170static PyMethodDef Noddy_methods[] = {
171 {"name", (PyCFunction)Noddy_name, METH_NOARGS,
172 "Return the name, combining the first and last name"
173 },
174 {NULL} /* Sentinel */
175};
176
177static PyTypeObject NoddyType = {
178 PyObject_HEAD_INIT(NULL)
179 0, /*ob_size*/
180 "noddy.Noddy", /*tp_name*/
181 sizeof(Noddy), /*tp_basicsize*/
182 0, /*tp_itemsize*/
183 (destructor)Noddy_dealloc, /*tp_dealloc*/
184 0, /*tp_print*/
185 0, /*tp_getattr*/
186 0, /*tp_setattr*/
187 0, /*tp_compare*/
188 0, /*tp_repr*/
189 0, /*tp_as_number*/
190 0, /*tp_as_sequence*/
191 0, /*tp_as_mapping*/
192 0, /*tp_hash */
193 0, /*tp_call*/
194 0, /*tp_str*/
195 0, /*tp_getattro*/
196 0, /*tp_setattro*/
197 0, /*tp_as_buffer*/
198 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
199 "Noddy objects", /* tp_doc */
200 0, /* tp_traverse */
201 0, /* tp_clear */
202 0, /* tp_richcompare */
203 0, /* tp_weaklistoffset */
204 0, /* tp_iter */
205 0, /* tp_iternext */
206 Noddy_methods, /* tp_methods */
207 Noddy_members, /* tp_members */
208 Noddy_getseters, /* tp_getset */
209 0, /* tp_base */
210 0, /* tp_dict */
211 0, /* tp_descr_get */
212 0, /* tp_descr_set */
213 0, /* tp_dictoffset */
214 (initproc)Noddy_init, /* tp_init */
215 0, /* tp_alloc */
216 Noddy_new, /* tp_new */
217};
218
219static PyMethodDef module_methods[] = {
220 {NULL} /* Sentinel */
221};
222
Jim Fulton1f325562003-05-16 13:53:43 +0000223#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
224#define PyMODINIT_FUNC void
225#endif
Jim Fultonaed0a4a2003-05-07 19:48:13 +0000226PyMODINIT_FUNC
227initnoddy3(void)
228{
229 PyObject* m;
230
231 if (PyType_Ready(&NoddyType) < 0)
232 return;
233
234 m = Py_InitModule3("noddy3", module_methods,
235 "Example module that creates an extension type.");
236
237 if (m == NULL)
238 return;
239
240 PyModule_AddObject(m, "Noddy", (PyObject *)&NoddyType);
241}