[Python-Dev] Let's update CObject API so it is safe and regular!
larry at hastings.org
Tue Mar 31 21:14:57 CEST 2009
The CObject API has two flaws.
First, there is no usable type safety mechanism. You can store a void
*object, and a void *description. There is no established schema for
the description; it could be an integer cast to a pointer, or it could
point to memory of any configuration, or it could be NULL. Thus users
of the CObject API generally ignore it--thus working without any type
safety whatsoever. A programmer could crash the interpreter from pure
Python by mixing and matching CObjects from different modules (e.g. give
"curses" a CObject from "_ctypes").
Second, the destructor callback is defined as taking *either* one *or*
two parameters, depending on whether the "descr" pointer is non-NULL.
One can debate the finer points of what is and isn't defined behavior in
C, but at its heart this is a sloppy API.
MvL and I discussed this last night and decided to float a revision of
the API. I wrote the patch, though, so don't blame Martin if you don't
like my specific approach.
The color of this particular bike shed is:
* The PyCObject is now a private data structure; you must use accessors.
I added accessors for all the members.
* The constructors and the main accessor (PyCObject_AsVoidPtr) now all
*require* a "const char *type" parameter, which must be a non-NULL C
string of non-zero length. If you call that accessor and the "type"
is invalid *or doesn't match*, it fails.
* The destructor now takes the PyObject *, not the PyCObject *. You
must use accessors to get your hands on the data inside to free it.
Yes, you can easily skip around the "matching type" restriction by
calling PyCObject_AsVoidPtr(cobj, PyCObject_GetType(cobj)). The point
of my API changes is to *encourage* correct use.
I've posted a patch implementing this change in the 3.1 trunk to the
I look forward to your comments!
More information about the Python-Dev