aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/libpyside/dynamicqmetaobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside2/libpyside/dynamicqmetaobject.cpp')
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.cpp77
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);
+ }
}