diff options
Diffstat (limited to 'sources/pyside2/libpyside/dynamicqmetaobject.cpp')
-rw-r--r-- | sources/pyside2/libpyside/dynamicqmetaobject.cpp | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp index 857d242a2..2fbda3f6a 100644 --- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp +++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp @@ -44,6 +44,7 @@ #include "pysideproperty.h" #include "pysideproperty_p.h" #include "pysideslot_p.h" +#include "pysideqenum.h" #include <shiboken.h> @@ -91,6 +92,10 @@ public: int addProperty(const QByteArray &property, PyObject *data); void addInfo(const QByteArray &key, const QByteArray &value); void addInfo(const QMap<QByteArray, QByteArray> &info); + void addEnumerator(const char *name, + bool flag, + bool scoped, + const QVector<QPair<QByteArray, int> > &entries); void removeProperty(int index); const QMetaObject *update(); @@ -140,7 +145,8 @@ MetaObjectBuilder::MetaObjectBuilder(PyTypeObject *type, const QMetaObject *meta MetaObjectBuilder::~MetaObjectBuilder() { - qDeleteAll(m_d->m_cachedMetaObjects); + for (auto *metaObject : m_d->m_cachedMetaObjects) + free(const_cast<QMetaObject*>(metaObject)); delete m_d->m_builder; delete m_d; } @@ -356,6 +362,28 @@ void MetaObjectBuilder::addInfo(const QMap<QByteArray, QByteArray> &info) m_d->addInfo(info); } +void MetaObjectBuilder::addEnumerator(const char *name, bool flag, bool scoped, + const QVector<QPair<QByteArray, int> > &entries) +{ + m_d->addEnumerator(name, flag, scoped, entries); +} + +void MetaObjectBuilderPrivate::addEnumerator(const char *name, bool flag, bool scoped, + const QVector<QPair<QByteArray, int> > &entries) +{ + auto builder = ensureBuilder(); + int have_already = builder->indexOfEnumerator(name); + if (have_already >= 0) + builder->removeEnumerator(have_already); + auto enumbuilder = builder->addEnumerator(name); + enumbuilder.setIsFlag(flag); + enumbuilder.setIsScoped(scoped); + + for (auto item : entries) + enumbuilder.addKey(item.first, item.second); + m_dirty = true; +} + void MetaObjectBuilderPrivate::removeProperty(int index) { index -= m_baseObject->propertyCount(); @@ -413,6 +441,10 @@ const QMetaObject *MetaObjectBuilderPrivate::update() if (!m_builder) return m_baseObject; if (m_cachedMetaObjects.empty() || m_dirty) { + // PYSIDE-803: The dirty branch needs to be protected by the GIL. + // This was moved from SignalManager::retrieveMetaObject to here, + // which is only the update in "return builder->update()". + Shiboken::GilState gil; m_cachedMetaObjects.push_back(m_builder->toMetaObject()); checkMethodOrder(m_cachedMetaObjects.back()); m_dirty = false; @@ -425,6 +457,8 @@ const QMetaObject *MetaObjectBuilder::update() return m_d->update(); } +using namespace Shiboken; + void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) { // Get all non-QObject-derived base types in method resolution order, filtering out the types @@ -434,7 +468,7 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) // existing connections. const PyObject *mro = type->tp_mro; const Py_ssize_t basesCount = PyTuple_GET_SIZE(mro); - PyTypeObject *qObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*"); + PyTypeObject *qObjectType = Conversions::getPythonTypeObject("QObject*"); std::vector<PyTypeObject *> basesToCheck; // Prepend the actual type that we are parsing. @@ -464,7 +498,8 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) if (Signal::checkType(value)) { // Register signals. auto data = reinterpret_cast<PySideSignal *>(value); - data->data->signalName = Shiboken::String::toCString(key); + if (data->data->signalName.isEmpty()) + data->data->signalName = String::toCString(key); for (const auto &s : data->data->signatures) { const auto sig = data->data->signalName + '(' + s.signature + ')'; if (m_baseObject->indexOfSignal(sig) == -1) { @@ -483,7 +518,7 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) } } - Shiboken::AutoDecRef slotAttrName(Shiboken::String::fromCString(PYSIDE_SLOT_LIST_ATTR)); + AutoDecRef slotAttrName(String::fromCString(PYSIDE_SLOT_LIST_ATTR)); // PYSIDE-315: Now take care of the rest. // Signals and slots should be separated, unless the types are modified, later. // We check for this using "is_sorted()". Sorting no longer happens at all. @@ -495,16 +530,17 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) while (PyDict_Next(attrs, &pos, &key, &value)) { if (Property::checkType(value)) { - const int index = m_baseObject->indexOfProperty(Shiboken::String::toCString(key)); + const int index = m_baseObject->indexOfProperty(String::toCString(key)); if (index == -1) - addProperty(Shiboken::String::toCString(key), value); - } else if (PyFunction_Check(value)) { + addProperty(String::toCString(key), value); + } else if (Py_TYPE(value)->tp_call != nullptr) { + // PYSIDE-198: PyFunction_Check does not work with Nuitka. // Register slots. if (PyObject_HasAttr(value, slotAttrName)) { PyObject *signatureList = PyObject_GetAttr(value, slotAttrName); for (Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) { PyObject *pySignature = PyList_GET_ITEM(signatureList, i); - QByteArray signature(Shiboken::String::toCString(pySignature)); + QByteArray signature(String::toCString(pySignature)); // Split the slot type and its signature. QByteArray type; const int spacePos = signature.indexOf(' '); @@ -524,4 +560,29 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type) } } } + // PYSIDE-957: Collect the delayed QEnums + auto collectedEnums = PySide::QEnum::resolveDelayedQEnums(type); + for (PyObject *obEnumType : collectedEnums) { + bool isFlag = PySide::QEnum::isFlag(obEnumType); + AutoDecRef obName(PyObject_GetAttr(obEnumType, PyMagicName::name())); + // Everything has been checked already in resolveDelayedQEnums. + // Therefore, we don't need to error-check here again. + auto name = String::toCString(obName); + AutoDecRef members(PyObject_GetAttr(obEnumType, PyMagicName::members())); + AutoDecRef items(PepMapping_Items(members)); + Py_ssize_t nr_items = PySequence_Length(items); + + QVector<QPair<QByteArray, int> > entries; + for (Py_ssize_t idx = 0; idx < nr_items; ++idx) { + AutoDecRef item(PySequence_GetItem(items, idx)); + AutoDecRef key(PySequence_GetItem(item, 0)); + AutoDecRef member(PySequence_GetItem(item, 1)); + AutoDecRef value(PyObject_GetAttr(member, Shiboken::PyName::value())); + auto ckey = String::toCString(key); + auto ivalue = PyInt_AsSsize_t(value); // int/long cheating + auto thing = QPair<QByteArray, int>(ckey, int(ivalue)); + entries.push_back(thing); + } + addEnumerator(name, isFlag, true, entries); + } } |