blob: 5f75b6cf8f9de6d6064b67f4ac9fd5ff8d10ffd0 [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
Guido van Rossum14ed0b21994-09-29 09:50:09 +00002/* Use this file as a template to start implementing a module that
Andrew M. Kuchlingf580d272000-08-19 15:36:41 +00003 also declares object types. All occurrences of 'Xxo' should be changed
Guido van Rossum14ed0b21994-09-29 09:50:09 +00004 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
7 foomodule.c.
Tim Petersc9ca5c82002-05-23 15:49:38 +00008
Guido van Rossum14ed0b21994-09-29 09:50:09 +00009 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. */
14
15/* Xxo objects */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000016
Guido van Rossum2b654441996-07-30 16:56:16 +000017#include "Python.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000018
Guido van Rossum2b654441996-07-30 16:56:16 +000019static PyObject *ErrorObject;
Guido van Rossum14ed0b21994-09-29 09:50:09 +000020
21typedef struct {
Guido van Rossum2b654441996-07-30 16:56:16 +000022 PyObject_HEAD
23 PyObject *x_attr; /* Attributes dictionary */
24} XxoObject;
Guido van Rossum14ed0b21994-09-29 09:50:09 +000025
Jeremy Hylton938ace62002-07-17 16:30:39 +000026static PyTypeObject Xxo_Type;
Guido van Rossum14ed0b21994-09-29 09:50:09 +000027
Guido van Rossum2b654441996-07-30 16:56:16 +000028#define XxoObject_Check(v) ((v)->ob_type == &Xxo_Type)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000029
Guido van Rossum2b654441996-07-30 16:56:16 +000030static XxoObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000031newXxoObject(PyObject *arg)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000032{
Guido van Rossum2b654441996-07-30 16:56:16 +000033 XxoObject *self;
Guido van Rossumb18618d2000-05-03 23:44:39 +000034 self = PyObject_New(XxoObject, &Xxo_Type);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000035 if (self == NULL)
36 return NULL;
37 self->x_attr = NULL;
38 return self;
39}
40
41/* Xxo methods */
42
43static void
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000044Xxo_dealloc(XxoObject *self)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000045{
Guido van Rossum2b654441996-07-30 16:56:16 +000046 Py_XDECREF(self->x_attr);
Guido van Rossumb18618d2000-05-03 23:44:39 +000047 PyObject_Del(self);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000048}
49
Guido van Rossum2b654441996-07-30 16:56:16 +000050static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000051Xxo_demo(XxoObject *self, PyObject *args)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000052{
Guido van Rossum43713e52000-02-29 13:59:29 +000053 if (!PyArg_ParseTuple(args, ":demo"))
Guido van Rossum14ed0b21994-09-29 09:50:09 +000054 return NULL;
Guido van Rossum2b654441996-07-30 16:56:16 +000055 Py_INCREF(Py_None);
56 return Py_None;
Guido van Rossum14ed0b21994-09-29 09:50:09 +000057}
58
Guido van Rossum2b654441996-07-30 16:56:16 +000059static PyMethodDef Xxo_methods[] = {
Skip Montanarod9e7d242002-08-14 01:44:33 +000060 {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
61 PyDoc_STR("demo() -> None")},
Guido van Rossum14ed0b21994-09-29 09:50:09 +000062 {NULL, NULL} /* sentinel */
63};
64
Guido van Rossum2b654441996-07-30 16:56:16 +000065static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000066Xxo_getattr(XxoObject *self, char *name)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000067{
68 if (self->x_attr != NULL) {
Guido van Rossum2b654441996-07-30 16:56:16 +000069 PyObject *v = PyDict_GetItemString(self->x_attr, name);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000070 if (v != NULL) {
Guido van Rossum2b654441996-07-30 16:56:16 +000071 Py_INCREF(v);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000072 return v;
73 }
74 }
Guido van Rossum2b654441996-07-30 16:56:16 +000075 return Py_FindMethod(Xxo_methods, (PyObject *)self, name);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000076}
77
78static int
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +000079Xxo_setattr(XxoObject *self, char *name, PyObject *v)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000080{
81 if (self->x_attr == NULL) {
Guido van Rossum2b654441996-07-30 16:56:16 +000082 self->x_attr = PyDict_New();
Guido van Rossum14ed0b21994-09-29 09:50:09 +000083 if (self->x_attr == NULL)
84 return -1;
85 }
86 if (v == NULL) {
Guido van Rossum2b654441996-07-30 16:56:16 +000087 int rv = PyDict_DelItemString(self->x_attr, name);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000088 if (rv < 0)
Guido van Rossum2b654441996-07-30 16:56:16 +000089 PyErr_SetString(PyExc_AttributeError,
90 "delete non-existing Xxo attribute");
Guido van Rossum14ed0b21994-09-29 09:50:09 +000091 return rv;
92 }
93 else
Guido van Rossum2b654441996-07-30 16:56:16 +000094 return PyDict_SetItemString(self->x_attr, name, v);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000095}
96
Tim Peters0c322792002-07-17 16:49:03 +000097static PyTypeObject Xxo_Type = {
Fred Drake67248351999-02-16 22:15:42 +000098 /* The ob_type field must be initialized in the module init function
99 * to be portable to Windows without using C++. */
100 PyObject_HEAD_INIT(NULL)
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000101 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000102 "xxmodule.Xxo", /*tp_name*/
Guido van Rossum2b654441996-07-30 16:56:16 +0000103 sizeof(XxoObject), /*tp_basicsize*/
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000104 0, /*tp_itemsize*/
105 /* methods */
Guido van Rossum2b654441996-07-30 16:56:16 +0000106 (destructor)Xxo_dealloc, /*tp_dealloc*/
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000107 0, /*tp_print*/
Guido van Rossum2b654441996-07-30 16:56:16 +0000108 (getattrfunc)Xxo_getattr, /*tp_getattr*/
109 (setattrfunc)Xxo_setattr, /*tp_setattr*/
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000110 0, /*tp_compare*/
111 0, /*tp_repr*/
112 0, /*tp_as_number*/
113 0, /*tp_as_sequence*/
114 0, /*tp_as_mapping*/
115 0, /*tp_hash*/
Martin v. Löwisffa7aff2001-10-09 10:46:58 +0000116 0, /*tp_call*/
117 0, /*tp_str*/
118 0, /*tp_getattro*/
119 0, /*tp_setattro*/
120 0, /*tp_as_buffer*/
121 Py_TPFLAGS_DEFAULT, /*tp_flags*/
122 0, /*tp_doc*/
123 0, /*tp_traverse*/
124 0, /*tp_clear*/
125 0, /*tp_richcompare*/
126 0, /*tp_weaklistoffset*/
127 0, /*tp_iter*/
128 0, /*tp_iternext*/
129 0, /*tp_methods*/
130 0, /*tp_members*/
131 0, /*tp_getset*/
132 0, /*tp_base*/
133 0, /*tp_dict*/
134 0, /*tp_descr_get*/
135 0, /*tp_descr_set*/
136 0, /*tp_dictoffset*/
137 0, /*tp_init*/
138 0, /*tp_alloc*/
139 0, /*tp_new*/
140 0, /*tp_free*/
141 0, /*tp_is_gc*/
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000142};
143/* --------------------------------------------------------------------- */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000144
145/* Function of two integers returning integer */
146
Skip Montanarod9e7d242002-08-14 01:44:33 +0000147PyDoc_STRVAR(xx_foo_doc,
148"foo(i,j)\n\
149\n\
150Return the sum of i and j.");
151
Guido van Rossum2b654441996-07-30 16:56:16 +0000152static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000153xx_foo(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000154{
155 long i, j;
156 long res;
Guido van Rossum43713e52000-02-29 13:59:29 +0000157 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000158 return NULL;
159 res = i+j; /* XXX Do something here */
Guido van Rossum2b654441996-07-30 16:56:16 +0000160 return PyInt_FromLong(res);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000161}
162
163
Guido van Rossum2b654441996-07-30 16:56:16 +0000164/* Function of no arguments returning new Xxo object */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000165
Guido van Rossum2b654441996-07-30 16:56:16 +0000166static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000167xx_new(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000168{
Guido van Rossum2b654441996-07-30 16:56:16 +0000169 XxoObject *rv;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000170
Guido van Rossum43713e52000-02-29 13:59:29 +0000171 if (!PyArg_ParseTuple(args, ":new"))
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000172 return NULL;
Guido van Rossum2b654441996-07-30 16:56:16 +0000173 rv = newXxoObject(args);
Tim Petersc9ca5c82002-05-23 15:49:38 +0000174 if (rv == NULL)
175 return NULL;
Guido van Rossum2b654441996-07-30 16:56:16 +0000176 return (PyObject *)rv;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000177}
178
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000179/* Example with subtle bug from extensions manual ("Thin Ice"). */
180
181static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000182xx_bug(PyObject *self, PyObject *args)
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000183{
184 PyObject *list, *item;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000185
Guido van Rossum43713e52000-02-29 13:59:29 +0000186 if (!PyArg_ParseTuple(args, "O:bug", &list))
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000187 return NULL;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000188
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000189 item = PyList_GetItem(list, 0);
190 /* Py_INCREF(item); */
191 PyList_SetItem(list, 1, PyInt_FromLong(0L));
192 PyObject_Print(item, stdout, 0);
193 printf("\n");
194 /* Py_DECREF(item); */
Tim Petersc9ca5c82002-05-23 15:49:38 +0000195
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000196 Py_INCREF(Py_None);
197 return Py_None;
198}
199
Guido van Rossumc525e431997-12-09 20:37:25 +0000200/* Test bad format character */
201
202static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000203xx_roj(PyObject *self, PyObject *args)
Guido van Rossumc525e431997-12-09 20:37:25 +0000204{
205 PyObject *a;
206 long b;
Guido van Rossum43713e52000-02-29 13:59:29 +0000207 if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
Guido van Rossumc525e431997-12-09 20:37:25 +0000208 return NULL;
209 Py_INCREF(Py_None);
210 return Py_None;
211}
212
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000213
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000214/* ---------- */
215
216static PyTypeObject Str_Type = {
217 /* The ob_type field must be initialized in the module init function
218 * to be portable to Windows without using C++. */
219 PyObject_HEAD_INIT(NULL)
220 0, /*ob_size*/
221 "xxmodule.Str", /*tp_name*/
222 0, /*tp_basicsize*/
223 0, /*tp_itemsize*/
224 /* methods */
225 0, /*tp_dealloc*/
226 0, /*tp_print*/
227 0, /*tp_getattr*/
228 0, /*tp_setattr*/
229 0, /*tp_compare*/
230 0, /*tp_repr*/
231 0, /*tp_as_number*/
232 0, /*tp_as_sequence*/
233 0, /*tp_as_mapping*/
234 0, /*tp_hash*/
235 0, /*tp_call*/
236 0, /*tp_str*/
237 0, /*tp_getattro*/
238 0, /*tp_setattro*/
239 0, /*tp_as_buffer*/
240 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
241 0, /*tp_doc*/
242 0, /*tp_traverse*/
243 0, /*tp_clear*/
244 0, /*tp_richcompare*/
245 0, /*tp_weaklistoffset*/
246 0, /*tp_iter*/
247 0, /*tp_iternext*/
248 0, /*tp_methods*/
249 0, /*tp_members*/
250 0, /*tp_getset*/
251 &PyString_Type, /*tp_base*/
252 0, /*tp_dict*/
253 0, /*tp_descr_get*/
254 0, /*tp_descr_set*/
255 0, /*tp_dictoffset*/
256 0, /*tp_init*/
257 0, /*tp_alloc*/
258 0, /*tp_new*/
259 0, /*tp_free*/
260 0, /*tp_is_gc*/
261};
262
Guido van Rossum72976502003-02-13 18:44:57 +0000263/* ---------- */
264
265static PyObject *
266null_richcompare(PyObject *self, PyObject *other, int op)
267{
268 Py_INCREF(Py_NotImplemented);
269 return Py_NotImplemented;
270}
271
272static PyTypeObject Null_Type = {
273 /* The ob_type field must be initialized in the module init function
274 * to be portable to Windows without using C++. */
275 PyObject_HEAD_INIT(NULL)
276 0, /*ob_size*/
277 "xxmodule.Null", /*tp_name*/
278 0, /*tp_basicsize*/
279 0, /*tp_itemsize*/
280 /* methods */
281 0, /*tp_dealloc*/
282 0, /*tp_print*/
283 0, /*tp_getattr*/
284 0, /*tp_setattr*/
285 0, /*tp_compare*/
286 0, /*tp_repr*/
287 0, /*tp_as_number*/
288 0, /*tp_as_sequence*/
289 0, /*tp_as_mapping*/
290 0, /*tp_hash*/
291 0, /*tp_call*/
292 0, /*tp_str*/
293 0, /*tp_getattro*/
294 0, /*tp_setattro*/
295 0, /*tp_as_buffer*/
296 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
297 0, /*tp_doc*/
298 0, /*tp_traverse*/
299 0, /*tp_clear*/
300 null_richcompare, /*tp_richcompare*/
301 0, /*tp_weaklistoffset*/
302 0, /*tp_iter*/
303 0, /*tp_iternext*/
304 0, /*tp_methods*/
305 0, /*tp_members*/
306 0, /*tp_getset*/
307 &PyBaseObject_Type, /*tp_base*/
308 0, /*tp_dict*/
309 0, /*tp_descr_get*/
310 0, /*tp_descr_set*/
311 0, /*tp_dictoffset*/
312 0, /*tp_init*/
313 0, /*tp_alloc*/
314 PyType_GenericNew, /*tp_new*/
315 0, /*tp_free*/
316 0, /*tp_is_gc*/
317};
318
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000319
320/* ---------- */
321
322
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000323/* List of functions defined in the module */
324
Guido van Rossum2b654441996-07-30 16:56:16 +0000325static PyMethodDef xx_methods[] = {
Skip Montanarod9e7d242002-08-14 01:44:33 +0000326 {"roj", xx_roj, METH_VARARGS,
327 PyDoc_STR("roj(a,b) -> None")},
328 {"foo", xx_foo, METH_VARARGS,
329 xx_foo_doc},
330 {"new", xx_new, METH_VARARGS,
331 PyDoc_STR("new() -> new Xx object")},
332 {"bug", xx_bug, METH_VARARGS,
333 PyDoc_STR("bug(o) -> None")},
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000334 {NULL, NULL} /* sentinel */
335};
336
Skip Montanarod9e7d242002-08-14 01:44:33 +0000337PyDoc_STRVAR(module_doc,
338"This is a template module just for instruction.");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000339
340/* Initialization function for the module (*must* be called initxx) */
341
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000342PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000343initxx(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000344{
Thomas Heller16305202002-04-09 12:50:13 +0000345 PyObject *m;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000346
Raymond Hettinger3c736f12002-12-29 17:16:49 +0000347 /* Finalize the type object including setting type of the new type
348 * object; doing it here is required for portability to Windows
349 * without requiring C++. */
350 if (PyType_Ready(&Xxo_Type) < 0)
351 return;
Fred Drake67248351999-02-16 22:15:42 +0000352
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000353 /* Create the module and add the functions */
Skip Montanarod9e7d242002-08-14 01:44:33 +0000354 m = Py_InitModule3("xx", xx_methods, module_doc);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000355
356 /* Add some symbolic constants to the module */
Fred Drake1de5a722002-03-12 21:49:44 +0000357 if (ErrorObject == NULL) {
358 ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
359 if (ErrorObject == NULL)
360 return;
361 }
362 Py_INCREF(ErrorObject);
Thomas Heller16305202002-04-09 12:50:13 +0000363 PyModule_AddObject(m, "error", ErrorObject);
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000364
365 /* Add Str */
366 if (PyType_Ready(&Str_Type) < 0)
367 return;
368 PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
Guido van Rossum72976502003-02-13 18:44:57 +0000369
370 /* Add Null */
371 if (PyType_Ready(&Null_Type) < 0)
372 return;
373 PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000374}