aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
Diffstat (limited to 'sources')
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp9
-rw-r--r--sources/pyside2/tests/QtWidgets/application_test.py8
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp2
-rw-r--r--sources/shiboken2/libshiboken/qapp_macro.cpp41
-rw-r--r--sources/shiboken2/libshiboken/qapp_macro.h2
5 files changed, 47 insertions, 15 deletions
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index f30607f6b..9db4e2e82 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -1340,18 +1340,17 @@ if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
// @snippet qcoreapplication-2
// @snippet qcoreapplication-instance
-QCoreApplication *app = QCoreApplication::instance();
PyObject *pyApp = Py_None;
-if (app) {
+if (qApp) {
pyApp = reinterpret_cast<PyObject*>(
- Shiboken::BindingManager::instance().retrieveWrapper(app));
+ Shiboken::BindingManager::instance().retrieveWrapper(qApp));
if (!pyApp)
- pyApp = %CONVERTTOPYTHON[QCoreApplication*](app);
+ pyApp = %CONVERTTOPYTHON[QCoreApplication*](qApp);
// this will keep app live after python exit (extra ref)
}
// PYSIDE-571: make sure that we return the singleton "None"
if (pyApp == Py_None)
- Py_DECREF(MakeSingletonQAppWrapper(0)); // here qApp and instance() diverge
+ Py_DECREF(MakeSingletonQAppWrapper(nullptr)); // here qApp and instance() diverge
%PYARG_0 = pyApp;
Py_XINCREF(%PYARG_0);
// @snippet qcoreapplication-instance
diff --git a/sources/pyside2/tests/QtWidgets/application_test.py b/sources/pyside2/tests/QtWidgets/application_test.py
index bd0f94125..0b8f73cd6 100644
--- a/sources/pyside2/tests/QtWidgets/application_test.py
+++ b/sources/pyside2/tests/QtWidgets/application_test.py
@@ -31,19 +31,25 @@
import unittest
from testbinding import TestObject
from PySide2.QtWidgets import QApplication
+from PySide2 import __all__ as all
class QApplicationInstance(unittest.TestCase):
def appDestroyed(self):
- sefl.assertTrue(False)
+ self.assertTrue(False)
def testInstanceObject(self):
+ self.assertEqual(type(qApp), type(None))
TestObject.createApp()
app1 = QApplication.instance()
app2 = QApplication.instance()
app1.setObjectName("MyApp")
self.assertEqual(app1, app2)
self.assertEqual(app2.objectName(), app1.objectName())
+ if len(all) > 3:
+ # an import triggers qApp initialization
+ __import__("PySide2." + all[-1])
+ self.assertEqual(app1, qApp)
app1.destroyed.connect(self.appDestroyed)
if __name__ == '__main__':
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 8ee0a9cf2..d1da3a4ba 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -5806,7 +5806,7 @@ bool CppGenerator::finishGeneration()
if (usePySideExtensions()) {
// initialize the qApp module.
- s << INDENT << "NotifyModuleForQApp(module);" << endl;
+ s << INDENT << "NotifyModuleForQApp(module, qApp);" << endl;
}
s << endl;
s << "SBK_MODULE_INIT_FUNCTION_END" << endl;
diff --git a/sources/shiboken2/libshiboken/qapp_macro.cpp b/sources/shiboken2/libshiboken/qapp_macro.cpp
index 19e985b20..ea9cf0c86 100644
--- a/sources/shiboken2/libshiboken/qapp_macro.cpp
+++ b/sources/shiboken2/libshiboken/qapp_macro.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "basewrapper.h"
+#include "autodecref.h"
extern "C"
{
@@ -93,13 +94,14 @@ static int qApp_var_ref = 0;
static int qApp_content_ref = 0;
static int
-reset_qApp_var()
+reset_qApp_var(void)
{
PyObject **mod_ptr;
- for (mod_ptr = qApp_moduledicts; *mod_ptr != NULL; mod_ptr++) {
+ for (mod_ptr = qApp_moduledicts; *mod_ptr != nullptr; mod_ptr++) {
// We respect whatever the user may have set.
- if (PyDict_GetItem(*mod_ptr, qApp_var) == NULL) {
+ PyObject *existing = PyDict_GetItem(*mod_ptr, qApp_var);
+ if (existing == nullptr || Py_TYPE(existing) == Py_NONE_TYPE) {
if (PyDict_SetItem(*mod_ptr, qApp_var, qApp_content) < 0)
return -1;
}
@@ -135,8 +137,13 @@ MakeSingletonQAppWrapper(PyTypeObject *type)
if (Py_REFCNT(qApp_content) > qApp_content_ref)
qApp_content_ref = Py_REFCNT(qApp_content);
- if (Py_TYPE(qApp_content) != Py_NONE_TYPE)
+ if (Py_TYPE(qApp_content) != Py_NONE_TYPE) {
+ // Remove the "_" variable which might hold a reference to qApp.
+ Shiboken::AutoDecRef pymain(PyImport_ImportModule("__main__"));
+ if (pymain.object() && PyObject_HasAttrString(pymain.object(), "_"))
+ PyObject_DelAttrString(pymain.object(), "_");
Py_REFCNT(qApp_var) = 1; // fuse is armed...
+ }
if (type == Py_NONE_TYPE) {
// Debug mode showed that we need to do more than just remove the
// reference. To keep everything in the right order, it is easiest
@@ -149,8 +156,8 @@ MakeSingletonQAppWrapper(PyTypeObject *type)
Py_TYPE(qApp_content) = Py_NONE_TYPE;
Py_REFCNT(qApp_var) = qApp_var_ref;
Py_REFCNT(qApp_content) = Py_REFCNT(Py_None);
- if (__moduleShutdown != NULL)
- Py_DECREF(PyObject_CallFunction(__moduleShutdown, (char *)"()"));
+ if (__moduleShutdown != nullptr)
+ Py_XDECREF(PyObject_CallFunction(__moduleShutdown, const_cast<char *>("()")));
}
else
(void)PyObject_INIT(qApp_content, type);
@@ -216,9 +223,29 @@ setup_qApp_var(PyObject *module)
}
void
-NotifyModuleForQApp(PyObject *module)
+NotifyModuleForQApp(PyObject *module, void *qApp)
{
setup_qApp_var(module);
+ /*
+ * PYSIDE-571: Check if an QApplication instance exists before the import.
+ * This happens in scriptableapplication and application_test.py .
+ *
+ * Crucial Observation
+ * ===================
+ *
+ * A Q*Application object from C++ does not have a wrapper or constructor
+ * like instances created by Python. It makes no sense to support
+ * deletion or special features like qApp resurrection.
+ *
+ * Therefore, the implementation is very simple and just redirects the
+ * qApp_contents variable and assigns the instance, instead of vice-versa.
+ */
+ if (qApp != nullptr) {
+ Shiboken::AutoDecRef pycore(PyImport_ImportModule("PySide2.QtCore"));
+ Shiboken::AutoDecRef coreapp(PyObject_GetAttrString(pycore, "QCoreApplication"));
+ qApp_content = PyObject_CallMethod(coreapp, "instance", "");
+ reset_qApp_var();
+ }
}
diff --git a/sources/shiboken2/libshiboken/qapp_macro.h b/sources/shiboken2/libshiboken/qapp_macro.h
index ded892383..be45241de 100644
--- a/sources/shiboken2/libshiboken/qapp_macro.h
+++ b/sources/shiboken2/libshiboken/qapp_macro.h
@@ -46,7 +46,7 @@ extern "C"
{
LIBSHIBOKEN_API PyObject *MakeSingletonQAppWrapper(PyTypeObject *type);
-LIBSHIBOKEN_API void NotifyModuleForQApp(PyObject *module);
+LIBSHIBOKEN_API void NotifyModuleForQApp(PyObject *module, void *qApp);
} // extern "C"