aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/pyside.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/libpyside/pyside.cpp')
-rw-r--r--sources/pyside6/libpyside/pyside.cpp63
1 files changed, 52 insertions, 11 deletions
diff --git a/sources/pyside6/libpyside/pyside.cpp b/sources/pyside6/libpyside/pyside.cpp
index 6d85597e1..75b7262b4 100644
--- a/sources/pyside6/libpyside/pyside.cpp
+++ b/sources/pyside6/libpyside/pyside.cpp
@@ -319,6 +319,34 @@ void initQApp()
setDestroyQApplication(destroyQCoreApplication);
}
+static QByteArray _sigWithMangledName(const QByteArray &signature, bool mangle)
+{
+ if (!mangle)
+ return signature;
+ auto bracePos = signature.indexOf('(');
+ auto limit = bracePos >= 0 ? bracePos : signature.size();
+ if (limit < 3)
+ return signature;
+ QByteArray result;
+ result.reserve(signature.size() + 4);
+ for (auto i = 0; i < limit; ++i) {
+ const char c = signature.at(i);
+ if (std::isupper(c)) {
+ if (i > 0) {
+ if (std::isupper(signature.at(i - 1)))
+ return signature; // Give up at consecutive upper chars
+ result.append('_');
+ }
+ result.append(std::tolower(c));
+ } else {
+ result.append(c);
+ }
+ }
+ // Copy the rest after the opening brace (if any)
+ result.append(signature.mid(limit));
+ return result;
+}
+
PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *name)
{
PyObject *attr = PyObject_GenericGetAttr(self, name);
@@ -333,27 +361,38 @@ PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *nam
attr = value;
}
- //mutate native signals to signal instance type
+ // Mutate native signals to signal instance type
if (attr && PyObject_TypeCheck(attr, PySideSignal_TypeF())) {
- PyObject *signal = reinterpret_cast<PyObject *>(Signal::initialize(reinterpret_cast<PySideSignal *>(attr), name, self));
- PyObject_SetAttr(self, name, reinterpret_cast<PyObject *>(signal));
- return signal;
+ auto *inst = Signal::initialize(reinterpret_cast<PySideSignal *>(attr), name, self);
+ PyObject *signalInst = reinterpret_cast<PyObject *>(inst);
+ PyObject_SetAttr(self, name, signalInst);
+ return signalInst;
}
- //search on metaobject (avoid internal attributes started with '__')
+ // Search on metaobject (avoid internal attributes started with '__')
if (!attr) {
+ PyObject *type, *value, *traceback;
+ PyErr_Fetch(&type, &value, &traceback); // This was omitted for a loong time.
+
const char *cname = Shiboken::String::toCString(name);
+ int flags = SbkObjectType_GetReserved(Py_TYPE(self));
+ int snake_flag = flags & 0x01;
uint cnameLen = qstrlen(cname);
if (std::strncmp("__", cname, 2)) {
const QMetaObject *metaObject = cppSelf->metaObject();
- //signal
QList<QMetaMethod> signalList;
- for(int i=0, i_max = metaObject->methodCount(); i < i_max; i++) {
+ for (int i=0, imax = metaObject->methodCount(); i < imax; i++) {
QMetaMethod method = metaObject->method(i);
- const QByteArray methSig_ = method.methodSignature();
+ // PYSIDE-1753: Snake case names must be renamed here too, or they will be
+ // found unexpectedly when forgetting to rename them.
+ auto origSignature = method.methodSignature();
+ // Currently, we rename only methods but no signals. This might change.
+ bool use_lower = snake_flag and method.methodType() != QMetaMethod::Signal;
+ const QByteArray methSig_ = _sigWithMangledName(origSignature, use_lower);
const char *methSig = methSig_.constData();
- bool methMacth = !std::strncmp(cname, methSig, cnameLen) && methSig[cnameLen] == '(';
- if (methMacth) {
+ bool methMatch = std::strncmp(cname, methSig, cnameLen) == 0
+ && methSig[cnameLen] == '(';
+ if (methMatch) {
if (method.methodType() == QMetaMethod::Signal) {
signalList.append(method);
} else {
@@ -367,11 +406,13 @@ PyObject *getMetaDataFromQObject(QObject *cppSelf, PyObject *self, PyObject *nam
}
}
if (!signalList.isEmpty()) {
- PyObject *pySignal = reinterpret_cast<PyObject *>(Signal::newObjectFromMethod(self, signalList));
+ PyObject *pySignal = reinterpret_cast<PyObject *>(
+ Signal::newObjectFromMethod(self, signalList));
PyObject_SetAttr(self, name, pySignal);
return pySignal;
}
}
+ PyErr_Restore(type, value, traceback);
}
return attr;
}