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

Mathias.Born at gmx.de Mathias.Born at gmx.de
Wed Aug 15 10:55:47 BST 2012


On 15.08.2012, 11:05:42 Phil Thompson wrote:
> 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?

I believe so.

Best Regards,
Mathias Born




More information about the PyQt mailing list