[Python-Dev] CObject take 2: Introducing the "Capsule"
larry at hastings.org
Mon Apr 6 10:00:57 CEST 2009
(See my posting "Let's update CObject API so it is safe and regular!"
from 2009/03/31 for "take 1").
I discussed this off-list with GvR. He was primarily concerned with
fixing the passing-around-a-vtable C API usage of CObject, but he wanted
to preserve as much backwards compatibility as possible. In the end, he
suggested I create a new API and leave CObject unchanged. I've done
that, incorporating many of GvR's suggestions, though the blame for the
proposed new API is ultimately mine.
The new object is called a "Capsule". (I *had* wanted to call it
"Wrapper", but there's already a PyWrapper_New in descrobject.h.)
Highlights of the new API:
* PyCapsule_New() replaces PyCObject_FromVoidPtr.
* It takes a void * pointer, a const char *name, and a destructor.
* The pointer must not be NULL.
* The name may be NULL; if it is not NULL, it must be a valid C string
which outlives the capsule.
* The destructor takes a PyObject *, not a void *.
* PyCapsule_GetPointer() replaces PyCObject_AsVoidPtr.
* It takes a PyObject * and a const char *name.
* The name must compare to the name inside the object; either they're
both NULL or they strcmp to be the same.
* PyCapsule_Import() replaces PyCObject_Import.
* It takes three arguments: const char *module_name, const char
*attribute_name, int no_block.
* It ensures that the "name" of the Capsule is "modulename.attributename".
* If no_block is true, it uses PyModule_ImportModuleNoBlock. If this
fails it sets no exception.
* The PyCapsule structure is private. There are accessors for all
fields: pointer, name, destructor, and "context".
* The "context" is a second "void *" you can set / get.
You can read the full API and its implementation in the patch I just
posted to the tracker:
The patch was written against svn r71304. The patch isn't ready to be
applied--there is no documentation for the new API beyond the header file.
GvR and I disagree on one point: he thinks that we should leave CObject
in forever, undeprecated. I think we should deprecate it now and remove
it... whenever we'd do that. The new API does everything the old one
does, and more, and it's cleaner and safer. Let me start an informal
poll: assuming we accept the new API, should we deprecate CObject?
More information about the Python-Dev