blob: edcd62157c02f36fd0e81afa9085449db1c28249 [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
Dong-hee Na1b55b652020-02-17 19:09:15 +090028#define XxoObject_Check(v) Py_IS_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);
Victor Stinner32bd68c2020-12-01 10:37:39 +010047 PyObject_Free(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) {
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020069 PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 if (v != NULL) {
71 Py_INCREF(v);
72 return v;
73 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020074 else if (PyErr_Occurred()) {
75 return NULL;
76 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 }
78 return PyObject_GenericGetAttr((PyObject *)self, name);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000079}
80
81static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020082Xxo_setattr(XxoObject *self, const char *name, PyObject *v)
Guido van Rossum14ed0b21994-09-29 09:50:09 +000083{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 if (self->x_attr == NULL) {
85 self->x_attr = PyDict_New();
86 if (self->x_attr == NULL)
87 return -1;
88 }
89 if (v == NULL) {
90 int rv = PyDict_DelItemString(self->x_attr, name);
Serhiy Storchakaa24107b2019-02-25 17:59:46 +020091 if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 PyErr_SetString(PyExc_AttributeError,
93 "delete non-existing Xxo attribute");
94 return rv;
95 }
96 else
97 return PyDict_SetItemString(self->x_attr, name, v);
Guido van Rossum14ed0b21994-09-29 09:50:09 +000098}
99
Tim Peters0c322792002-07-17 16:49:03 +0000100static PyTypeObject Xxo_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 /* The ob_type field must be initialized in the module init function
102 * to be portable to Windows without using C++. */
103 PyVarObject_HEAD_INIT(NULL, 0)
104 "xxmodule.Xxo", /*tp_name*/
105 sizeof(XxoObject), /*tp_basicsize*/
106 0, /*tp_itemsize*/
107 /* methods */
Eli Benderskyb829dea2013-01-01 07:41:51 -0800108 (destructor)Xxo_dealloc, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200109 0, /*tp_vectorcall_offset*/
Eli Benderskyb829dea2013-01-01 07:41:51 -0800110 (getattrfunc)0, /*tp_getattr*/
111 (setattrfunc)Xxo_setattr, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200112 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 0, /*tp_repr*/
114 0, /*tp_as_number*/
115 0, /*tp_as_sequence*/
116 0, /*tp_as_mapping*/
117 0, /*tp_hash*/
Eli Benderskyb829dea2013-01-01 07:41:51 -0800118 0, /*tp_call*/
119 0, /*tp_str*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 (getattrofunc)Xxo_getattro, /*tp_getattro*/
Eli Benderskyb829dea2013-01-01 07:41:51 -0800121 0, /*tp_setattro*/
122 0, /*tp_as_buffer*/
123 Py_TPFLAGS_DEFAULT, /*tp_flags*/
124 0, /*tp_doc*/
125 0, /*tp_traverse*/
126 0, /*tp_clear*/
127 0, /*tp_richcompare*/
128 0, /*tp_weaklistoffset*/
129 0, /*tp_iter*/
130 0, /*tp_iternext*/
131 Xxo_methods, /*tp_methods*/
132 0, /*tp_members*/
133 0, /*tp_getset*/
134 0, /*tp_base*/
135 0, /*tp_dict*/
136 0, /*tp_descr_get*/
137 0, /*tp_descr_set*/
138 0, /*tp_dictoffset*/
139 0, /*tp_init*/
140 0, /*tp_alloc*/
141 0, /*tp_new*/
142 0, /*tp_free*/
143 0, /*tp_is_gc*/
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000144};
145/* --------------------------------------------------------------------- */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000146
147/* Function of two integers returning integer */
148
Skip Montanarod9e7d242002-08-14 01:44:33 +0000149PyDoc_STRVAR(xx_foo_doc,
150"foo(i,j)\n\
151\n\
152Return the sum of i and j.");
153
Guido van Rossum2b654441996-07-30 16:56:16 +0000154static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000155xx_foo(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 long i, j;
158 long res;
159 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
160 return NULL;
161 res = i+j; /* XXX Do something here */
162 return PyLong_FromLong(res);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000163}
164
165
Guido van Rossum2b654441996-07-30 16:56:16 +0000166/* Function of no arguments returning new Xxo object */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000167
Guido van Rossum2b654441996-07-30 16:56:16 +0000168static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000169xx_new(PyObject *self, PyObject *args)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 XxoObject *rv;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 if (!PyArg_ParseTuple(args, ":new"))
174 return NULL;
175 rv = newXxoObject(args);
176 if (rv == NULL)
177 return NULL;
178 return (PyObject *)rv;
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000179}
180
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000181/* Example with subtle bug from extensions manual ("Thin Ice"). */
182
183static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000184xx_bug(PyObject *self, PyObject *args)
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 PyObject *list, *item;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000188 if (!PyArg_ParseTuple(args, "O:bug", &list))
189 return NULL;
Tim Petersc9ca5c82002-05-23 15:49:38 +0000190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 item = PyList_GetItem(list, 0);
192 /* Py_INCREF(item); */
193 PyList_SetItem(list, 1, PyLong_FromLong(0L));
194 PyObject_Print(item, stdout, 0);
195 printf("\n");
196 /* Py_DECREF(item); */
Tim Petersc9ca5c82002-05-23 15:49:38 +0000197
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 Py_INCREF(Py_None);
199 return Py_None;
Guido van Rossumfbcfd521996-12-13 02:57:25 +0000200}
201
Guido van Rossumc525e431997-12-09 20:37:25 +0000202/* Test bad format character */
203
204static PyObject *
Peter Schneider-Kampc4bc0e02000-07-10 11:56:03 +0000205xx_roj(PyObject *self, PyObject *args)
Guido van Rossumc525e431997-12-09 20:37:25 +0000206{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 PyObject *a;
208 long b;
209 if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
210 return NULL;
211 Py_INCREF(Py_None);
212 return Py_None;
Guido van Rossumc525e431997-12-09 20:37:25 +0000213}
214
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000215
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000216/* ---------- */
217
218static PyTypeObject Str_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 /* The ob_type field must be initialized in the module init function
220 * to be portable to Windows without using C++. */
221 PyVarObject_HEAD_INIT(NULL, 0)
222 "xxmodule.Str", /*tp_name*/
223 0, /*tp_basicsize*/
224 0, /*tp_itemsize*/
225 /* methods */
226 0, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200227 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 0, /*tp_getattr*/
229 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200230 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 0, /*tp_repr*/
232 0, /*tp_as_number*/
233 0, /*tp_as_sequence*/
234 0, /*tp_as_mapping*/
235 0, /*tp_hash*/
236 0, /*tp_call*/
237 0, /*tp_str*/
238 0, /*tp_getattro*/
239 0, /*tp_setattro*/
240 0, /*tp_as_buffer*/
241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
242 0, /*tp_doc*/
243 0, /*tp_traverse*/
244 0, /*tp_clear*/
245 0, /*tp_richcompare*/
246 0, /*tp_weaklistoffset*/
247 0, /*tp_iter*/
248 0, /*tp_iternext*/
249 0, /*tp_methods*/
250 0, /*tp_members*/
251 0, /*tp_getset*/
252 0, /* see PyInit_xx */ /*tp_base*/
253 0, /*tp_dict*/
254 0, /*tp_descr_get*/
255 0, /*tp_descr_set*/
256 0, /*tp_dictoffset*/
257 0, /*tp_init*/
258 0, /*tp_alloc*/
259 0, /*tp_new*/
260 0, /*tp_free*/
261 0, /*tp_is_gc*/
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000262};
263
Guido van Rossum72976502003-02-13 18:44:57 +0000264/* ---------- */
265
266static PyObject *
267null_richcompare(PyObject *self, PyObject *other, int op)
268{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 Py_INCREF(Py_NotImplemented);
270 return Py_NotImplemented;
Guido van Rossum72976502003-02-13 18:44:57 +0000271}
272
273static PyTypeObject Null_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 /* The ob_type field must be initialized in the module init function
275 * to be portable to Windows without using C++. */
276 PyVarObject_HEAD_INIT(NULL, 0)
277 "xxmodule.Null", /*tp_name*/
278 0, /*tp_basicsize*/
279 0, /*tp_itemsize*/
280 /* methods */
281 0, /*tp_dealloc*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200282 0, /*tp_vectorcall_offset*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 0, /*tp_getattr*/
284 0, /*tp_setattr*/
Jeroen Demeyer530f5062019-05-31 04:13:39 +0200285 0, /*tp_as_async*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 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 0, /* see PyInit_xx */ /*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*/
Stefan Krahca725892017-09-22 17:44:58 +0200314 PyType_GenericNew, /*tp_new*/
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000315 0, /*tp_free*/
316 0, /*tp_is_gc*/
Guido van Rossum72976502003-02-13 18:44:57 +0000317};
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[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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")},
334 {NULL, NULL} /* sentinel */
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000335};
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
Martin v. Löwis1a214512008-06-11 05:26:20 +0000340
Nick Coghland5cacbb2015-05-23 22:24:10 +1000341static int
342xx_exec(PyObject *m)
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000343{
Stefan Krahca725892017-09-22 17:44:58 +0200344 /* Slot initialization is subject to the rules of initializing globals.
345 C99 requires the initializers to be "address constants". Function
346 designators like 'PyType_GenericNew', with implicit conversion to
347 a pointer, are valid C99 address constants.
348
349 However, the unary '&' operator applied to a non-static variable
350 like 'PyBaseObject_Type' is not required to produce an address
351 constant. Compilers may support this (gcc does), MSVC does not.
352
353 Both compilers are strictly standard conforming in this particular
354 behavior.
355 */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 Null_Type.tp_base = &PyBaseObject_Type;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 Str_Type.tp_base = &PyUnicode_Type;
Christian Heimes80101a82007-11-18 21:30:36 +0000358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 /* Finalize the type object including setting type of the new type
360 * object; doing it here is required for portability, too. */
361 if (PyType_Ready(&Xxo_Type) < 0)
362 goto fail;
Fred Drake67248351999-02-16 22:15:42 +0000363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 /* Add some symbolic constants to the module */
365 if (ErrorObject == NULL) {
366 ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
367 if (ErrorObject == NULL)
368 goto fail;
369 }
370 Py_INCREF(ErrorObject);
371 PyModule_AddObject(m, "error", ErrorObject);
Guido van Rossum9eb67ea2003-02-11 21:19:11 +0000372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000373 /* Add Str */
374 if (PyType_Ready(&Str_Type) < 0)
375 goto fail;
376 PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
Guido van Rossum72976502003-02-13 18:44:57 +0000377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000378 /* Add Null */
379 if (PyType_Ready(&Null_Type) < 0)
380 goto fail;
381 PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000382 return 0;
Martin v. Löwis1a214512008-06-11 05:26:20 +0000383 fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 Py_XDECREF(m);
Nick Coghland5cacbb2015-05-23 22:24:10 +1000385 return -1;
386}
387
388static struct PyModuleDef_Slot xx_slots[] = {
389 {Py_mod_exec, xx_exec},
390 {0, NULL},
391};
392
393static struct PyModuleDef xxmodule = {
394 PyModuleDef_HEAD_INIT,
395 "xx",
396 module_doc,
397 0,
398 xx_methods,
399 xx_slots,
400 NULL,
401 NULL,
402 NULL
403};
404
405/* Export function for the module (*must* be called PyInit_xx) */
406
407PyMODINIT_FUNC
408PyInit_xx(void)
409{
410 return PyModuleDef_Init(&xxmodule);
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000411}