diff options
Diffstat (limited to 'sources/pyside2/libpyside/pysidesignal.cpp')
-rw-r--r-- | sources/pyside2/libpyside/pysidesignal.cpp | 206 |
1 files changed, 101 insertions, 105 deletions
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp index ed1dcb729..5c030316e 100644 --- a/sources/pyside2/libpyside/pysidesignal.cpp +++ b/sources/pyside2/libpyside/pysidesignal.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt for Python. @@ -88,6 +88,7 @@ static void signalFree(void *); static void signalInstanceFree(void *); static PyObject *signalGetItem(PyObject *self, PyObject *key); static PyObject *signalToString(PyObject *self); +static PyObject *signalDescrGet(PyObject *self, PyObject *obj, PyObject *type); // Signal Instance methods static PyObject *signalInstanceConnect(PyObject *, PyObject *, PyObject *); @@ -107,16 +108,16 @@ static PyMethodDef MetaSignal_methods[] = { }; static PyType_Slot PySideMetaSignalType_slots[] = { - {Py_tp_methods, (void *)MetaSignal_methods}, - {Py_tp_base, (void *)&PyType_Type}, - {Py_tp_free, (void *)PyObject_GC_Del}, - {Py_tp_dealloc, (void *)object_dealloc}, + {Py_tp_methods, reinterpret_cast<void *>(MetaSignal_methods)}, + {Py_tp_base, reinterpret_cast<void *>(&PyType_Type)}, + {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)}, + {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, {0, 0} }; static PyType_Spec PySideMetaSignalType_spec = { - "PySide2.QtCore.MetaSignal", + "2:PySide2.QtCore.MetaSignal", 0, - // sizeof(PyHeapTypeObject) is filled in by PyType_FromSpecWithBases + // sizeof(PyHeapTypeObject) is filled in by SbkType_FromSpecWithBases // which calls PyType_Ready which calls inherit_special. 0, Py_TPFLAGS_DEFAULT, @@ -124,29 +125,30 @@ static PyType_Spec PySideMetaSignalType_spec = { }; -PyTypeObject *PySideMetaSignalTypeF(void) +static PyTypeObject *PySideMetaSignalTypeF(void) { static PyTypeObject *type = nullptr; if (!type) { PyObject *bases = Py_BuildValue("(O)", &PyType_Type); - type = (PyTypeObject *)PyType_FromSpecWithBases(&PySideMetaSignalType_spec, bases); + type = (PyTypeObject *)SbkType_FromSpecWithBases(&PySideMetaSignalType_spec, bases); Py_XDECREF(bases); } return type; } static PyType_Slot PySideSignalType_slots[] = { - {Py_mp_subscript, (void *)signalGetItem}, - {Py_tp_call, (void *)signalCall}, - {Py_tp_str, (void *)signalToString}, - {Py_tp_init, (void *)signalTpInit}, - {Py_tp_new, (void *)PyType_GenericNew}, - {Py_tp_free, (void *)signalFree}, - {Py_tp_dealloc, (void *)object_dealloc}, + {Py_mp_subscript, reinterpret_cast<void *>(signalGetItem)}, + {Py_tp_descr_get, reinterpret_cast<void *>(signalDescrGet)}, + {Py_tp_call, reinterpret_cast<void *>(signalCall)}, + {Py_tp_str, reinterpret_cast<void *>(signalToString)}, + {Py_tp_init, reinterpret_cast<void *>(signalTpInit)}, + {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)}, + {Py_tp_free, reinterpret_cast<void *>(signalFree)}, + {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, {0, 0} }; static PyType_Spec PySideSignalType_spec = { - "PySide2.QtCore.Signal", + "2:PySide2.QtCore.Signal", sizeof(PySideSignal), 0, Py_TPFLAGS_DEFAULT, @@ -158,7 +160,7 @@ PyTypeObject *PySideSignalTypeF(void) { static PyTypeObject *type = nullptr; if (!type) { - type = (PyTypeObject *)PyType_FromSpec(&PySideSignalType_spec); + type = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(&PySideSignalType_spec)); PyTypeObject *hold = Py_TYPE(type); Py_TYPE(type) = PySideMetaSignalTypeF(); Py_INCREF(Py_TYPE(type)); @@ -175,17 +177,16 @@ static PyMethodDef SignalInstance_methods[] = { }; static PyType_Slot PySideSignalInstanceType_slots[] = { - //{Py_tp_as_mapping, (void *)&SignalInstance_as_mapping}, - {Py_mp_subscript, (void *)signalInstanceGetItem}, - {Py_tp_call, (void *)signalInstanceCall}, - {Py_tp_methods, (void *)SignalInstance_methods}, - {Py_tp_new, (void *)PyType_GenericNew}, - {Py_tp_free, (void *)signalInstanceFree}, - {Py_tp_dealloc, (void *)object_dealloc}, + {Py_mp_subscript, reinterpret_cast<void *>(signalInstanceGetItem)}, + {Py_tp_call, reinterpret_cast<void *>(signalInstanceCall)}, + {Py_tp_methods, reinterpret_cast<void *>(SignalInstance_methods)}, + {Py_tp_new, reinterpret_cast<void *>(PyType_GenericNew)}, + {Py_tp_free, reinterpret_cast<void *>(signalInstanceFree)}, + {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)}, {0, 0} }; static PyType_Spec PySideSignalInstanceType_spec = { - "PySide2.QtCore.SignalInstance", + "2:PySide2.QtCore.SignalInstance", sizeof(PySideSignalInstance), 0, Py_TPFLAGS_DEFAULT, @@ -196,11 +197,11 @@ static PyType_Spec PySideSignalInstanceType_spec = { PyTypeObject *PySideSignalInstanceTypeF(void) { static PyTypeObject *type = - (PyTypeObject *)PyType_FromSpec(&PySideSignalInstanceType_spec); + reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(&PySideSignalInstanceType_spec)); return type; } -int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) +static int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) { static PyObject *emptyTuple = nullptr; static const char *kwlist[] = {"name", "arguments", nullptr}; @@ -241,7 +242,7 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) for (Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) { PyObject *arg = PyTuple_GET_ITEM(args, i); - if (PySequence_Check(arg) && !Shiboken::String::check(arg)) { + if (PySequence_Check(arg) && !Shiboken::String::check(arg) && !PyEnumMeta_Check(arg)) { tupledArgs = true; const auto sig = PySide::Signal::parseSignature(arg); PySide::Signal::appendSignature( @@ -260,7 +261,7 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -void signalFree(void *self) +static void signalFree(void *self) { auto pySelf = reinterpret_cast<PyObject *>(self); auto data = reinterpret_cast<PySideSignal *>(self); @@ -272,7 +273,7 @@ void signalFree(void *self) Py_TYPE(pySelf)->tp_base->tp_free(self); } -PyObject *signalGetItem(PyObject *self, PyObject *key) +static PyObject *signalGetItem(PyObject *self, PyObject *key) { auto data = reinterpret_cast<PySideSignal *>(self); QByteArray sigKey; @@ -287,12 +288,12 @@ PyObject *signalGetItem(PyObject *self, PyObject *key) } -PyObject *signalToString(PyObject *self) +static PyObject *signalToString(PyObject *self) { return signalGetItem(self, 0); } -void signalInstanceFree(void *self) +static void signalInstanceFree(void *self) { auto pySelf = reinterpret_cast<PyObject *>(self); auto data = reinterpret_cast<PySideSignalInstance *>(self); @@ -310,7 +311,7 @@ void signalInstanceFree(void *self) Py_TYPE(pySelf)->tp_base->tp_free(self); } -PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) +static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *slot = nullptr; PyObject *type = nullptr; @@ -360,7 +361,7 @@ PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) if (isMethod || isFunction) { PyObject *function = isMethod ? PyMethod_GET_FUNCTION(slot) : slot; - PyCodeObject *objCode = reinterpret_cast<PyCodeObject *>(PyFunction_GET_CODE(function)); + auto *objCode = reinterpret_cast<PepCodeObject *>(PyFunction_GET_CODE(function)); useSelf = isMethod; slotArgs = PepCode_GET_FLAGS(objCode) & CO_VARARGS ? -1 : PepCode_GET_ARGCOUNT(objCode); if (useSelf) @@ -430,12 +431,12 @@ PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -int argCountInSignature(const char *signature) +static int argCountInSignature(const char *signature) { return QByteArray(signature).count(",") + 1; } -PyObject *signalInstanceEmit(PyObject *self, PyObject *args) +static PyObject *signalInstanceEmit(PyObject *self, PyObject *args) { PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self); @@ -474,7 +475,7 @@ PyObject *signalInstanceEmit(PyObject *self, PyObject *args) return PyObject_CallObject(pyMethod, tupleArgs); } -PyObject *signalInstanceGetItem(PyObject *self, PyObject *key) +static PyObject *signalInstanceGetItem(PyObject *self, PyObject *key) { auto data = reinterpret_cast<PySideSignalInstance *>(self); const auto sigName = data->d->signalName; @@ -494,7 +495,7 @@ PyObject *signalInstanceGetItem(PyObject *self, PyObject *key) return 0; } -PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args) +static PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args) { auto source = reinterpret_cast<PySideSignalInstance *>(self); Shiboken::AutoDecRef pyArgs(PyList_New(0)); @@ -547,7 +548,20 @@ PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args) return 0; } -PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) +// PYSIDE-68: Supply the missing __get__ function +static PyObject *signalDescrGet(PyObject *self, PyObject *obj, PyObject * /*type*/) +{ + auto signal = reinterpret_cast<PySideSignal *>(self); + // Return the unbound signal if there is nothing to bind it to. + if (obj == nullptr || obj == Py_None) { + Py_INCREF(self); + return self; + } + Shiboken::AutoDecRef name(Py_BuildValue("s", signal->data->signalName.data())); + return reinterpret_cast<PyObject *>(PySide::Signal::initialize(signal, name, obj)); +} + +static PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) { auto signal = reinterpret_cast<PySideSignal *>(self); @@ -567,7 +581,11 @@ PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) Shiboken::AutoDecRef homonymousMethod(getDescriptor(signal->homonymousMethod, 0, 0)); if (PyCFunction_Check(homonymousMethod) && (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC)) { +#if PY_VERSION_HEX >= 0x03090000 + return PyObject_Call(homonymousMethod, args, kw); +#else return PyCFunction_Call(homonymousMethod, args, kw); +#endif } // Assumes homonymousMethod is not a static method. @@ -575,7 +593,7 @@ PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw) return callFunc(homonymousMethod, args, kw); } -PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw) +static PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw) { auto PySideSignal = reinterpret_cast<PySideSignalInstance *>(self); if (!PySideSignal->d->homonymousMethod) { @@ -585,7 +603,11 @@ PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw) descrgetfunc getDescriptor = Py_TYPE(PySideSignal->d->homonymousMethod)->tp_descr_get; Shiboken::AutoDecRef homonymousMethod(getDescriptor(PySideSignal->d->homonymousMethod, PySideSignal->d->source, 0)); +#if PY_VERSION_HEX >= 0x03090000 + return PyObject_Call(homonymousMethod, args, kw); +#else return PyCFunction_Call(homonymousMethod, args, kw); +#endif } static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *arg) @@ -617,17 +639,17 @@ static const char *SignalInstance_SignatureStrings[] = { void init(PyObject *module) { - if (SbkSpecial_Type_Ready(module, PySideMetaSignalTypeF(), MetaSignal_SignatureStrings) < 0) + if (InitSignatureStrings(PySideMetaSignalTypeF(), MetaSignal_SignatureStrings) < 0) return; - Py_INCREF(PySideSignalTypeF()); + Py_INCREF(PySideMetaSignalTypeF()); PyModule_AddObject(module, "MetaSignal", reinterpret_cast<PyObject *>(PySideMetaSignalTypeF())); - if (SbkSpecial_Type_Ready(module, PySideSignalTypeF(), Signal_SignatureStrings) < 0) + if (InitSignatureStrings(PySideSignalTypeF(), Signal_SignatureStrings) < 0) return; Py_INCREF(PySideSignalTypeF()); PyModule_AddObject(module, "Signal", reinterpret_cast<PyObject *>(PySideSignalTypeF())); - if (SbkSpecial_Type_Ready(module, PySideSignalInstanceTypeF(), SignalInstance_SignatureStrings) < 0) + if (InitSignatureStrings(PySideSignalInstanceTypeF(), SignalInstance_SignatureStrings) < 0) return; Py_INCREF(PySideSignalInstanceTypeF()); PyModule_AddObject(module, "SignalInstance", reinterpret_cast<PyObject *>(PySideSignalInstanceTypeF())); @@ -679,6 +701,8 @@ QByteArray getTypeName(PyObject *type) return QByteArrayLiteral("double"); if (objType == &PyBool_Type) return QByteArrayLiteral("bool"); + if (objType == &PyList_Type) + return QByteArrayLiteral("QVariantList"); if (Py_TYPE(objType) == SbkEnumType_TypeF()) return Shiboken::Enum::getCppName(objType); return QByteArrayLiteral("PyObject"); @@ -694,12 +718,12 @@ QByteArray getTypeName(PyObject *type) return QByteArray(); } -QByteArray buildSignature(const QByteArray &name, const QByteArray &signature) +static QByteArray buildSignature(const QByteArray &name, const QByteArray &signature) { return QMetaObject::normalizedSignature(name + '(' + signature + ')'); } -QByteArray parseSignature(PyObject *args) +static QByteArray parseSignature(PyObject *args) { if (args && (Shiboken::String::check(args) || !PySequence_Check(args))) return getTypeName(args); @@ -717,22 +741,12 @@ QByteArray parseSignature(PyObject *args) return signature; } -void appendSignature(PySideSignal *self, const SignalSignature &signature) +static void appendSignature(PySideSignal *self, const SignalSignature &signature) { self->data->signatures.append({signature.m_parameterTypes, signature.m_attributes}); } -PySideSignalInstance *initialize(PySideSignal *self, PyObject *name, PyObject *object) -{ - PySideSignalInstance *instance = PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF()); - auto sbkObj = reinterpret_cast<SbkObject *>(object); - if (!Shiboken::Object::wasCreatedByPython(sbkObj)) - Py_INCREF(object); // PYSIDE-79: this flag was crucial for a wrapper call. - instanceInitialize(instance, name, self, object, 0); - return instance; -} - -void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal *data, PyObject *source, int index) +static void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal *data, PyObject *source, int index) { self->d = new PySideSignalInstancePrivate; PySideSignalInstancePrivate *selfPvt = self->d; @@ -758,6 +772,17 @@ void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal } } +PySideSignalInstance *initialize(PySideSignal *self, PyObject *name, PyObject *object) +{ + PySideSignalInstance *instance = PyObject_New(PySideSignalInstance, + PySideSignalInstanceTypeF()); + instanceInitialize(instance, name, self, object, 0); + auto sbkObj = reinterpret_cast<SbkObject *>(object); + if (!Shiboken::Object::wasCreatedByPython(sbkObj)) + Py_INCREF(object); // PYSIDE-79: this flag was crucial for a wrapper call. + return instance; +} + bool connect(PyObject *source, const char *signal, PyObject *callback) { Shiboken::AutoDecRef pyMethod(PyObject_GetAttr(source, @@ -804,32 +829,6 @@ PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMet return root; } -PySideSignal *newObject(const char *name, ...) -{ - va_list listSignatures; - char *sig = nullptr; - PySideSignal *self = PyObject_New(PySideSignal, PySideSignalTypeF()); - self->data = new PySideSignalData; - self->data->signalName = name; - self->homonymousMethod = 0; - - va_start(listSignatures, name); - sig = va_arg(listSignatures, char *); - - while (sig != NULL) { - if (strcmp(sig, "void") == 0) - appendSignature(self, SignalSignature("")); - else - appendSignature(self, SignalSignature(sig)); - - sig = va_arg(listSignatures, char *); - } - - va_end(listSignatures); - - return self; -} - template<typename T> static typename T::value_type join(T t, const char *sep) { @@ -867,6 +866,12 @@ static bool compareSignals(const SignalSignature &sig1, const SignalSignature &) return sig1.m_parameterTypes.isEmpty(); } +static PyObject *buildQtCompatible(const QByteArray &signature) +{ + const auto ba = QT_SIGNAL_SENTINEL + signature; + return Shiboken::String::fromStringAndSize(ba, ba.size()); +} + void registerSignals(SbkObjectType *pyObj, const QMetaObject *metaObject) { typedef QHash<QByteArray, QList<SignalSignature> > SignalSigMap; @@ -907,17 +912,6 @@ void registerSignals(SbkObjectType *pyObj, const QMetaObject *metaObject) } } -PyObject *buildQtCompatible(const QByteArray &signature) -{ - const auto ba = QT_SIGNAL_SENTINEL + signature; - return Shiboken::String::fromStringAndSize(ba, ba.size()); -} - -void addSignalToWrapper(SbkObjectType *wrapperType, const char *signalName, PySideSignal *signal) -{ - _addSignalToWrapper(wrapperType, signalName, signal); -} - PyObject *getObject(PySideSignalInstance *signal) { return signal->d->source; @@ -930,20 +924,22 @@ const char *getSignature(PySideSignalInstance *signal) QStringList getArgsFromSignature(const char *signature, bool *isShortCircuit) { - const QString qsignature = QLatin1String(signature); + QString qsignature = QString::fromLatin1(signature).trimmed(); QStringList result; - QRegExp splitRegex(QLatin1String("\\s*,\\s*")); if (isShortCircuit) *isShortCircuit = !qsignature.contains(QLatin1Char('(')); if (qsignature.contains(QLatin1String("()")) || qsignature.contains(QLatin1String("(void)"))) return result; - if (qsignature.contains(QLatin1Char('('))) { - static QRegExp regex(QLatin1String(".+\\((.*)\\)")); - //get args types - QString types = qsignature; - types.replace(regex, QLatin1String("\\1")); - result = types.split(splitRegex); + if (qsignature.endsWith(QLatin1Char(')'))) { + const int paren = qsignature.indexOf(QLatin1Char('(')); + if (paren >= 0) { + qsignature.chop(1); + qsignature.remove(0, paren + 1); + result = qsignature.split(QLatin1Char(',')); + for (QString &type : result) + type = type.trimmed(); + } } return result; } @@ -958,7 +954,7 @@ QString getCallbackSignature(const char *signal, QObject *receiver, PyObject *ca if (isMethod || isFunction) { PyObject *function = isMethod ? PyMethod_GET_FUNCTION(callback) : callback; - auto objCode = reinterpret_cast<PyCodeObject *>(PyFunction_GET_CODE(function)); + auto objCode = reinterpret_cast<PepCodeObject *>(PyFunction_GET_CODE(function)); functionName = Shiboken::String::toCString(PepFunction_GetName(function)); useSelf = isMethod; numArgs = PepCode_GET_FLAGS(objCode) & CO_VARARGS ? -1 : PepCode_GET_ARGCOUNT(objCode); |