diff options
11 files changed, 77 insertions, 35 deletions
diff --git a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml index e4b39ed0a..f001178cc 100644 --- a/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml +++ b/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml @@ -1777,8 +1777,8 @@ <include file-name="QList" location="global"/> <!-- Expose operator==, != inherited from QList, which the parser does not see due to the TMP expression of the return type. --> - <add-function signature="operator==(const QItemSelection&)" return-type="bool"/> - <add-function signature="operator!=(const QItemSelection&)" return-type="bool"/> + <declare-function signature="operator==(const QItemSelection&)" return-type="bool"/> + <declare-function signature="operator!=(const QItemSelection&)" return-type="bool"/> <!-- For some reason, the empty selection is not seen. Maybe related to the new [default] tag in Qt6? PYSIDE-2756: The return-type attribute is unnecessary --> @@ -3173,8 +3173,8 @@ <modify-function signature="operator+=(QVector<QXmlStreamAttribute>)" remove="all"/> <!-- Expose operator==, != inherited from QList, which the parser does not see due to the TMP expression of the return type. --> - <add-function signature="operator==(const QXmlStreamAttributes&)" return-type="bool"/> - <add-function signature="operator!=(const QXmlStreamAttributes&)" return-type="bool"/> + <declare-function signature="operator==(const QXmlStreamAttributes&)" return-type="bool"/> + <declare-function signature="operator!=(const QXmlStreamAttributes&)" return-type="bool"/> </value-type> <value-type name="QXmlStreamNamespaceDeclaration"/> <value-type name="QXmlStreamNotationDeclaration"/> diff --git a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml index 5192c7120..e7cdb5c0e 100644 --- a/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml +++ b/sources/pyside6/PySide6/QtGui/typesystem_gui_common.xml @@ -464,8 +464,8 @@ </extra-includes> <!-- Expose operator==, != inherited from QList, which the parser does not see due to the TMP expression of the return type. --> - <add-function signature="operator==(const QPolygon&)" return-type="bool"/> - <add-function signature="operator!=(const QPolygon&)" return-type="bool"/> + <declare-function signature="operator==(const QPolygon&)" return-type="bool"/> + <declare-function signature="operator!=(const QPolygon&)" return-type="bool"/> <add-function signature="__reduce__" return-type="str"> <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qpolygon-reduce"> @@ -494,8 +494,8 @@ </extra-includes> <!-- Expose operator==, != inherited from QList, which the parser does not see due to the TMP expression of the return type. --> - <add-function signature="operator==(const QPolygonF&)" return-type="bool"/> - <add-function signature="operator!=(const QPolygonF&)" return-type="bool"/> + <declare-function signature="operator==(const QPolygonF&)" return-type="bool"/> + <declare-function signature="operator!=(const QPolygonF&)" return-type="bool"/> <!-- ### A QList parameter, for no defined type, will generate wrong code. --> <modify-function signature="operator+=(QList<QPointF>)" remove="all"/> diff --git a/sources/pyside6/doc/building_from_source/index.rst b/sources/pyside6/doc/building_from_source/index.rst index 3899f4361..a20143726 100644 --- a/sources/pyside6/doc/building_from_source/index.rst +++ b/sources/pyside6/doc/building_from_source/index.rst @@ -484,7 +484,7 @@ The target executes several steps: #. ``sphinx`` is run to produce the documentation in HTML format. Re-running the command will not execute step 1 unless the file -``qdoc-output/webxml/qtcore-index.webxml`` is removed from the build tree. +``qdoc-output/qtcore/webxml/qtcore-index.webxml`` is removed from the build tree. Similarly, step 2 will not be executed unless the file ``base/PySide6/QtCore/index.rst`` is removed. diff --git a/sources/pyside6/libpyside/pyside6.pc.in b/sources/pyside6/libpyside/pyside6.pc.in index eb45cb9a8..65822e6ec 100644 --- a/sources/pyside6/libpyside/pyside6.pc.in +++ b/sources/pyside6/libpyside/pyside6.pc.in @@ -1,7 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ libdir=@LIB_INSTALL_DIR@ -includedir=@CMAKE_INSTALL_PREFIX@/include/PySide6@pyside6_SUFFIX@ +includedir=@CMAKE_INSTALL_PREFIX@/PySide6@pyside6_SUFFIX@/include typesystemdir=@CMAKE_INSTALL_PREFIX@/share/PySide6@pyside6_SUFFIX@/typesystems gluedir=@CMAKE_INSTALL_PREFIX@/share/PySide6@pyside6_SUFFIX@/glue pythonpath=@PYTHON_SITE_PACKAGES@ diff --git a/sources/pyside6/libpyside/pysideproperty.cpp b/sources/pyside6/libpyside/pysideproperty.cpp index 9df584df7..3d1968045 100644 --- a/sources/pyside6/libpyside/pysideproperty.cpp +++ b/sources/pyside6/libpyside/pysideproperty.cpp @@ -208,10 +208,38 @@ void PySidePropertyPrivate::metaCall(PyObject *source, QMetaObject::Call call, v } } -static PyObject *qpropertyTpNew(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */) +// Helpers & name for passing the the PySidePropertyPrivate +// as a capsule when constructing. +static const char dataCapsuleName[] = "PropertyPrivate"; +static const char dataCapsuleKeyName[] = "_PropertyPrivate"; // key in keyword args + +static PySidePropertyPrivate *getDataFromKwArgs(PyObject *kwds) +{ + if (kwds != nullptr && PyDict_Check(kwds) != 0) { + static PyObject *key = PyUnicode_InternFromString(dataCapsuleKeyName); + if (PyDict_Contains(kwds, key) != 0) { + Shiboken::AutoDecRef data(PyDict_GetItem(kwds, key)); + if (PyCapsule_CheckExact(data.object()) != 0) { + if (void *p = PyCapsule_GetPointer(data.object(), dataCapsuleName)) + return reinterpret_cast<PySidePropertyPrivate *>(p); + } + } + } + return nullptr; +} + +static void addDataCapsuleToKwArgs(const AutoDecRef &kwds, PySidePropertyPrivate *data) +{ + auto *capsule = PyCapsule_New(data, dataCapsuleName, nullptr); + PyDict_SetItemString(kwds.object(), dataCapsuleKeyName, capsule); +} + +static PyObject *qpropertyTpNew(PyTypeObject *subtype, PyObject * /* args */, PyObject *kwds) { auto *me = PepExt_TypeCallAlloc<PySideProperty>(subtype, 0); - me->d = new PySidePropertyPrivate; + me->d = getDataFromKwArgs(kwds); + if (me->d == nullptr) + me->d = new PySidePropertyPrivate; return reinterpret_cast<PyObject *>(me); } @@ -222,21 +250,23 @@ static int qpropertyTpInit(PyObject *self, PyObject *args, PyObject *kwds) static const char *kwlist[] = {"type", "fget", "fset", "freset", "fdel", "doc", "notify", "designable", "scriptable", "stored", - "user", "constant", "final", nullptr}; + "user", "constant", "final", dataCapsuleKeyName, nullptr}; char *doc{}; PyObject *type{}, *fget{}, *fset{}, *freset{}, *fdel{}, *notify{}; + PyObject *dataCapsule{}; bool designable{true}, scriptable{true}, stored{true}; bool user{false}, constant{false}, finalProp{false}; if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|OOOOsObbbbbb:QtCore.Property", + "O|OOOOsObbbbbbO:QtCore.Property", const_cast<char **>(kwlist), /*OO*/ &type, &fget, /*OOO*/ &fset, &freset, &fdel, /*s*/ &doc, /*O*/ ¬ify, /*bbb*/ &designable, &scriptable, &stored, - /*bbb*/ &user, &constant, &finalProp)) { + /*bbb*/ &user, &constant, &finalProp, + /*O*/ &dataCapsule)) { return -1; } @@ -614,10 +644,13 @@ PyObject *getTypeObject(const PySideProperty *self) } PyObject *create(const char *typeName, PyObject *getter, - PyObject *setter, PyObject *notifySignature) + PyObject *setter, PyObject *notifySignature, + PySidePropertyPrivate *data) { Shiboken::AutoDecRef kwds(PyDict_New()); PyDict_SetItemString(kwds.object(), "type", PyUnicode_FromString(typeName)); + if (data != nullptr) + addDataCapsuleToKwArgs(kwds, data); if (getter != nullptr && getter != Py_None) PyDict_SetItemString(kwds.object(), "fget", getter); if (setter != nullptr && getter != Py_None) @@ -635,12 +668,13 @@ PyObject *create(const char *typeName, PyObject *getter, } PyObject *create(const char *typeName, PyObject *getter, - PyObject *setter, const char *notifySignature) + PyObject *setter, const char *notifySignature, + PySidePropertyPrivate *data) { PyObject *obNotifySignature = notifySignature != nullptr ? PyUnicode_FromString(notifySignature) : nullptr; - PyObject *result = create(typeName, getter, setter, obNotifySignature); + PyObject *result = create(typeName, getter, setter, obNotifySignature, data); Py_XDECREF(obNotifySignature); return result; } diff --git a/sources/pyside6/libpyside/pysideproperty.h b/sources/pyside6/libpyside/pysideproperty.h index 897da6ac2..90c40e174 100644 --- a/sources/pyside6/libpyside/pysideproperty.h +++ b/sources/pyside6/libpyside/pysideproperty.h @@ -70,11 +70,13 @@ PYSIDE_API void setTypeName(PySideProperty *self, const char *typeName); /// Create a property from type, getter, setter and notification signature. PYSIDE_API PyObject *create(const char *typeName, PyObject *getter, - PyObject *setter, PyObject *notifySignature); + PyObject *setter, PyObject *notifySignature, + PySidePropertyPrivate *data = nullptr); /// Create a property from type, getter, optional setter and notification signature. PYSIDE_API PyObject *create(const char *typeName, PyObject *getter, PyObject *setter = nullptr, - const char *notifySignature = nullptr); + const char *notifySignature = nullptr, + PySidePropertyPrivate *data = nullptr); } //namespace PySide::Property diff --git a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml index 55309ab04..fed84ba0d 100644 --- a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml +++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml @@ -120,7 +120,7 @@ </conversion-rule> </primitive-type> - <primitive-type name="std::optional<long>" target-langapi-name="PyObject"> + <primitive-type name="std::optional<long>"> <conversion-rule> <native-to-target> if (!%in.has_value()) diff --git a/sources/shiboken6_generator/generator/generator.cpp b/sources/shiboken6_generator/generator/generator.cpp index 314cee227..2db73ca0b 100644 --- a/sources/shiboken6_generator/generator/generator.cpp +++ b/sources/shiboken6_generator/generator/generator.cpp @@ -376,6 +376,12 @@ QString Generator::getFullTypeName(const AbstractMetaClassCPtr &metaClass) return metaClass->isTypeDef() ? qualName : addGlobalScopePrefix(qualName); } +QString Generator::getFullTypeName(const GeneratorContext &classContext) +{ + return classContext.forSmartPointer() + ? getFullTypeName(classContext.preciseType()) : getFullTypeName(classContext.metaClass()); +} + QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type) { if (type.isCString()) diff --git a/sources/shiboken6_generator/generator/generator.h b/sources/shiboken6_generator/generator/generator.h index 9963ed718..46397b3c2 100644 --- a/sources/shiboken6_generator/generator/generator.h +++ b/sources/shiboken6_generator/generator/generator.h @@ -170,6 +170,7 @@ protected: static QString getFullTypeName(TypeEntryCPtr type); static QString getFullTypeName(const AbstractMetaType &type); static QString getFullTypeName(const AbstractMetaClassCPtr &metaClass); + static QString getFullTypeName(const GeneratorContext &classContext); /** * Returns the full qualified C++ name for an AbstractMetaType, but removing modifiers diff --git a/sources/shiboken6_generator/generator/shiboken/cppgenerator.cpp b/sources/shiboken6_generator/generator/shiboken/cppgenerator.cpp index f713ad2ca..4854ebf79 100644 --- a/sources/shiboken6_generator/generator/shiboken/cppgenerator.cpp +++ b/sources/shiboken6_generator/generator/shiboken/cppgenerator.cpp @@ -1769,16 +1769,19 @@ void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMeta s << '\n'; } -static void writePointerToPythonConverter(TextStream &c, - const AbstractMetaClassCPtr &metaClass, - const QString &typeName, - const QString &cpythonType) +void CppGenerator::writePointerToPythonConverter(TextStream &c, + const GeneratorContext &context, + const QString &cpythonType) { + const auto &metaClass = context.metaClass(); c << "auto *pyOut = reinterpret_cast<PyObject *>(" << retrieveWrapper(metaClass, "cppIn") << ");\n" << "if (pyOut) {\n" << indent << "Py_INCREF(pyOut);\nreturn pyOut;\n" << outdent << "}\n"; + QString instanceCast = "auto *tCppIn = reinterpret_cast<const "_L1 + getFullTypeName(context) + + " *>(cppIn);\n"_L1; + const QString nameFunc = metaClass->typeEntry()->polymorphicNameFunction(); if (nameFunc.isEmpty() && !metaClass->hasVirtualDestructor()) { c << "return Shiboken::Object::newObjectWithHeuristics(" @@ -1786,8 +1789,7 @@ static void writePointerToPythonConverter(TextStream &c, return; } - c << "auto *tCppIn = reinterpret_cast<const " << typeName << R"( *>(cppIn); -const char *typeName = )"; + c << instanceCast << "const char *typeName = "; if (nameFunc.isEmpty()) c << "typeid(*tCppIn).name();\n"; else @@ -1819,13 +1821,8 @@ void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClas if (metaClass->isNamespace()) return; - QString typeName; - if (!classContext.forSmartPointer()) - typeName = getFullTypeName(metaClass); - else - typeName = getFullTypeName(classContext.preciseType()); - - QString cpythonType = cpythonTypeName(metaClass); + const QString typeName = getFullTypeName(classContext); + const QString cpythonType = cpythonTypeName(metaClass); // Returns the C++ pointer of the Python wrapper. s << "// Python to C++ pointer conversion - returns the C++ object of the Python wrapper (keeps object identity).\n"; @@ -1848,7 +1845,7 @@ void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClas c << "return PySide::getWrapperForQObject(reinterpret_cast<" << typeName << " *>(const_cast<void *>(cppIn)), " << cpythonType << ");\n"; } else { - writePointerToPythonConverter(c, metaClass, typeName, cpythonType); + writePointerToPythonConverter(c, classContext, cpythonType); } std::swap(targetTypeName, sourceTypeName); writeCppToPythonFunction(s, c.toString(), sourceTypeName, targetTypeName); diff --git a/sources/shiboken6_generator/generator/shiboken/cppgenerator.h b/sources/shiboken6_generator/generator/shiboken/cppgenerator.h index 0729b24f6..7142284e7 100644 --- a/sources/shiboken6_generator/generator/shiboken/cppgenerator.h +++ b/sources/shiboken6_generator/generator/shiboken/cppgenerator.h @@ -106,6 +106,8 @@ private: static void writeMetaCast(TextStream &s, const GeneratorContext &classContext); void writeEnumConverterFunctions(TextStream &s, const AbstractMetaEnum &metaEnum) const; + static void writePointerToPythonConverter(TextStream &c, const GeneratorContext &context, + const QString &cpythonType); void writeConverterFunctions(TextStream &s, const AbstractMetaClassCPtr &metaClass, const GeneratorContext &classContext) const; void writeCustomConverterFunctions(TextStream &s, |
