Hello, I'm using the nuitka python compiler (http://nuitka.net) in conjunction with PySide. However, this won't work with the current PySide version. According to Nuitka's main developper, this is a common problem when using nuitka with toolkit bindings, and requires some fix in the toolkits. For instance, he contributed patches fixing wxWdiget (http://trac.wxwidgets.org/ticket/14025) and PyQt4 (http://www.freelists.org/post/nuitka-dev/C-libraries-that-call-back-into-compiled-instance-methods,2).
Following these examples, I've found some fixes that enable PySide to work correctly when run under Nuitka (patches attached). There were two issues that prevented PySide to run with Nuitka. The first one was that the slot registration mechanism was guarded by a PyFunction_Check which doesn't work with Nuitka's compiled functions, and the mechanism that added the "_slots" attribute to the slots was also making the assumption that it would be called on a PyFunctionObject. The second issue was in shiboken, the wrapping procedure was using PyMethod_Check. I hope these patches can get merged. If you feel these patches are not ready for merge yet, please let me know. Regards, Vincent Barrielle
>From e991734e44359b39f39e0ffed3b1bc8c2237cd47 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle <[email protected]> Date: Mon, 3 Feb 2014 08:23:18 +0100 Subject: [PATCH] Fix slot registration when running under the Nuitka python compiler The usage of PyMethod_Check fails to properly detect compiled functions as callables. --- libpyside/dynamicqmetaobject.cpp | 2 +- libpyside/pysideslot.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index 4f9af32..a570ecd 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -500,7 +500,7 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject* type) if (d.superdata->indexOfSignal(sig) == -1) addSignal(sig); } - } else if (PyFunction_Check(value)) { // Register slots + } else if (Py_TYPE(value)->tp_call != NULL) { // Register slots if (PyObject_HasAttr(value, slotAttrName)) { PyObject* signatureList = PyObject_GetAttr(value, slotAttrName); for(Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) { diff --git a/libpyside/pysideslot.cpp b/libpyside/pysideslot.cpp index 97aa60d..43cd4ee 100644 --- a/libpyside/pysideslot.cpp +++ b/libpyside/pysideslot.cpp @@ -140,15 +140,18 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw) PyObject* slotCall(PyObject* self, PyObject* args, PyObject* kw) { static PyObject* pySlotName = 0; + static PyObject* pyNameAttrName = NULL; PyObject* callback; callback = PyTuple_GetItem(args, 0); Py_INCREF(callback); - if (PyFunction_Check(callback)) { + if (Py_TYPE(callback)->tp_call != NULL) { PySideSlot *data = reinterpret_cast<PySideSlot*>(self); if (!data->slotName) { - PyObject *funcName = reinterpret_cast<PyFunctionObject*>(callback)->func_name; + if (!pyNameAttrName) + pyNameAttrName = Shiboken::String::fromCString("__name__"); + PyObject * funcName = PyObject_GetAttr(callback, pyNameAttrName); data->slotName = strdup(Shiboken::String::toCString(funcName)); } -- 1.8.5.2
>From e4f0f6987bd8af38fe0670046dc576d8825ea32b Mon Sep 17 00:00:00 2001 From: Vincent Barrielle <[email protected]> Date: Mon, 3 Feb 2014 16:39:28 +0100 Subject: [PATCH] Enable wrapping of functions compiled by Nuitka Functions compiled by Nuitka do not pass tests such as PyMethod_Check, even though they are callable. --- libshiboken/bindingmanager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp index cb61000..6f232c4 100644 --- a/libshiboken/bindingmanager.cpp +++ b/libshiboken/bindingmanager.cpp @@ -256,8 +256,10 @@ PyObject* BindingManager::getOverride(const void* cptr, const char* methodName) PyObject* pyMethodName = Shiboken::String::fromCString(methodName); PyObject* method = PyObject_GetAttr((PyObject*)wrapper, pyMethodName); - if (method && PyMethod_Check(method) - && reinterpret_cast<PyMethodObject*>(method)->im_self == reinterpret_cast<PyObject*>(wrapper)) { + bool isMethod = method && PyMethod_Check(method); + bool isCompiled = !isMethod && Py_TYPE(method)->tp_call != NULL; + bool wrapsParent = reinterpret_cast<PyMethodObject*>(method)->im_self == reinterpret_cast<PyObject*>(wrapper); + if ((isMethod && wrapsParent) || isCompiled) { PyObject* defaultMethod; PyObject* mro = Py_TYPE(wrapper)->tp_mro; -- 1.8.5.3
_______________________________________________ PySide mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/pyside
