blob: c0564ea9674eac85f0bba40ce0e26ae65987fc2a [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*/
Stefan Krahca725892017-09-22 17:44:58 +0200311 PyType_GenericNew, /*tp_new*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 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{
Stefan Krahca725892017-09-22 17:44:58 +0200341 /* Slot initialization is subject to the rules of initializing globals.
342 C99 requires the initializers to be "address constants". Function
343 designators like 'PyType_GenericNew', with implicit conversion to
344 a pointer, are valid C99 address constants.
345
346 However, the unary '&' operator applied to a non-static variable
347 like 'PyBaseObject_Type' is not required to produce an address
348 constant. Compilers may support this (gcc does), MSVC does not.
349
350 Both compilers are strictly standard conforming in this particular
351 behavior.
352 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 Null_Type.tp_base = &PyBaseObject_Type;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 Str_Type.tp_base = &PyUnicode_Type;
Christian Heimes80101a82007-11-18 21:30:36 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 /* Finalize the type object including setting type of the new type
357 * object; doing it here is required for portability, too. */
358 if (PyType_Ready(&Xxo_Type) < 0)
359 goto fail;
Fred Drake67248351999-02-16 22:15:42 +0000360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 /* Add some symbolic constants to the module */
362 if (ErrorObject == NULL) {
363 ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
364 if (ErrorObject == NULL)
365 goto fail;
366 }
367 Py_INCREF(ErrorObject);
368 PyModule_AddObject(m, "error", ErrorObject);
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 /* Add Str */
371 if (PyType_Ready(&Str_Type) < 0)
372 goto fail;
373 PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
Guido van Rossum72976502003-02-13 18:44:57 +0000374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 /* Add Null */
376 if (PyType_Ready(&Null_Type) < 0)
377 goto fail;
378 PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000379 return 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000380 fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 Py_XDECREF(m);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000382 return -1;
383}
384
385static struct PyModuleDef_Slot xx_slots[] = {
386 {Py_mod_exec, xx_exec},
387 {0, NULL},
388};
389
390static struct PyModuleDef xxmodule = {
391 PyModuleDef_HEAD_INIT,
392 "xx",
393 module_doc,
394 0,
395 xx_methods,
396 xx_slots,
397 NULL,
398 NULL,
399 NULL
400};
401
402/* Export function for the module (*must* be called PyInit_xx) */
403
404PyMODINIT_FUNC
405PyInit_xx(void)
406{
407 return PyModuleDef_Init(&xxmodule);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000408}