blob: 0feff662d539eea98cf395c88bf1881dd742fc12 [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
Mark Dickinsond19052c2010-06-27 18:19:09 +000013 floatobject.h for an example. */
Guido van Rossum14ed0b21994-09-29 09:50:09 +000014
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 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000022 PyObject_HEAD
23 PyObject *x_attr; /* Attributes dictionary */
Guido van Rossum2b654441996-07-30 16:56:16 +000024} 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
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028#define XxoObject_Check(v) (Py_TYPE(v) == &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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000033 XxoObject *self;
34 self = PyObject_New(XxoObject, &Xxo_Type);
35 if (self == NULL)
36 return NULL;
37 self->x_attr = NULL;
38 return self;
Guido van Rossum14ed0b21994-09-29 09:50:09 +000039}
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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 Py_XDECREF(self->x_attr);
47 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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000053 if (!PyArg_ParseTuple(args, ":demo"))
54 return NULL;
55 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[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
61 PyDoc_STR("demo() -> None")},
62 {NULL, NULL} /* sentinel */
Guido van Rossum14ed0b21994-09-29 09:50:09 +000063};
64
Guido van Rossum2b654441996-07-30 16:56:16 +000065static PyObject *
Amaury Forgeot d'Arc1f900f12008-07-02 22:38:47 +000066Xxo_getattro(XxoObject *self, PyObject *name)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 if (self->x_attr != NULL) {
69 PyObject *v = PyDict_GetItem(self->x_attr, name);
70 if (v != NULL) {
71 Py_INCREF(v);
72 return v;
73 }
74 }
75 return PyObject_GenericGetAttr((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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 if (self->x_attr == NULL) {
82 self->x_attr = PyDict_New();
83 if (self->x_attr == NULL)
84 return -1;
85 }
86 if (v == NULL) {
87 int rv = PyDict_DelItemString(self->x_attr, name);
88 if (rv < 0)
89 PyErr_SetString(PyExc_AttributeError,
90 "delete non-existing Xxo attribute");
91 return rv;
92 }
93 else
94 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 = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 /* The ob_type field must be initialized in the module init function
99 * to be portable to Windows without using C++. */
100 PyVarObject_HEAD_INIT(NULL, 0)
101 "xxmodule.Xxo", /*tp_name*/
102 sizeof(XxoObject), /*tp_basicsize*/
103 0, /*tp_itemsize*/
104 /* methods */
Eli Benderskyb829dea2013-01-01 07:41:51 -0800105 (destructor)Xxo_dealloc, /*tp_dealloc*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 0, /*tp_print*/
Eli Benderskyb829dea2013-01-01 07:41:51 -0800107 (getattrfunc)0, /*tp_getattr*/
108 (setattrfunc)Xxo_setattr, /*tp_setattr*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 0, /*tp_reserved*/
110 0, /*tp_repr*/
111 0, /*tp_as_number*/
112 0, /*tp_as_sequence*/
113 0, /*tp_as_mapping*/
114 0, /*tp_hash*/
Eli Benderskyb829dea2013-01-01 07:41:51 -0800115 0, /*tp_call*/
116 0, /*tp_str*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 (getattrofunc)Xxo_getattro, /*tp_getattro*/
Eli Benderskyb829dea2013-01-01 07:41:51 -0800118 0, /*tp_setattro*/
119 0, /*tp_as_buffer*/
120 Py_TPFLAGS_DEFAULT, /*tp_flags*/
121 0, /*tp_doc*/
122 0, /*tp_traverse*/
123 0, /*tp_clear*/
124 0, /*tp_richcompare*/
125 0, /*tp_weaklistoffset*/
126 0, /*tp_iter*/
127 0, /*tp_iternext*/
128 Xxo_methods, /*tp_methods*/
129 0, /*tp_members*/
130 0, /*tp_getset*/
131 0, /*tp_base*/
132 0, /*tp_dict*/
133 0, /*tp_descr_get*/
134 0, /*tp_descr_set*/
135 0, /*tp_dictoffset*/
136 0, /*tp_init*/
137 0, /*tp_alloc*/
138 0, /*tp_new*/
139 0, /*tp_free*/
140 0, /*tp_is_gc*/
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000141};
142/* --------------------------------------------------------------------- */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000143
144/* Function of two integers returning integer */
145
Skip Montanarod9e7d242002-08-14 01:44:33 +0000146PyDoc_STRVAR(xx_foo_doc,
147"foo(i,j)\n\
148\n\
149Return the sum of i and j.");
150
Guido van Rossum2b654441996-07-30 16:56:16 +0000151static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000152xx_foo(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000153{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 long i, j;
155 long res;
156 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
157 return NULL;
158 res = i+j; /* XXX Do something here */
159 return PyLong_FromLong(res);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000160}
161
162
Guido van Rossum2b654441996-07-30 16:56:16 +0000163/* Function of no arguments returning new Xxo object */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000164
Guido van Rossum2b654441996-07-30 16:56:16 +0000165static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000166xx_new(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 XxoObject *rv;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000169
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000170 if (!PyArg_ParseTuple(args, ":new"))
171 return NULL;
172 rv = newXxoObject(args);
173 if (rv == NULL)
174 return NULL;
175 return (PyObject *)rv;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000176}
177
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000178/* Example with subtle bug from extensions manual ("Thin Ice"). */
179
180static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000181xx_bug(PyObject *self, PyObject *args)
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000182{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 PyObject *list, *item;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 if (!PyArg_ParseTuple(args, "O:bug", &list))
186 return NULL;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 item = PyList_GetItem(list, 0);
189 /* Py_INCREF(item); */
190 PyList_SetItem(list, 1, PyLong_FromLong(0L));
191 PyObject_Print(item, stdout, 0);
192 printf("\n");
193 /* Py_DECREF(item); */
Tim Petersc9ca5c82002-05-23 15:49:38 +0000194
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 Py_INCREF(Py_None);
196 return Py_None;
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000197}
198
Guido van Rossumc525e431997-12-09 20:37:25 +0000199/* Test bad format character */
200
201static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000202xx_roj(PyObject *self, PyObject *args)
Guido van Rossumc525e431997-12-09 20:37:25 +0000203{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 PyObject *a;
205 long b;
206 if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
207 return NULL;
208 Py_INCREF(Py_None);
209 return Py_None;
Guido van Rossumc525e431997-12-09 20:37:25 +0000210}
211
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000212
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000213/* ---------- */
214
215static PyTypeObject Str_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 /* The ob_type field must be initialized in the module init function
217 * to be portable to Windows without using C++. */
218 PyVarObject_HEAD_INIT(NULL, 0)
219 "xxmodule.Str", /*tp_name*/
220 0, /*tp_basicsize*/
221 0, /*tp_itemsize*/
222 /* methods */
223 0, /*tp_dealloc*/
224 0, /*tp_print*/
225 0, /*tp_getattr*/
226 0, /*tp_setattr*/
227 0, /*tp_reserved*/
228 0, /*tp_repr*/
229 0, /*tp_as_number*/
230 0, /*tp_as_sequence*/
231 0, /*tp_as_mapping*/
232 0, /*tp_hash*/
233 0, /*tp_call*/
234 0, /*tp_str*/
235 0, /*tp_getattro*/
236 0, /*tp_setattro*/
237 0, /*tp_as_buffer*/
238 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
239 0, /*tp_doc*/
240 0, /*tp_traverse*/
241 0, /*tp_clear*/
242 0, /*tp_richcompare*/
243 0, /*tp_weaklistoffset*/
244 0, /*tp_iter*/
245 0, /*tp_iternext*/
246 0, /*tp_methods*/
247 0, /*tp_members*/
248 0, /*tp_getset*/
249 0, /* see PyInit_xx */ /*tp_base*/
250 0, /*tp_dict*/
251 0, /*tp_descr_get*/
252 0, /*tp_descr_set*/
253 0, /*tp_dictoffset*/
254 0, /*tp_init*/
255 0, /*tp_alloc*/
256 0, /*tp_new*/
257 0, /*tp_free*/
258 0, /*tp_is_gc*/
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000259};
260
Guido van Rossum72976502003-02-13 18:44:57 +0000261/* ---------- */
262
263static PyObject *
264null_richcompare(PyObject *self, PyObject *other, int op)
265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 Py_INCREF(Py_NotImplemented);
267 return Py_NotImplemented;
Guido van Rossum72976502003-02-13 18:44:57 +0000268}
269
270static PyTypeObject Null_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 /* The ob_type field must be initialized in the module init function
272 * to be portable to Windows without using C++. */
273 PyVarObject_HEAD_INIT(NULL, 0)
274 "xxmodule.Null", /*tp_name*/
275 0, /*tp_basicsize*/
276 0, /*tp_itemsize*/
277 /* methods */
278 0, /*tp_dealloc*/
279 0, /*tp_print*/
280 0, /*tp_getattr*/
281 0, /*tp_setattr*/
282 0, /*tp_reserved*/
283 0, /*tp_repr*/
284 0, /*tp_as_number*/
285 0, /*tp_as_sequence*/
286 0, /*tp_as_mapping*/
287 0, /*tp_hash*/
288 0, /*tp_call*/
289 0, /*tp_str*/
290 0, /*tp_getattro*/
291 0, /*tp_setattro*/
292 0, /*tp_as_buffer*/
293 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
294 0, /*tp_doc*/
295 0, /*tp_traverse*/
296 0, /*tp_clear*/
297 null_richcompare, /*tp_richcompare*/
298 0, /*tp_weaklistoffset*/
299 0, /*tp_iter*/
300 0, /*tp_iternext*/
301 0, /*tp_methods*/
302 0, /*tp_members*/
303 0, /*tp_getset*/
304 0, /* see PyInit_xx */ /*tp_base*/
305 0, /*tp_dict*/
306 0, /*tp_descr_get*/
307 0, /*tp_descr_set*/
308 0, /*tp_dictoffset*/
309 0, /*tp_init*/
310 0, /*tp_alloc*/
311 0, /* see PyInit_xx */ /*tp_new*/
312 0, /*tp_free*/
313 0, /*tp_is_gc*/
Guido van Rossum72976502003-02-13 18:44:57 +0000314};
315
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000316
317/* ---------- */
318
319
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000320/* List of functions defined in the module */
321
Guido van Rossum2b654441996-07-30 16:56:16 +0000322static PyMethodDef xx_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 {"roj", xx_roj, METH_VARARGS,
324 PyDoc_STR("roj(a,b) -> None")},
325 {"foo", xx_foo, METH_VARARGS,
326 xx_foo_doc},
327 {"new", xx_new, METH_VARARGS,
328 PyDoc_STR("new() -> new Xx object")},
329 {"bug", xx_bug, METH_VARARGS,
330 PyDoc_STR("bug(o) -> None")},
331 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000332};
333
Skip Montanarod9e7d242002-08-14 01:44:33 +0000334PyDoc_STRVAR(module_doc,
335"This is a template module just for instruction.");
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000336
Martin v. Löwis1a214512008-06-11 05:26:20 +0000337/* Initialization function for the module (*must* be called PyInit_xx) */
338
339
340static struct PyModuleDef xxmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 PyModuleDef_HEAD_INIT,
342 "xx",
343 module_doc,
344 -1,
345 xx_methods,
346 NULL,
347 NULL,
348 NULL,
349 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000350};
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000351
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000352PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000353PyInit_xx(void)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 PyObject *m = NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 /* Due to cross platform compiler issues the slots must be filled
358 * here. It's required for portability to Windows without requiring
359 * C++. */
360 Null_Type.tp_base = &PyBaseObject_Type;
361 Null_Type.tp_new = PyType_GenericNew;
362 Str_Type.tp_base = &PyUnicode_Type;
Christian Heimes80101a82007-11-18 21:30:36 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 /* Finalize the type object including setting type of the new type
365 * object; doing it here is required for portability, too. */
366 if (PyType_Ready(&Xxo_Type) < 0)
367 goto fail;
Fred Drake67248351999-02-16 22:15:42 +0000368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 /* Create the module and add the functions */
370 m = PyModule_Create(&xxmodule);
371 if (m == NULL)
372 goto fail;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 /* Add some symbolic constants to the module */
375 if (ErrorObject == NULL) {
376 ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
377 if (ErrorObject == NULL)
378 goto fail;
379 }
380 Py_INCREF(ErrorObject);
381 PyModule_AddObject(m, "error", ErrorObject);
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000383 /* Add Str */
384 if (PyType_Ready(&Str_Type) < 0)
385 goto fail;
386 PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
Guido van Rossum72976502003-02-13 18:44:57 +0000387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 /* Add Null */
389 if (PyType_Ready(&Null_Type) < 0)
390 goto fail;
391 PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
392 return m;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000393 fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 Py_XDECREF(m);
395 return NULL;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000396}