On Sat, 2010-08-14 at 19:42 +0100, Richard W.M. Jones wrote:
On Fri, Aug 13, 2010 at 02:20:51PM -0400, David Malcolm wrote:
> (Sorry about the length of this email)
>
> Python 2.7 deprecated the PyCObject API in favor of a new "capsule" API.
>
http://docs.python.org/dev/whatsnew/2.7.html#capsules
> (b) try to fix the ones that are self-contained; send fixes upstream
I couldn't really tell from the link above how one can migrate code.
Any suggestion how to change the code below? Variants of this are
used in both libvirt and libguestfs.
typedef struct {
PyObject_HEAD
guestfs_h *g;
} Pyguestfs_Object;
static guestfs_h *
get_handle (PyObject *obj)
{
assert (obj);
assert (obj != Py_None);
return ((Pyguestfs_Object *) obj)->g;
}
FWIW, this code looks a little dubious to me: obj is actually a
PyCObject, which is:
typedef struct {
PyObject_HEAD
void *cobject;
void *desc;
void (*destructor)(void *);
} PyCObject;
It works because Pyguestfs_Object->g has the same offset from the top of
the struct as the PyCObject->cobject field, but if PyCObject had changed
layout it would crash.
Do you use Pyguestfs_Object elsewhere in the code? Looking at
libguestfs-1.5.2/src/generator.ml it doesn't seem to be, so it looks
like get_handle should have read:
static guestfs_h *
get_handle (PyObject *obj)
{
assert (obj);
assert (obj != Py_None);
return (guestfs_h*)PyCObject_AsVoidPtr(obj);
}
static PyObject *
put_handle (guestfs_h *g)
{
assert (g);
return
PyCObject_FromVoidPtrAndDesc ((void *) g, (char *) "guestfs_h", NULL);
}
Porting to the capsule API, I believe the code needs to look something
like this (caution: untested):
static guestfs_h *
get_handle (PyObject *obj)
{
assert (obj);
assert (obj != Py_None);
return (guestfs_h*)PyCapsule_GetPointer(obj, "guestfs_h");
}
static PyObject *
put_handle (guestfs_h *g)
{
assert (g);
return PyCapsule_New((void *) g, "guestfs_h", NULL);
}