aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-12-16 09:11:13 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-12-16 09:11:13 +0100
commita3e70f98630f79c1857fd45b1be3272e966bfb7d (patch)
tree485e33fa1b73ee1e48eb7e56b75041f426589126
parentd73b75b08dc3f5998697d0f4936122c2a109b3cb (diff)
parent3a9ae5af078203b164a15b9fc4e9a726b84c849e (diff)
Merge remote-tracking branch 'origin/5.15' into dev
-rw-r--r--sources/pyside2/doc/api.rst1
-rw-r--r--sources/pyside2/doc/contents.rst2
-rw-r--r--sources/pyside2/doc/deployment-fbs.rst2
-rw-r--r--sources/pyside2/doc/extras/QtCore.ClassInfo.rst2
-rw-r--r--sources/pyside2/doc/extras/QtCore.Property.rst62
-rw-r--r--sources/pyside2/doc/extras/QtCore.Signal.rst2
-rw-r--r--sources/pyside2/doc/extras/QtCore.Slot.rst2
-rw-r--r--sources/pyside2/doc/gettingstarted-linux.rst20
-rw-r--r--sources/pyside2/doc/gettingstarted-macOS.rst18
-rw-r--r--sources/pyside2/doc/gettingstarted-windows.rst31
-rw-r--r--sources/pyside2/doc/index.rst9
-rw-r--r--sources/pyside2/doc/tutorials/expenses/expenses.rst2
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp36
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp43
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h4
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp9
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h36
-rw-r--r--sources/shiboken2/generator/generator.cpp47
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp3
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp136
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp12
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp27
-rw-r--r--sources/shiboken2/tests/libsmart/smart.cpp25
-rw-r--r--sources/shiboken2/tests/libsmart/smart_integer.h8
-rw-r--r--sources/shiboken2/tests/libsmart/smart_obj.h4
-rw-r--r--sources/shiboken2/tests/smartbinding/smart_pointer_test.py16
-rw-r--r--tools/debug_windows.py23
-rw-r--r--tools/missing_bindings.py1
29 files changed, 378 insertions, 211 deletions
diff --git a/sources/pyside2/doc/api.rst b/sources/pyside2/doc/api.rst
index 34d065f49..2cc258c75 100644
--- a/sources/pyside2/doc/api.rst
+++ b/sources/pyside2/doc/api.rst
@@ -1,4 +1,5 @@
.. _pyside-api:
+
|project| Modules
=================
diff --git a/sources/pyside2/doc/contents.rst b/sources/pyside2/doc/contents.rst
index 2a6f08266..598a65c92 100644
--- a/sources/pyside2/doc/contents.rst
+++ b/sources/pyside2/doc/contents.rst
@@ -11,6 +11,8 @@
examples/index.rst
videos.rst
deployment.rst
+ licenses.rst
+ modules.rst
considerations.rst
shiboken2/index.rst
diff --git a/sources/pyside2/doc/deployment-fbs.rst b/sources/pyside2/doc/deployment-fbs.rst
index 311c78ac7..0a75f2c4d 100644
--- a/sources/pyside2/doc/deployment-fbs.rst
+++ b/sources/pyside2/doc/deployment-fbs.rst
@@ -1,7 +1,7 @@
|project| & fbs
####################
-`fbs`_ provides a powerful environment for packaging,
+``fbs`` provides a powerful environment for packaging,
creating installers, and signing your application. It also lets you manage updates to
your application. As it is based on PyInstaller, it supports Linux, macOS, and Windows.
diff --git a/sources/pyside2/doc/extras/QtCore.ClassInfo.rst b/sources/pyside2/doc/extras/QtCore.ClassInfo.rst
index d2267be9c..89ca926c7 100644
--- a/sources/pyside2/doc/extras/QtCore.ClassInfo.rst
+++ b/sources/pyside2/doc/extras/QtCore.ClassInfo.rst
@@ -1,4 +1,4 @@
-.. module:: PySide2.QtCore
+.. currentmodule:: PySide2.QtCore
.. _ClassInfo:
ClassInfo
diff --git a/sources/pyside2/doc/extras/QtCore.Property.rst b/sources/pyside2/doc/extras/QtCore.Property.rst
new file mode 100644
index 000000000..209704c46
--- /dev/null
+++ b/sources/pyside2/doc/extras/QtCore.Property.rst
@@ -0,0 +1,62 @@
+.. currentmodule:: PySide2.QtCore
+.. _Property:
+Property
+********
+
+Detailed Description
+--------------------
+
+The Property function lets you declare properties that
+behave both as Qt and Python properties, and have their
+setters and getters defined as Python functions.
+
+Here is an example that illustrates how to use this
+function:
+
+.. code-block::
+ :linenos:
+
+from PySide2.QtCore import QObject, Property
+
+class MyObject(QObject):
+ def __init__(self,startval=42):
+ QObject.__init__(self)
+ self.ppval = startval
+
+ def readPP(self):
+ return self.ppval
+
+ def setPP(self,val):
+ self.ppval = val
+
+ pp = Property(int, readPP, setPP)
+
+obj = MyObject()
+obj.pp = 47
+print(obj.pp)
+
+Properties in QML expressions
+-----------------------------
+
+If you are using properties of your objects in QML expressions,
+QML requires that the property changes are notified. Here is an
+example illustrating how to do this:
+
+.. code-block::
+ :linenos:
+
+from PySide2.QtCore import QObject, Signal, Property
+
+class Person(QObject):
+ def __init__(self, name):
+ QObject.__init__(self)
+ self._person_name = name
+
+ def _name(self):
+ return self._person_name
+
+ @Signal
+ def name_changed(self):
+ pass
+
+ name = Property(str, _name, notify=name_changed)
diff --git a/sources/pyside2/doc/extras/QtCore.Signal.rst b/sources/pyside2/doc/extras/QtCore.Signal.rst
index 16c640831..a0660f88f 100644
--- a/sources/pyside2/doc/extras/QtCore.Signal.rst
+++ b/sources/pyside2/doc/extras/QtCore.Signal.rst
@@ -1,4 +1,4 @@
-.. module:: PySide2.QtCore
+.. currentmodule:: PySide2.QtCore
.. _Signal:
Signal
diff --git a/sources/pyside2/doc/extras/QtCore.Slot.rst b/sources/pyside2/doc/extras/QtCore.Slot.rst
index 3bc64c03a..5a59a2ae3 100644
--- a/sources/pyside2/doc/extras/QtCore.Slot.rst
+++ b/sources/pyside2/doc/extras/QtCore.Slot.rst
@@ -1,4 +1,4 @@
-.. module:: PySide2.QtCore
+.. currentmodule:: PySide2.QtCore
.. _Slot:
Slot
diff --git a/sources/pyside2/doc/gettingstarted-linux.rst b/sources/pyside2/doc/gettingstarted-linux.rst
index fd5b83223..6192ab190 100644
--- a/sources/pyside2/doc/gettingstarted-linux.rst
+++ b/sources/pyside2/doc/gettingstarted-linux.rst
@@ -4,19 +4,25 @@ Getting Started on Linux
Requirements
------------
- * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12 or greater)
+ * Qt package from `here`_ or a custom build of Qt (preferably
+ Qt 5.12 or greater)
* A Python interpreter (version Python 3.5+ or Python 2.7).
-
- * You can use the one provided by your OS, or you can get python from the `official website`_.
- * GCC,
+ You can either use the one provided by your OS, or get it
+ from the `official website`_.
+ * GCC
* `CMake`_ version 3.1 or greater
* Git version 2 or greater
- * `libclang_` from your system or from the `precompiled Qt packages`_ is recommended.
+ * `libclang`_ from your system or the prebuilt version from the
+ ``Qt Downloads`` page is recommended.
* ``virtualenv`` is strongly recommended, but optional.
* ``sphinx`` package for the documentation (optional).
- * Depending on your OS, other dependencies packages might be required:
+ * Depending on your linux distribution, the following dependencies might
+ also be required:
- * ``libgl-dev, python-dev, python-distutils, and python-setuptools``.
+ * ``libgl-dev``,
+ * ``python-dev``,
+ * ``python-distutils``,
+ * and ``python-setuptools``.
.. _here: https://qt.io/download
.. _official website: https://www.python.org/downloads/
diff --git a/sources/pyside2/doc/gettingstarted-macOS.rst b/sources/pyside2/doc/gettingstarted-macOS.rst
index 11305247f..fa6fc6037 100644
--- a/sources/pyside2/doc/gettingstarted-macOS.rst
+++ b/sources/pyside2/doc/gettingstarted-macOS.rst
@@ -4,19 +4,25 @@ Getting Started on macOS
Requirements
------------
- * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12 or greater)
+ * Qt package from `here`_ or a custom build of Qt (preferably
+ Qt 5.12 or greater)
* A Python interpreter (version Python 3.5+ or Python 2.7).
-
- * You can use the one provided by HomeBrew, or you can get python from the `official website`_.
+ You can use the one provided by HomeBrew, or you can get
+ python from the `official website`_.
* `XCode`_ 8.2 (macOS 10.11), 8.3.3 (macOS 10.12), 9 (macOS 10.13), 10.1 (macOS 10.14)
* `CMake`_ version 3.1 or greater
* Git version 2 or greater
- * `libclang_` from your system or from the `precompiled Qt packages`_ is recommended.
+ * `libclang`_ from your system or the prebuilt version from the
+ ``Qt Downloads`` page is recommended.
* ``virtualenv`` is strongly recommended, but optional.
* ``sphinx`` package for the documentation (optional).
- * Depending on your OS, other dependencies packages might be required:
+ * Depending on your OS, the following dependencies might also
+ be required:
- * ``libgl-dev, python-dev, python-distutils, and python-setuptools``.
+ * ``libgl-dev``,
+ * ``python-dev``,
+ * ``python-distutils``,
+ * and ``python-setuptools``.
.. _XCode: https://developer.apple.com/xcode/
.. _here: https://qt.io/download
diff --git a/sources/pyside2/doc/gettingstarted-windows.rst b/sources/pyside2/doc/gettingstarted-windows.rst
index dea781545..8de20769e 100644
--- a/sources/pyside2/doc/gettingstarted-windows.rst
+++ b/sources/pyside2/doc/gettingstarted-windows.rst
@@ -7,27 +7,28 @@ selected when using the online installer.
Requirements
------------
- * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12 or greater)
- * A Python interpreter (version Python 3.5+).
-
- * Preferably get python from the `official website`_.
-
- .. note:: Python 2.7 interpreter is not supported.
- The official Python 2.7 binary package which can be downloaded at
- https://www.python.org/downloads/ is built using MSVC 2007, while
- the Qt libraries are built using MSVC 2015/2017.
- Note that if you build your own custom Python2.7 interpreter with
- an MSVC version equivalent to the one that Qt was built with,
- you can safely build and use Qt for Python against that interpreter.
-
+ * Qt package from `here`_ or a custom build of Qt (preferably Qt 5.12
+ or greater)
+ * A Python interpreter (version Python 3.5+). Preferably get it
+ from the `official website`_.
* `MSVC2017`_ (or MSVC2019) for Python 3 on Windows,
* `CMake`_ version 3.1 or greater
* `Git`_ version 2 or greater
- * `libclang_` from the `precompiled Qt packages`_ is recommended.
- * `OpenSSL`_ (optional for SSL support, Qt must have been configured using the same SSL library)
+ * `libclang`_ prebuilt version from the
+ ``Qt Downloads`` page is recommended.
+ * `OpenSSL`_ (optional for SSL support, Qt must have been
+ configured using the same SSL library).
* ``virtualenv`` is strongly recommended, but optional.
* ``sphinx`` package for the documentation (optional).
+.. note:: Python 2.7 interpreter is not supported.
+ The official Python 2.7 binary package offerred on the
+ `official website`_ is built using MSVC 2007, while
+ the Qt libraries are built using MSVC 2015/2017.
+ If you intend to use Python 2.7, build the interpreter yourself
+ with MSVC 2015 or later, and build Qt for Python with it.
+
+
.. _here: https://qt.io/download
.. _official website: https://www.python.org/downloads/
.. _MSVC2017: https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools
diff --git a/sources/pyside2/doc/index.rst b/sources/pyside2/doc/index.rst
index 5ffe405a5..93e3451c5 100644
--- a/sources/pyside2/doc/index.rst
+++ b/sources/pyside2/doc/index.rst
@@ -40,3 +40,12 @@ Documentation
<td><a href="shiboken2/index.html" style="display: block;"><p><strong>Shiboken</strong><br/>Generate C++ to Python binding.</p></a></td>
</tr>
</table>
+
+.. toctree::
+ :hidden:
+ :glob:
+
+ contents.rst
+ gettingstarted*
+ pyside-examples/pyside2examples*
+ overviews/*
diff --git a/sources/pyside2/doc/tutorials/expenses/expenses.rst b/sources/pyside2/doc/tutorials/expenses/expenses.rst
index a19cec5c3..f643ec299 100644
--- a/sources/pyside2/doc/tutorials/expenses/expenses.rst
+++ b/sources/pyside2/doc/tutorials/expenses/expenses.rst
@@ -32,7 +32,7 @@ The base structure for a `QApplication` is located inside the `if __name__ == "_
code block.
.. code-block:: python
- :dedent: 4
+ :linenos:
if __name__ == "__main__":
app = QApplication([])
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 312f72523..f6c9e407c 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -550,11 +550,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
if (!entry->isPrimitive()) {
if ((entry->isValue() || entry->isObject())
&& !types->shouldDropTypeEntry(entry->qualifiedCppName())
- && !entry->isString()
- && !entry->isChar()
&& !entry->isContainer()
&& !entry->isCustom()
- && !entry->isVariant()
&& (entry->generateCode() & TypeEntry::GenerateTargetLang)
&& !AbstractMetaClass::findClass(m_metaClasses, entry)) {
qCWarning(lcShiboken).noquote().nospace()
@@ -758,7 +755,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
<< QStringLiteral("namespace '%1' does not have a type entry").arg(namespaceName);
return nullptr;
}
- type->setInlineNamespace(namespaceItem->type() == NamespaceType::Inline);
+
+ if (namespaceItem->type() == NamespaceType::Inline) {
+ type->setInlineNamespace(true);
+ TypeDatabase::instance()->addInlineNamespaceLookups(type);
+ }
// Continue populating namespace?
AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
@@ -1294,33 +1295,6 @@ static bool _compareAbstractMetaTypes(const AbstractMetaType *type,
&& (type == nullptr || type->compare(*other, flags));
}
-static bool _compareAbstractMetaFunctions(const AbstractMetaFunction *func,
- const AbstractMetaFunction *other,
- AbstractMetaType::ComparisonFlags argumentFlags = {})
-{
- if (!func && !other)
- return true;
- if (!func || !other)
- return false;
- if (func->name() != other->name())
- return false;
- const int argumentsCount = func->arguments().count();
- if (argumentsCount != other->arguments().count()
- || func->isConstant() != other->isConstant()
- || func->isStatic() != other->isStatic()
- || !_compareAbstractMetaTypes(func->type(), other->type())) {
- return false;
- }
- for (int i = 0; i < argumentsCount; ++i) {
- if (!_compareAbstractMetaTypes(func->arguments().at(i)->type(),
- other->arguments().at(i)->type(),
- argumentFlags)) {
- return false;
- }
- }
- return true;
-}
-
AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass::Attributes *constructorAttributes,
AbstractMetaClass *currentClass)
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index 546e9c4ed..d4cf53efe 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -334,8 +334,10 @@ QString msgCannotFindSmartPointer(const QString &instantiationType,
QString result;
QTextStream str(&result);
str << "Unable to find smart pointer type for " << instantiationType << " (known types:";
- for (auto t : pointers)
- str << ' ' << t->fullName();
+ for (auto t : pointers) {
+ auto typeEntry = t->typeEntry();
+ str << ' ' << typeEntry->targetLangName() << '/' << typeEntry->qualifiedCppName();
+ }
str << ").";
return result;
}
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 659a69922..c952f7b0e 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -149,6 +149,20 @@ void TypeDatabase::addSystemInclude(const QString &name)
m_systemIncludes.append(name.toUtf8());
}
+// Add a lookup for the short name excluding inline namespaces
+// so that "std::shared_ptr" finds "std::__1::shared_ptr" as well.
+// Note: This inserts duplicate TypeEntry * into m_entries.
+void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntry *n)
+{
+ QVector<TypeEntry *> additionalEntries; // Store before modifying the hash
+ for (TypeEntry *entry : m_entries) {
+ if (entry->isChildOf(n))
+ additionalEntries.append(entry);
+ }
+ for (const auto &ae : additionalEntries)
+ m_entries.insert(ae->shortName(), ae);
+}
+
ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
@@ -703,6 +717,35 @@ static void _computeTypeIndexes()
computeTypeIndexes = false;
}
+// Build the C++ name excluding any inline namespaces
+// ("std::__1::shared_ptr" -> "std::shared_ptr"
+QString TypeEntry::shortName() const
+{
+ if (m_cachedShortName.isEmpty()) {
+ QVarLengthArray<const TypeEntry *> parents;
+ bool foundInlineNamespace = false;
+ for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
+ if (p->type() == TypeEntry::NamespaceType
+ && static_cast<const NamespaceTypeEntry *>(p)->isInlineNamespace()) {
+ foundInlineNamespace = true;
+ } else {
+ parents.append(p);
+ }
+ }
+ if (foundInlineNamespace) {
+ m_cachedShortName.reserve(m_name.size());
+ for (int i = parents.size() - 1; i >= 0; --i) {
+ m_cachedShortName.append(parents.at(i)->entryName());
+ m_cachedShortName.append(QLatin1String("::"));
+ }
+ m_cachedShortName.append(m_entryName);
+ } else {
+ m_cachedShortName = m_name;
+ }
+ }
+ return m_cachedShortName;
+}
+
void TypeEntry::setRevision(int r)
{
if (m_revision != r) {
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h
index 6d800a3f0..f1bd0ac9f 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase.h
@@ -87,6 +87,8 @@ public:
const QByteArrayList &systemIncludes() const { return m_systemIncludes; }
void addSystemInclude(const QString &name);
+ void addInlineNamespaceLookups(const NamespaceTypeEntry *n);
+
PrimitiveTypeEntry *findPrimitiveType(const QString &name) const;
ComplexTypeEntry *findComplexType(const QString &name) const;
ObjectTypeEntry *findObjectType(const QString &name) const;
@@ -174,7 +176,7 @@ private:
TypeEntry *resolveTypeDefEntry(TypedefEntry *typedefEntry, QString *errorMessage);
bool m_suppressWarnings = true;
- TypeEntryMultiMap m_entries;
+ TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups).
TypeEntryMap m_flagsEntries;
TypedefEntryMap m_typedefEntries;
TemplateEntryMap m_templates;
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 637dde363..f8199622a 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -684,6 +684,15 @@ TypeEntry::~TypeEntry()
delete m_customConversion;
}
+bool TypeEntry::isChildOf(const TypeEntry *p) const
+{
+ for (auto e = m_parent; e; e = e->parent()) {
+ if (e == p)
+ return true;
+ }
+ return false;
+}
+
const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
{
for (auto e = this; e; e = e->parent()) {
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 0cbcc9c25..d0739c19b 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -562,20 +562,14 @@ public:
EnumValue,
ConstantValueType,
TemplateArgumentType,
- ThreadType,
BasicValueType,
- StringType,
ContainerType,
InterfaceType,
ObjectType,
NamespaceType,
- VariantType,
- JObjectWrapperType,
- CharType,
ArrayType,
TypeSystemType,
CustomType,
- TargetLangType,
FunctionType,
SmartPointerType,
TypedefType
@@ -605,6 +599,7 @@ public:
const TypeEntry *parent() const { return m_parent; }
void setParent(const TypeEntry *p) { m_parent = p; }
+ bool isChildOf(const TypeEntry *p) const;
const TypeSystemTypeEntry *typeSystemTypeEntry() const;
// cf AbstractMetaClass::targetLangEnclosingClass()
const TypeEntry *targetLangEnclosingEntry() const;
@@ -629,14 +624,6 @@ public:
{
return m_type == ObjectType;
}
- bool isString() const
- {
- return m_type == StringType;
- }
- bool isChar() const
- {
- return m_type == CharType;
- }
bool isNamespace() const
{
return m_type == NamespaceType;
@@ -649,14 +636,6 @@ public:
{
return m_type == SmartPointerType;
}
- bool isVariant() const
- {
- return m_type == VariantType;
- }
- bool isJObjectWrapper() const
- {
- return m_type == JObjectWrapperType;
- }
bool isArray() const
{
return m_type == ArrayType;
@@ -673,18 +652,10 @@ public:
{
return m_type == VarargsType;
}
- bool isThread() const
- {
- return m_type == ThreadType;
- }
bool isCustom() const
{
return m_type == CustomType;
}
- bool isBasicValue() const
- {
- return m_type == BasicValueType;
- }
bool isTypeSystem() const
{
return m_type == TypeSystemType;
@@ -710,6 +681,8 @@ public:
// The type's name in C++, fully qualified
QString name() const { return m_name; }
+ // C++ excluding inline namespaces
+ QString shortName() const;
// Name as specified in XML
QString entryName() const { return m_entryName; }
@@ -898,7 +871,8 @@ protected:
private:
const TypeEntry *m_parent;
- QString m_name; // fully qualified
+ QString m_name; // C++ fully qualified
+ mutable QString m_cachedShortName; // C++ excluding inline namespaces
QString m_entryName;
QString m_targetLangPackage;
mutable QString m_cachedTargetLangName; // "Foo.Bar"
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index b14edfc4c..585102b01 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -159,7 +159,6 @@ struct Generator::GeneratorPrivate
QString licenseComment;
QString moduleName;
QStringList instantiatedContainersNames;
- QStringList instantiatedSmartPointerNames;
QVector<const AbstractMetaType *> instantiatedContainers;
QVector<const AbstractMetaType *> instantiatedSmartPointers;
@@ -211,6 +210,31 @@ QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType *type)
return typeName;
}
+// Strip a "const QSharedPtr<const Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016/454)
+const AbstractMetaType *canonicalSmartPtrInstantiation(const AbstractMetaType *type)
+{
+ AbstractMetaTypeList instantiations = type->instantiations();
+ Q_ASSERT(instantiations.size() == 1);
+ const bool needsFix = type->isConstant() || type->referenceType() != NoReference;
+ const bool pointeeNeedsFix = instantiations.constFirst()->isConstant();
+ if (!needsFix && !pointeeNeedsFix)
+ return type;
+ auto fixedType = type->copy();
+ fixedType->setReferenceType(NoReference);
+ fixedType->setConstant(false);
+ if (pointeeNeedsFix) {
+ auto fixedPointeeType = instantiations.constFirst()->copy();
+ fixedPointeeType->setConstant(false);
+ fixedType->setInstantiations(AbstractMetaTypeList(1, fixedPointeeType));
+ }
+ return fixedType;
+}
+
+static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType *smartPtrType)
+{
+ return smartPtrType->instantiations().constFirst()->typeEntry();
+}
+
void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType *type,
const QString &context)
{
@@ -244,18 +268,15 @@ void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType
m_d->instantiatedContainers.append(type);
}
} else {
- // Is smart pointer.
- if (!m_d->instantiatedSmartPointerNames.contains(typeName)) {
- m_d->instantiatedSmartPointerNames.append(typeName);
- if (type->isConstant() || type->referenceType() != NoReference) {
- // Strip a "const QSharedPtr<Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016)
- auto fixedType = type->copy();
- fixedType->setReferenceType(NoReference);
- fixedType->setConstant(false);
- type = fixedType;
- }
- m_d->instantiatedSmartPointers.append(type);
- }
+ // Is smart pointer. Check if the (const?) pointee is already known
+ auto pt = pointeeTypeEntry(type);
+ const bool present =
+ std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(),
+ [pt] (const AbstractMetaType *t) {
+ return pointeeTypeEntry(t) == pt;
+ });
+ if (!present)
+ m_d->instantiatedSmartPointers.append(canonicalSmartPtrInstantiation(type));
}
}
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 5bb2e5558..2b7efd6e7 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -2115,6 +2115,9 @@ static void writeFancyToc(QTextStream& s, const QStringList& items, int cols = 4
continue;
if (item.startsWith(Q) && item.length() > 1)
idx = item[1];
+ else
+ idx = item[0]; // To group classes without the 'Q' prefix
+
item.chop(4); // Remove the .rst extension
tocMap[idx] << item;
}
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 80c0f5a37..eaa9fe8c4 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -343,7 +343,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
for (AbstractMetaClass *innerClass : innerClasses) {
GeneratorContext innerClassContext(innerClass);
- if (shouldGenerate(innerClass)) {
+ if (shouldGenerate(innerClass) && !innerClass->typeEntry()->isSmartPointer()) {
QString headerfile = fileNameForContext(innerClassContext);
headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
s << "#include \"" << headerfile << "\"\n";
@@ -5270,6 +5270,7 @@ void CppGenerator::writeGetattroFunction(QTextStream &s, GeneratorContext &conte
const AbstractMetaClass *metaClass = context.metaClass();
s << "static PyObject *" << cpythonGetattroFunctionName(metaClass)
<< "(PyObject *self, PyObject *name)\n{\n";
+ s << INDENT << "assert(self);\n";
QString getattrFunc;
if (usePySideExtensions() && metaClass->isQObject()) {
@@ -5278,112 +5279,95 @@ void CppGenerator::writeGetattroFunction(QTextStream &s, GeneratorContext &conte
<< cpythonWrapperCPtr(qobjectClass, QLatin1String("self"))
<< ", self, name)";
} else {
- getattrFunc = QLatin1String("PyObject_GenericGetAttr(") + QLatin1String("self")
- + QLatin1String(", name)");
+ getattrFunc = QLatin1String("PyObject_GenericGetAttr(self, name)");
}
if (classNeedsGetattroFunction(metaClass)) {
- s << INDENT << "if (self) {\n";
+ s << INDENT << "// Search the method in the instance dict\n";
+ s << INDENT << "if (auto ob_dict = reinterpret_cast<SbkObject *>(self)->ob_dict) {\n";
{
Indentation indent(INDENT);
- s << INDENT << "// Search the method in the instance dict\n";
- s << INDENT << "if (reinterpret_cast<SbkObject *>(self)->ob_dict) {\n";
+ s << INDENT << "if (auto meth = PyDict_GetItem(ob_dict, name)) {\n";
{
Indentation indent(INDENT);
- s << INDENT << "PyObject *meth = PyDict_GetItem(reinterpret_cast<SbkObject *>(self)->ob_dict, name);\n";
- s << INDENT << "if (meth) {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "Py_INCREF(meth);\n";
- s << INDENT << "return meth;\n";
- }
- s << INDENT << "}\n";
+ s << INDENT << "Py_INCREF(meth);\n";
+ s << INDENT << "return meth;\n";
}
s << INDENT << "}\n";
- s << INDENT << "// Search the method in the type dict\n";
- s << INDENT << "if (Shiboken::Object::isUserType(self)) {\n";
+ }
+ s << INDENT << "}\n";
+ s << INDENT << "// Search the method in the type dict\n";
+ s << INDENT << "if (Shiboken::Object::isUserType(self)) {\n";
+ {
+ Indentation indent(INDENT);
+ // PYSIDE-772: Perform optimized name mangling.
+ s << INDENT << "Shiboken::AutoDecRef tmp(_Pep_PrivateMangle(self, name));\n";
+ s << INDENT << "if (auto meth = PyDict_GetItem(Py_TYPE(self)->tp_dict, tmp))\n";
{
Indentation indent(INDENT);
- // PYSIDE-772: Perform optimized name mangling.
- s << INDENT << "Shiboken::AutoDecRef tmp(_Pep_PrivateMangle(self, name));\n";
- s << INDENT << "PyObject *meth = PyDict_GetItem(Py_TYPE(self)->tp_dict, tmp);\n";
- s << INDENT << "if (meth)\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "return PyFunction_Check(meth) ? SBK_PyMethod_New(meth, self) : " << getattrFunc << ";\n";
- }
+ s << INDENT << "return PyFunction_Check(meth) ? SBK_PyMethod_New(meth, self) : " << getattrFunc << ";\n";
}
- s << INDENT << "}\n";
+ }
+ s << INDENT << "}\n";
- const AbstractMetaFunctionList &funcs = getMethodsWithBothStaticAndNonStaticMethods(metaClass);
- for (const AbstractMetaFunction *func : funcs) {
- QString defName = cpythonMethodDefinitionName(func);
- s << INDENT << "static PyMethodDef non_static_" << defName << " = {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << defName << ".ml_name,\n";
- s << INDENT << defName << ".ml_meth,\n";
- s << INDENT << defName << ".ml_flags & (~METH_STATIC),\n";
- s << INDENT << defName << ".ml_doc,\n";
- }
- s << INDENT << "};\n";
- s << INDENT << "if (Shiboken::String::compare(name, \"" << func->name() << "\") == 0)\n";
+ const AbstractMetaFunctionList &funcs = getMethodsWithBothStaticAndNonStaticMethods(metaClass);
+ for (const AbstractMetaFunction *func : funcs) {
+ QString defName = cpythonMethodDefinitionName(func);
+ s << INDENT << "static PyMethodDef non_static_" << defName << " = {\n";
+ {
Indentation indent(INDENT);
- s << INDENT << "return PyCFunction_NewEx(&non_static_" << defName << ", self, 0);\n";
+ s << INDENT << defName << ".ml_name,\n";
+ s << INDENT << defName << ".ml_meth,\n";
+ s << INDENT << defName << ".ml_flags & (~METH_STATIC),\n";
+ s << INDENT << defName << ".ml_doc,\n";
}
+ s << INDENT << "};\n";
+ s << INDENT << "if (Shiboken::String::compare(name, \"" << func->name() << "\") == 0)\n";
+ Indentation indent(INDENT);
+ s << INDENT << "return PyCFunction_NewEx(&non_static_" << defName << ", self, 0);\n";
}
- s << INDENT << "}\n";
}
if (context.forSmartPointer()) {
s << INDENT << "PyObject *tmp = " << getattrFunc << ";\n";
- s << INDENT << "if (tmp) {\n";
+ s << INDENT << "if (tmp)\n";
{
Indentation indent(INDENT);
s << INDENT << "return tmp;\n";
}
- s << INDENT << "} else {\n";
+ s << INDENT << "if (!PyErr_ExceptionMatches(PyExc_AttributeError))\n";
{
Indentation indent(INDENT);
- s << INDENT << "if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return nullptr;\n";
- s << INDENT << "PyErr_Clear();\n";
-
- s << INDENT << "// Try to find the 'name' attribute, by retrieving the PyObject for "
- "the corresponding C++ object held by the smart pointer.\n";
- s << INDENT << "PyObject *rawObj = PyObject_CallMethod(self, "
- << writeSmartPointerGetterCast() << ", 0);\n";
- s << INDENT << "if (rawObj) {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "PyObject *attribute = PyObject_GetAttr(rawObj, name);\n";
- s << INDENT << "if (attribute) {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "tmp = attribute;\n";
- }
- s << INDENT << "}\n";
- s << INDENT << "Py_DECREF(rawObj);\n";
- }
- s << INDENT << "}\n";
- s << INDENT << "if (!tmp) {\n";
- {
- Indentation indent(INDENT);
- s << INDENT << "PyTypeObject *tp = Py_TYPE(self);\n";
- s << INDENT << "PyErr_Format(PyExc_AttributeError,\n";
- s << INDENT << " \"'%.50s' object has no attribute '%.400s'\",\n";
- s << INDENT << " tp->tp_name, Shiboken::String::toCString(name));\n";
- s << INDENT << "return nullptr;\n";
- }
- s << INDENT << "} else {\n";
+ s << INDENT << "return nullptr;\n";
+ }
+ s << INDENT << "PyErr_Clear();\n";
+
+ // This generates the code which dispatches access to member functions
+ // and fields from the smart pointer to its pointee.
+ s << INDENT << "// Try to find the 'name' attribute, by retrieving the PyObject for "
+ "the corresponding C++ object held by the smart pointer.\n";
+ s << INDENT << "if (auto rawObj = PyObject_CallMethod(self, "
+ << writeSmartPointerGetterCast() << ", 0)) {\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "if (auto attribute = PyObject_GetAttr(rawObj, name))\n";
{
Indentation indent(INDENT);
- s << INDENT << "return tmp;\n";
+ s << INDENT << "tmp = attribute;\n";
}
- s << INDENT << "}\n";
-
+ s << INDENT << "Py_DECREF(rawObj);\n";
}
s << INDENT << "}\n";
-
+ s << INDENT << "if (!tmp) {\n";
+ {
+ Indentation indent(INDENT);
+ s << INDENT << "PyTypeObject *tp = Py_TYPE(self);\n";
+ s << INDENT << "PyErr_Format(PyExc_AttributeError,\n";
+ s << INDENT << " \"'%.50s' object has no attribute '%.400s'\",\n";
+ s << INDENT << " tp->tp_name, Shiboken::String::toCString(name));\n";
+ }
+ s << INDENT << "}\n";
+ s << INDENT << "return tmp;\n";
} else {
s << INDENT << "return " << getattrFunc << ";\n";
}
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index cf96c8d5c..a565659de 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -401,9 +401,17 @@ bool HeaderGenerator::finishGeneration()
int smartPointerCount = 0;
const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
- _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(metaType),
- smartPointerCountIndex);
+ QString indexName = getTypeIndexVariableName(metaType);
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
macrosStream << ", // " << metaType->cppSignature() << Qt::endl;
+ // Add a the same value for const pointees (shared_ptr<const Foo>).
+ const auto ptrName = metaType->typeEntry()->entryName();
+ int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
+ if (pos >= 0) {
+ indexName.insert(pos + ptrName.size() + 1, QLatin1String("CONST"));
+ _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
+ macrosStream << ", // (const)\n";
+ }
++smartPointerCountIndex;
++smartPointerCount;
}
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index dd5dc43e9..71efe12c0 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -58,6 +58,8 @@
#include "qapp_macro.h"
#include "voidptr.h"
+#include <iostream>
+
#if defined(__APPLE__)
#include <dlfcn.h>
#endif
@@ -505,12 +507,14 @@ PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *k
// PYSIDE-939: This is a temporary patch that circumvents the problem
// with Py_TPFLAGS_METHOD_DESCRIPTOR until this is finally solved.
- PyObject *ob_PyType_Type = reinterpret_cast<PyObject *>(&PyType_Type);
- static PyObject *mro = PyObject_GetAttr(ob_PyType_Type, Shiboken::PyName::mro());
- auto hold = Py_TYPE(mro)->tp_flags;
- Py_TYPE(mro)->tp_flags &= ~Py_TPFLAGS_METHOD_DESCRIPTOR;
+ // PyType_Ready uses mro(). We need to temporarily remove the flag from it's type.
+ // We cannot use PyMethodDescr_Type since it is not exported by Python 2.7 .
+ static PyTypeObject *PyMethodDescr_TypePtr = Py_TYPE(
+ PyObject_GetAttr(reinterpret_cast<PyObject *>(&PyType_Type), Shiboken::PyName::mro()));
+ auto hold = PyMethodDescr_TypePtr->tp_flags;
+ PyMethodDescr_TypePtr->tp_flags &= ~Py_TPFLAGS_METHOD_DESCRIPTOR;
auto *newType = reinterpret_cast<SbkObjectType *>(type_new(metatype, args, kwds));
- Py_TYPE(mro)->tp_flags = hold;
+ PyMethodDescr_TypePtr->tp_flags = hold;
if (!newType)
return nullptr;
@@ -917,8 +921,11 @@ introduceWrapperType(PyObject *enclosingObject,
}
}
// PYSIDE-510: Here is the single change to support signatures.
- if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0)
+ if (SbkSpecial_Type_Ready(enclosingObject, reinterpret_cast<PyTypeObject *>(type), signatureStrings) < 0) {
+ std::cerr << "Warning: " << __FUNCTION__ << " returns nullptr for "
+ << typeName << '/' << originalName << " due to SbkSpecial_Type_Ready() failing\n";
return nullptr;
+ }
initPrivateData(type);
auto sotp = PepType_SOTP(type);
@@ -934,7 +941,13 @@ introduceWrapperType(PyObject *enclosingObject,
// PyModule_AddObject steals type's reference.
Py_INCREF(ob_type);
- return PyModule_AddObject(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
+ if (PyModule_AddObject(enclosingObject, typeName, ob_type) != 0) {
+ std::cerr << "Warning: " << __FUNCTION__ << " returns nullptr for "
+ << typeName << '/' << originalName << " due to PyModule_AddObject(enclosingObject="
+ << enclosingObject << ",ob_type=" << ob_type << ") failing\n";
+ return nullptr;
+ }
+ return type;
}
void setSubTypeInitHook(SbkObjectType *type, SubTypeInitHook func)
diff --git a/sources/shiboken2/tests/libsmart/smart.cpp b/sources/shiboken2/tests/libsmart/smart.cpp
index 6a4deb50a..81fa30c7e 100644
--- a/sources/shiboken2/tests/libsmart/smart.cpp
+++ b/sources/shiboken2/tests/libsmart/smart.cpp
@@ -93,7 +93,7 @@ Obj::~Obj()
void Obj::printObj() {
if (shouldPrint()) {
std::cout << "integer value: " << m_integer
- << " internal integer value: " << m_internalInteger->m_int << '\n';
+ << " internal integer value: " << m_internalInteger->value() << '\n';
}
}
@@ -134,6 +134,17 @@ int Obj::takeSharedPtrToObj(SharedPtr<Obj> pObj)
int Obj::takeSharedPtrToInteger(SharedPtr<Integer> pInt)
{
pInt->printInteger();
+ return pInt->value();
+}
+
+SharedPtr<const Integer> Obj::giveSharedPtrToConstInteger()
+{
+ SharedPtr<const Integer> co(new Integer);
+ return co;
+}
+
+int Obj::takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt)
+{
return pInt->m_int;
}
@@ -173,7 +184,17 @@ Integer::~Integer()
std::cout << "Integer destructor " << this << '\n';
}
-void Integer::printInteger()
+int Integer::value() const
+{
+ return m_int;
+}
+
+void Integer::setValue(int v)
+{
+ m_int = v;
+}
+
+void Integer::printInteger() const
{
if (shouldPrint())
std::cout << "Integer value for object " << this << " is " << m_int << '\n';
diff --git a/sources/shiboken2/tests/libsmart/smart_integer.h b/sources/shiboken2/tests/libsmart/smart_integer.h
index 3756f68b0..126894120 100644
--- a/sources/shiboken2/tests/libsmart/smart_integer.h
+++ b/sources/shiboken2/tests/libsmart/smart_integer.h
@@ -37,8 +37,12 @@ public:
Integer(const Integer &other);
Integer &operator=(const Integer &other);
~Integer();
- void printInteger();
- int m_int;
+ void printInteger() const;
+
+ int value() const;
+ void setValue(int v);
+
+ int m_int; // public for testing member field access.
};
namespace Smart {
diff --git a/sources/shiboken2/tests/libsmart/smart_obj.h b/sources/shiboken2/tests/libsmart/smart_obj.h
index 12425366e..e5709a071 100644
--- a/sources/shiboken2/tests/libsmart/smart_obj.h
+++ b/sources/shiboken2/tests/libsmart/smart_obj.h
@@ -49,11 +49,13 @@ public:
SharedPtr<Obj> giveSharedPtrToObj();
std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
SharedPtr<Integer> giveSharedPtrToInteger();
+ SharedPtr<const Integer> giveSharedPtrToConstInteger();
+ int takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt);
SharedPtr<Smart::Integer2> giveSharedPtrToInteger2();
int takeSharedPtrToObj(SharedPtr<Obj> pObj);
int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
- int m_integer;
+ int m_integer; // public for testing member field access.
Integer *m_internalInteger;
};
diff --git a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
index e1883c7cc..6c4c2c8e9 100644
--- a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
@@ -116,6 +116,10 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(integer.m_int, 50)
# Set and get a member value via shared pointer (like operator->).
+ ptrToInteger.setValue(150)
+ self.assertEqual(ptrToInteger.value(), 150)
+
+ # Set and get a member field via shared pointer (like operator->).
ptrToInteger.m_int = 100
self.assertEqual(ptrToInteger.m_int, 100)
@@ -143,6 +147,18 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(objCount(), 0)
self.assertEqual(integerCount(), 0)
+ def testConstIntegerSmartPointer(self):
+ # Uncomment to see more debug info about creation of objects and ref counts.
+ # Registry.getInstance().setShouldPrint(True)
+
+ # Create Obj.
+ o = Obj()
+ ptrToConstInteger = o.giveSharedPtrToConstInteger()
+ self.assertEqual(ptrToConstInteger.m_int, 456)
+ result = o.takeSharedPtrToConstInteger(ptrToConstInteger)
+ self.assertEqual(result, 456)
+ self.assertEqual(ptrToConstInteger.value(), 456)
+
def testSmartPointersWithNamespace(self):
# Create the main object
o = Obj()
diff --git a/tools/debug_windows.py b/tools/debug_windows.py
index ab1c03aba..dbde5f534 100644
--- a/tools/debug_windows.py
+++ b/tools/debug_windows.py
@@ -154,17 +154,22 @@ def get_installed_windows_kits():
roots_key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots"
log.info("Searching for Windows kits in registry path: "
"{}".format(roots_key))
- roots = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, roots_key, 0,
- winreg.KEY_READ)
+
kits = []
pattern = re.compile(r'KitsRoot(\d+)')
+ try:
+ roots = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, roots_key, 0,
+ winreg.KEY_READ)
+
+ for (name, value, value_type) in sub_values(roots):
+ if value_type == winreg.REG_SZ and name.startswith('KitsRoot'):
+ match = pattern.search(name)
+ if match:
+ version = match.group(1)
+ kits.append({'version': version, 'value': value})
- for (name, value, value_type) in sub_values(roots):
- if value_type == winreg.REG_SZ and name.startswith('KitsRoot'):
- match = pattern.search(name)
- if match:
- version = match.group(1)
- kits.append({'version': version, 'value': value})
+ except WindowsError as e:
+ log.exception(e)
if not kits:
log.error(dedent("""
@@ -263,7 +268,7 @@ def find_error_like_snippets(content):
('ERROR: Module load completed but symbols could '
'not be loaded')}
return (re.search('error', l, re.IGNORECASE)
- and all(e not in errors for e in errors))
+ and all(e not in l for e in errors))
for i in range(1, len(lines)):
line = lines[i]
diff --git a/tools/missing_bindings.py b/tools/missing_bindings.py
index 850716a2f..a4a418a6e 100644
--- a/tools/missing_bindings.py
+++ b/tools/missing_bindings.py
@@ -113,7 +113,6 @@ modules_to_test['QtDataVisualization'] = 'qtdatavisualization-module.html'
modules_to_test['QtOpenGL'] = 'qtopengl-module.html'
modules_to_test['QtPositioning'] = 'qtpositioning-module.html'
modules_to_test['QtRemoteObjects'] = 'qtremoteobjects-module.html'
-modules_to_test['QtScript'] = 'qtscript-module.html'
modules_to_test['QtScriptTools'] = 'qtscripttools-module.html'
modules_to_test['QtSensors'] = 'qtsensors-module.html'
types_to_ignore = set()