Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-11-24 17:31:10 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2023-11-29 08:56:12 +0100
commit51636b43d90bc29996f3bbd8372f333eb1a321d0 (patch)
tree8157d035daa530d9494dd558f606591eeb88e904 /sources/pyside6/libpyside/pysidesignal.cpp
parentdaf77773a72980a369ba6aabcb8cf1ca835bbbe7 (diff)
Enable connecting signals to slots with default parameters
Find the number of default parameters using PyFunction_GetDefaults() and change the argCount() helper to return the min/max argument count. With that, try to match the slot using the most argument. [ChangeLog][PySide6] It is now possible to connect signals to slots/lambdas with more arguments provided they have default parameters. Fixes: PYSIDE-2524 Change-Id: I134d33e3ee78b62689fa36887a9acd41951c02e1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
Diffstat (limited to 'sources/pyside6/libpyside/pysidesignal.cpp')
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp35
1 files changed, 27 insertions, 8 deletions
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
index 16e7b8411..0c6a23245 100644
--- a/sources/pyside6/libpyside/pysidesignal.cpp
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -441,11 +441,25 @@ static FunctionArgumentsResult extractFunctionArgumentsFromSlot(PyObject *slot)
return ret;
}
-static int argCount(const FunctionArgumentsResult &args)
+struct ArgCount
+{
+ int min;
+ int max;
+};
+
+// Return a pair of minimum / arg count "foo(p1, p2=0)" -> {1, 2}
+ArgCount argCount(const FunctionArgumentsResult &args)
{
Q_ASSERT(args.objCode);
- return (PepCode_GET_FLAGS(args.objCode) & CO_VARARGS) != 0
- ? -1 : PepCode_GET_ARGCOUNT(args.objCode);
+ ArgCount result{-1, -1};
+ if ((PepCode_GET_FLAGS(args.objCode) & CO_VARARGS) == 0) {
+ result.min = result.max = PepCode_GET_ARGCOUNT(args.objCode);
+ if (args.function != nullptr) {
+ if (auto *defaultArgs = PepFunction_GetDefaults(args.function))
+ result.min -= PyTuple_Size(defaultArgs);
+ }
+ }
+ return result;
}
// Find Signal Instance for argument count.
@@ -510,14 +524,19 @@ static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject
PySideSignalInstance *matchedSlot = nullptr;
if (args.function != nullptr) {
- qsizetype slotArgs = argCount(args);
- if (args.isMethod)
- slotArgs -= 1;
+ auto slotArgRange = argCount(args);
+ if (args.isMethod) {
+ slotArgRange.min -= 1;
+ slotArgRange.max -= 1;
+ }
// Get signature args
// Iterate the possible types of connection for this signal and compare
// it with slot arguments
- matchedSlot = findSignalInstance(source, slotArgs);
+ for (int slotArgs = slotArgRange.max;
+ slotArgs >= slotArgRange.min && matchedSlot == nullptr; --slotArgs) {
+ matchedSlot = findSignalInstance(source, slotArgs);
+ }
}
// Adding references to pyArgs
@@ -1205,7 +1224,7 @@ QByteArray getCallbackSignature(const char *signal, QObject *receiver,
qsizetype useSelf = slotArgs.isMethod ? 1 : 0;
if (slotArgs.function != nullptr) {
- numArgs = argCount(slotArgs);
+ numArgs = argCount(slotArgs).max;
#ifdef PYPY_VERSION
} else if (Py_TYPE(callback) == PepBuiltinMethod_TypePtr) {
// PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction.