From e52ebf296e8fcd84fa4055c80a3c489ae1431c9e Mon Sep 17 00:00:00 2001 From: Andreas Beckermann Date: Thu, 12 Sep 2019 15:10:46 +0200 Subject: Add support for __repr__ in QObject derived classes Currently shiboken generates classes without __repr__ for QObject derived classes. However for all non-QObject classes that have an operator<<() for QDebug, it *does* add a valid repr implementation. Extend this behavior to QObject classes as well. In order for this to become more useful, also check for the indirection of operator<<(): If operator<<(QDebug, Foo*) is available, use the current non-value-type behavior, (i.e. provide cppSelf to operator<<()), but if operator<<(QDebug, const Foo&) is available instead, use the same behavior as for value-types, i.e. provide *cppSelf. This greatly increases the number of classes where operator<<() provides useful results. Also make sure to check for operator<<() in namespaces (recursively), not just at global scope. Change-Id: Ief9158455a25e332f07169f09692cafb8097078b Reviewed-by: Friedemann Kleint --- sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp | 17 +++++++++++------ sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h | 1 + sources/shiboken2/ApiExtractor/abstractmetalang.h | 9 ++++++++- sources/shiboken2/generator/shiboken2/cppgenerator.cpp | 11 +++++++---- sources/shiboken2/generator/shiboken2/cppgenerator.h | 2 +- 5 files changed, 28 insertions(+), 12 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 4b31dbb05..6aafe68be 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -248,6 +248,15 @@ void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &f } } +void AbstractMetaBuilderPrivate::registerToStringCapabilityIn(const NamespaceModelItem &nsItem) +{ + const FunctionList &streamOps = nsItem->findFunctions(QLatin1String("operator<<")); + for (const FunctionModelItem &item : streamOps) + registerToStringCapability(item, nullptr); + for (const NamespaceModelItem &ni : nsItem->namespaces()) + registerToStringCapabilityIn(ni); +} + /** * Check if a class has a debug stream operator that can be used as toString */ @@ -261,7 +270,7 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI const ArgumentModelItem &arg = arguments.at(1); if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) { if (arg->type().indirections() < 2) - cls->setToStringCapability(true); + cls->setToStringCapability(true, arg->type().indirections()); } } } @@ -591,11 +600,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) registerHashFunction(item, nullptr); } - { - const FunctionList &streamOps = dom->findFunctions(QLatin1String("operator<<")); - for (const FunctionModelItem &item : streamOps) - registerToStringCapability(item, nullptr); - } + registerToStringCapabilityIn(dom); { FunctionList binaryOperators = dom->findFunctions(QStringLiteral("operator==")); diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index fec2eddb9..9b1b181cc 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -106,6 +106,7 @@ public: void checkFunctionModifications(); void registerHashFunction(const FunctionModelItem &functionItem, AbstractMetaClass *currentClass); + void registerToStringCapabilityIn(const NamespaceModelItem &namespaceItem); void registerToStringCapability(const FunctionModelItem &functionItem, AbstractMetaClass *currentClass); diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h index afb4e5fbd..91ca4d7a9 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h @@ -1691,9 +1691,10 @@ public: return m_stream; } - void setToStringCapability(bool value) + void setToStringCapability(bool value, uint indirections = 0) { m_hasToStringCapability = value; + m_toStringCapabilityIndirections = indirections; } bool hasToStringCapability() const @@ -1701,6 +1702,11 @@ public: return m_hasToStringCapability; } + uint toStringCapabilityIndirections() const + { + return m_toStringCapabilityIndirections; + } + bool deleteInMainThread() const; static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, @@ -1753,6 +1759,7 @@ private: // FunctionModelItem m_qDebugStreamFunction; bool m_stream = false; + uint m_toStringCapabilityIndirections = 0; }; Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaClass::FunctionQueryOptions) diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 7de0cfc09..61429b383 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -3933,9 +3933,10 @@ void CppGenerator::writeClassDefinition(QTextStream &s, m_tpFuncs[func->name()] = cpythonFunctionName(func); } if (m_tpFuncs.value(QLatin1String("__repr__")).isEmpty() - && !metaClass->isQObject() && metaClass->hasToStringCapability()) { - m_tpFuncs[QLatin1String("__repr__")] = writeReprFunction(s, classContext); + m_tpFuncs[QLatin1String("__repr__")] = writeReprFunction(s, + classContext, + metaClass->toStringCapabilityIndirections()); } // class or some ancestor has multiple inheritance @@ -6006,7 +6007,9 @@ void CppGenerator::writeIndexError(QTextStream &s, const QString &errorMsg) s << INDENT << '}' << endl; } -QString CppGenerator::writeReprFunction(QTextStream &s, GeneratorContext &context) +QString CppGenerator::writeReprFunction(QTextStream &s, + GeneratorContext &context, + uint indirections) { const AbstractMetaClass *metaClass = context.metaClass(); QString funcName = cpythonBaseName(metaClass) + QLatin1String("__repr__"); @@ -6019,7 +6022,7 @@ QString CppGenerator::writeReprFunction(QTextStream &s, GeneratorContext &contex s << INDENT << "buffer.open(QBuffer::ReadWrite);" << endl; s << INDENT << "QDebug dbg(&buffer);" << endl; s << INDENT << "dbg << "; - if (metaClass->typeEntry()->isValue()) + if (metaClass->typeEntry()->isValue() || indirections == 0) s << '*'; s << CPP_SELF_VAR << ';' << endl; s << INDENT << "buffer.close();" << endl; diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h index ae6da9582..005518f96 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.h +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h @@ -336,7 +336,7 @@ private: /// Helper function for writeStdListWrapperMethods. void writeIndexError(QTextStream &s, const QString &errorMsg); - QString writeReprFunction(QTextStream &s, GeneratorContext &context); + QString writeReprFunction(QTextStream &s, GeneratorContext &context, uint indirections); const AbstractMetaFunction *boolCast(const AbstractMetaClass *metaClass) const; bool hasBoolCast(const AbstractMetaClass *metaClass) const -- cgit v1.2.3 From e940872c12399e8fc5c33ed2e52a719373bc03cf Mon Sep 17 00:00:00 2001 From: Andreas Beckermann Date: Thu, 17 Oct 2019 08:49:52 +0200 Subject: Fix hasVirtualDestructor() for implicit destructors If a derived class does not declare an explicit destructor, AbstractMetaClass::hasVirtualDestructor() is set to false. However this is incorrect for classes that have a base class that in turn provide a virtual destructor. Consequently shiboken generates incorrect code in cases where it depends on that value (e.g. for methods that override ownership of the returned object - instead of releasing ownership, shiboken invalidates it). This patch considers the baseClass()->hasVirtualDestructor() after traversing all functions (which checks for explicit destructors). Change-Id: Ifc4a472290d835dd6ef7d702b912643c9a2b42da Reviewed-by: Friedemann Kleint --- .../shiboken2/ApiExtractor/abstractmetabuilder.cpp | 6 +++- .../ApiExtractor/tests/testdtorinformation.cpp | 33 ++++++++++++++++++++++ .../ApiExtractor/tests/testdtorinformation.h | 1 + 3 files changed, 39 insertions(+), 1 deletion(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp index 6aafe68be..84721968d 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp @@ -512,8 +512,12 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) ReportHandler::startProgress("Fixing class inheritance..."); for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { - if (!cls->isInterface() && !cls->isNamespace()) + if (!cls->isInterface() && !cls->isNamespace()) { setupInheritance(cls); + if (!cls->hasVirtualDestructor() && cls->baseClass() + && cls->baseClass()->hasVirtualDestructor()) + cls->setHasVirtualDestructor(true); + } } ReportHandler::startProgress("Detecting inconsistencies in class model..."); diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp index f4204e9b9..0eee8af24 100644 --- a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp +++ b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp @@ -69,6 +69,39 @@ void TestDtorInformation::testDtorIsVirtual() QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasVirtualDestructor(), true); } +void TestDtorInformation::testDtorFromBaseIsVirtual() +{ + const char* cppCode = R"CPP(class ControlBase { public: ~ControlBase() {} }; +class Control : public ControlBase {}; +class SubjectBase { public: virtual ~SubjectBase() {} }; +class Subject : public SubjectBase {}; +)CPP"; + const char* xmlCode = R"XML( +" +" + + +)XML"; + QScopedPointer builder(TestUtil::parse(cppCode, xmlCode)); + QVERIFY(!builder.isNull()); + AbstractMetaClassList classes = builder->classes(); + QCOMPARE(classes.count(), 4); + + auto klass = AbstractMetaClass::findClass(classes, QLatin1String("ControlBase")); + QVERIFY(klass); + QVERIFY(!klass->hasVirtualDestructor()); + klass = AbstractMetaClass::findClass(classes, QLatin1String("Control")); + QVERIFY(klass); + QVERIFY(!klass->hasVirtualDestructor()); + + klass = AbstractMetaClass::findClass(classes, QLatin1String("SubjectBase")); + QVERIFY(klass); + QVERIFY(klass->hasVirtualDestructor()); + klass = AbstractMetaClass::findClass(classes, QLatin1String("Subject")); + QVERIFY(klass); + QVERIFY(klass->hasVirtualDestructor()); +} + void TestDtorInformation::testClassWithVirtualDtorIsPolymorphic() { const char* cppCode ="class Control { public: virtual ~Control() {} }; class Subject { protected: virtual ~Subject() {} };"; diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h index 068ef4952..0a57dd8d1 100644 --- a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h +++ b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h @@ -40,6 +40,7 @@ private slots: void testDtorIsPrivate(); void testDtorIsProtected(); void testDtorIsVirtual(); + void testDtorFromBaseIsVirtual(); void testClassWithVirtualDtorIsPolymorphic(); }; -- cgit v1.2.3 From 9b50d79a024155b491d6c09a829b3e382823003c Mon Sep 17 00:00:00 2001 From: Andreas Beckermann Date: Fri, 18 Oct 2019 17:20:47 +0200 Subject: shiboken: Fix pyi generation for external modules enum_sig.py is used to generate .pyi files (in sources/pyside2/PySide2/support/generate_pyi.py) from the bindings. The file can also be useful by external modules that were generated by shiboken, however the check for the modulename being PySide2 or shiboken2 prevents this. Remove this check, as discussed on IRC. This seems to be working internally as well and re-adds support for usages by external modules. Change-Id: I81af943c43f8f84aa0b0d89260cd99215acdb10d Reviewed-by: Christian Tismer --- .../files.dir/shibokensupport/signature/lib/enum_sig.py | 5 ----- 1 file changed, 5 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py index b026a5d20..a5e3247b1 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py @@ -96,11 +96,6 @@ class ExactEnumerator(object): return ret def klass(self, class_name, klass): - modname = klass.__module__ - if not (modname.startswith("PySide2") or modname.startswith("shiboken2")): - # don't look into any foreign classes! - ret = self.result_type() - return ret bases_list = [] for base in klass.__bases__: name = base.__name__ -- cgit v1.2.3 From 46776ca0ab7ae212e928de64a2819104d8789c3a Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Thu, 24 Oct 2019 14:05:46 +0200 Subject: Shiboken: QtDoc: Fix how brief and class tags are handled - The brief attribute of a page tag should be ignored to avoid briefs appearing twice. - The class ref pages should use the .. currentmodule:: rst directive instead of the .. module::. Change-Id: Iac205d60f79db49eb8c69a2593f09fb206a5b1a3 Reviewed-by: Friedemann Kleint --- sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp index 3b6d1c870..86abf21b0 100644 --- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp +++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp @@ -1236,10 +1236,6 @@ void QtXmlToSphinx::handlePageTag(QXmlStreamReader &reader) : writeEscapedRstText(m_output, fullTitle); m_output << endl << Pad('*', size) << endl << endl; - - const QStringRef brief = reader.attributes().value(briefAttribute()); - if (!brief.isEmpty()) - m_output << escape(brief) << endl << endl; } void QtXmlToSphinx::handleTargetTag(QXmlStreamReader &reader) @@ -1625,7 +1621,7 @@ void QtDocGenerator::generateClass(QTextStream &s, GeneratorContext &classContex m_docParser->setPackageName(metaClass->package()); m_docParser->fillDocumentation(const_cast(metaClass)); - s << ".. module:: " << metaClass->package() << endl; + s << ".. currentmodule:: " << metaClass->package() << endl; QString className = getClassTargetFullName(metaClass, false); s << ".. _" << className << ":" << endl << endl; -- cgit v1.2.3 From 73fa249c298f72548e8d728ec33aa802b1016e10 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 25 Oct 2019 11:18:32 +0200 Subject: abstractmetabuilder_p.h: Fix compilation with some versions of g++ Fix the return type, which caused complaints by some versions of g++: sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h: In member function 'ScopeModelItem AbstractMetaBuilderPrivate::popScope()': sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h:61:57: error: could not convert 'QList::takeLast() [with T = QSharedPointer<_NamespaceModelItem>]()' from 'QSharedPointer<_NamespaceModelItem>' to 'QSharedPointer<_ScopeModelItem>' Change-Id: I94abdfb9d76d3f0078e198b4230129150d2f43ea Reviewed-by: Cristian Maureira-Fredes --- sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h index 9b1b181cc..18c5afc17 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h @@ -56,7 +56,7 @@ public: void dumpLog() const; AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList, const Dependencies &additionalDependencies = Dependencies()) const; - ScopeModelItem popScope() { return m_scopes.takeLast(); } + NamespaceModelItem popScope() { return m_scopes.takeLast(); } void pushScope(const NamespaceModelItem &item); -- cgit v1.2.3 From 7317f708fa00c328fb289d40630b6f517ddae98f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 25 Oct 2019 14:35:38 +0200 Subject: Fix Python 3 deprecation warning about Buffer API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use new buffer protocol, fixing: sources/shiboken2/libshiboken/shibokenbuffer.cpp: In function ‘bool Shiboken::Buffer::checkType(PyObject*)’: sources/shiboken2/libshiboken/shibokenbuffer.cpp:46:42: warning: ‘int PyObject_CheckReadBuffer(PyObject*)’ is deprecated [-Wdeprecated-declarations] Change-Id: I3e3a403306d86c940bf1bd71fc672db6e0a2ea60 Reviewed-by: Christian Tismer --- sources/shiboken2/libshiboken/shibokenbuffer.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sources/shiboken2') diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.cpp b/sources/shiboken2/libshiboken/shibokenbuffer.cpp index 330470183..dd6e46320 100644 --- a/sources/shiboken2/libshiboken/shibokenbuffer.cpp +++ b/sources/shiboken2/libshiboken/shibokenbuffer.cpp @@ -43,7 +43,11 @@ bool Shiboken::Buffer::checkType(PyObject *pyObj) { +#ifdef IS_PY3K + return PyObject_CheckBuffer(pyObj) != 0; +#else return PyObject_CheckReadBuffer(pyObj) != 0; +#endif } void *Shiboken::Buffer::getPointer(PyObject *pyObj, Py_ssize_t *size) -- cgit v1.2.3