blob: 076440703f5f71cefb4ab948131dbf1508fe7b5a [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
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020079Xxo_setattr(XxoObject *self, const 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
Nick Coghland5cacbb2015-05-23 22:24:10 +1000338static int
339xx_exec(PyObject *m)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 /* Due to cross platform compiler issues the slots must be filled
342 * here. It's required for portability to Windows without requiring
343 * C++. */
344 Null_Type.tp_base = &PyBaseObject_Type;
345 Null_Type.tp_new = PyType_GenericNew;
346 Str_Type.tp_base = &PyUnicode_Type;
Christian Heimes80101a82007-11-18 21:30:36 +0000347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 /* Finalize the type object including setting type of the new type
349 * object; doing it here is required for portability, too. */
350 if (PyType_Ready(&Xxo_Type) < 0)
351 goto fail;
Fred Drake67248351999-02-16 22:15:42 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 /* Add some symbolic constants to the module */
354 if (ErrorObject == NULL) {
355 ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
356 if (ErrorObject == NULL)
357 goto fail;
358 }
359 Py_INCREF(ErrorObject);
360 PyModule_AddObject(m, "error", ErrorObject);
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 /* Add Str */
363 if (PyType_Ready(&Str_Type) < 0)
364 goto fail;
365 PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
Guido van Rossum72976502003-02-13 18:44:57 +0000366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 /* Add Null */
368 if (PyType_Ready(&Null_Type) < 0)
369 goto fail;
370 PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000371 return 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000372 fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 Py_XDECREF(m);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000374 return -1;
375}
376
377static struct PyModuleDef_Slot xx_slots[] = {
378 {Py_mod_exec, xx_exec},
379 {0, NULL},
380};
381
382static struct PyModuleDef xxmodule = {
383 PyModuleDef_HEAD_INIT,
384 "xx",
385 module_doc,
386 0,
387 xx_methods,
388 xx_slots,
389 NULL,
390 NULL,
391 NULL
392};
393
394/* Export function for the module (*must* be called PyInit_xx) */
395
396PyMODINIT_FUNC
397PyInit_xx(void)
398{
399 return PyModuleDef_Init(&xxmodule);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000400}