Registering C methods when writing a C extension type?

Donn Cave donn at oz.net
Thu Jan 4 00:57:40 EST 2001


Quoth Tom Epperly <tepperly at llnl.gov>:
| I planning to write a C extension type (not module) to provide a Python
| binding for an object or interface defined in an IDL (interface definition
| language) for high performance scientific computing. In the example from
| Mark Lutz's Programming Python (the only documentation I've found that
| directly addresses writing extension types), it does something like the
| following to make the object methods visible (in myobject.c):
|
| static struct PyMethodDef myobject_methods[] = {
|   {"method_one", (PyCFunction)method_one, 1},
|   {"method_two", (PyCFunction)method_two, 1},
|   {"method_three", (PyCFunction)method_three, 1},
|   {NULL, NULL}
| };
|
| static PyObject *
| myobject_getattr(myobject *self, char *name) {
|  /* other stuff deleted */
|  return Py_FindMethod(object_methods, self, name);
| }
|
| /* tp_getattr points to myobject_getattr */
|
| I am wondering what the relative merits/penalties of doing something like
| the following in the constructor for the hypothetical myobject instead of
| the above. I would like feedback about issues of style (am I violating the
| designers intent or using functions intended for internal use only),
| forward/backward portability, and efficiency.
|
| static myobject *
| new_myobject()
| {
|   myobject *self;
|   const int len = sizeof(object_methods)/sizeof(PyMethodDef);
|   int i;
|   self = PyObject_NEW(myobject, &myobjecttype);
|   if (self == NULL) return NULL;
|   for(i = 0 ; i < len ; i++){
|     PyObject *func = PyCFunction_New(object_methods + i, self);
|     if (func != NULL) {
|       PyObject_SetAttrString(self, object_methods[i].ml_name, func);
|       Py_DECREF(func); /* remove extra reference */
|     }
|   }
|   return self;
| }
|
| In this case, the getattr method does not call Py_FindMethod.

I guess you must already know all the work you must do to
implement it.  I mean, if I have this right, myobjecttype
must implement a meaningful setattr function, so you can
indirectly call it via PyObject_SetAttrString();  plus,
the complementary getattr, of course.  I guess you must
have some fairly compelling reason to want to do all that,
instead of simply the normal lookup in the object_method
table you already have anyway.

So my reaction is, that implies to me that the implementation
is pretty complex, and relative to that, questions like whether
PyMethodDef's members are intentionally exposed to application
programmers are no big worry.  It obviously is not the way we
normally do it, but you knew that.  Its efficiency is going
to depend, again, on the implementation - where you wrote
"/* other stuff deleted */".

	Donn Cave, donn at oz.net



More information about the Python-list mailing list