Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--sources/pyside6/tests/pysidetest/CMakeLists.txt1
-rw-r--r--sources/pyside6/tests/pysidetest/mock_as_slot_test.py59
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.cpp3
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings.cpp2
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings.h1
10 files changed, 79 insertions, 11 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
{
diff --git a/sources/pyside6/tests/pysidetest/CMakeLists.txt b/sources/pyside6/tests/pysidetest/CMakeLists.txt
index 880433ad9..9fec250b5 100644
--- a/sources/pyside6/tests/pysidetest/CMakeLists.txt
+++ b/sources/pyside6/tests/pysidetest/CMakeLists.txt
@@ -157,3 +157,4 @@ PYSIDE_TEST(signalinstance_equality_test.py)
PYSIDE_TEST(signalwithdefaultvalue_test.py)
PYSIDE_TEST(typedef_signal_test.py)
PYSIDE_TEST(version_test.py)
+PYSIDE_TEST(mock_as_slot_test.py)
diff --git a/sources/pyside6/tests/pysidetest/mock_as_slot_test.py b/sources/pyside6/tests/pysidetest/mock_as_slot_test.py
new file mode 100644
index 000000000..2e332002e
--- /dev/null
+++ b/sources/pyside6/tests/pysidetest/mock_as_slot_test.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2022 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+""" PYSIDE-1755: https://bugreports.qt.io/projects/PYSIDE/issues/PYSIDE-1755
+ Tests that a unittest.mock.MagicMock() can be used as a slot for quick
+ prototyping. """
+
+import os
+import sys
+import unittest
+from unittest.mock import MagicMock
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from init_paths import init_test_paths
+init_test_paths(False)
+
+from PySide6.QtCore import QObject
+
+
+class MockAsSlot(unittest.TestCase):
+ def testMockAsSlot(self):
+ obj = QObject()
+ mock = MagicMock()
+ obj.objectNameChanged.connect(mock)
+
+ obj.objectNameChanged.emit("test")
+ mock.assert_called_once()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/sources/shiboken6/libshiboken/bindingmanager.cpp b/sources/shiboken6/libshiboken/bindingmanager.cpp
index 6fa625907..cfbbc47cc 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken6/libshiboken/bindingmanager.cpp
@@ -326,7 +326,8 @@ PyObject *BindingManager::getOverride(const void *cptr,
method = nullptr;
}
} else if (PyObject_HasAttr(method, PyName::im_self())
- && PyObject_HasAttr(method, PyName::im_func())) {
+ && PyObject_HasAttr(method, PyName::im_func())
+ && PyObject_HasAttr(method, Shiboken::PyMagicName::code())) {
PyObject *im_self = PyObject_GetAttr(method, PyName::im_self());
// Not retaining a reference inline with what PyMethod_GET_SELF does.
Py_DECREF(im_self);
diff --git a/sources/shiboken6/libshiboken/sbkstaticstrings.cpp b/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
index 20aa1b8a0..f85267574 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
@@ -96,12 +96,12 @@ STATIC_STRING_IMPL(property_methods, "__property_methods__")
STATIC_STRING_IMPL(qualname, "__qualname__")
STATIC_STRING_IMPL(self, "__self__")
STATIC_STRING_IMPL(select_i, "__self__")
+STATIC_STRING_IMPL(code, "__code__")
// Internal:
STATIC_STRING_IMPL(base, "__base__")
STATIC_STRING_IMPL(bases, "__bases__")
STATIC_STRING_IMPL(builtins, "__builtins__")
-STATIC_STRING_IMPL(code, "__code__")
STATIC_STRING_IMPL(dictoffset, "__dictoffset__")
STATIC_STRING_IMPL(func, "__func__")
STATIC_STRING_IMPL(func_kind, "__func_kind__")
diff --git a/sources/shiboken6/libshiboken/sbkstaticstrings.h b/sources/shiboken6/libshiboken/sbkstaticstrings.h
index fd0c06e43..3bf220b6c 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings.h
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings.h
@@ -82,6 +82,7 @@ LIBSHIBOKEN_API PyObject *property_methods();
LIBSHIBOKEN_API PyObject *qualname();
LIBSHIBOKEN_API PyObject *self();
LIBSHIBOKEN_API PyObject *opaque_container();
+LIBSHIBOKEN_API PyObject *code();
} // namespace PyMagicName
} // namespace Shiboken