123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /* Use this file as a template to start implementing a module that
- also declares object types. All occurrences of 'Xxo' should be changed
- to something reasonable for your objects. After that, all other
- occurrences of 'xx' should be changed to something reasonable for your
- module. If your module is named foo your sourcefile should be named
- foomodule.c.
- You will probably want to delete all references to 'x_attr' and add
- your own types of attributes instead. Maybe you want to name your
- local variables other than 'self'. If your object type is needed in
- other files, you'll have to create a file "foobarobject.h"; see
- floatobject.h for an example. */
- /* Xxo objects */
- #include "Python.h"
- static PyObject *ErrorObject;
- typedef struct {
- PyObject_HEAD
- PyObject *x_attr; /* Attributes dictionary */
- } XxoObject;
- static PyTypeObject Xxo_Type;
- #define XxoObject_Check(v) Py_IS_TYPE(v, &Xxo_Type)
- static XxoObject *
- newXxoObject(PyObject *arg)
- {
- XxoObject *self;
- self = PyObject_New(XxoObject, &Xxo_Type);
- if (self == NULL)
- return NULL;
- self->x_attr = NULL;
- return self;
- }
- /* Xxo methods */
- static void
- Xxo_dealloc(XxoObject *self)
- {
- Py_XDECREF(self->x_attr);
- PyObject_Del(self);
- }
- static PyObject *
- Xxo_demo(XxoObject *self, PyObject *args)
- {
- if (!PyArg_ParseTuple(args, ":demo"))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
- }
- static PyMethodDef Xxo_methods[] = {
- {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
- PyDoc_STR("demo() -> None")},
- {NULL, NULL} /* sentinel */
- };
- static PyObject *
- Xxo_getattro(XxoObject *self, PyObject *name)
- {
- if (self->x_attr != NULL) {
- PyObject *v = PyDict_GetItemWithError(self->x_attr, name);
- if (v != NULL) {
- Py_INCREF(v);
- return v;
- }
- else if (PyErr_Occurred()) {
- return NULL;
- }
- }
- return PyObject_GenericGetAttr((PyObject *)self, name);
- }
- static int
- Xxo_setattr(XxoObject *self, const char *name, PyObject *v)
- {
- if (self->x_attr == NULL) {
- self->x_attr = PyDict_New();
- if (self->x_attr == NULL)
- return -1;
- }
- if (v == NULL) {
- int rv = PyDict_DelItemString(self->x_attr, name);
- if (rv < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
- PyErr_SetString(PyExc_AttributeError,
- "delete non-existing Xxo attribute");
- return rv;
- }
- else
- return PyDict_SetItemString(self->x_attr, name, v);
- }
- static PyTypeObject Xxo_Type = {
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(NULL, 0)
- "xxmodule.Xxo", /*tp_name*/
- sizeof(XxoObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)Xxo_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- (getattrfunc)0, /*tp_getattr*/
- (setattrfunc)Xxo_setattr, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- (getattrofunc)Xxo_getattro, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- Xxo_methods, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- 0, /*tp_init*/
- 0, /*tp_alloc*/
- 0, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
- };
- /* --------------------------------------------------------------------- */
- /* Function of two integers returning integer */
- PyDoc_STRVAR(xx_foo_doc,
- "foo(i,j)\n\
- \n\
- Return the sum of i and j.");
- static PyObject *
- xx_foo(PyObject *self, PyObject *args)
- {
- long i, j;
- long res;
- if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
- return NULL;
- res = i+j; /* XXX Do something here */
- return PyLong_FromLong(res);
- }
- /* Function of no arguments returning new Xxo object */
- static PyObject *
- xx_new(PyObject *self, PyObject *args)
- {
- XxoObject *rv;
- if (!PyArg_ParseTuple(args, ":new"))
- return NULL;
- rv = newXxoObject(args);
- if (rv == NULL)
- return NULL;
- return (PyObject *)rv;
- }
- /* Example with subtle bug from extensions manual ("Thin Ice"). */
- static PyObject *
- xx_bug(PyObject *self, PyObject *args)
- {
- PyObject *list, *item;
- if (!PyArg_ParseTuple(args, "O:bug", &list))
- return NULL;
- item = PyList_GetItem(list, 0);
- /* Py_INCREF(item); */
- PyList_SetItem(list, 1, PyLong_FromLong(0L));
- PyObject_Print(item, stdout, 0);
- printf("\n");
- /* Py_DECREF(item); */
- Py_INCREF(Py_None);
- return Py_None;
- }
- /* Test bad format character */
- static PyObject *
- xx_roj(PyObject *self, PyObject *args)
- {
- PyObject *a;
- long b;
- if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
- }
- /* ---------- */
- static PyTypeObject Str_Type = {
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(NULL, 0)
- "xxmodule.Str", /*tp_name*/
- 0, /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- 0, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- 0, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /* see PyInit_xx */ /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- 0, /*tp_init*/
- 0, /*tp_alloc*/
- 0, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
- };
- /* ---------- */
- static PyObject *
- null_richcompare(PyObject *self, PyObject *other, int op)
- {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- static PyTypeObject Null_Type = {
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(NULL, 0)
- "xxmodule.Null", /*tp_name*/
- 0, /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- 0, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- null_richcompare, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- 0, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /* see PyInit_xx */ /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- 0, /*tp_init*/
- 0, /*tp_alloc*/
- PyType_GenericNew, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
- };
- /* ---------- */
- /* List of functions defined in the module */
- static PyMethodDef xx_methods[] = {
- {"roj", xx_roj, METH_VARARGS,
- PyDoc_STR("roj(a,b) -> None")},
- {"foo", xx_foo, METH_VARARGS,
- xx_foo_doc},
- {"new", xx_new, METH_VARARGS,
- PyDoc_STR("new() -> new Xx object")},
- {"bug", xx_bug, METH_VARARGS,
- PyDoc_STR("bug(o) -> None")},
- {NULL, NULL} /* sentinel */
- };
- PyDoc_STRVAR(module_doc,
- "This is a template module just for instruction.");
- static int
- xx_exec(PyObject *m)
- {
- /* Slot initialization is subject to the rules of initializing globals.
- C99 requires the initializers to be "address constants". Function
- designators like 'PyType_GenericNew', with implicit conversion to
- a pointer, are valid C99 address constants.
- However, the unary '&' operator applied to a non-static variable
- like 'PyBaseObject_Type' is not required to produce an address
- constant. Compilers may support this (gcc does), MSVC does not.
- Both compilers are strictly standard conforming in this particular
- behavior.
- */
- Null_Type.tp_base = &PyBaseObject_Type;
- Str_Type.tp_base = &PyUnicode_Type;
- /* Finalize the type object including setting type of the new type
- * object; doing it here is required for portability, too. */
- if (PyType_Ready(&Xxo_Type) < 0)
- goto fail;
- /* Add some symbolic constants to the module */
- if (ErrorObject == NULL) {
- ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
- if (ErrorObject == NULL)
- goto fail;
- }
- Py_INCREF(ErrorObject);
- PyModule_AddObject(m, "error", ErrorObject);
- /* Add Str */
- if (PyType_Ready(&Str_Type) < 0)
- goto fail;
- PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
- /* Add Null */
- if (PyType_Ready(&Null_Type) < 0)
- goto fail;
- PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
- return 0;
- fail:
- Py_XDECREF(m);
- return -1;
- }
- static struct PyModuleDef_Slot xx_slots[] = {
- {Py_mod_exec, xx_exec},
- {0, NULL},
- };
- static struct PyModuleDef xxmodule = {
- PyModuleDef_HEAD_INIT,
- "xx",
- module_doc,
- 0,
- xx_methods,
- xx_slots,
- NULL,
- NULL,
- NULL
- };
- /* Export function for the module (*must* be called PyInit_xx) */
- PyMODINIT_FUNC
- PyInit_xx(void)
- {
- return PyModuleDef_Init(&xxmodule);
- }
|