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