Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2022-01-10 10:22:09 +0100
committerShyamnath Premnadh <Shyamnath.Premnadh@qt.io>2022-01-18 13:07:01 +0100
commit56f66f128566bd08f027fee46bb42a6c4f57a26e (patch)
treed6a0f87ea3251af90fe965bd79ee877918ce8cd5 /sources/pyside6/libpyside
parent32b811150e273dc0b92179ae0fcd4a82330d3b21 (diff)
Safe distinction of Nuitka compiled methods
Adds an extra check to see if __code__ is present. As mentioned in PYSIDE-1755, Mocks are callable objects without __code__ attribute, unlike Python Method or Functions. However, a Mock also has im_func__ and im__self attributes. We made the assumption __code__ would be present if im_func and im_self are present, and this makes it fall under the category of a compiled method. This patch makes an extra check to see if __code__ is present. If it is not, then the Slot (here Mock) is considered as a callable method. Task-number: PYSIDE-1755 Pick-to: 6.2 Change-Id: If7e8f52dfb2409cd856eec0d0b41891d751d8a69 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside6/libpyside')
-rw-r--r--sources/pyside6/libpyside/globalreceiverv2.cpp6
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp6
-rw-r--r--sources/pyside6/libpyside/qobjectconnect.cpp3
-rw-r--r--sources/pyside6/libpyside/signalmanager.cpp7
-rw-r--r--sources/pyside6/libpyside/signalmanager.h2
5 files changed, 15 insertions, 9 deletions
diff --git a/sources/pyside6/libpyside/globalreceiverv2.cpp b/sources/pyside6/libpyside/globalreceiverv2.cpp
index ef6097764..cf2508a97 100644
--- a/sources/pyside6/libpyside/globalreceiverv2.cpp
+++ b/sources/pyside6/libpyside/globalreceiverv2.cpp
@@ -114,8 +114,7 @@ DynamicSlotDataV2::DynamicSlotDataV2(PyObject *callback, GlobalReceiverV2 *paren
//monitor class from method lifetime
m_weakRef = WeakRef::create(m_pythonSelf, DynamicSlotDataV2::onCallbackDestroyed, this);
- } else if (PyObject_HasAttr(callback, PySide::PyName::im_func())
- && PyObject_HasAttr(callback, PySide::PyName::im_self())) {
+ } else if (PySide::isCompiledMethod(callback)) {
// PYSIDE-1523: PyMethod_Check is not accepting compiled form, we just go by attributes.
m_isMethod = true;
@@ -141,8 +140,7 @@ GlobalReceiverKey DynamicSlotDataV2::key(PyObject *callback)
if (PyMethod_Check(callback)) {
// PYSIDE-1422: Avoid hash on self which might be unhashable.
return {PyMethod_GET_SELF(callback), PyMethod_GET_FUNCTION(callback)};
- } else if (PyObject_HasAttr(callback, PySide::PyName::im_func())
- && PyObject_HasAttr(callback, PySide::PyName::im_self())) {
+ } else if (PySide::isCompiledMethod(callback)) {
// PYSIDE-1589: Fix for slots in compiled functions
Shiboken::AutoDecRef self(PyObject_GetAttr(callback, PySide::PyName::im_self()));
Shiboken::AutoDecRef func(PyObject_GetAttr(callback, PySide::PyName::im_func()));
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
index 9e9105712..dfe96427d 100644
--- a/sources/pyside6/libpyside/pysidesignal.cpp
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -330,7 +330,7 @@ static void extractFunctionArgumentsFromSlot(PyObject *slot,
if (functionName != nullptr) {
*functionName = Shiboken::String::toCString(PepFunction_GetName(function));
}
- } else if (PyObject_HasAttr(slot, PySide::PyName::im_func())) {
+ } else if (PySide::isCompiledMethod(slot)) {
// PYSIDE-1523: PyFunction_Check and PyMethod_Check are not accepting compiled forms, we
// just go by attributes.
isMethod = true;
@@ -381,6 +381,7 @@ static void extractFunctionArgumentsFromSlot(PyObject *slot,
function = nullptr;
}
}
+ // any other callback
}
static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds)
@@ -1172,8 +1173,7 @@ QString codeCallbackName(PyObject *callback, const QString &funcName)
return funcName + QString::number(quint64(self), 16) + QString::number(quint64(func), 16);
}
// PYSIDE-1523: Handle the compiled case.
- if (PyObject_HasAttr(callback, PySide::PyName::im_func())
- && PyObject_HasAttr(callback, PySide::PyName::im_self())) {
+ if (PySide::isCompiledMethod(callback)) {
// Not retaining references inline with what PyMethod_GET_(SELF|FUNC) does.
Shiboken::AutoDecRef self(PyObject_GetAttr(callback, PySide::PyName::im_self()));
Shiboken::AutoDecRef func(PyObject_GetAttr(callback, PySide::PyName::im_func()));
diff --git a/sources/pyside6/libpyside/qobjectconnect.cpp b/sources/pyside6/libpyside/qobjectconnect.cpp
index bad0589a2..fda174cdc 100644
--- a/sources/pyside6/libpyside/qobjectconnect.cpp
+++ b/sources/pyside6/libpyside/qobjectconnect.cpp
@@ -115,8 +115,7 @@ static GetReceiverResult getReceiver(QObject *source, const char *signal,
} else if (PyCFunction_Check(callback)) {
result.self = PyCFunction_GET_SELF(callback);
result.receiver = PySide::convertToQObject(result.self, false);
- } else if (PyObject_HasAttr(callback, Shiboken::PyName::im_func())
- && PyObject_HasAttr(callback, Shiboken::PyName::im_self())) {
+ } else if (PySide::isCompiledMethod(callback)) {
result.self = PyObject_GetAttr(callback, Shiboken::PyName::im_self());
Py_DECREF(result.self);
result.receiver = PySide::convertToQObject(result.self, false);
diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp
index bf9a5a4ad..a996d1e6c 100644
--- a/sources/pyside6/libpyside/signalmanager.cpp
+++ b/sources/pyside6/libpyside/signalmanager.cpp
@@ -46,6 +46,7 @@
#include "pyside_p.h"
#include "dynamicqmetaobject.h"
#include "pysidemetafunction_p.h"
+#include "pysidestaticstrings.h"
#include <autodecref.h>
#include <basewrapper.h>
@@ -88,6 +89,12 @@ namespace {
namespace PySide {
+bool isCompiledMethod(PyObject *callback)
+{
+ return PyObject_HasAttr(callback, PySide::PyName::im_func())
+ && PyObject_HasAttr(callback, PySide::PyName::im_self())
+ && PyObject_HasAttr(callback, PySide::PyMagicName::code());
+}
PyObjectWrapper::PyObjectWrapper()
:m_me(Py_None)
diff --git a/sources/pyside6/libpyside/signalmanager.h b/sources/pyside6/libpyside/signalmanager.h
index c066aacdf..e32349a36 100644
--- a/sources/pyside6/libpyside/signalmanager.h
+++ b/sources/pyside6/libpyside/signalmanager.h
@@ -54,6 +54,8 @@ QT_FORWARD_DECLARE_CLASS(QDataStream)
namespace PySide
{
+PYSIDE_API bool isCompiledMethod(PyObject *callback);
+
/// Thin wrapper for PyObject which increases the reference count at the constructor but *NOT* at destructor.
class PYSIDE_API PyObjectWrapper
{