From 72485050f28e3d9f6f99c2f9d112d451f5066d4e Mon Sep 17 00:00:00 2001 From: Christian Tismer Date: Wed, 23 Dec 2020 13:28:16 +0200 Subject: qApp: fix flag handling in Python 3.8+ and a Python 3.9 issue This is an old problem that was solved for Python 2.7. From Python 3.8 on, the behavior is the same with Python 3. The fix finally was to extend a Python 2.7 patch to Python 3 as well. See the Jira issue for details. Other little changes: This patch includes also a small patch that was mentioned as necessary for Python 3.9: Python issue 40217. I have seen no effect of this change yet but applied the patch, anyway. When searching for a solution of this problem, a lot of time was spent debugging qapp_macro.cpp, although it was error-free. As a side effect for better understanding, the variables were renamed to more common style. These more independent changes could have got their own check-in, but the complication of a pick-to and the small code size wasn't worth the effort. Change-Id: I7638f1a711315b4678af6b7389265b905c6404a1 Fixes: PYSIDE-1447 Reviewed-by: Dmitry Shachnev Reviewed-by: Friedemann Kleint (cherry picked from commit c1f776570adbe4f9aa21aa818a82f5ebd1258a76) --- sources/shiboken2/libshiboken/basewrapper.cpp | 12 ++++++++++-- sources/shiboken2/libshiboken/qapp_macro.cpp | 28 +++++++++++++-------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index 4b1e6e564..ac086b354 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -319,6 +319,11 @@ static int SbkObject_traverse(PyObject *self, visitproc visit, void *arg) if (sbkSelf->ob_dict) Py_VISIT(sbkSelf->ob_dict); + +#if PY_VERSION_HEX >= 0x03090000 + // This was not needed before Python 3.9 (Python issue 35810 and 40217) + Py_VISIT(Py_TYPE(self)); +#endif return 0; } @@ -769,12 +774,15 @@ PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *, PyObject *) // PYSIDE-560: // We avoid to use this in Python 3, because we have a hard time to get // write access to these flags -#ifndef IS_PY3K + + // PYSIDE-1447: + // Since Python 3.8, we have the same weird flags handling in Python 3.8 + // as well. The singleton Python is no longer needed and we could remove + // the whole special handling, maybe in another checkin. if (PyType_HasFeature(subtype, Py_TPFLAGS_HAVE_GC)) { subtype->tp_flags &= ~Py_TPFLAGS_HAVE_GC; subtype->tp_free = PyObject_Del; } -#endif auto self = reinterpret_cast(MakeQAppWrapper(subtype)); return self == nullptr ? nullptr : _setupNew(self, subtype); } diff --git a/sources/shiboken2/libshiboken/qapp_macro.cpp b/sources/shiboken2/libshiboken/qapp_macro.cpp index 3ef3a51c6..03a8d0496 100644 --- a/sources/shiboken2/libshiboken/qapp_macro.cpp +++ b/sources/shiboken2/libshiboken/qapp_macro.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt for Python. @@ -54,38 +54,36 @@ extern "C" // This variable is also able to destroy the app by qApp.shutdown(). // -static PyObject *qApp_var = nullptr; -static PyObject *qApp_content = nullptr; +static PyObject *qApp_name = nullptr; +static PyObject *qApp_last = nullptr; -static PyObject * -monitor_qApp_var(PyObject *qApp) +static PyObject *monitor_qApp_var(PyObject *qApp_curr) { static bool init_done; static PyObject *builtins = PyEval_GetBuiltins(); if (!init_done) { - qApp_var = Py_BuildValue("s", "qApp"); - if (qApp_var == nullptr) + qApp_name = Py_BuildValue("s", "qApp"); + if (qApp_name == nullptr) return nullptr; // This is a borrowed reference Py_INCREF(builtins); init_done = true; } - if (PyDict_SetItem(builtins, qApp_var, qApp) < 0) + if (PyDict_SetItem(builtins, qApp_name, qApp_curr) < 0) return nullptr; - qApp_content = qApp; - Py_INCREF(qApp); - return qApp; + qApp_last = qApp_curr; + Py_INCREF(qApp_curr); + return qApp_curr; } -PyObject * -MakeQAppWrapper(PyTypeObject *type) +PyObject *MakeQAppWrapper(PyTypeObject *type) { if (type == nullptr) type = Py_TYPE(Py_None); - if (!(type == Py_TYPE(Py_None) || Py_TYPE(qApp_content) == Py_TYPE(Py_None))) { - const char *res_name = PepType_GetNameStr(Py_TYPE(qApp_content)); + if (!(type == Py_TYPE(Py_None) || Py_TYPE(qApp_last) == Py_TYPE(Py_None))) { + const char *res_name = PepType_GetNameStr(Py_TYPE(qApp_last)); const char *type_name = PepType_GetNameStr(type); PyErr_Format(PyExc_RuntimeError, "Please destroy the %s singleton before" " creating a new %s instance.", res_name, type_name); -- cgit v1.2.3