[Python-Dev] CObject take 2: Introducing the "Capsule"

Larry Hastings 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:
    http://bugs.python.org/issue5630
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?


/larry/


More information about the Python-Dev mailing list