[PyQt] sip: how to make a python instance owned by C++ without using a parent

Phil Thompson phil at riverbankcomputing.com
Wed Aug 15 10:05:42 BST 2012


On Tue, 14 Aug 2012 23:47:51 +0200, Mathias.Born at gmx.de wrote:
> Thanks for the answer. However, it appears I've not made myself
> clear enough.
> I don't want the C++ wrapper to be owned by Python; surely, I
> can achieve that with "sipTransferTo". But nothing is done about the
> Python part. When I delete the wrapper in C++, the Python part it wraps
> stays alive, because its reference count is not touched. (No parent!)
> I have to manually, explicitely decrease the reference count to get
> rid of it. I'm not complaining. I get this Python object from a Python
> function, so I have to take care of it.
> 
> However, the sip module already contains some code that essentially
> already would do what I want:
> 
> ======================== siplib.c ===================================
> void sip_api_common_dtor(sipSimpleWrapper *sipSelf)
> {
>     if (sipSelf != NULL && sipInterpreter != NULL)
>     {
>         PyObject *xtype, *xvalue, *xtb;
> 
>         SIP_BLOCK_THREADS
> 
>         /* We may be tidying up after an exception so preserve it. */
>         PyErr_Fetch(&xtype, &xvalue, &xtb);
>         callPyDtor(sipSelf);
>         PyErr_Restore(xtype, xvalue, xtb);
> 
>         sipOMRemoveObject(&cppPyMap, sipSelf);
> 
>         /* This no longer points to anything useful. */
>         clear_access_func(sipSelf);
> 
>         /*
>          * If C/C++ has a reference (and therefore no parent) then
remove
>          it.
>          * Otherwise remove the object from any parent.
>          */
>         if (sipCppHasRef(sipSelf))
>         {
>             sipResetCppHasRef(sipSelf);
>             Py_DECREF(sipSelf);
>         }
>         else if (PyObject_TypeCheck((PyObject *)sipSelf, (PyTypeObject
>         *)&sipWrapper_Type))
>             removeFromParent((sipWrapper *)sipSelf);
> 
>         SIP_UNBLOCK_THREADS
>     }
> }
> =====================================================================
> 
> What about:
> 
>         if (sipCppHasRef(sipSelf))
>         {
>             sipResetCppHasRef(sipSelf);
>             Py_DECREF(sipSelf);
>         }
> 
> Is there an official way for my wrapper to have the "SIP_CPP_HAS_REF"
flag
> set?
> It would then automatically dispose its Python counterpart.

I could change sipTransferTo() to do this if the owner was Py_None. At the
moment this is undocumented behaviour. Would this be sufficient?

Phil


More information about the PyQt mailing list