[Python-Dev] Feature request: better support for "wrapper" objects

Thomas Heller thomas.heller@ion-tof.com
Thu, 10 Jan 2002 10:10:58 +0100


> > > If we had something like ("O@", typeobject) calldll could 
> > > be extended so you could do something like
> > > psapilib = calldll.getlibrary(....)
> > > ps_GetDrawableSurface = calldll.newcall(psapilib.ps_GetDrawableSurface,
> > > Carbon.Qd.GrafPortType)
> > > 
> > > (newcall() arguments are funcpointer, return value type, arg1 type, ...)
> > > 
> > > You cannot do this currently
> > 
> > Please let me try to summarize what this is doing: Given a type object
> > and a long, create an instance of that type. Is that a correct
> > analysis of what has to be done?
> 
> That would allow you to do the same thing, but rather more error prone
> (i.e. I think it is much more of a hack than what I'm trying to get
> at). As you noted above WinObj's unfortunately need such a hack, but I
> would expect to get rid of it as soon as possible. I really don't like
> passing C pointers around in Python integers.
> 
> > I completely fail to see how O& fits into the puzzle. AFAICT,
> > conversion of the return value occurs inside cdc_call. There is no
> > tuple to parse anyway nearby.
> 
> Not at the moment, but in calldll version 2 there would be. In stead
> of passing types as "l" or "h" you would pass type objects to
> newcall(). Newcall() would probably special-case the various ints but
> for all other types simply call PyArg_Parse(arg, "O@", typeobj,
> &voidptr). 


Here's an outline which could work in 2.2:

Create a subtype of type, having a tp_convert slot:

typedef int (*convert_func)(PyTypeObject *, void **);

typedef struct {
    PyTypeObject type;
    convert_func tp_convert;
} WrapperTypeType;

and use it as metaclass (metatype?) for your WindowObj:

class WindowObj(...):
    __metaclass__ = WrapperTypeType

Write a function to return a conversion function:

convert_func *get_converter(PyTypeObject *type)
{
    if (WrapperTypeType_Check(type))
        return ((WrapperTypeType *)type)->tp_convert;
    /* code to check additional types and return their converters */
    ....
}

and then

if (!PyArg_ParseTuple(args, "O&", get_converter(WinObj_Type), &Window))

How does this sound?

Thomas