diff options
Diffstat (limited to 'sources/shiboken2/libshiboken')
-rw-r--r-- | sources/shiboken2/libshiboken/basewrapper.cpp | 10 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/qapp_macro.cpp | 41 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/qapp_macro.h | 2 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/signature.cpp | 20 | ||||
-rw-r--r-- | sources/shiboken2/libshiboken/signature.h | 2 |
5 files changed, 67 insertions, 8 deletions
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp index faaca5e4b..f38b55b56 100644 --- a/sources/shiboken2/libshiboken/basewrapper.cpp +++ b/sources/shiboken2/libshiboken/basewrapper.cpp @@ -76,11 +76,21 @@ extern "C" static void SbkObjectTypeDealloc(PyObject* pyObj); static PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds); +// PYSIDE-908: The function PyType_Modified does not work in PySide, so we need to +// explicitly pass __doc__. For __signature__ it _did_ actually work, because +// it was not existing before. We add them both for clarity. +static PyGetSetDef SbkObjectType_Type_getsetlist[] = { + {const_cast<char*>("__signature__"), (getter)Sbk_TypeGet___signature__}, + {const_cast<char*>("__doc__"), (getter)Sbk_TypeGet___doc__}, + {nullptr} // Sentinel +}; + static PyType_Slot SbkObjectType_Type_slots[] = { {Py_tp_dealloc, (void *)SbkObjectTypeDealloc}, {Py_tp_setattro, (void *)PyObject_GenericSetAttr}, {Py_tp_base, (void *)&PyType_Type}, {Py_tp_alloc, (void *)PyType_GenericAlloc}, + {Py_tp_getset, (void *)SbkObjectType_Type_getsetlist}, {Py_tp_new, (void *)SbkObjectTypeTpNew}, {Py_tp_free, (void *)PyObject_GC_Del}, {0, 0} 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" diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp index c83f90d64..8003f142a 100644 --- a/sources/shiboken2/libshiboken/signature.cpp +++ b/sources/shiboken2/libshiboken/signature.cpp @@ -1180,4 +1180,24 @@ SetError_Argument(PyObject *args, const char *func_name) PyErr_SetObject(err, msg); } +/* + * Support for the metatype SbkObjectType_Type's tp_getset. + * + * This was not necessary for __signature__, because PyType_Type inherited it. + * But the __doc__ attribute existed already by inheritance, and calling + * PyType_Modified() is not supported. So we added the getsets explicitly + * to the metatype. + */ + +PyObject * +Sbk_TypeGet___signature__(PyObject *ob, const char *modifier) +{ + return pyside_tp_get___signature__(ob, modifier); +} + +PyObject *Sbk_TypeGet___doc__(PyObject *ob) +{ + return pyside_tp_get___doc__(ob); +} + } //extern "C" diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h index 6b477c52e..57fd4047a 100644 --- a/sources/shiboken2/libshiboken/signature.h +++ b/sources/shiboken2/libshiboken/signature.h @@ -48,6 +48,8 @@ extern "C" LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *[]); LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]); LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *); +LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, const char *); +LIBSHIBOKEN_API PyObject *Sbk_TypeGet___doc__(PyObject *); } // extern "C" |