Delete all PySide2 QObjects before Py_Finalize() (#1386)

This commit is contained in:
Florian Märkl 2019-03-24 13:11:54 +01:00 committed by GitHub
parent c7adeb4dd6
commit 76bcac8aa7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -13,6 +13,12 @@
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
#include <shiboken.h>
#include <pyside.h>
#include <signalmanager.h>
#endif
#include "QtResImporter.h" #include "QtResImporter.h"
static PythonManager *uniqueInstance = nullptr; static PythonManager *uniqueInstance = nullptr;
@ -84,14 +90,57 @@ void PythonManager::initialize()
saveThread(); saveThread();
} }
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
static void pySideDestructionVisitor(SbkObject* pyObj, void* data)
{
void **realData = reinterpret_cast<void**>(data);
auto pyQApp = reinterpret_cast<SbkObject*>(realData[0]);
auto pyQObjectType = reinterpret_cast<PyTypeObject*>(realData[1]);
if (pyObj == pyQApp || !PyObject_TypeCheck(pyObj, pyQObjectType)) {
return;
}
if (!Shiboken::Object::hasOwnership(pyObj) || !Shiboken::Object::isValid(pyObj, false)) {
return;
}
const char *reprStr = "";
PyObject *repr = PyObject_Repr(reinterpret_cast<PyObject *>(pyObj));
if (repr) {
reprStr = PyUnicode_AsUTF8(repr);
}
qWarning() << "Warning: QObject from Python remaining (leaked from plugin?):" << reprStr;
if (repr) {
Py_DecRef(repr);
}
Shiboken::Object::setValidCpp(pyObj, false);
Py_BEGIN_ALLOW_THREADS
Shiboken::callCppDestructor<QObject>(Shiboken::Object::cppPointer(pyObj, pyQObjectType));
Py_END_ALLOW_THREADS
};
#endif
void PythonManager::shutdown() void PythonManager::shutdown()
{ {
emit willShutDown(); emit willShutDown();
restoreThread();
#ifdef CUTTER_ENABLE_PYTHON_BINDINGS
// This is necessary to prevent a segfault when the CutterCore instance is deleted after the Shiboken::BindingManager // This is necessary to prevent a segfault when the CutterCore instance is deleted after the Shiboken::BindingManager
Core()->setProperty("_PySideInvalidatePtr", QVariant()); Core()->setProperty("_PySideInvalidatePtr", QVariant());
restoreThread(); // see PySide::destroyQCoreApplication()
PySide::SignalManager::instance().clear();
Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
SbkObject* pyQApp = bm.retrieveWrapper(QCoreApplication::instance());
PyTypeObject* pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
void* data[2] = {pyQApp, pyQObjectType};
bm.visitAllPyObjects(&pySideDestructionVisitor, &data);
PySide::runCleanupFunctions();
#endif
Py_Finalize(); Py_Finalize();