On Tue, 2009-11-17 at 19:45 -0500, Terry Reedy wrote: > A.M. Kuchling wrote: > > On Mon, Nov 16, 2009 at 03:27:53PM -0500, David Malcolm wrote: > >> Has anyone else looked at using Coccinelle/spatch[1] on CPython source > >> code? > > > > For an excellent explanation of Coccinelle, see > > <http://lwn.net/Articles/315686/>. > > For those who have not looked, Coccinelle means ladybug (a bug-eating > bug ;-) in French. Its principle use to to take C code and a SmPl file > of high-level patch descriptions (fixers, in 2to3 talk) and produce a > standard diff file. I wonder if this could be used to help people > migrate C extensions to 3.1, by developing a SmPl file with the needed > changes dictated by API changes. This is similar to its motivating > application to Linux. From > > http://coccinelle.lip6.fr/ > > "Coccinelle is a program matching and transformation engine which > provides the language SmPL (Semantic Patch Language) for specifying > desired matches and transformations in C code. Coccinelle was initially > targeted towards performing collateral evolutions in Linux. Such > evolutions comprise the changes that are needed in client code in > response to evolutions in library APIs, and may include modifications > such as renaming a function, adding a function argument whose value is > somehow context-dependent, and reorganizing a data structure. " > > As I understand it, the problem with C extensions and 3.1 is the current > lack of a "collateral evolution" tool like 2to3 for Python code. Indeed; I think it may be possible to use Coccinelle for this.
Here's a .cocci semantic patch to convert non-PyObject* dereferences of an "ob_type" field to use Py_TYPE macro instead. @@ PyObject *py_obj_ptr; type T; T non_py_obj_ptr; @@ ( py_obj_ptr->ob_type | - non_py_obj_ptr->ob_type + Py_TYPE(non_py_obj_ptr) ) I was able to use this to generate the attached patch for the DBus python bindings. Note that it leaves dereferences of a PyObject* untouched, and works inside sub-expressions. (There's some noise at the typedef of Server; I don't know why). Hope this is helpful Dave
diff --git a/_dbus_bindings/conn.c b/_dbus_bindings/conn.c index c30f167..157218d 100644 --- a/_dbus_bindings/conn.c +++ b/_dbus_bindings/conn.c @@ -389,7 +389,7 @@ static void Connection_tp_dealloc(Connection *self) DBG("Connection at %p: freeing self", self); PyErr_Restore(et, ev, etb); - (self->ob_type->tp_free)((PyObject *)self); + (Py_TYPE(self)->tp_free)((PyObject *)self); } /* Connection type object =========================================== */ diff --git a/_dbus_bindings/libdbusconn.c b/_dbus_bindings/libdbusconn.c index 9bd8def..c33bb7c 100644 --- a/_dbus_bindings/libdbusconn.c +++ b/_dbus_bindings/libdbusconn.c @@ -73,7 +73,7 @@ DBusPyLibDBusConnection_tp_dealloc(Connection *self) } PyErr_Restore(et, ev, etb); - (self->ob_type->tp_free)((PyObject *) self); + (Py_TYPE(self)->tp_free)((PyObject *) self); } PyTypeObject DBusPyLibDBusConnection_Type = { diff --git a/_dbus_bindings/message.c b/_dbus_bindings/message.c index a2c04c3..ee0cbd6 100644 --- a/_dbus_bindings/message.c +++ b/_dbus_bindings/message.c @@ -53,7 +53,7 @@ static void Message_tp_dealloc(Message *self) if (self->msg) { dbus_message_unref(self->msg); } - self->ob_type->tp_free((PyObject *)self); + Py_TYPE(self)->tp_free((PyObject *)self); } static PyObject * diff --git a/_dbus_bindings/server.c b/_dbus_bindings/server.c index 7fc4f70..ba39f74 100644 --- a/_dbus_bindings/server.c +++ b/_dbus_bindings/server.c @@ -40,7 +40,7 @@ typedef struct { PyObject *weaklist; PyObject *mainloop; -} Server; +}Server; PyDoc_STRVAR(Server_tp_doc, "A D-Bus server.\n" @@ -429,7 +429,7 @@ static void Server_tp_dealloc(Server *self) DBG("Server at %p: freeing self", self); PyErr_Restore(et, ev, etb); - (self->ob_type->tp_free)((PyObject *)self); + (Py_TYPE(self)->tp_free)((PyObject *)self); } PyDoc_STRVAR(Server_disconnect__doc__,
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com