diff --git a/generator/main.cpp b/generator/main.cpp index 621542f5..b9d12af9 100644 --- a/generator/main.cpp +++ b/generator/main.cpp @@ -217,7 +217,20 @@ namespace QRegularExpression re("#define\\s+QTCORE_VERSION\\s+0x([0-9a-f]+)", QRegularExpression::CaseInsensitiveOption); for (const QString &includeDir: getIncludeDirectories(commandLineIncludes)) { - QFileInfo fi(QDir(includeDir), "qtcoreversion.h"); + std::list candiate_paths; + candiate_paths.emplace_back("qtcoreversion.h"); + candiate_paths.emplace_back("QtCore/qtcoreversion.h"); + candiate_paths.emplace_back("QtCore.framework/Headers/qtcoreversion.h"); + QFileInfo fi(QDir(includeDir), QString("qtcoreversion.h")); + for (const std::string &candidate : candiate_paths) + { + QFileInfo candidate_fi(QDir(includeDir), candidate.c_str()); + if (candidate_fi.exists() && candidate_fi.isFile()) + { + fi = candidate_fi; + break; + } + } if (fi.exists()) { QString filePath = fi.absoluteFilePath(); diff --git a/generator/parser/name_compiler.cpp b/generator/parser/name_compiler.cpp index 2cc05060..ba5fbcd2 100644 --- a/generator/parser/name_compiler.cpp +++ b/generator/parser/name_compiler.cpp @@ -108,7 +108,7 @@ void NameCompiler::visitUnqualifiedName(UnqualifiedNameAST *node) // ### cleanup _M_name.last() += QLatin1String("<"); visitNodes(this, node->template_arguments); - _M_name.last().truncate(_M_name.last().count() - 1); // remove the last ',' + _M_name.last().truncate(_M_name.last().length() - 1); // remove the last ',' _M_name.last() += QLatin1String(">"); } diff --git a/generator/simplecpp/simplecpp.cpp b/generator/simplecpp/simplecpp.cpp index ee8f7f7c..b7c0ce71 100644 --- a/generator/simplecpp/simplecpp.cpp +++ b/generator/simplecpp/simplecpp.cpp @@ -3116,6 +3116,22 @@ static std::string getIncludePathFileName(const std::string &includePath, const return path + header; } +#ifdef __APPLE__ +static std::string get_apple_framework_relative_path(const std::string& header) +{ + std::string appleFrameworkHeader = {header}; + // try the Framework path on Mac, if there is a path in front + // ### what about escaped slashes? + size_t slashPos = appleFrameworkHeader.find('/'); + if (slashPos != std::string::npos) + { + constexpr auto framework_separator{ ".framework/Headers" }; + appleFrameworkHeader.insert(slashPos, framework_separator); + } + return appleFrameworkHeader; +} +#endif // __APPLE__ + static std::string openHeaderIncludePath(std::ifstream &f, const simplecpp::DUI &dui, const std::string &header) { for (std::list::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { @@ -3123,6 +3139,17 @@ static std::string openHeaderIncludePath(std::ifstream &f, const simplecpp::DUI if (!simplePath.empty()) return simplePath; } +#ifdef __APPLE__ + std::string appleFrameworkHeader = get_apple_framework_relative_path(header); + if (appleFrameworkHeader != header) + { + for (std::list::const_iterator it = dui.includePaths.begin(); it != dui.includePaths.end(); ++it) { + std::string simplePath = openHeader(f, getIncludePathFileName(*it, appleFrameworkHeader)); + if (!simplePath.empty()) + return simplePath; + } + } +#endif // __APPLE__ return ""; } diff --git a/generator/simplecpp/simplecpp.h b/generator/simplecpp/simplecpp.h index f5c69593..df2e7818 100644 --- a/generator/simplecpp/simplecpp.h +++ b/generator/simplecpp/simplecpp.h @@ -39,6 +39,9 @@ #endif namespace simplecpp { + + std::string get_apple_framework_relative_path(const std::string& header); + /** C code standard */ enum cstd_t { CUnknown=-1, C89, C99, C11, C17, C23 }; diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 95f5b3c7..80fc8240 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -102,7 +102,11 @@ void PythonQtClassInfo::setupCPPObject(const QByteArray& classname) { _isQObject = false; _wrappedClassName = classname; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + _metaTypeId = QMetaType::fromName(classname).id(); +#else _metaTypeId = QMetaType::type(classname); +#endif if (_metaTypeId == 0) { _metaTypeId = -1; } diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index ca131374..94342ad8 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -270,7 +270,11 @@ PyObject* PythonQtConv::convertQtValueToPythonInternal(int type, const void* dat default: // check if we have a QList of pointers, which we can circumvent with a QList if (info.isQList && (info.innerNamePointerCount == 1)) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static int id = QMetaType::fromName("QList").id(); +#else static int id = QMetaType::type("QList"); +#endif PythonQtArgumentFrame_ADD_VARIANT_VALUE_BY_ID(frame, id, ptr); // return the constData pointer that will be filled with the result value later on ptr = (void*)((QVariant*)ptr)->constData(); @@ -310,11 +314,17 @@ PyObject* PythonQtConv::convertQtValueToPythonInternal(int type, const void* dat void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject, PythonQtArgumentFrame* frame) { void* ptr = alreadyAllocatedCPPObject; - - static int penId = QMetaType::type("QPen"); - static int brushId = QMetaType::type("QBrush"); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static int penId = QMetaType::fromName("QPen").id(); + static int brushId = QMetaType::fromName("QBrush").id(); + static int cursorId = QMetaType::fromName("QCursor").id(); + static int colorId = QMetaType::fromName("QColor").id(); +#else + static int penId = QMetaType::type("QPen"); + static int brushId = QMetaType::type("QBrush"); static int cursorId = QMetaType::type("QCursor"); - static int colorId = QMetaType::type("QColor"); + static int colorId = QMetaType::type("QColor"); +#endif static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", nullptr); if (typeId == cursorId) { static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", nullptr); @@ -728,7 +738,11 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) { // check for QList case, where we will use a QList QVariant if (info.isQList && (info.innerNamePointerCount == 1)) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static int id = QMetaType::fromName("QList").id(); +#else static int id = QMetaType::type("QList"); +#endif if (!alreadyAllocatedCPPObject) { PythonQtArgumentFrame_ADD_VARIANT_VALUE_BY_ID_IF_NEEDED(alreadyAllocatedCPPObject, frame, id, ptr); ptr = (void*)((QVariant*)ptr)->constData(); @@ -1094,22 +1108,26 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) ) { // no special type requested if (val == nullptr) { - type = QVariant::Invalid; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + type = QMetaType::UnknownType; +#else + type = 0; // Equivalent to QVariant::Invalid or unregistered type +#endif } else if (PyBytes_Check(val)) { #ifdef PY3K // In Python 3, it is a ByteArray - type = QVariant::ByteArray; + type = QMetaType::QByteArray; #else // In Python 2, we need to use String, since it might be a string - type = QVariant::String; + type = QMetaType::QString; #endif } else if (PyUnicode_Check(val)) { - type = QVariant::String; + type = QMetaType::QString; } else if (val == Py_False || val == Py_True) { - type = QVariant::Bool; + type = QMetaType::Bool; #ifndef PY3K } else if (PyObject_TypeCheck(val, &PyInt_Type)) { - type = QVariant::Int; + type = QMetaType::Int; #endif } else if (PyLong_Check(val)) { // return int if the value fits into that range, @@ -1117,12 +1135,12 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) qint64 d = PyLong_AsLongLong(val); if (d > std::numeric_limits::max() || d < std::numeric_limits::min()) { - type = QVariant::LongLong; + type = QMetaType::LongLong; } else { - type = QVariant::Int; + type = QMetaType::Int; } } else if (PyFloat_Check(val)) { - type = QVariant::Double; + type = QMetaType::Double; } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) { PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val; // c++ wrapper, check if the class names of the c++ objects match @@ -1144,11 +1162,15 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) return v; } else if (val == Py_None) { // none is invalid - type = QVariant::Invalid; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + type = QMetaType::UnknownType; +#else + type = 0; // Equivalent to QVariant::Invalid or unregistered type +#endif } else if (PyDict_Check(val)) { - type = QVariant::Map; + type = QMetaType::QVariantMap; } else if (PyList_Check(val) || PyTuple_Check(val) || PySequence_Check(val)) { - type = QVariant::List; + type = QMetaType::QVariantList; } else { // transport the Python objects directly inside of QVariant: v = PythonQtObjectPtr(val).toVariant(); @@ -1157,28 +1179,32 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } // special type request: switch (type) { - case QVariant::Invalid: +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + case QMetaType::UnknownType: +#else + case 0: // Equivalent to QVariant::Invalid or unregistered type +#endif return v; break; - case QVariant::Int: + case QMetaType::Int: { int d = PyObjGetInt(val, false, ok); if (ok) return QVariant(d); } break; - case QVariant::UInt: + case QMetaType::UInt: { int d = PyObjGetInt(val, false,ok); if (ok) v = QVariant((unsigned int)d); } break; - case QVariant::Bool: + case QMetaType::Bool: { int d = PyObjGetBool(val,false,ok); if (ok) v = QVariant((bool)(d!=0)); } break; - case QVariant::Double: + case QMetaType::Double: { double d = PyObjGetDouble(val,false,ok); if (ok) v = QVariant(d); @@ -1239,7 +1265,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } break; - case QVariant::ByteArray: + case QMetaType::QByteArray: { bool ok; #ifdef PY3K @@ -1249,20 +1275,20 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) #endif } break; - case QVariant::String: + case QMetaType::QString: { bool ok; v = QVariant(PyObjGetString(val, false, ok)); } break; - case QVariant::Map: + case QMetaType::QVariantMap: pythonToMapVariant(val, v); break; - case QVariant::Hash: + case QMetaType::QVariantHash: pythonToMapVariant(val, v); break; - case QVariant::List: + case QMetaType::QVariantList: { bool isListOrTuple = PyList_Check(val) || PyTuple_Check(val); if (isListOrTuple || PySequence_Check(val)) { @@ -1288,7 +1314,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } } break; - case QVariant::StringList: + case QMetaType::QStringList: { bool ok; QStringList l = PyObjToStringList(val, false, ok); @@ -1308,7 +1334,11 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) // Try to convert the object to a QVariant based on the typeName bool ok; bool isPtr = false; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QByteArray typeName = QMetaType(type).name(); +#else QByteArray typeName = QMetaType::typeName(type); +#endif if (typeName.endsWith("*")) { isPtr = true; typeName.truncate(typeName.length() - 1); @@ -1323,7 +1353,7 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) } } } - } else if (static_cast(type) >= QVariant::UserType) { + } else if (static_cast(type) >= QMetaType::User) { // not an instance wrapper, but there might be other converters // Maybe we have a special converter that is registered for that type: PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(type); @@ -1505,66 +1535,66 @@ bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList(data); r = QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::SizeF: { + case QMetaType::QSizeF: { const QSizeF* s = static_cast(data); r = QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Point: { + case QMetaType::QPoint: { const QPoint* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); } break; - case QVariant::PointF: { + case QMetaType::QPointF: { const QPointF* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); } break; - case QVariant::Rect: { + case QMetaType::QRect: { const QRect* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); r += ", " + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::RectF: { + case QMetaType::QRectF: { const QRectF* s = static_cast(data); r = QString::number(s->x()) + ", " + QString::number(s->y()); r += ", " + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Date: { + case QMetaType::QDate: { const QDate* s = static_cast(data); r = s->toString(Qt::ISODate); } break; - case QVariant::DateTime: { + case QMetaType::QDateTime: { const QDateTime* s = static_cast(data); r = s->toString(Qt::ISODate); } break; - case QVariant::Time: { + case QMetaType::QTime: { const QTime* s = static_cast(data); r = s->toString(Qt::ISODate); } break; - case QVariant::Pixmap: + case QMetaType::QPixmap: { const QPixmap* s = static_cast(data); r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Image: + case QMetaType::QImage: { const QImage* s = static_cast(data); r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height()); } break; - case QVariant::Url: + case QMetaType::QUrl: { const QUrl* s = static_cast(data); r = s->toString(); @@ -1574,7 +1604,7 @@ QString PythonQtConv::CPPObjectToString(int type, const void* data) { default: // this creates a copy, but that should not be expensive for typical simple variants // (but we do not want to do this for our own user types!) - if (type>0 && type < (int)QVariant::UserType) { + if (type>0 && type < (int)QMetaType::User) { r = variantFromType(type, data).toString(); } } @@ -1584,13 +1614,19 @@ QString PythonQtConv::CPPObjectToString(int type, const void* data) { PyObject* PythonQtConv::createCopyFromMetaType( int type, const void* data ) { // if the type is known, we can construct it via QMetaType::construct -#if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) ) - void* newCPPObject = QMetaType::create(type, data); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + void* newCPPObject = QMetaType(type).create(data); + // XXX this could be optimized by using metatypeid directly + PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType(type).name()); +#elif QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + void* newCPPObject = QMetaType::create(type, data); + // XXX this could be optimized by using metatypeid directly + PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type)); #else - void* newCPPObject = QMetaType::construct(type, data); -#endif + void* newCPPObject = QMetaType::construct(type, data); // XXX this could be optimized by using metatypeid directly PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type)); +#endif wrap->_ownedByPythonQt = true; wrap->_useQMetaTypeDestroy = true; return (PyObject*)wrap; diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index d0f0eeb1..da991505 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -237,9 +237,15 @@ template PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* /*QList* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; +#else static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; +#endif } PyObject* result = PyTuple_New(list->size()); int i = 0; @@ -254,9 +260,15 @@ template bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* /*QList* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; +#else static const int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; +#endif } bool result = false; if (PySequence_Check(obj)) { @@ -287,10 +299,17 @@ template PyObject* PythonQtConvertListOfKnownClassToPythonList(const void* /*QList* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QMetaType(metaTypeId).name())); + if (innerType == nullptr) { + std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType(metaTypeId).name() << std::endl; + } +#else static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(QMetaType::typeName(metaTypeId)))); if (innerType == nullptr) { std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyTuple_New(list->size()); int i = 0; Q_FOREACH(const T& value, *list) { @@ -307,10 +326,17 @@ template bool PythonQtConvertPythonListToListOfKnownClass(PyObject* obj, void* /*QList* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QMetaType(metaTypeId).name())); + if (innerType == nullptr) { + std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType(metaTypeId).name() << std::endl; + } +#else static PythonQtClassInfo* innerType = PythonQt::priv()->getClassInfo(PythonQtMethodInfo::getInnerListTypeName(QByteArray(QMetaType::typeName(metaTypeId)))); if (innerType == nullptr) { std::cerr << "PythonQtConvertListOfKnownClassToPythonList: unknown inner type for " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -350,14 +376,27 @@ PyObject* PythonQtConvertPairToPython(const void* /*QPair* */ inPair, int static int innerType1 = -1; static int innerType2 = -1; if (innerType1==-1) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType1 = QMetaType::fromName(names.at(0).trimmed()).id(); + innerType2 = QMetaType::fromName(names.at(1).trimmed()).id(); +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType1 = QMetaType::type(names.at(0).trimmed()); innerType2 = QMetaType::type(names.at(1).trimmed()); +#endif } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPairToPython: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { std::cerr << "PythonQtConvertPairToPython: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyTuple_New(2); PyTuple_SET_ITEM(result, 0, PythonQtConv::convertQtValueToPythonInternal(innerType1, &pair->first)); PyTuple_SET_ITEM(result, 1, PythonQtConv::convertQtValueToPythonInternal(innerType2, &pair->second)); @@ -371,14 +410,27 @@ bool PythonQtConvertPythonToPair(PyObject* obj, void* /*QPair* */ outPair static int innerType1 = -1; static int innerType2 = -1; if (innerType1 == -1) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType1 = QMetaType::fromName(names.at(0).trimmed()).id(); + innerType2 = QMetaType::fromName(names.at(1).trimmed()).id(); +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType1 = QMetaType::type(names.at(0).trimmed()); innerType2 = QMetaType::type(names.at(1).trimmed()); +#endif + } +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (innerType1 == QMetaType::UnknownType || innerType2 == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; } +#else if (innerType1 == QVariant::Invalid || innerType2 == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonToPair: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -416,10 +468,17 @@ template PyObject* PythonQtConvertListOfPairToPythonList(const void* /*QList >* */ inList, int metaTypeId) { ListType* list = (ListType*)inList; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertListOfPairToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyTuple_New(list->size()); int i = 0; typedef const QPair Pair; @@ -435,10 +494,17 @@ template bool PythonQtConvertPythonListToListOfPair(PyObject* obj, void* /*QList >* */ outList, int metaTypeId, bool /*strict*/) { ListType* list = (ListType*)outList; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QMetaType(metaTypeId).name()); + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else static int innerType = PythonQtMethodInfo::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId))); if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonListToListOfPair: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PySequence_Check(obj)) { int count = PySequence_Size(obj); @@ -470,6 +536,15 @@ PyObject* PythonQtConvertIntegerMapToPython(const void* /*QMap* */ inMap MapType* map = (MapType*)inMap; static int innerType = -1; if (innerType == -1) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType = QMetaType::fromName(names.at(1).trimmed()).id(); + } + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType = QMetaType::type(names.at(1).trimmed()); @@ -477,6 +552,7 @@ PyObject* PythonQtConvertIntegerMapToPython(const void* /*QMap* */ inMap if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertIntegerMapToPython: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif PyObject* result = PyDict_New(); typename MapType::const_iterator t = map->constBegin(); @@ -498,6 +574,15 @@ bool PythonQtConvertPythonToIntegerMap(PyObject* val, void* /*QMap* */ o MapType* map = (MapType*)outMap; static int innerType = -1; if (innerType == -1) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QMetaType(metaTypeId).name()); + QList names = innerTypes.split(','); + innerType = QMetaType::fromName(names.at(1).trimmed()).id(); + } + if (innerType == QMetaType::UnknownType) { + std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << QMetaType(metaTypeId).name() << std::endl; + } +#else QByteArray innerTypes = PythonQtMethodInfo::getInnerTemplateTypeName(QByteArray(QMetaType::typeName(metaTypeId))); QList names = innerTypes.split(','); innerType = QMetaType::type(names.at(1).trimmed()); @@ -505,6 +590,7 @@ bool PythonQtConvertPythonToIntegerMap(PyObject* val, void* /*QMap* */ o if (innerType == QVariant::Invalid) { std::cerr << "PythonQtConvertPythonToIntegerMap: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl; } +#endif bool result = false; if (PyMapping_Check(val)) { result = true; diff --git a/src/PythonQtInstanceWrapper.cpp b/src/PythonQtInstanceWrapper.cpp index aff024fa..08349191 100644 --- a/src/PythonQtInstanceWrapper.cpp +++ b/src/PythonQtInstanceWrapper.cpp @@ -70,7 +70,11 @@ static void PythonQtInstanceWrapper_deleteObject(PythonQtInstanceWrapper* self, int type = self->classInfo()->metaTypeId(); if (self->_useQMetaTypeDestroy && type>=0) { // use QMetaType to destroy the object - QMetaType::destroy(type, self->_wrappedPtr); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QMetaType(type).destroy(self->_wrappedPtr); +#else + QMetaType::destroy(type, self->_wrappedPtr); +#endif } else { PythonQtSlotInfo* slot = self->classInfo()->destructor(); if (slot) { @@ -82,7 +86,11 @@ static void PythonQtInstanceWrapper_deleteObject(PythonQtInstanceWrapper* self, } else { if (type>=0) { // use QMetaType to destroy the object +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QMetaType(type).destroy(self->_wrappedPtr); +#else QMetaType::destroy(type, self->_wrappedPtr); +#endif } else { // TODO: warn about not being able to destroy the object? } @@ -484,8 +492,11 @@ static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) switch (member._type) { case PythonQtMemberInfo::Property: if (wrapper->_obj) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (member._property.userType() != QMetaType::UnknownType) { +#else if (member._property.userType() != QVariant::Invalid) { - +#endif PythonQt::ProfilingCB* profilingCB = PythonQt::priv()->profilingCB(); if (profilingCB) { QString methodName = "getProperty('"; @@ -764,7 +775,11 @@ static PyObject * PythonQtInstanceWrapper_str(PyObject * obj) PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; // QByteArray should be directly returned as a str - if (wrapper->classInfo()->metaTypeId()==QVariant::ByteArray) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (wrapper->classInfo()->metaTypeId() == QMetaType::QByteArray) { +#else + if (wrapper->classInfo()->metaTypeId() == QVariant::ByteArray) { +#endif QByteArray* b = (QByteArray*) wrapper->_wrappedPtr; #ifdef PY3K // Note: In Python 2, this was used to access the data() of a byte array. diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index f428ce5f..853d0d48 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -191,7 +191,11 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray type.typeId = nameToType(name); if (type.typeId == Unknown) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + type.typeId = QMetaType::fromName(name.constData()).id(); +#else type.typeId = QMetaType::type(name.constData()); +#endif #if( QT_VERSION >= QT_VERSION_CHECK(5,0,0) ) if (type.typeId == QMetaType::UnknownType) { #else @@ -234,7 +238,11 @@ int PythonQtMethodInfo::getInnerTemplateMetaType(const QByteArray& typeName) int idx2 = typeName.lastIndexOf(">"); if (idx2 > 0) { QByteArray innerType = typeName.mid(idx + 1, idx2 - idx - 1).trimmed(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return QMetaType::fromName(innerType.constData()).id(); +#else return QMetaType::type(innerType.constData()); +#endif } } return QMetaType::Void; @@ -442,7 +450,11 @@ const PythonQtMethodInfo::ParameterInfo& PythonQtMethodInfo::getParameterInfoFor return it.value(); } ParameterInfo info; - fillParameterInfo(info, QMetaType::typeName(type)); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + fillParameterInfo(info, QMetaType(type).name()); +#else + fillParameterInfo(info, QMetaType::typeName(type)); +#endif _cachedParameterInfos.insert(type, info); return _cachedParameterInfos[type]; } diff --git a/src/PythonQtSignal.cpp b/src/PythonQtSignal.cpp index 04e19fee..ebaf0e9f 100644 --- a/src/PythonQtSignal.cpp +++ b/src/PythonQtSignal.cpp @@ -365,7 +365,18 @@ meth_hash(PythonQtSignalFunctionObject *a) if (x == -1) return -1; } +#if PY_VERSION_HEX >= 0x30D0000 /* 0x30D0000 == 3.13.0a0 */ + y = Py_HashPointer((void*)(a->m_ml)); /* public in 3.13+ */ +#elif !defined(Py_LIMITED_API) + /* fallback: use CPython’s private helper (requires full API) */ y = _Py_HashPointer((void*)(a->m_ml)); +#else + /* portable fallback for the limited/stable ABI */ + uintptr_t v = (uintptr_t)(void*)(a->m_ml); + /* simple mixing, similar to CPython’s */ + Py_hash_t y = (Py_hash_t)(v >> 4) ^ (Py_hash_t)(v >> (sizeof(v)*4)); + if (y == -1) y = -2; /* never return −1 */ +#endif if (y == -1) return -1; x ^= y; diff --git a/src/PythonQtSlot.cpp b/src/PythonQtSlot.cpp index 2fc077e4..39fc7a31 100644 --- a/src/PythonQtSlot.cpp +++ b/src/PythonQtSlot.cpp @@ -553,7 +553,7 @@ meth_get__doc__(PythonQtSlotFunctionObject * m, void * /*closure*/) } else if (returnType.startsWith("QHash<") || returnType.startsWith("QMap<") || returnType == "QVariantMap" || returnType == "QVariantHash") { pyReturnType = "dict"; - } else if (returnTypeId == QVariant::Bool) { + } else if (returnTypeId == QMetaType::Bool) { pyReturnType = "bool"; } else if (returnTypeId == PythonQtMethodInfo::Variant) { pyReturnType = "object"; @@ -772,6 +772,18 @@ meth_hash(PythonQtSlotFunctionObject *a) return -1; } y = _Py_HashPointer((void*)(a->m_ml)); +#if PY_VERSION_HEX >= 0x30D0000 /* 0x30D0000 == 3.13.0a0 */ + y = Py_HashPointer((void*)(a->m_ml)); /* public in 3.13+ */ +#elif !defined(Py_LIMITED_API) + /* fallback: use CPython’s private helper (requires full API) */ + y = _Py_HashPointer((void*)(a->m_ml)); +#else + /* portable fallback for the limited/stable ABI */ + uintptr_t v = (uintptr_t)(void*)(a->m_ml); + /* simple mixing, similar to CPython’s */ + Py_hash_t y = (Py_hash_t)(v >> 4) ^ (Py_hash_t)(v >> (sizeof(v)*4)); + if (y == -1) y = -2; /* never return −1 */ +#endif if (y == -1) return -1; x ^= y;