# copy these lines to a file named: setup.py # To build and install the elemlist module you need the following # setup.py file that uses the distutils: from distutils.core import setup, Extension setup (name = "elemlist", version = "1.0", maintainer = "Alex Martelli", maintainer_email = "aleax@aleax.it", description = "Sample Python module", ext_modules = [Extension('elemlist',sources=['elemlist.c'])] ) # end of file: setup.py /* copy these lines to a file named: elemlist.c */ /* and here comes elemlist.c itself with really minimal comments: */ #include "Python.h" /* type-definition & utility-macros */ typedef struct { PyObject_HEAD PyObject *car, *cdr; } cons_cell; staticforward PyTypeObject cons_type; /* a typetesting macro (we don't use it here) */ #define is_cons(v) ((v)->ob_type == &cons_type) /* macros to access car & cdr, both as lvalues & rvalues */ #define carof(v) (((cons_cell*)(v))->car) #define cdrof(v) (((cons_cell*)(v))->cdr) /* ctor (factory-function) and dtor */ static cons_cell* cons_new(PyObject *car, PyObject *cdr) { cons_cell *cons = PyObject_NEW(cons_cell, &cons_type); if(cons) { cons->car = car; Py_INCREF(car); /* INCREF when holding a PyObject* */ cons->cdr = cdr; Py_INCREF(cdr); /* ditto */ } return cons; } static void cons_dealloc(cons_cell* cons) { /* DECREF when releasing previously-held PyObject*'s */ Py_DECREF(carof(cons)); Py_DECREF(cdrof(cons)); PyObject_DEL(cons); } /* Python type-object */ statichere PyTypeObject cons_type = { PyObject_HEAD_INIT(0) /* initialize to 0 to ensure Win32 portability */ 0, /*ob_size*/ "cons", /*tp_name*/ sizeof(cons_cell), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)cons_dealloc, /*tp_dealloc*/ /* implied by ISO C: all zeros thereafter */ }; /* module-functions */ static PyObject* cons(PyObject *self, PyObject *args) /* the exposed factory-function */ { PyObject *car, *cdr; if(!PyArg_ParseTuple(args, "OO", &car, &cdr)) return 0; return (PyObject*)cons_new(car, cdr); } static PyObject* car(PyObject *self, PyObject *args) /* car-accessor */ { PyObject *cons; if(!PyArg_ParseTuple(args, "O!", &cons_type, &cons)) /* type-checked */ return 0; return Py_BuildValue("O", carof(cons)); } static PyObject* cdr(PyObject *self, PyObject *args) /* cdr-accessor */ { PyObject *cons; if(!PyArg_ParseTuple(args, "O!", &cons_type, &cons)) /* type-checked */ return 0; return Py_BuildValue("O", cdrof(cons)); } static PyMethodDef elemlist_methods[] = { {"cons", cons, METH_VARARGS}, {"car", car, METH_VARARGS}, {"cdr", cdr, METH_VARARGS}, {0, 0} }; /* module entry-point (module-initialization) function */ void initelemlist(void) { /* Create the module and add the functions */ PyObject *m = Py_InitModule("elemlist", elemlist_methods); /* Finish initializing the type-objects */ cons_type.ob_type = &PyType_Type; } /* end of file: elemlist.c */