Resolving Shiboken6 type caching issues with wrapInstance in Maya 2027

The Problem

A customer recently ran into a behavior change in PySide6/Shiboken6 between Maya 2026 and Maya 2027. Their workflow involves retrieving the correct Python type from a raw pointer by first wrapping it as a QObject and inspecting its metaObject:

qObj = shiboken6.wrapInstance(int(ptr), QtCore.QObject)
metaObj = qObj.metaObject()
cls = metaObj.className()
superCls = metaObj.superClass().className()
...
return shiboken6.wrapInstance((int)ptr, classType)

In Maya 2026 and earlier, they could get correct type from the second wrapInstance. But in Maya 2027, they could only get QObject instead.

Root Cause

It is caused by a new feature which has been introduced since Qt 6.7.

PYSIDE-31 Shiboken.wrapInstance() now returns existing instances (preserving ids).

Back in Qt 6.5.3(Maya 2026), the wrapInstance will always return a new instance:

 auto *pyType = reinterpret_cast<PyTypeObject *>(%2); 
            if (Shiboken::ObjectType::checkType(pyType)) { 
                %PYARG_0 = Shiboken::Object::newObject(pyType, 
                                                       reinterpret_cast<void *>(%1), 
                                                       false, true); 
            } else { 
                PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); 
            }

But in Qt 6.8.3(Maya 2027), it became below:

auto *pyType = reinterpret_cast<PyTypeObject *>(%2); 
if (Shiboken::ObjectType::checkType(pyType)) { 
    auto *ptr = reinterpret_cast<void *>(%1); 
    if (auto *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(ptr)) { 
        Py_INCREF(wrapper); 
        %PYARG_0 = reinterpret_cast<PyObject *>(wrapper); 
    } else { 
        %PYARG_0 = Shiboken::Object::newObject(pyType, ptr, false, true); 
    } 
} else { 
    PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type."); 
}

Workaround

There isn’t a documented way to remove wrapped object from the BindingManager. However, if you check typesystem_shiboken.xml, there is an undocumented method(invalidate):

<add-function signature="invalidate(PyObject*)"> 
        <inject-code> 
            Shiboken::Object::invalidate(%1); 
        </inject-code> 
</add-function> 

The method code be tracked to libshiboken/basewrapper.cpp. And it will call recursive_invalidate which calls BindingManager::releaseWrapper.

By calling it before the second wrapInstance, I could get a new wrapped instance with correct type.

Since it is an undocumented method, please use it with caution.


Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading