Hello all. Is there a convenient scheme within a C extension to add methods to a type in such a way as to allow me to transparently add a "proxy" around them? For example:
typedef PyObject* (*PyMethodCall)(PyObject*, PyObject*); PyObject* middleMan(PyObject* self, PyObject* args) { printf("Before call to wrapped funct\n"); PyMethodCall actualFunc = getRealFunction(...); PyObject* retval = actualFunc(self, args); printf("After call to wrapped func\n"); return retval; } void addMethod(PyTypeObject* t, PyMethodCall* m, char* name, char* doc) { // code to forward calls to "middleMan" while putting the // pointer to "m" somewhere convenient ... } My current solution is cumbersome and involves adding a special field to the PyObject associated with my type, a custom tp_getattro function and the "middleMan" function: struct MyPyObj { PyObject_HEAD PyMethodCall realfunc; }; // when adding the method def for "m" instead of pointing it to // the given function, I point it to the middle man and save // the "m" function somewhere I can find it later. void addMethod(PyTypeObject* t, PyMethodCall m, char* name, char* doc) { PyMethodDef* def = allocPyMethodDef(t, name); def->ml_name = name; def->ml_doc = doc; def->ml_meth = middleMan; def->ml_flags = METH_VARARGS; saveTargetFunction(name, m); // note I add these here so that documentation is // available within the interpreter PyObject* methobj = PyDescr_NewMethod(t, def); PyDict_SetItemString(t->tp_dict, def->ml_name, methobj); Py_DECREF(methobj); } // when the interpreter does a lookup on an instance of my // type I set the "realfunc" member of my PyObject and return // a bound method (which will call into middleMan). PyObject* customGetaAttro(PyObject* self, PyObject* name) { MyPyObj* rself = (MyPyObj*)self; rself->realfunc = findSavedTargetFunc(name); PyMethodDef* mdef = getMethodDef(self->ob_type, name); return PyCFunction_New(def, self); } // finally, when the middle man is called it extracts the "real" // function from self and calls that. PyObject* middleMan(PyObject* self, PyObject* args) { MyPyObj* rself = (MyPyObj*)(self); printf("pre call\n"); PyObject* rv = rself->realfunc(rself->obj, args); printf("post call\n"); rself->realfunc = 0; return rv; } The problem here is that this doesn't work for static functions which lack a self argument, or for module level functions. Is there a better way? Thanks, Iker Arizmendi -- http://mail.python.org/mailman/listinfo/python-list