blob: 661b6e294af363d1b2c7ac8e49c9ba141f7c53e0 [file] [log] [blame]
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001
2/* Use this file as a template to start implementing a module that
3 also declares object types. All occurrences of 'Xxo' should be changed
4 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.
8
9 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 floatobject.h for an example. */
14
15/* Xxo objects */
16
17#include "Python.h"
18
19static PyObject *ErrorObject;
20
21typedef struct {
22 PyObject_HEAD
23 PyObject *x_attr; /* Attributes dictionary */
24} XxoObject;
25
26static PyObject *Xxo_Type;
27
28#define XxoObject_Check(v) (Py_TYPE(v) == Xxo_Type)
29
30static XxoObject *
31newXxoObject(PyObject *arg)
32{
33 XxoObject *self;
34 self = PyObject_New(XxoObject, (PyTypeObject*)Xxo_Type);
35 if (self == NULL)
36 return NULL;
37 self->x_attr = NULL;
38 return self;
39}
40
41/* Xxo methods */
42
43static void
44Xxo_dealloc(XxoObject *self)
45{
46 Py_XDECREF(self->x_attr);
47 PyObject_Del(self);
48}
49
50static PyObject *
51Xxo_demo(XxoObject *self, PyObject *args)
52{
Martin v. Löwis738236d2011-02-05 20:35:29 +000053 PyObject *o = NULL;
54 if (!PyArg_ParseTuple(args, "|O:demo", &o))
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000055 return NULL;
Martin v. Löwis738236d2011-02-05 20:35:29 +000056 /* Test availability of fast type checks */
57 if (o != NULL && PyUnicode_Check(o)) {
58 Py_INCREF(o);
59 return o;
60 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +000061 Py_INCREF(Py_None);
62 return Py_None;
63}
64
65static PyMethodDef Xxo_methods[] = {
66 {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
67 PyDoc_STR("demo() -> None")},
68 {NULL, NULL} /* sentinel */
69};
70
71static PyObject *
72Xxo_getattro(XxoObject *self, PyObject *name)
73{
74 if (self->x_attr != NULL) {
75 PyObject *v = PyDict_GetItem(self->x_attr, name);
76 if (v != NULL) {
77 Py_INCREF(v);
78 return v;
79 }
80 }
81 return PyObject_GenericGetAttr((PyObject *)self, name);
82}
83
84static int
85Xxo_setattr(XxoObject *self, char *name, PyObject *v)
86{
87 if (self->x_attr == NULL) {
88 self->x_attr = PyDict_New();
89 if (self->x_attr == NULL)
90 return -1;
91 }
92 if (v == NULL) {
93 int rv = PyDict_DelItemString(self->x_attr, name);
94 if (rv < 0)
95 PyErr_SetString(PyExc_AttributeError,
96 "delete non-existing Xxo attribute");
97 return rv;
98 }
99 else
100 return PyDict_SetItemString(self->x_attr, name, v);
101}
102
103static PyType_Slot Xxo_Type_slots[] = {
Martin v. Löwis69168062011-02-11 20:47:49 +0000104 {Py_tp_doc, "The Xxo type"},
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000105 {Py_tp_dealloc, Xxo_dealloc},
106 {Py_tp_getattro, Xxo_getattro},
107 {Py_tp_setattr, Xxo_setattr},
108 {Py_tp_methods, Xxo_methods},
109 {0, 0},
110};
111
112static PyType_Spec Xxo_Type_spec = {
Martin v. Löwis69168062011-02-11 20:47:49 +0000113 "xxlimited.Xxo",
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000114 sizeof(XxoObject),
115 0,
116 Py_TPFLAGS_DEFAULT,
117 Xxo_Type_slots
118};
119
120/* --------------------------------------------------------------------- */
121
122/* Function of two integers returning integer */
123
124PyDoc_STRVAR(xx_foo_doc,
125"foo(i,j)\n\
126\n\
127Return the sum of i and j.");
128
129static PyObject *
130xx_foo(PyObject *self, PyObject *args)
131{
132 long i, j;
133 long res;
134 if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
135 return NULL;
136 res = i+j; /* XXX Do something here */
137 return PyLong_FromLong(res);
138}
139
140
141/* Function of no arguments returning new Xxo object */
142
143static PyObject *
144xx_new(PyObject *self, PyObject *args)
145{
146 XxoObject *rv;
147
148 if (!PyArg_ParseTuple(args, ":new"))
149 return NULL;
150 rv = newXxoObject(args);
151 if (rv == NULL)
152 return NULL;
153 return (PyObject *)rv;
154}
155
156/* Test bad format character */
157
158static PyObject *
159xx_roj(PyObject *self, PyObject *args)
160{
161 PyObject *a;
162 long b;
163 if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
164 return NULL;
165 Py_INCREF(Py_None);
166 return Py_None;
167}
168
169
170/* ---------- */
171
172static PyType_Slot Str_Type_slots[] = {
173 {Py_tp_base, NULL}, /* filled out in module init function */
174 {0, 0},
175};
176
177static PyType_Spec Str_Type_spec = {
178 "xxlimited.Str",
179 0,
180 0,
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000181 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
182 Str_Type_slots
183};
184
185/* ---------- */
186
187static PyObject *
188null_richcompare(PyObject *self, PyObject *other, int op)
189{
Brian Curtindfc80e32011-08-10 20:28:54 -0500190 Py_RETURN_NOTIMPLEMENTED;
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000191}
192
193static PyType_Slot Null_Type_slots[] = {
194 {Py_tp_base, NULL}, /* filled out in module init */
195 {Py_tp_new, NULL},
196 {Py_tp_richcompare, null_richcompare},
197 {0, 0}
198};
199
200static PyType_Spec Null_Type_spec = {
201 "xxlimited.Null",
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000202 0, /* basicsize */
203 0, /* itemsize */
204 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
205 Null_Type_slots
206};
207
208/* ---------- */
209
210/* List of functions defined in the module */
211
212static PyMethodDef xx_methods[] = {
213 {"roj", xx_roj, METH_VARARGS,
214 PyDoc_STR("roj(a,b) -> None")},
215 {"foo", xx_foo, METH_VARARGS,
216 xx_foo_doc},
217 {"new", xx_new, METH_VARARGS,
218 PyDoc_STR("new() -> new Xx object")},
219 {NULL, NULL} /* sentinel */
220};
221
222PyDoc_STRVAR(module_doc,
223"This is a template module just for instruction.");
224
225/* Initialization function for the module (*must* be called PyInit_xx) */
226
227
228static struct PyModuleDef xxmodule = {
229 PyModuleDef_HEAD_INIT,
Martin v. Löwis69168062011-02-11 20:47:49 +0000230 "xxlimited",
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000231 module_doc,
232 -1,
233 xx_methods,
234 NULL,
235 NULL,
236 NULL,
237 NULL
238};
239
240PyMODINIT_FUNC
241PyInit_xxlimited(void)
242{
243 PyObject *m = NULL;
244 PyObject *o;
245
246 /* Due to cross platform compiler issues the slots must be filled
247 * here. It's required for portability to Windows without requiring
248 * C++. */
249 Null_Type_slots[0].pfunc = &PyBaseObject_Type;
250 Null_Type_slots[1].pfunc = PyType_GenericNew;
251 Str_Type_slots[0].pfunc = &PyUnicode_Type;
252
253 Xxo_Type = PyType_FromSpec(&Xxo_Type_spec);
254 if (Xxo_Type == NULL)
255 goto fail;
256
257 /* Create the module and add the functions */
258 m = PyModule_Create(&xxmodule);
259 if (m == NULL)
260 goto fail;
261
262 /* Add some symbolic constants to the module */
263 if (ErrorObject == NULL) {
Martin v. Löwis69168062011-02-11 20:47:49 +0000264 ErrorObject = PyErr_NewException("xxlimited.error", NULL, NULL);
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000265 if (ErrorObject == NULL)
266 goto fail;
267 }
268 Py_INCREF(ErrorObject);
269 PyModule_AddObject(m, "error", ErrorObject);
270
271 /* Add Str */
272 o = PyType_FromSpec(&Str_Type_spec);
273 if (o == NULL)
274 goto fail;
275 PyModule_AddObject(m, "Str", o);
276
277 /* Add Null */
278 o = PyType_FromSpec(&Null_Type_spec);
279 if (o == NULL)
280 goto fail;
281 PyModule_AddObject(m, "Null", o);
282 return m;
283 fail:
284 Py_XDECREF(m);
285 return NULL;
286}