diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-10-09 09:22:56 +0200 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-10-23 12:26:07 +0200 |
commit | 4d09403f7167afbee285155177e2c1c9e4857e14 (patch) | |
tree | 1f5b5895e1834c862e18ba33ac69b1073ffdf48f /sources/pyside6/libpyside/pysideclassinfo.cpp | |
parent | b77586da0e7041501c5456f229d1c80b68a78e64 (diff) |
QML registration code: Extract a setter from the ClassInfo decorator
Change it to operate on a list of key/value pairs instead of a QMap
(no use in enforcing sorting) and extract a setter for setting
QMetaClassInfo data on a PyTypeObject of a QObject.
To be used for QML decorators.
As a drive-by, fix some static analysis warnings about implicit bool
casts.
Task-number: PYSIDE-2484
Change-Id: Ia759bb42740ed279f36c0850306ebd9bee526ecf
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/pyside6/libpyside/pysideclassinfo.cpp')
-rw-r--r-- | sources/pyside6/libpyside/pysideclassinfo.cpp | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/sources/pyside6/libpyside/pysideclassinfo.cpp b/sources/pyside6/libpyside/pysideclassinfo.cpp index 2cecb0990..9ab5a7ad0 100644 --- a/sources/pyside6/libpyside/pysideclassinfo.cpp +++ b/sources/pyside6/libpyside/pysideclassinfo.cpp @@ -56,21 +56,14 @@ PyObject *ClassInfoPrivate::tp_call(PyObject *self, PyObject *args, PyObject * / return nullptr; } - bool validClass = false; - PyTypeObject *klassType = reinterpret_cast<PyTypeObject *>(klass); - if (auto userData = PySide::retrieveTypeUserData(klassType)) { - PySide::MetaObjectBuilder &mo = userData->mo; - mo.addInfo(pData->m_data); - pData->m_alreadyWrapped = true; - validClass = true; - } - - if (!validClass) { + if (!PySide::ClassInfo::setClassInfo(klassType, pData->m_data)) { PyErr_SetString(PyExc_TypeError, "This decorator can only be used on classes that are subclasses of QObject"); return nullptr; } + pData->m_alreadyWrapped = true; + Py_INCREF(klass); return klass; } @@ -79,7 +72,7 @@ int ClassInfoPrivate::tp_init(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *infoDict = nullptr; auto size = PyTuple_Size(args); - if (size == 1 && !kwds) { + if (size == 1 && kwds == nullptr) { PyObject *tmp = PyTuple_GET_ITEM(args, 0); if (PyDict_Check(tmp)) infoDict = tmp; @@ -87,7 +80,7 @@ int ClassInfoPrivate::tp_init(PyObject *self, PyObject *args, PyObject *kwds) infoDict = kwds; } - if (!infoDict) { + if (infoDict == nullptr) { PyErr_Format(PyExc_TypeError, "ClassInfo() takes either keyword argument(s) or " "a single dictionary argument"); return -1; @@ -95,15 +88,17 @@ int ClassInfoPrivate::tp_init(PyObject *self, PyObject *args, PyObject *kwds) auto *pData = DecoratorPrivate::get<ClassInfoPrivate>(self); - PyObject *key; - PyObject *value; + PyObject *key{}; + PyObject *value{}; Py_ssize_t pos = 0; // PyDict_Next causes a segfault if kwds is empty if (PyDict_Size(infoDict) > 0) { while (PyDict_Next(infoDict, &pos, &key, &value)) { if (Shiboken::String::check(key) && Shiboken::String::check(value)) { - pData->m_data[Shiboken::String::toCString(key)] = Shiboken::String::toCString(value); + ClassInfo info{Shiboken::String::toCString(key), + Shiboken::String::toCString(value)}; + pData->m_data.append(info); } else { PyErr_SetString(PyExc_TypeError, "All keys and values provided to ClassInfo() " "must be strings"); @@ -112,7 +107,7 @@ int ClassInfoPrivate::tp_init(PyObject *self, PyObject *args, PyObject *kwds) } } - return PyErr_Occurred() ? -1 : 0; + return PyErr_Occurred() != nullptr ? -1 : 0; } static const char *ClassInfo_SignatureStrings[] = { @@ -130,15 +125,38 @@ void init(PyObject *module) bool checkType(PyObject *pyObj) { - if (pyObj) - return PyType_IsSubtype(Py_TYPE(pyObj), PySideClassInfo_TypeF()); - return false; + return pyObj != nullptr + && PyType_IsSubtype(Py_TYPE(pyObj), PySideClassInfo_TypeF()) != 0; } -QMap<QByteArray, QByteArray> getMap(PyObject *obj) +ClassInfoList getClassInfoList(PyObject *decorator) { - auto *pData = PySide::ClassDecorator::DecoratorPrivate::get<ClassInfoPrivate>(obj); + auto *pData = PySide::ClassDecorator::DecoratorPrivate::get<ClassInfoPrivate>(decorator); return pData->m_data; } -} //namespace PySide::Property +bool setClassInfo(PyTypeObject *type, const QByteArray &key, + const QByteArray &value) +{ + auto *userData = PySide::retrieveTypeUserData(type); + const bool result = userData != nullptr; + if (result) { + PySide::MetaObjectBuilder &mo = userData->mo; + mo.addInfo(key, value); + } + return result; +} + +bool setClassInfo(PyTypeObject *type, const ClassInfoList &list) +{ + auto *userData = PySide::retrieveTypeUserData(type); + const bool result = userData != nullptr; + if (result) { + PySide::MetaObjectBuilder &mo = userData->mo; + for (const auto &info : list) + mo.addInfo(info.key.constData(), info.value.constData()); + } + return result; +} + +} //namespace PySide::ClassInfo |