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

Reply via email to