aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-01-14 12:30:48 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-01-14 12:30:50 +0100
commit317eb0ad107d056f4af097ff94d99233009c393d (patch)
treef4b8aaa87f49dce41400b6a05980ad8cd434728b
parent907ff205912cc8d8d0a09c8096f5089dae5eeca9 (diff)
parent2fc25e72b289b0f8e10110ffa886cad864d3147c (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--README.pyside2.md12
-rw-r--r--README.shiboken2-generator.md2
-rw-r--r--README.shiboken2.md6
-rw-r--r--build_scripts/config.py5
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml36
-rw-r--r--sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp7
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml2
-rw-r--r--sources/pyside2/PySide2/support/signature/mapping.py1
-rw-r--r--sources/pyside2/PySide2/templates/core_common.xml7
-rw-r--r--sources/pyside2/cmake/Macros/PySideModules.cmake6
-rw-r--r--sources/pyside2/doc/extras/PySide.QtCore.Slot.rst30
-rw-r--r--sources/pyside2/doc/pyside-config.qdocconf.in2
-rw-r--r--sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py12
-rw-r--r--sources/pyside2/tests/registry/exists_darwin_5_12_0_ci.py4
-rw-r--r--sources/pyside2/tests/registry/exists_opensuse423_5_12_0_ci.py4
-rw-r--r--sources/pyside2/tests/registry/exists_redhatenterpriselinuxworkstation74_5_12_0_ci.py4
-rw-r--r--sources/pyside2/tests/registry/exists_win32_5_12_0_ci.py4
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp2
-rw-r--r--sources/shiboken2/generator/generator.h4
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp10
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp379
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp12
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h12
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp40
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h4
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp29
-rw-r--r--sources/shiboken2/libshiboken/signature.h1
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt2
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/errorhandler.py124
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/loader.py2
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/mapping.py1
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/parser.py3
-rw-r--r--sources/shiboken2/tests/samplebinding/decisor_test.py6
33 files changed, 465 insertions, 310 deletions
diff --git a/README.pyside2.md b/README.pyside2.md
index 53f7bc9d0..f1bd8aaa4 100644
--- a/README.pyside2.md
+++ b/README.pyside2.md
@@ -2,11 +2,11 @@
### Introduction
-PySide is the [Python Qt bindings project](http://wiki.qt.io/Qt_for_Python),
-providing access to the complete Qt 5.12+ framework as well as to generator
-tools for rapidly generating Python bindings for any C++ libraries.
+PySide2 is the official Python module from the
+[Qt for Python project](http://wiki.qt.io/Qt_for_Python),
+which provides access to the complete Qt 5.12+ framework.
-The PySide project is developed in the open, with all facilities you'd expect
+The Qt for Python project is developed in the open, with all facilities you'd expect
from any modern OSS project such as all code in a git repository and an open
design process. We welcome any contribution conforming to the
[Qt Contribution Agreement](https://www.qt.io/contributionagreement/).
@@ -21,7 +21,7 @@ and [PyPi](https://pypi.org/project/PySide2/):
#### Dependencies
-PySide versions following 5.12 use a C++ parser based on
+PySide2 versions following 5.12 use a C++ parser based on
[Clang](http://clang.org/). The Clang library (C-bindings), version 6.0 or
higher is required for building. Prebuilt versions of it can be downloaded from
[download.qt.io](http://download.qt.io/development_releases/prebuilt/libclang/).
@@ -51,7 +51,7 @@ This process will include getting the code:
then install the dependencies, and following the instructions per platform.
A common build command will look like:
- python setup.py install --qmake=<path/to/qmake/> --jobs=8 --build-tests
+ python setup.py install --qmake=<path/to/qmake/> --parallel=8 --build-tests
You can obtain more information about the options to build PySide
and Shiboken in [our wiki](https://wiki.qt.io/Qt_for_Python/).
diff --git a/README.shiboken2-generator.md b/README.shiboken2-generator.md
index f29f40634..a7fd32244 100644
--- a/README.shiboken2-generator.md
+++ b/README.shiboken2-generator.md
@@ -1,4 +1,4 @@
-# shiboken2-generator
+# Shiboken2-generator
Shiboken is the generator used by the Qt for Python project.
It outputs C++ code for CPython extensions, which can be compiled
diff --git a/README.shiboken2.md b/README.shiboken2.md
index d9cd32a40..3d92f2a46 100644
--- a/README.shiboken2.md
+++ b/README.shiboken2.md
@@ -1,7 +1,7 @@
-# shiboken2 module
+# Shiboken2 module
-The purpose of the shiboken2 Python module is to access information
-related to the binding generation that could be used to integrate
+The purpose of the [shiboken2 Python module](https://wiki.qt.io/Qt_for_Python/Shiboken)
+is to access information related to the binding generation that could be used to integrate
C++ programs to Python, or even to get useful information to debug
an application.
diff --git a/build_scripts/config.py b/build_scripts/config.py
index f47230a6d..8356be302 100644
--- a/build_scripts/config.py
+++ b/build_scripts/config.py
@@ -125,7 +125,7 @@ class Config(object):
setup_kwargs = {}
setup_kwargs['long_description'] = self.get_long_description()
- setup_kwargs['long_description_content_type'] = 'text/markdown',
+ setup_kwargs['long_description_content_type'] = 'text/markdown'
setup_kwargs['keywords'] = 'Qt'
setup_kwargs['author'] = 'Qt for Python Team'
setup_kwargs['author_email'] = 'pyside@qt-project.org'
@@ -207,8 +207,7 @@ class Config(object):
elif self.internal_build_type == self.pyside_option_name:
setup_kwargs['name'] = self.pyside_st_name
- setup_kwargs['description'] = ("Python bindings for the Qt cross-platform application"
- " and UI framework"),
+ setup_kwargs['description'] = "Python bindings for the Qt cross-platform application and UI framework"
setup_kwargs['install_requires'] = [self.shiboken_module_st_name]
setup_kwargs['entry_points'] = {
'console_scripts': [
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index c70049d8e..7531b33b8 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -1210,6 +1210,11 @@
</add-function>
</value-type>
<value-type name="QPersistentModelIndex" hash-function="qHash">
+ <modify-function signature="internalPointer()const">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_internal_pointer" />
+ </inject-code>
+ </modify-function>
<modify-function signature="operator const QModelIndex&amp;()const">
<modify-argument index="return">
<parent index="this" action="add"/>
@@ -1460,12 +1465,38 @@
<object-type name="QAbstractItemModel">
<enum-type name="CheckIndexOption" flags="CheckIndexOptions" since="5.11"/>
<enum-type name="LayoutChangeHint"/>
+ <!-- This function was replaced by a added function -->
+ <modify-function signature="createIndex(int,int,void*)const" remove="all"/>
<!-- This function is the same as createIndex(int, int, int)const -->
<modify-function signature="createIndex(int,int,quintptr)const">
<modify-argument index="3">
<replace-default-expression with="0"/>
</modify-argument>
</modify-function>
+ <add-function signature="createIndex(int,int,PyObject*)const" return-type="QModelIndex">
+ <modify-argument index="1">
+ <rename to="row"/>
+ </modify-argument>
+ <modify-argument index="2">
+ <rename to="column"/>
+ </modify-argument>
+ <modify-argument index="3">
+ <rename to="ptr"/>
+ </modify-argument>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qabstractitemmodel-createindex"/>
+ <inject-documentation mode="append" format="target">
+ Creates a model index for the given row and column with the internal pointer ptr.
+ When using a QSortFilterProxyModel, its indexes have their own internal pointer.
+ It is not advisable to access this internal pointer outside of the model.
+ Use the data() function instead.
+ This function provides a consistent interface that model subclasses must use to create model indexes.
+
+ .. warning:: Because of some Qt/Python itegration rules, the ptr argument do not get the reference
+ incremented during the QModelIndex life time. So it is necessary to keep the object used
+ on ptr argument alive during the whole process.
+ Do not destroy the object if you are not sure about that.
+ </inject-documentation>
+ </add-function>
<inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qabstractitemmodel"/>
<modify-function signature="mimeData(QModelIndexList)const">
<modify-argument index="return">
@@ -2774,6 +2805,11 @@
</modify-function>
</object-type>
<value-type name="QModelIndex" hash-function="qHash">
+ <modify-function signature="internalPointer()const">
+ <inject-code class="target" position="beginning">
+ <insert-template name="return_internal_pointer" />
+ </inject-code>
+ </modify-function>
<modify-function signature="model()const">
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
diff --git a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
index 93a8f281e..e50b1dfc7 100644
--- a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
+++ b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
@@ -40,6 +40,7 @@
#include "pysidequickregistertype.h"
#include <pyside.h>
+#include <pyside_p.h>
#include <shiboken.h>
// Auto generated headers.
@@ -122,7 +123,7 @@ void registerTypeIfInheritsFromClass(
PyTypeObject *typeToRegister,
const QByteArray &typePointerName,
const QByteArray &typeListName,
- QMetaObject *typeMetaObject,
+ const QMetaObject *typeMetaObject,
QQmlPrivate::RegisterType *type,
bool &registered)
{
@@ -199,9 +200,7 @@ bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int v
return false;
// Used inside macros to register the type.
- QMetaObject *metaObject =
- reinterpret_cast<QMetaObject *>(
- ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType *>(pyObj)));
+ const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObj);
Q_ASSERT(metaObject);
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
index e6021bfe1..456a411d3 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
@@ -660,7 +660,7 @@
<modify-argument index="2">
<reference-count action="set"/>
</modify-argument>
- <inject-code file="../glue/qtwidgets.cpp" snippet="qitemeditorfactory-registerEditor"/>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qitemeditorfactory-registereditor"/>
</modify-function>
<modify-function signature="setDefaultFactory(QItemEditorFactory*)">
<modify-argument index="1">
diff --git a/sources/pyside2/PySide2/support/signature/mapping.py b/sources/pyside2/PySide2/support/signature/mapping.py
index 61fa2d41f..96afd3c7a 100644
--- a/sources/pyside2/PySide2/support/signature/mapping.py
+++ b/sources/pyside2/PySide2/support/signature/mapping.py
@@ -63,6 +63,7 @@ class Reloader(Sbk_Reloader):
Sbk_Reloader.update(self, globals())
update_mapping = Reloader().update
+namespace = globals() # our module's __dict__, updated
def init_QtCore():
diff --git a/sources/pyside2/PySide2/templates/core_common.xml b/sources/pyside2/PySide2/templates/core_common.xml
index 0fe19273b..4f715ee1f 100644
--- a/sources/pyside2/PySide2/templates/core_common.xml
+++ b/sources/pyside2/PySide2/templates/core_common.xml
@@ -260,6 +260,13 @@
%PYARG_0 = Shiboken::String::fromCString(qPrintable(format));
</template>
+ <template name="return_internal_pointer">
+ %PYARG_0 = reinterpret_cast&lt;PyObject*>(%CPPSELF.%FUNCTION_NAME());
+ if (!%PYARG_0)
+ %PYARG_0 = Py_None;
+ Py_INCREF(%PYARG_0);
+ </template>
+
<!-- Helpers for modifying "bool nativeEventFilter(QByteArray, void*, long *result)"
to return a tuple of bool,long -->
<template name="return_native_eventfilter_conversion_variables">
diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake
index 98efd8c73..2cbda3975 100644
--- a/sources/pyside2/cmake/Macros/PySideModules.cmake
+++ b/sources/pyside2/cmake/Macros/PySideModules.cmake
@@ -170,9 +170,9 @@ macro(create_pyside_module)
# install
install(TARGETS ${module_NAME} LIBRARY DESTINATION "${PYTHON_SITE_PACKAGES}/PySide2")
- install(DIRECTORY "${CMAKE_BINARY_DIR}/" DESTINATION "${PYTHON_SITE_PACKAGES}"
- OPTIONAL
- FILES_MATCHING PATTERN "*.pyi")
+ file(GLOB hinting_stub_files RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/PySide2" "${CMAKE_CURRENT_BINARY_DIR}/PySide2/*.pyi")
+ install(FILES ${hinting_stub_files}
+ DESTINATION "${PYTHON_SITE_PACKAGES}/PySide2")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PySide2/${module_NAME}/pyside2_${lower_module_name}_python.h
DESTINATION include/PySide2${pyside2_SUFFIX}/${module_NAME}/)
diff --git a/sources/pyside2/doc/extras/PySide.QtCore.Slot.rst b/sources/pyside2/doc/extras/PySide.QtCore.Slot.rst
index 6b93014cf..3bc64c03a 100644
--- a/sources/pyside2/doc/extras/PySide.QtCore.Slot.rst
+++ b/sources/pyside2/doc/extras/PySide.QtCore.Slot.rst
@@ -7,33 +7,33 @@ Slot
Detailed Description
--------------------
- PySide adopt PyQt's new signal and slot syntax as-is. The PySide
- implementation is functionally compatible with the PyQt 4.5 one, with the
- exceptions listed bellow.
+ PySide2 adopt PyQt5's new signal and slot syntax as-is. The PySide2
+ implementation is functionally compatible with the PyQt5 one, with the
+ exceptions listed below.
- PyQt's new signal and slot style utilizes method and decorator names
+ PyQt5's new signal and slot style utilizes method and decorator names
specific to their implementation. These will be generalized according to
the table below:
- ======= ====================== =============
- Module PyQt factory function PySide class
- ======= ====================== =============
- QtCore pyqtSignal Signal
- QtCore pyqtSlot Slot
- ======= ====================== =============
+ ======= ======================= =============
+ Module PyQt5 factory function PySide2 class
+ ======= ======================= =============
+ QtCore pyqtSignal Signal
+ QtCore pyqtSlot Slot
+ ======= ======================= =============
Q_INVOKABLE
-----------
- PySide doesn't offer something identical to Q_INVOKABLE macro of Qt, the
- reason is simple, PySide slots can have return values, so if you need to
- create a invokable method that returns some value, declare it as a slot,
- e.g.:
+ There is no equivalent of the Q_INVOKABLE macro of Qt
+ since PySide2 slots can actually have return values.
+ If you need to create a invokable method that returns some value,
+ declare it as a slot, e.g.:
::
class Foo(QObject):
- @Slot(result=int, float)
+ @Slot(float, result=int)
def getFloatReturnInt(self, f):
return int(f)
diff --git a/sources/pyside2/doc/pyside-config.qdocconf.in b/sources/pyside2/doc/pyside-config.qdocconf.in
index e897069ad..3fd567165 100644
--- a/sources/pyside2/doc/pyside-config.qdocconf.in
+++ b/sources/pyside2/doc/pyside-config.qdocconf.in
@@ -1,6 +1,8 @@
buildversion = @PYSIDE_QT_VERSION@
navigation.homepage = Qt for Python
+macro.nullptr = "\\c{None}"
+
outputdir = @DOC_DATA_DIR@
outputformats = WebXML
WebXML.quotinginformation = true
diff --git a/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py b/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py
index a67bb380a..770600ea3 100644
--- a/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py
+++ b/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py
@@ -33,7 +33,6 @@
import sys
import unittest
from PySide2.QtCore import *
-from PySide2.support import VoidPtr
class MyModel (QAbstractListModel):
pass
@@ -51,21 +50,20 @@ class TestQModelIndexInternalPointer(unittest.TestCase):
def testInternalPointer(self):
#Test QAbstractListModel.createIndex and
- #QModelIndex.internalPointer
+ #QModelIndex.internalPointer with regular Python objects
obj = QObject()
- obj_ptr = VoidPtr(obj)
- idx = self.model.createIndex(0, 0, obj)
+ idx = self.model.createIndex(0, 0, "Hello")
i = idx.internalPointer()
- self.assertEqual(int(obj_ptr), int(i))
+ self.assertEqual(i, "Hello")
def testReferenceCounting(self):
#Test reference counting when retrieving data with
#QModelIndex.internalPointer
- o = QObject()
+ o = [1, 2, 3]
o_refcnt = sys.getrefcount(o)
idx = self.model.createIndex(0, 0, o)
ptr = idx.internalPointer()
- self.assertEqual(sys.getrefcount(o), o_refcnt)
+ self.assertEqual(sys.getrefcount(o), o_refcnt + 1)
def testIndexForDefaultDataArg(self):
diff --git a/sources/pyside2/tests/registry/exists_darwin_5_12_0_ci.py b/sources/pyside2/tests/registry/exists_darwin_5_12_0_ci.py
index a2b6aa14f..7a070abfe 100644
--- a/sources/pyside2/tests/registry/exists_darwin_5_12_0_ci.py
+++ b/sources/pyside2/tests/registry/exists_darwin_5_12_0_ci.py
@@ -157,7 +157,7 @@ if "PySide2.QtCore" in sys.modules:
"QAbstractItemModel.changePersistentIndexList": ('typing.List[int]', 'typing.List[int]'),
"QAbstractItemModel.checkIndex": ('PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QAbstractItemModel.CheckIndexOptions'),
"QAbstractItemModel.columnCount": ('PySide2.QtCore.QModelIndex',),
- "QAbstractItemModel.createIndex": ('int', 'int', 'int'),
+ "QAbstractItemModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object')],
"QAbstractItemModel.data": ('PySide2.QtCore.QModelIndex', 'int'),
"QAbstractItemModel.decodeData": ('int', 'int', 'PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QDataStream'),
"QAbstractItemModel.dropMimeData": ('PySide2.QtCore.QMimeData', 'PySide2.QtCore.Qt.DropAction', 'int', 'int', 'PySide2.QtCore.QModelIndex'),
@@ -15202,7 +15202,7 @@ if "PySide2.QtHelp" in sys.modules:
"QHelpEngineCore.unregisterDocumentation": ('str',),
# class PySide2.QtHelp.QHelpIndexModel:
- "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('str',)],
+ "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object'), ('str',)],
"QHelpIndexModel.filter": ('str', 'str'),
"QHelpIndexModel.isCreatingIndex": (),
"QHelpIndexModel.linksForKeyword": ('str',),
diff --git a/sources/pyside2/tests/registry/exists_opensuse423_5_12_0_ci.py b/sources/pyside2/tests/registry/exists_opensuse423_5_12_0_ci.py
index 5cb8a2306..6caa0947d 100644
--- a/sources/pyside2/tests/registry/exists_opensuse423_5_12_0_ci.py
+++ b/sources/pyside2/tests/registry/exists_opensuse423_5_12_0_ci.py
@@ -157,7 +157,7 @@ if "PySide2.QtCore" in sys.modules:
"QAbstractItemModel.changePersistentIndexList": ('typing.List[int]', 'typing.List[int]'),
"QAbstractItemModel.checkIndex": ('PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QAbstractItemModel.CheckIndexOptions'),
"QAbstractItemModel.columnCount": ('PySide2.QtCore.QModelIndex',),
- "QAbstractItemModel.createIndex": ('int', 'int', 'int'),
+ "QAbstractItemModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object')],
"QAbstractItemModel.data": ('PySide2.QtCore.QModelIndex', 'int'),
"QAbstractItemModel.decodeData": ('int', 'int', 'PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QDataStream'),
"QAbstractItemModel.dropMimeData": ('PySide2.QtCore.QMimeData', 'PySide2.QtCore.Qt.DropAction', 'int', 'int', 'PySide2.QtCore.QModelIndex'),
@@ -15213,7 +15213,7 @@ if "PySide2.QtHelp" in sys.modules:
"QHelpEngineCore.unregisterDocumentation": ('str',),
# class PySide2.QtHelp.QHelpIndexModel:
- "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('str',)],
+ "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object'), ('str',)],
"QHelpIndexModel.filter": ('str', 'str'),
"QHelpIndexModel.isCreatingIndex": (),
"QHelpIndexModel.linksForKeyword": ('str',),
diff --git a/sources/pyside2/tests/registry/exists_redhatenterpriselinuxworkstation74_5_12_0_ci.py b/sources/pyside2/tests/registry/exists_redhatenterpriselinuxworkstation74_5_12_0_ci.py
index 969ac36c8..c7b58c3fb 100644
--- a/sources/pyside2/tests/registry/exists_redhatenterpriselinuxworkstation74_5_12_0_ci.py
+++ b/sources/pyside2/tests/registry/exists_redhatenterpriselinuxworkstation74_5_12_0_ci.py
@@ -157,7 +157,7 @@ if "PySide2.QtCore" in sys.modules:
"QAbstractItemModel.changePersistentIndexList": ('typing.List[int]', 'typing.List[int]'),
"QAbstractItemModel.checkIndex": ('PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QAbstractItemModel.CheckIndexOptions'),
"QAbstractItemModel.columnCount": ('PySide2.QtCore.QModelIndex',),
- "QAbstractItemModel.createIndex": ('int', 'int', 'int'),
+ "QAbstractItemModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object')],
"QAbstractItemModel.data": ('PySide2.QtCore.QModelIndex', 'int'),
"QAbstractItemModel.decodeData": ('int', 'int', 'PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QDataStream'),
"QAbstractItemModel.dropMimeData": ('PySide2.QtCore.QMimeData', 'PySide2.QtCore.Qt.DropAction', 'int', 'int', 'PySide2.QtCore.QModelIndex'),
@@ -15213,7 +15213,7 @@ if "PySide2.QtHelp" in sys.modules:
"QHelpEngineCore.unregisterDocumentation": ('str',),
# class PySide2.QtHelp.QHelpIndexModel:
- "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('str',)],
+ "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object'), ('str',)],
"QHelpIndexModel.filter": ('str', 'str'),
"QHelpIndexModel.isCreatingIndex": (),
"QHelpIndexModel.linksForKeyword": ('str',),
diff --git a/sources/pyside2/tests/registry/exists_win32_5_12_0_ci.py b/sources/pyside2/tests/registry/exists_win32_5_12_0_ci.py
index 189e5c74d..0a3f587f3 100644
--- a/sources/pyside2/tests/registry/exists_win32_5_12_0_ci.py
+++ b/sources/pyside2/tests/registry/exists_win32_5_12_0_ci.py
@@ -159,7 +159,7 @@ if "PySide2.QtCore" in sys.modules:
"QAbstractItemModel.changePersistentIndexList": ('typing.List', 'typing.List'),
"QAbstractItemModel.checkIndex": ('PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QAbstractItemModel.CheckIndexOptions'),
"QAbstractItemModel.columnCount": ('PySide2.QtCore.QModelIndex',),
- "QAbstractItemModel.createIndex": ('int', 'int', 'int'),
+ "QAbstractItemModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object')],
"QAbstractItemModel.data": ('PySide2.QtCore.QModelIndex', 'int'),
"QAbstractItemModel.decodeData": ('int', 'int', 'PySide2.QtCore.QModelIndex', 'PySide2.QtCore.QDataStream'),
"QAbstractItemModel.dropMimeData": ('PySide2.QtCore.QMimeData', 'PySide2.QtCore.Qt.DropAction', 'int', 'int', 'PySide2.QtCore.QModelIndex'),
@@ -15335,7 +15335,7 @@ if "PySide2.QtHelp" in sys.modules:
"QHelpEngineCore.unregisterDocumentation": ('str',),
# class PySide2.QtHelp.QHelpIndexModel:
- "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('str',)],
+ "QHelpIndexModel.createIndex": [('int', 'int', 'int'), ('int', 'int', 'object'), ('str',)],
"QHelpIndexModel.filter": ('str', 'str'),
"QHelpIndexModel.isCreatingIndex": (),
"QHelpIndexModel.linksForKeyword": ('str',),
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
index 9f71b495a..c438e0c37 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
@@ -59,7 +59,7 @@ void TestCodeInjections::testReadFile()
const char* cppCode ="struct A {};\n";
int argc = 0;
- char *argv[] = {NULL};
+ char *argv[] = {nullptr};
QCoreApplication app(argc, argv);
QString attribute = QLatin1String("file='") + filePath + QLatin1Char('\'');
diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h
index 225e7aec7..cdf6d89b3 100644
--- a/sources/shiboken2/generator/generator.h
+++ b/sources/shiboken2/generator/generator.h
@@ -288,10 +288,10 @@ protected:
/// Returns all container types found by APIExtractor
ContainerTypeEntryList containerTypes() const;
- /// Returns an AbstractMetaEnum for a given TypeEntry that is an EnumTypeEntry, or NULL if not found.
+ /// Returns an AbstractMetaEnum for a given TypeEntry that is an EnumTypeEntry, or nullptr if not found.
const AbstractMetaEnum* findAbstractMetaEnum(const TypeEntry* typeEntry) const;
- /// Returns an AbstractMetaEnum for a given AbstractMetaType that holds an EnumTypeEntry, or NULL if not found.
+ /// Returns an AbstractMetaEnum for a given AbstractMetaType that holds an EnumTypeEntry, or nullptr if not found.
const AbstractMetaEnum* findAbstractMetaEnum(const AbstractMetaType* metaType) const;
/// Generates a file for given AbstractMetaClass or AbstractMetaType (smart pointer case).
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 19ddd5f37..ea971287a 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -53,6 +53,8 @@ static inline QString titleAttribute() { return QStringLiteral("title"); }
static inline QString fullTitleAttribute() { return QStringLiteral("fulltitle"); }
static inline QString briefAttribute() { return QStringLiteral("brief"); }
+static inline QString none() { return QStringLiteral("None"); }
+
static bool shouldSkip(const AbstractMetaFunction* func)
{
// Constructors go to separate section
@@ -1787,11 +1789,13 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */
|| defValue.startsWith(QLatin1String("QList"))) {
defValue = QLatin1String("list()");
} else if (defValue == QLatin1String("QVariant()")) {
- defValue = QLatin1String("None");
+ defValue = none();
} else {
defValue.replace(QLatin1String("::"), QLatin1String("."));
- if (defValue == QLatin1String("0") && (arg->type()->isQObject() || arg->type()->isObject()))
- defValue = QLatin1String("None");
+ if (defValue == QLatin1String("nullptr"))
+ defValue = none();
+ else if (defValue == QLatin1String("0") && (arg->type()->isQObject() || arg->type()->isObject()))
+ defValue = none();
}
ret += QLatin1Char('=') + defValue;
}
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 99bfae9f0..3d87fcff0 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -48,7 +48,7 @@ static const char CPP_ARG0[] = "cppArg0";
QHash<QString, QString> CppGenerator::m_nbFuncs = QHash<QString, QString>();
QHash<QString, QString> CppGenerator::m_sqFuncs = QHash<QString, QString>();
QHash<QString, QString> CppGenerator::m_mpFuncs = QHash<QString, QString>();
-QString CppGenerator::m_currentErrorCode(QLatin1String("0"));
+QString CppGenerator::m_currentErrorCode(QLatin1String("{}"));
static const char typeNameFunc[] = R"CPP(
template <class T>
@@ -552,9 +552,11 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// Write methods definition
s << "static PyMethodDef " << className << "_methods[] = {" << endl;
s << methodsDefinitions << endl;
- if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer())
- s << INDENT << "{\"__copy__\", (PyCFunction)" << className << "___copy__" << ", METH_NOARGS}," << endl;
- s << INDENT << "{0} // Sentinel" << endl;
+ if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
+ s << INDENT << "{\"__copy__\", reinterpret_cast<PyCFunction>(" << className << "___copy__)"
+ << ", METH_NOARGS}," << endl;
+ }
+ s << INDENT << '{' << NULL_PTR << ", " << NULL_PTR << "} // Sentinel" << endl;
s << "};" << endl << endl;
// Write tp_getattro function
@@ -650,10 +652,10 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (canGenerateFieldSetter(metaField))
s << cpythonSetterFunctionName(metaField);
else
- s << '0';
+ s << NULL_PTR;
s << "}," << endl;
}
- s << INDENT << "{0} // Sentinel" << endl;
+ s << INDENT << '{' << NULL_PTR << "} // Sentinel" << endl;
s << "};" << endl << endl;
}
@@ -962,7 +964,8 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
if (!injectedCodeCallsPythonOverride(func)) {
s << INDENT;
- s << "Shiboken::AutoDecRef " << PYTHON_RETURN_VAR << "(PyObject_Call(" << PYTHON_OVERRIDE_VAR << ", " << PYTHON_ARGS << ", NULL));" << endl;
+ s << "Shiboken::AutoDecRef " << PYTHON_RETURN_VAR << "(PyObject_Call("
+ << PYTHON_OVERRIDE_VAR << ", " << PYTHON_ARGS << ", nullptr));" << endl;
s << INDENT << "// An error happened in python code!" << endl;
s << INDENT << "if (" << PYTHON_RETURN_VAR << ".isNull()) {" << endl;
@@ -1090,7 +1093,7 @@ void CppGenerator::writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass
s << INDENT << "if (QObject::d_ptr->metaObject)" << endl
<< INDENT << INDENT << "return QObject::d_ptr->dynamicMetaObject();" << endl;
s << INDENT << "SbkObject* pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);" << endl;
- s << INDENT << "if (pySelf == NULL)" << endl;
+ s << INDENT << "if (pySelf == nullptr)" << endl;
s << INDENT << INDENT << "return " << metaClass->qualifiedCppName() << "::metaObject();" << endl;
s << INDENT << "return PySide::SignalManager::retrieveMetaObject(reinterpret_cast<PyObject*>(pySelf));" << endl;
s << '}' << endl << endl;
@@ -1099,7 +1102,7 @@ void CppGenerator::writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass
s << "int " << wrapperClassName << "::qt_metacall(QMetaObject::Call call, int id, void** args)" << endl;
s << "{" << endl;
- AbstractMetaFunction *func = NULL;
+ AbstractMetaFunction *func = nullptr;
AbstractMetaFunctionList list = metaClass->queryFunctionsByName(QLatin1String("qt_metacall"));
if (list.size() == 1)
func = list[0];
@@ -1127,7 +1130,7 @@ void CppGenerator::writeMetaCast(QTextStream& s, const AbstractMetaClass* metaCl
QString wrapperClassName = wrapperName(metaClass);
s << "void* " << wrapperClassName << "::qt_metacast(const char* _clname)" << endl;
s << '{' << endl;
- s << INDENT << "if (!_clname) return 0;" << endl;
+ s << INDENT << "if (!_clname) return {};" << endl;
s << INDENT << "SbkObject* pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);" << endl;
s << INDENT << "if (pySelf && PySide::inherits(Py_TYPE(pySelf), _clname))" << endl;
s << INDENT << INDENT << "return static_cast<void*>(const_cast< " << wrapperClassName << "* >(this));" << endl;
@@ -1156,11 +1159,12 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry*
}
QString code;
QTextStream c(&code);
- c << INDENT << "*((" << cppTypeName << "*)cppOut) = ";
+ c << INDENT << "*reinterpret_cast<" << cppTypeName << "*>(cppOut) =\n"
+ << INDENT << " ";
if (enumType->isFlags())
- c << cppTypeName << "(QFlag((int)PySide::QFlags::getValue(reinterpret_cast<PySideQFlagsObject*>(pyIn))))";
+ c << cppTypeName << "(QFlag(int(PySide::QFlags::getValue(reinterpret_cast<PySideQFlagsObject*>(pyIn)))))";
else
- c << "(" << cppTypeName << ") Shiboken::Enum::getValue(pyIn)";
+ c << "static_cast<" << cppTypeName << ">(Shiboken::Enum::getValue(pyIn))";
c << ';' << endl;
writePythonToCppFunction(s, code, typeName, typeName);
@@ -1173,11 +1177,12 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry*
<< cppTypeName << " *>(cppIn));" << endl;
c << INDENT;
c << "return ";
- if (enumType->isFlags())
- c << "reinterpret_cast<PyObject*>(PySide::QFlags::newObject(castCppIn, " << enumPythonType << "))";
-
- else
+ if (enumType->isFlags()) {
+ c << "reinterpret_cast<PyObject*>(PySide::QFlags::newObject(castCppIn, "
+ << enumPythonType << "))";
+ } else {
c << "Shiboken::Enum::newItem(" << enumPythonType << ", castCppIn)";
+ }
c << ';' << endl;
writeCppToPythonFunction(s, code, typeName, typeName);
s << endl;
@@ -1195,8 +1200,9 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry*
code.clear();
cppTypeName = getFullTypeName(flags).trimmed();
- c << INDENT << "*((" << cppTypeName << "*)cppOut) = " << cppTypeName;
- c << "(QFlag((int)Shiboken::Enum::getValue(pyIn)));" << endl;
+ c << INDENT << "*reinterpret_cast<" << cppTypeName << "*>(cppOut) =\n"
+ << INDENT << " " << cppTypeName
+ << "(QFlag(int(Shiboken::Enum::getValue(pyIn))));" << endl;
QString flagsTypeName = fixedCppTypeName(flags);
writePythonToCppFunction(s, code, typeName, flagsTypeName);
@@ -1204,11 +1210,20 @@ void CppGenerator::writeEnumConverterFunctions(QTextStream& s, const TypeEntry*
code.clear();
c << INDENT << "Shiboken::AutoDecRef pyLong(PyNumber_Long(pyIn));" << endl;
- c << INDENT << "*((" << cppTypeName << "*)cppOut) = " << cppTypeName;
- c << "(QFlag((int)PyLong_AsLong(pyLong.object())));" << endl;
+ c << INDENT << "*reinterpret_cast<" << cppTypeName << "*>(cppOut) =\n"
+ << INDENT << " " << cppTypeName
+ << "(QFlag(int(PyLong_AsLong(pyLong.object()))));" << endl;
+ // PYSIDE-898: Include an additional condition to detect if the type of the
+ // enum corresponds to the object that is being evaluated.
+ // Using only `PyNumber_Check(...)` is too permissive,
+ // then we would have been unable to detect the difference between
+ // a PolarOrientation and Qt::AlignmentFlag, which was the main
+ // issue of the bug.
+ const QString numberCondition = QStringLiteral("PyNumber_Check(pyIn) && ") + pyTypeCheck;
writePythonToCppFunction(s, code, QLatin1String("number"), flagsTypeName);
- writeIsPythonConvertibleToCppFunction(s, QLatin1String("number"), flagsTypeName,
- QLatin1String("PyNumber_Check(pyIn)"));
+ writeIsPythonConvertibleToCppFunction(s, QLatin1String("number"), flagsTypeName, numberCondition);
+
+
}
void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaClass *metaClass,
@@ -1247,7 +1262,8 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
writePythonToCppFunction(s, code, sourceTypeName, targetTypeName);
// "Is convertible" function for the Python object to C++ pointer conversion.
- QString pyTypeCheck = QStringLiteral("PyObject_TypeCheck(pyIn, (PyTypeObject*)%1)").arg(cpythonType);
+ const QString pyTypeCheck = QLatin1String("PyObject_TypeCheck(pyIn, reinterpret_cast<PyTypeObject*>(")
+ + cpythonType + QLatin1String("))");
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck, QString(), true);
s << endl;
@@ -1256,9 +1272,10 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
code.clear();
if (usePySideExtensions() && metaClass->isQObject())
{
- c << INDENT << "return PySide::getWrapperForQObject((" << typeName << "*)cppIn, " << cpythonType << ");" << endl;
+ c << INDENT << "return PySide::getWrapperForQObject(reinterpret_cast<"
+ << typeName << "*>(const_cast<void*>(cppIn)), " << cpythonType << ");" << endl;
} else {
- c << INDENT << "PyObject* pyOut = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(cppIn);" << endl;
+ c << INDENT << "auto pyOut = reinterpret_cast<PyObject*>(Shiboken::BindingManager::instance().retrieveWrapper(cppIn));" << endl;
c << INDENT << "if (pyOut) {" << endl;
{
Indentation indent(INDENT);
@@ -1306,8 +1323,9 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
else
computedWrapperName = wrapperName(classContext.preciseType());
- c << INDENT << "return Shiboken::Object::newObject(" << cpythonType << ", new ::" << computedWrapperName;
- c << "(*((" << typeName << "*)cppIn)), true, true);";
+ c << INDENT << "return Shiboken::Object::newObject(" << cpythonType
+ << ", new ::" << computedWrapperName << "(*reinterpret_cast<const "
+ << typeName << "*>(cppIn)), true, true);";
writeCppToPythonFunction(s, code, sourceTypeName, targetTypeName);
s << endl;
@@ -1328,7 +1346,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
else
wrappedCPtrExpression = cpythonWrapperCPtr(classContext.preciseType(), pyInVariable);
- c << INDENT << "*((" << typeName << "*)cppOut) = *"
+ c << INDENT << "*reinterpret_cast<" << typeName << "*>(cppOut) = *"
<< wrappedCPtrExpression << ';';
writePythonToCppFunction(s, code, sourceTypeName, targetTypeName);
@@ -1593,7 +1611,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
} else {
s << context.preciseType()->cppSignature();
}
- s << "* cptr = 0;" << endl;
+ s << "* cptr{};" << endl;
initPythonArguments = maxArgs > 0;
usesNamedArguments = !ownerClass->isQObject() && overloadData.hasArgumentWithDefaultValue();
@@ -1604,7 +1622,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
writeCppSelfDefinition(s, rfunc, context, overloadData.hasStaticFunction());
}
if (!rfunc->isInplaceOperator() && overloadData.hasNonVoidReturnType())
- s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << " = 0;" << endl;
+ s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << "{};" << endl;
initPythonArguments = minArgs != maxArgs || maxArgs > 1;
usesNamedArguments = rfunc->isCallOperator() || overloadData.hasArgumentWithDefaultValue();
@@ -1613,9 +1631,14 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
if (maxArgs > 0) {
s << INDENT << "int overloadId = -1;" << endl;
s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR;
- if (pythonFunctionWrapperUsesListOfArguments(overloadData))
- s << "[] = { 0" << QString::fromLatin1(", 0").repeated(maxArgs-1) << " }";
- s << ';' << endl;
+ if (pythonFunctionWrapperUsesListOfArguments(overloadData)) {
+ s << "[] = { " << NULL_PTR;
+ for (int i = 1; i < maxArgs; ++i)
+ s << ", " << NULL_PTR;
+ s << " };" << endl;
+ } else {
+ s << "{};" << endl;
+ }
writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
}
@@ -1659,7 +1682,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
QStringList argNamesList = argNamesSet.toList();
qSort(argNamesList.begin(), argNamesList.end());
if (argNamesList.isEmpty()) {
- s << INDENT << "const char** argNames = 0;" << endl;
+ s << INDENT << "const char** argNames{};" << endl;
} else {
s << INDENT << "const char* argNames[] = {\""
<< argNamesList.join(QLatin1String("\", \"")) << "\"};" << endl;
@@ -1854,7 +1877,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
Indentation indent(INDENT);
s << INDENT << "PyErr_Clear();" << endl;
s << INDENT << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");" << endl;
- s << INDENT << PYTHON_RETURN_VAR << " = 0;" << endl;
+ s << INDENT << PYTHON_RETURN_VAR << " = " << NULL_PTR << ';' << endl;
}
s << INDENT << '}' << endl;
}
@@ -2083,93 +2106,8 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData)
QString argsVar = pythonFunctionWrapperUsesListOfArguments(overloadData)
? QLatin1String("args") : QLatin1String(PYTHON_ARG);
- if (verboseErrorMessagesDisabled()) {
- s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\", 0);" << endl;
- } else {
- QStringList overloadSignatures;
- const OverloadData::MetaFunctionList &overloads = overloadData.overloads();
- for (const AbstractMetaFunction *f : overloads) {
- QStringList args;
- const AbstractMetaArgumentList &arguments = f->arguments();
- for (AbstractMetaArgument *arg : arguments) {
- QString strArg;
- AbstractMetaType* argType = arg->type();
- if (isCString(argType)) {
- strArg = QLatin1String("\" SBK_BYTES_NAME \"");
- } else if (argType->isPrimitive()) {
- const PrimitiveTypeEntry* ptp = reinterpret_cast<const PrimitiveTypeEntry*>(argType->typeEntry());
- while (ptp->referencedTypeEntry())
- ptp = ptp->referencedTypeEntry();
- strArg = ptp->name();
- if (strArg == QLatin1String("QString")) {
- strArg = QLatin1String("unicode");
- } else if (strArg == QLatin1String("QChar")) {
- strArg = QLatin1String("1-unicode");
- } else {
- strArg = ptp->name();
- static const QRegularExpression regex(QStringLiteral("^signed\\s+"));
- Q_ASSERT(regex.isValid());
- strArg.remove(regex);
- if (strArg == QLatin1String("double"))
- strArg = QLatin1String("float");
- }
- } else if (argType->typeEntry()->isContainer()) {
- strArg = argType->fullName();
- if (strArg == QLatin1String("QList") || strArg == QLatin1String("QVector")
- || strArg == QLatin1String("QLinkedList") || strArg == QLatin1String("QStack")
- || strArg == QLatin1String("QQueue")) {
- strArg = QLatin1String("list");
- } else if (strArg == QLatin1String("QMap") || strArg == QLatin1String("QHash")
- || strArg == QLatin1String("QMultiMap") || strArg == QLatin1String("QMultiHash")) {
- strArg = QLatin1String("dict");
- } else if (strArg == QLatin1String("QPair")) {
- strArg = QLatin1String("2-tuple");
- }
- } else {
- strArg = argType->fullName();
- if (strArg == QLatin1String("PyUnicode"))
- strArg = QLatin1String("unicode");
- else if (strArg == QLatin1String("PyString"))
- strArg = QLatin1String("str");
- else if (strArg == QLatin1String("PyBytes"))
- strArg = QLatin1String("\" SBK_BYTES_NAME \"");
- else if (strArg == QLatin1String("PyByteArray"))
- strArg = QLatin1String("bytearray");
- else if (strArg == QLatin1String("PySequence"))
- strArg = QLatin1String("list");
- else if (strArg == QLatin1String("PyTuple"))
- strArg = QLatin1String("tuple");
- else if (strArg == QLatin1String("PyDict"))
- strArg = QLatin1String("dict");
- else if (strArg == QLatin1String("PyObject"))
- strArg = QLatin1String("object");
- else if (strArg == QLatin1String("PyCallable"))
- strArg = QLatin1String("callable");
- else if (strArg == QLatin1String("uchar"))
- strArg = QLatin1String("buffer"); // This depends on an inject code to be true, but if it's not true
- // the function wont work at all, so it must be true.
- }
- if (!arg->defaultValueExpression().isEmpty()) {
- strArg += QLatin1String(" = ");
- if ((isCString(argType) || isPointerToWrapperType(argType))
- && arg->defaultValueExpression() == QLatin1String("0")) {
- strArg += QLatin1String("None");
- } else {
- QString e = arg->defaultValueExpression();
- e.replace(QLatin1String("::"), QLatin1String("."));
- e.replace(QLatin1String("\""), QLatin1String("\\\""));
- strArg += e;
- }
- }
- args << strArg;
- }
- overloadSignatures << QLatin1Char('"') + args.join(QLatin1String(", ")) + QLatin1Char('"');
- }
- s << INDENT << "const char* overloads[] = {" << overloadSignatures.join(QLatin1String(", "))
- << ", 0};" << endl;
- s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\", overloads);" << endl;
- }
- s << INDENT << returnStatement(m_currentErrorCode) << endl;
+ s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\");" << endl;
+ s << INDENT << "return " << m_currentErrorCode << ';' << endl;
}
void CppGenerator::writeFunctionReturnErrorCheckSection(QTextStream& s, bool hasReturnValue)
@@ -2528,7 +2466,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(QTextStream& s, const Overload
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"reverse operator not implemented.\");" << endl;
- s << INDENT << "return 0;" << endl;
+ s << INDENT << "return {};" << endl;
}
s << INDENT << "}" << endl << endl;
}
@@ -2767,7 +2705,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
// When an argument is removed from a method signature and no other means of calling
// the method are provided (as with code injection) the generator must abort.
qFatal(qPrintable(QString::fromLatin1("No way to call '%1::%2' with the modifications described in the type system.")
- .arg(func->ownerClass()->name(), func->signature())), NULL);
+ .arg(func->ownerClass()->name(), func->signature())));
}
removedArgs++;
continue;
@@ -2848,7 +2786,8 @@ void CppGenerator::writeCppToPythonFunction(QTextStream& s, const QString& code,
static void replaceCppToPythonVariables(QString& code, const QString& typeName)
{
- code.prepend(QString::fromLatin1("%1& cppInRef = *((%1*)cppIn);\n").arg(typeName));
+ code.prepend(QLatin1String("auto &cppInRef = *reinterpret_cast<")
+ + typeName + QLatin1String("*>(const_cast<void *>(cppIn));\n"));
code.replace(QLatin1String("%INTYPE"), typeName);
code.replace(QLatin1String("%OUTTYPE"), QLatin1String("PyObject*"));
code.replace(QLatin1String("%in"), QLatin1String("cppInRef"));
@@ -2864,9 +2803,9 @@ void CppGenerator::writeCppToPythonFunction(QTextStream& s, const AbstractMetaTy
{
const CustomConversion* customConversion = containerType->typeEntry()->customConversion();
if (!customConversion) {
- qFatal(qPrintable(QString::fromLatin1("Can't write the C++ to Python conversion function for container type '%1' - "\
- "no conversion rule was defined for it in the type system.")
- .arg(containerType->typeEntry()->qualifiedCppName())), NULL);
+ qFatal("Can't write the C++ to Python conversion function for container type '%s' - "\
+ "no conversion rule was defined for it in the type system.",
+ qPrintable(containerType->typeEntry()->qualifiedCppName()));
}
if (!containerType->typeEntry()->isContainer()) {
writeCppToPythonFunction(s, customConversion);
@@ -2919,7 +2858,7 @@ void CppGenerator::writeIsPythonConvertibleToCppFunction(QTextStream& s,
Indentation indent(INDENT);
s << INDENT << "return " << pythonToCppFuncName << ';' << endl;
}
- s << INDENT << "return 0;" << endl;
+ s << INDENT << "return {};" << endl;
s << '}' << endl;
}
@@ -2939,8 +2878,9 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s,
conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType->typeEntry(), QLatin1String("pyIn"));
if (!preConversion.isEmpty())
c << INDENT << preConversion << endl;
- c << INDENT << QString::fromLatin1("*((%1*)cppOut) = %1(%2);")
- .arg(getFullTypeName(targetType->typeEntry()), conversion);
+ const QString fullTypeName = getFullTypeName(targetType->typeEntry());
+ c << INDENT << "*reinterpret_cast<" << fullTypeName << "*>(cppOut) = "
+ << fullTypeName << '(' << conversion << ");";
QString sourceTypeName = fixedCppTypeName(sourceType);
QString targetTypeName = fixedCppTypeName(targetType);
writePythonToCppFunction(s, code, sourceTypeName, targetTypeName);
@@ -2966,7 +2906,8 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s,
code.replace(QLatin1String("%INTYPE"), inType);
code.replace(QLatin1String("%OUTTYPE"), targetType->qualifiedCppName());
code.replace(QLatin1String("%in"), QLatin1String("pyIn"));
- code.replace(QLatin1String("%out"), QString::fromLatin1("*((%1*)cppOut)").arg(getFullTypeName(targetType)));
+ code.replace(QLatin1String("%out"),
+ QLatin1String("*reinterpret_cast<") + getFullTypeName(targetType) + QLatin1String("*>(cppOut)"));
QString sourceTypeName = fixedCppTypeName(toNative);
QString targetTypeName = fixedCppTypeName(targetType);
@@ -2991,9 +2932,9 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s,
}
if (typeCheck.isEmpty()) {
if (!toNative->sourceType() || toNative->sourceType()->isPrimitive()) {
- qFatal(qPrintable(QString::fromLatin1("User added implicit conversion for C++ type '%1' must provide either an input "\
- "type check function or a non primitive type entry.")
- .arg(targetType->qualifiedCppName())), NULL);
+ qFatal("User added implicit conversion for C++ type '%s' must provide either an input "\
+ "type check function or a non primitive type entry.",
+ qPrintable(targetType->qualifiedCppName()));
}
typeCheck = QString::fromLatin1("PyObject_TypeCheck(%in, %1)").arg(cpythonTypeNameExt(toNative->sourceType()));
@@ -3019,7 +2960,8 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s, const Abs
QString cppTypeName = getFullTypeNameWithoutModifiers(containerType);
QString code;
QTextStream c(&code);
- c << INDENT << QString::fromLatin1("%1& cppOutRef = *((%1*)cppOut);").arg(cppTypeName) << endl;
+ c << INDENT << "auto &cppOutRef = *reinterpret_cast<"
+ << cppTypeName << "*>(cppOut);\n";
code.append(toCppConversions.constFirst()->conversion());
for (int i = 0; i < containerType->instantiations().count(); ++i) {
const AbstractMetaType* type = containerType->instantiations().at(i);
@@ -3384,8 +3326,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
mc << func->originalName();
} else {
- if (!func->isStatic())
- mc << "((::" << wrapperName(func->ownerClass()) << "*) " << CPP_SELF_VAR << ")->";
+ if (!func->isStatic()) {
+ const auto *owner = func->ownerClass();
+ const bool directInheritance = context.metaClass() == owner;
+ mc << (directInheritance ? "static_cast" : "reinterpret_cast")
+ << "<::" << wrapperName(owner) << "*>(" << CPP_SELF_VAR << ")->";
+ }
if (!func->isAbstract())
mc << (func->isProtected() ? wrapperName(func->ownerClass()) :
@@ -3836,6 +3782,29 @@ bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass* metaClass)
return false;
}
+struct pyTypeSlotEntry
+{
+ explicit pyTypeSlotEntry(const char *name, const QString &function) :
+ m_name(name), m_function(function) {}
+
+ const char *m_name;
+ const QString &m_function;
+};
+
+QTextStream &operator<<(QTextStream &str, const pyTypeSlotEntry &e)
+{
+ str << '{' << e.m_name << ',';
+ const int padding = qMax(0, 18 - int(strlen(e.m_name)));
+ for (int p = 0; p < padding; ++p)
+ str << ' ';
+ if (e.m_function.isEmpty())
+ str << NULL_PTR;
+ else
+ str << "reinterpret_cast<void*>(" << e.m_function << ')';
+ str << "},\n";
+ return str;
+}
+
void CppGenerator::writeClassDefinition(QTextStream &s,
const AbstractMetaClass *metaClass,
GeneratorContext &classContext)
@@ -3844,11 +3813,11 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
QString tp_init;
QString tp_new;
QString tp_dealloc;
- QString tp_hash(QLatin1Char('0'));
- QString tp_call = tp_hash;
+ QString tp_hash;
+ QString tp_call;
QString cppClassName = metaClass->qualifiedCppName();
const QString className = chopType(cpythonTypeName(metaClass));
- QString baseClassName(QLatin1Char('0'));
+ QString baseClassName;
AbstractMetaFunctionList ctors;
const AbstractMetaFunctionList &allCtors = metaClass->queryFunctions(AbstractMetaClass::Constructors);
for (AbstractMetaFunction *f : allCtors) {
@@ -3869,7 +3838,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
tp_dealloc = metaClass->hasPrivateDestructor() ?
QLatin1String("SbkDeallocWrapperWithPrivateDtor") :
QLatin1String("object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */");
- tp_init = QLatin1String("0");
+ tp_init.clear();
} else {
QString deallocClassName;
if (shouldGenerateCppWrapper(metaClass))
@@ -3880,11 +3849,12 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
tp_dealloc = QLatin1String("&SbkDeallocQAppWrapper");
else
tp_dealloc = QLatin1String("&SbkDeallocWrapper");
- tp_init = (onlyPrivCtor || ctors.isEmpty()) ? QLatin1String("0") : cpythonFunctionName(ctors.constFirst());
+ if (!onlyPrivCtor && !ctors.isEmpty())
+ tp_init = cpythonFunctionName(ctors.constFirst());
}
- QString tp_getattro(QLatin1Char('0'));
- QString tp_setattro = tp_getattro;
+ QString tp_getattro;
+ QString tp_setattro;
if (usePySideExtensions() && (metaClass->qualifiedCppName() == QLatin1String("QObject"))) {
tp_getattro = cpythonGetattroFunctionName(metaClass);
tp_setattro = cpythonSetattroFunctionName(metaClass);
@@ -3921,11 +3891,11 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
tp_flags.append(QLatin1String("|Py_TPFLAGS_HAVE_GC"));
}
- QString tp_richcompare = QString(QLatin1Char('0'));
+ QString tp_richcompare;
if (!metaClass->isNamespace() && metaClass->hasComparisonOperatorOverload())
tp_richcompare = cpythonBaseName(metaClass) + QLatin1String("_richcompare");
- QString tp_getset = QString(QLatin1Char('0'));
+ QString tp_getset;
if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer())
tp_getset = cpythonGettersSettersDefinitionName(metaClass);
@@ -3936,7 +3906,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
if (m_tpFuncs.contains(func->name()))
m_tpFuncs[func->name()] = cpythonFunctionName(func);
}
- if (m_tpFuncs[QLatin1String("__repr__")] == QLatin1String("0")
+ if (m_tpFuncs.value(QLatin1String("__repr__")).isEmpty()
&& !metaClass->isQObject()
&& metaClass->hasToStringCapability()) {
m_tpFuncs[QLatin1String("__repr__")] = writeReprFunction(s, classContext);
@@ -3979,23 +3949,23 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
s << "}" << endl;
s << endl;
s << "static PyType_Slot " << className << "_slots[] = {" << endl;
- s << INDENT << "{Py_tp_base, (void *)0}, // inserted by introduceWrapperType" << endl;
- s << INDENT << "{Py_tp_dealloc, (void *)" << tp_dealloc << "}," << endl;
- s << INDENT << "{Py_tp_repr, (void *)" << m_tpFuncs[QLatin1String("__repr__")] << "}," << endl;
- s << INDENT << "{Py_tp_hash, (void *)" << tp_hash << "}," << endl;
- s << INDENT << "{Py_tp_call, (void *)" << tp_call << "}," << endl;
- s << INDENT << "{Py_tp_str, (void *)" << m_tpFuncs[QLatin1String("__str__")] << "}," << endl;
- s << INDENT << "{Py_tp_getattro, (void *)" << tp_getattro << "}," << endl;
- s << INDENT << "{Py_tp_setattro, (void *)" << tp_setattro << "}," << endl;
- s << INDENT << "{Py_tp_traverse, (void *)" << className << "_traverse}," << endl;
- s << INDENT << "{Py_tp_clear, (void *)" << className << "_clear}," << endl;
- s << INDENT << "{Py_tp_richcompare, (void *)" << tp_richcompare << "}," << endl;
- s << INDENT << "{Py_tp_iter, (void *)" << m_tpFuncs[QLatin1String("__iter__")] << "}," << endl;
- s << INDENT << "{Py_tp_iternext, (void *)" << m_tpFuncs[QLatin1String("__next__")] << "}," << endl;
- s << INDENT << "{Py_tp_methods, (void *)" << className << "_methods}," << endl;
- s << INDENT << "{Py_tp_getset, (void *)" << tp_getset << "}," << endl;
- s << INDENT << "{Py_tp_init, (void *)" << tp_init << "}," << endl;
- s << INDENT << "{Py_tp_new, (void *)" << tp_new << "}," << endl;
+ s << INDENT << "{Py_tp_base, nullptr}, // inserted by introduceWrapperType" << endl;
+ s << INDENT << pyTypeSlotEntry("Py_tp_dealloc", tp_dealloc)
+ << INDENT << pyTypeSlotEntry("Py_tp_repr", m_tpFuncs.value(QLatin1String("__repr__")))
+ << INDENT << pyTypeSlotEntry("Py_tp_hash", tp_hash)
+ << INDENT << pyTypeSlotEntry("Py_tp_call", tp_call)
+ << INDENT << pyTypeSlotEntry("Py_tp_str", m_tpFuncs.value(QLatin1String("__str__")))
+ << INDENT << pyTypeSlotEntry("Py_tp_getattro", tp_getattro)
+ << INDENT << pyTypeSlotEntry("Py_tp_setattro", tp_setattro)
+ << INDENT << pyTypeSlotEntry("Py_tp_traverse", className + QLatin1String("_traverse"))
+ << INDENT << pyTypeSlotEntry("Py_tp_clear", className + QLatin1String("_clear"))
+ << INDENT << pyTypeSlotEntry("Py_tp_richcompare", tp_richcompare)
+ << INDENT << pyTypeSlotEntry("Py_tp_iter", m_tpFuncs.value(QLatin1String("__iter__")))
+ << INDENT << pyTypeSlotEntry("Py_tp_iternext", m_tpFuncs.value(QLatin1String("__next__")))
+ << INDENT << pyTypeSlotEntry("Py_tp_methods", className + QLatin1String("_methods"))
+ << INDENT << pyTypeSlotEntry("Py_tp_getset", tp_getset)
+ << INDENT << pyTypeSlotEntry("Py_tp_init", tp_init)
+ << INDENT << pyTypeSlotEntry("Py_tp_new", tp_new);
if (supportsSequenceProtocol(metaClass)) {
s << INDENT << "// type supports sequence protocol" << endl;
writeTypeAsSequenceDefinition(s, metaClass);
@@ -4009,7 +3979,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
s << INDENT << "// type supports number protocol" << endl;
writeTypeAsNumberDefinition(s, metaClass);
}
- s << INDENT << "{0, 0}" << endl;
+ s << INDENT << "{0, " << NULL_PTR << '}' << endl;
s << "};" << endl;
s << "static PyType_Spec " << className << "_spec = {" << endl;
s << INDENT << "\"" << computedClassTargetFullName << "\"," << endl;
@@ -4259,7 +4229,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
const AbstractMetaField *metaField,
GeneratorContext &context)
{
- ErrorCode errorCode(0);
+ ErrorCode errorCode(QString::fromLatin1(NULL_PTR));
s << "static PyObject* " << cpythonGetterFunctionName(metaField) << "(PyObject* self, void*)" << endl;
s << '{' << endl;
@@ -4271,9 +4241,9 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
QString cppField;
if (avoidProtectedHack() && metaField->isProtected()) {
- cppField = QString::fromLatin1("((%1*)%2)->%3()")
- .arg(wrapperName(metaField->enclosingClass()), QLatin1String(CPP_SELF_VAR),
- protectedFieldGetterName(metaField));
+ QTextStream(&cppField) << "static_cast<"
+ << wrapperName(metaField->enclosingClass()) << "*>("
+ << CPP_SELF_VAR << ")->" << protectedFieldGetterName(metaField) << "()";
} else {
cppField = QLatin1String(CPP_SELF_VAR) + QLatin1String("->") + metaField->name();
if (newWrapperSameObject) {
@@ -4296,7 +4266,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
cppField = QLatin1String("fieldValue");
}
- s << INDENT << "PyObject* pyOut = 0;\n";
+ s << INDENT << "PyObject* pyOut = {};\n";
if (newWrapperSameObject) {
// Special case colocated field with same address (first field in a struct)
s << INDENT << "if (reinterpret_cast<void *>("
@@ -4316,7 +4286,8 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
s << INDENT << "else if (Shiboken::BindingManager::instance().hasWrapper(" << cppField << ")) {" << "\n";
{
Indentation indent(INDENT);
- s << INDENT << "pyOut = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(" << cppField << ");" << "\n";
+ s << INDENT << "pyOut = reinterpret_cast<PyObject*>(Shiboken::BindingManager::instance().retrieveWrapper("
+ << cppField << "));" << "\n";
s << INDENT << "Py_IncRef(pyOut);" << "\n";
s << INDENT << "return pyOut;" << "\n";
}
@@ -4346,7 +4317,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
writeCppSelfDefinition(s, context);
- s << INDENT << "if (pyIn == 0) {" << endl;
+ s << INDENT << "if (pyIn == " << NULL_PTR << ") {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"'";
@@ -4375,9 +4346,9 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << getFullTypeNameWithoutModifiers(fieldType);
s << (fieldType->indirections() == 1 ? "*" : "") << " cppOut;" << endl;
s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut);" << endl;
- s << INDENT << QString::fromLatin1("((%1*)%2)->%3(cppOut)")
- .arg(wrapperName(metaField->enclosingClass()),
- QLatin1String(CPP_SELF_VAR), protectedFieldSetterName(metaField));
+ s << INDENT << "static_cast<" << wrapperName(metaField->enclosingClass())
+ << "*>(" << CPP_SELF_VAR << ")->" << protectedFieldSetterName(metaField)
+ << "(cppOut)";
} else if (isCppIntegralPrimitive(fieldType) || fieldType->typeEntry()->isEnum() || fieldType->typeEntry()->isFlags()) {
s << getFullTypeNameWithoutModifiers(fieldType) << " cppOut_local = " << cppField << ';' << endl;
s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_local);" << endl;
@@ -4410,7 +4381,7 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << '{' << endl;
writeCppSelfDefinition(s, context, false, true);
writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
- s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << " = 0;" << endl;
+ s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << "{};" << endl;
s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ';' << endl;
writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
s << endl;
@@ -4531,7 +4502,8 @@ void CppGenerator::writeMethodDefinitionEntry(QTextStream& s, const AbstractMeta
int min = overloadData.minArgs();
int max = overloadData.maxArgs();
- s << '"' << func->name() << "\", (PyCFunction)" << cpythonFunctionName(func) << ", ";
+ s << '"' << func->name() << "\", reinterpret_cast<PyCFunction>("
+ << cpythonFunctionName(func) << "), ";
if ((min == max) && (max < 2) && !usePyArgs) {
if (max == 0)
s << "METH_NOARGS";
@@ -4842,7 +4814,7 @@ void CppGenerator::writeFlagsNumberMethodsDefinition(QTextStream& s, const Abstr
s << "#ifndef IS_PY3K" << endl;
s << INDENT << "{Py_nb_long, (void *)" << cpythonName << "_long}," << endl;
s << "#endif" << endl;
- s << INDENT << "{0, 0} // sentinel" << endl;
+ s << INDENT << "{0, " << NULL_PTR << "} // sentinel" << endl;
s << "};" << endl << endl;
}
@@ -4858,11 +4830,15 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream& s, const AbstractMetaEn
AbstractMetaType* flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry);
s << INDENT << "::" << flagsEntry->originalName() << " cppResult, " << CPP_SELF_VAR << ", cppArg;" << endl;
s << "#ifdef IS_PY3K" << endl;
- s << INDENT << CPP_SELF_VAR << " = (::" << flagsEntry->originalName() << ")(int)PyLong_AsLong(self);" << endl;
- s << INDENT << "cppArg = (" << flagsEntry->originalName() << ")(int)PyLong_AsLong(" << PYTHON_ARG << ");" << endl;
+ s << INDENT << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName()
+ << ">(int(PyLong_AsLong(self)));" << endl;
+ s << INDENT << "cppArg = static_cast<" << flagsEntry->originalName() << ">(int(PyLong_AsLong("
+ << PYTHON_ARG << ")));" << endl;
s << "#else" << endl;
- s << INDENT << CPP_SELF_VAR << " = (::" << flagsEntry->originalName() << ")(int)PyInt_AsLong(self);" << endl;
- s << INDENT << "cppArg = (" << flagsEntry->originalName() << ")(int)PyInt_AsLong(" << PYTHON_ARG << ");" << endl;
+ s << INDENT << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName()
+ << ">(int(PyInt_AsLong(self)));" << endl;
+ s << INDENT << "cppArg = static_cast<" << flagsEntry->originalName()
+ << ">(int(PyInt_AsLong(" << PYTHON_ARG << ")));" << endl;
s << "#endif" << endl << endl;
s << INDENT << "cppResult = " << CPP_SELF_VAR << " " << cppOpName << " cppArg;" << endl;
s << INDENT << "return ";
@@ -4941,15 +4917,16 @@ void CppGenerator::writeClassRegister(QTextStream &s,
QString pyTypeBasesVariable = chopType(pyTypeName) + QLatin1String("_Type_bases");
const AbstractMetaClassList baseClasses = getBaseClasses(metaClass);
if (metaClass->baseClassNames().size() > 1) {
- s << INDENT << "PyObject* " << pyTypeBasesVariable << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl;
- QStringList bases;
- for (const AbstractMetaClass *base : baseClasses)
- bases << QLatin1String("(PyObject*)") + cpythonTypeNameExt(base->typeEntry());
+ s << INDENT << "PyObject* " << pyTypeBasesVariable
+ << " = PyTuple_Pack(" << baseClasses.size() << ',' << endl;
Indentation indent(INDENT);
- QString separator;
- QTextStream sep(&separator);
- sep << "," << endl << INDENT;
- s << INDENT << bases.join(separator) << ");" << endl << endl;
+ for (int i = 0, size = baseClasses.size(); i < size; ++i) {
+ if (i)
+ s << "," << endl;
+ s << INDENT << "reinterpret_cast<PyObject*>("
+ << cpythonTypeNameExt(baseClasses.at(i)->typeEntry()) << ')';
+ }
+ s << ");" << endl << endl;
}
// Create type and insert it in the module or enclosing class.
@@ -5215,7 +5192,7 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta
}
}
- s << INDENT << "return 0;" << endl;
+ s << INDENT << "return {};" << endl;
s << "}\n\n";
}
@@ -5344,7 +5321,7 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte
s << INDENT << "} else {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL;" << endl;
+ s << INDENT << "if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return nullptr;" << endl;
s << INDENT << "PyErr_Clear();" << endl;
s << INDENT << "// Try to find the 'name' attribute, by retrieving the PyObject for "
@@ -5371,7 +5348,7 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte
s << INDENT << "PyErr_Format(PyExc_AttributeError," << endl;
s << INDENT << " \"'%.50s' object has no attribute '%.400s'\"," << endl;
s << INDENT << " tp->tp_name, PyBytes_AS_STRING(name));" << endl;
- s << INDENT << "return NULL;" << endl;
+ s << INDENT << "return nullptr;" << endl;
}
s << INDENT << "} else {" << endl;
{
@@ -5644,13 +5621,13 @@ bool CppGenerator::finishGeneration()
s << "static struct PyModuleDef moduledef = {" << endl;
s << " /* m_base */ PyModuleDef_HEAD_INIT," << endl;
s << " /* m_name */ \"" << moduleName() << "\"," << endl;
- s << " /* m_doc */ 0," << endl;
+ s << " /* m_doc */ nullptr," << endl;
s << " /* m_size */ -1," << endl;
s << " /* m_methods */ " << moduleName() << "_methods," << endl;
- s << " /* m_reload */ 0," << endl;
- s << " /* m_traverse */ 0," << endl;
- s << " /* m_clear */ 0," << endl;
- s << " /* m_free */ 0" << endl;
+ s << " /* m_reload */ nullptr," << endl;
+ s << " /* m_traverse */ nullptr," << endl;
+ s << " /* m_clear */ nullptr," << endl;
+ s << " /* m_free */ nullptr" << endl;
s << "};" << endl << endl;
s << "#endif" << endl;
s << "SBK_MODULE_INIT_FUNCTION_BEGIN(" << moduleName() << ")" << endl;
@@ -5963,7 +5940,7 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " << CPP_SELF_VAR << "->begin();" << endl;
s << INDENT << "for (Py_ssize_t pos = 0; pos < _i; pos++) _item++;" << endl;
s << INDENT << "*_item = cppValue;" << endl;
- s << INDENT << "return 0;" << endl;
+ s << INDENT << "return {};" << endl;
s << '}' << endl;
}
void CppGenerator::writeIndexError(QTextStream& s, const QString& errorMsg)
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index b9eea7529..ac0b2ffaf 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -41,7 +41,6 @@
#include <limits>
#include <memory>
-static const char NULL_VALUE[] = "NULL";
static const char AVOID_PROTECTED_HACK[] = "avoid-protected-hack";
static const char PARENT_CTOR_HEURISTIC[] = "enable-parent-ctor-heuristic";
static const char RETURN_VALUE_HEURISTIC[] = "enable-return-value-heuristic";
@@ -53,6 +52,7 @@ const char *CPP_ARG = "cppArg";
const char *CPP_ARG_REMOVED = "removed_cppArg";
const char *CPP_RETURN_VAR = "cppResult";
const char *CPP_SELF_VAR = "cppSelf";
+const char *NULL_PTR = "nullptr";
const char *PYTHON_ARG = "pyArg";
const char *PYTHON_ARGS = "pyArgs";
const char *PYTHON_OVERRIDE_VAR = "pyOverride";
@@ -151,10 +151,10 @@ ShibokenGenerator::~ShibokenGenerator() = default;
void ShibokenGenerator::clearTpFuncs()
{
- m_tpFuncs.insert(QLatin1String("__str__"), QLatin1String("0"));
- m_tpFuncs.insert(QLatin1String("__repr__"), QLatin1String("0"));
- m_tpFuncs.insert(QLatin1String("__iter__"), QLatin1String("0"));
- m_tpFuncs.insert(QLatin1String("__next__"), QLatin1String("0"));
+ m_tpFuncs.insert(QLatin1String("__str__"), QString());
+ m_tpFuncs.insert(QLatin1String("__repr__"), QString());
+ m_tpFuncs.insert(QLatin1String("__iter__"), QString());
+ m_tpFuncs.insert(QLatin1String("__next__"), QString());
}
void ShibokenGenerator::initPrimitiveTypesCorrespondences()
@@ -1396,7 +1396,7 @@ QString ShibokenGenerator::argumentString(const AbstractMetaFunction *func,
{
QString default_value = argument->originalDefaultValueExpression();
if (default_value == QLatin1String("NULL"))
- default_value = QLatin1String(NULL_VALUE);
+ default_value = QLatin1String(NULL_PTR);
//WORKAROUND: fix this please
if (default_value.startsWith(QLatin1String("new ")))
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index 60e31a99b..d2c4b3292 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -33,6 +33,7 @@ extern const char *CPP_ARG;
extern const char *CPP_ARG_REMOVED;
extern const char *CPP_RETURN_VAR;
extern const char *CPP_SELF_VAR;
+extern const char *NULL_PTR;
extern const char *PYTHON_ARG;
extern const char *PYTHON_ARGS;
extern const char *PYTHON_OVERRIDE_VAR;
@@ -200,7 +201,7 @@ protected:
void writeToCppConversion(QTextStream& s, const AbstractMetaType* type, const AbstractMetaClass* context, const QString& inArgName, const QString& outArgName);
void writeToCppConversion(QTextStream& s, const AbstractMetaClass* metaClass, const QString& inArgName, const QString& outArgName);
- /// Returns true if the argument is a pointer that rejects NULL values.
+ /// Returns true if the argument is a pointer that rejects nullptr values.
bool shouldRejectNullPointerArgument(const AbstractMetaFunction* func, int argIndex);
/// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
@@ -208,7 +209,7 @@ protected:
/// Adds enums eligible for generation from classes/namespaces marked not to be generated.
static void lookForEnumsInClassesNotToBeGenerated(AbstractMetaEnumList& enumList, const AbstractMetaClass* metaClass);
- /// Returns the enclosing class for an enum, or NULL if it should be global.
+ /// Returns the enclosing class for an enum, or nullptr if it should be global.
const AbstractMetaClass* getProperEnclosingClassForEnum(const AbstractMetaEnum* metaEnum);
QString wrapperName(const AbstractMetaClass* metaClass) const;
@@ -299,7 +300,7 @@ protected:
* \param type A string representing the type to be discovered.
* \param metaType A pointer to an AbstractMetaType pointer, to where write a new meta type object
* if one is produced from the \p type string. This object must be deallocated by
- * the caller. It will set the target variable to NULL, is \p type is a Python type.
+ * the caller. It will set the target variable to nullptr, is \p type is a Python type.
* \return A custom check if \p type is a custom type, or an empty string if \p metaType
* receives an existing type object.
*/
@@ -377,9 +378,10 @@ protected:
/**
* Builds an AbstractMetaType object from a QString.
- * Returns NULL if no type could be built from the string.
+ * Returns nullptr if no type could be built from the string.
* \param typeSignature The string describing the type to be built.
- * \return A new AbstractMetaType object that must be deleted by the caller, or a NULL pointer in case of failure.
+ * \return A new AbstractMetaType object that must be deleted by the caller,
+ * or a nullptr pointer in case of failure.
*/
AbstractMetaType *buildAbstractMetaTypeFromString(QString typeSignature,
QString *errorMessage = nullptr);
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index e820e749b..3e1a7e8e5 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -596,42 +596,10 @@ void init()
shibokenAlreadInitialised = true;
}
-void setErrorAboutWrongArguments(PyObject* args, const char* funcName, const char** cppOverloads)
-{
- std::string msg;
- std::string params;
- if (args) {
- if (PyTuple_Check(args)) {
- for (Py_ssize_t i = 0, max = PyTuple_GET_SIZE(args); i < max; ++i) {
- if (i)
- params += ", ";
- PyObject* arg = PyTuple_GET_ITEM(args, i);
- params += Py_TYPE(arg)->tp_name;
- }
- } else {
- params = Py_TYPE(args)->tp_name;
- }
- }
-
- if (!cppOverloads) {
- msg = "'" + std::string(funcName) + "' called with wrong argument types: " + params;
- } else {
- msg = "'" + std::string(funcName) + "' called with wrong argument types:\n ";
- msg += funcName;
- msg += '(';
- msg += params;
- msg += ")\n";
- msg += "Supported signatures:";
- for (int i = 0; cppOverloads[i]; ++i) {
- msg += "\n ";
- msg += funcName;
- msg += '(';
- msg += cppOverloads[i];
- msg += ')';
- }
- }
- PyErr_SetString(PyExc_TypeError, msg.c_str());
-
+// setErrorAboutWrongArguments now gets overload info from the signature module.
+void setErrorAboutWrongArguments(PyObject *args, const char *funcName)
+{
+ SetError_Argument(args, funcName);
}
class FindBaseTypeVisitor : public HierarchyVisitor
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index 15682c600..e1cc64ba9 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -141,7 +141,9 @@ void callCppDestructor(void* cptr)
* Shiboken::importModule is DEPRECATED. Use Shiboken::Module::import() instead.
*/
SBK_DEPRECATED(LIBSHIBOKEN_API bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr));
-LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject* args, const char* funcName, const char** cppOverloads);
+
+// setErrorAboutWrongArguments now gets overload info from the signature module.
+LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject* args, const char* funcName);
namespace ObjectType {
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 564e5fcef..a8874e2e0 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -74,6 +74,7 @@ typedef struct safe_globals_struc {
// init part 2: run module
PyObject *sigparse_func;
PyObject *createsig_func;
+ PyObject *seterror_argument_func;
} safe_globals_struc, *safe_globals;
static safe_globals pyside_globals = 0;
@@ -510,6 +511,9 @@ init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
p->createsig_func = PyObject_GetAttrString(p->helper_module, "create_signature");
if (p->createsig_func == NULL)
goto error;
+ p->seterror_argument_func = PyObject_GetAttrString(p->helper_module, "seterror_argument");
+ if (p->seterror_argument_func == NULL)
+ goto error;
return 0;
error:
@@ -950,4 +954,29 @@ FinishSignatureInitialization(PyObject *module, const char *signatures)
}
}
+void
+SetError_Argument(PyObject *args, const char *func_name)
+{
+ /*
+ * This function replaces the type error construction with extra
+ * overloads parameter in favor of using the signature module.
+ * Error messages are rare, so we do it completely in Python.
+ */
+ init_module_1();
+ init_module_2();
+ Shiboken::AutoDecRef res(PyObject_CallFunction(
+ pyside_globals->seterror_argument_func,
+ const_cast<char *>("(Os)"), args, func_name));
+ if (res.isNull()) {
+ PyErr_Print();
+ Py_FatalError("seterror_argument did not receive a result");
+ }
+ PyObject *err, *msg;
+ if (!PyArg_UnpackTuple(res, func_name, 2, 2, &err, &msg)) {
+ PyErr_Print();
+ Py_FatalError("unexpected failure in seterror_argument");
+ }
+ PyErr_SetObject(err, msg);
+}
+
} //extern "C"
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index b65317662..c850698a6 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -47,6 +47,7 @@ extern "C"
LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *); //WS
LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *);
+LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *);
} // extern "C"
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index 0eba3eaff..373ce102f 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -57,6 +57,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/__init__.py"
"${CMAKE_CURRENT_BINARY_DIR}/support/__init__.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/__init__.py"
"${CMAKE_CURRENT_BINARY_DIR}/support/signature/__init__.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/errorhandler.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/errorhandler.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/layout.py"
"${CMAKE_CURRENT_BINARY_DIR}/support/signature/layout.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/loader.py"
diff --git a/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py
new file mode 100644
index 000000000..902bb05af
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/errorhandler.py
@@ -0,0 +1,124 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+errorhandler.py
+
+This module handles the TypeError messages which were previously
+produced by the generated C code.
+
+This version is at least consistent with the signatures, which
+are created by the same module.
+
+Experimentally, we are trying to guess those errors which are
+just the wrong number of elements in an iterator.
+At the moment, it is unclear whether the information given is
+enough to produce a useful ValueError.
+
+This matter will be improved in a later version.
+"""
+
+from signature_loader import get_signature, inspect
+from signature_loader.mapping import update_mapping, namespace
+from textwrap import dedent
+
+
+def qt_isinstance(inst, the_type):
+ if the_type == float:
+ return isinstance(inst, int) or isinstance(int, float)
+ try:
+ return isinstance(inst, the_type)
+ except TypeError as e:
+ print("FIXME", e)
+ return False
+
+
+def matched_type(args, sigs):
+ for sig in sigs:
+ params = list(sig.parameters.values())
+ if len(args) > len(params):
+ continue
+ if len(args) < len(params):
+ k = len(args)
+ if params[k].default is params[k].empty:
+ # this is a necessary parameter, so it fails.
+ continue
+ ok = True
+ for arg, param in zip(args, params):
+ ann = param.annotation
+ if qt_isinstance(arg, ann):
+ continue
+ ok = False
+ if ok:
+ return sig
+ return None
+
+
+def seterror_argument(args, func_name):
+ update_mapping()
+ func = eval(func_name, namespace)
+ sigs = get_signature(func, "typeerror")
+ if type(sigs) != list:
+ sigs = [sigs]
+ if type(args) != tuple:
+ args = (args,)
+ # temp!
+ found = matched_type(args, sigs)
+ if found:
+ msg = dedent("""
+ '{func_name}' called with wrong argument values:
+ {func_name}{args}
+ Found signature:
+ {func_name}{found}
+ """.format(**locals())).strip()
+ return ValueError, msg
+ type_str = ", ".join(type(arg).__name__ for arg in args)
+ msg = dedent("""
+ '{func_name}' called with wrong argument types:
+ {func_name}({type_str})
+ Supported signatures:
+ """.format(**locals())).strip()
+ for sig in sigs:
+ msg += "\n {func_name}{sig}".format(**locals())
+ # We don't raise the error here, to avoid the loader in the traceback.
+ return TypeError, msg
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/support/signature/loader.py b/sources/shiboken2/shibokenmodule/support/signature/loader.py
index de27d441c..be30483fe 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/loader.py
@@ -181,6 +181,8 @@ with ensure_import_support():
mapping = sbk_mapping
mapping.__name__ = "mapping"
put_into_loader_package(mapping)
+ from support.signature import errorhandler
+ put_into_loader_package(errorhandler)
from support.signature import layout
put_into_loader_package(layout)
from support.signature.lib import enum_sig
diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
index 0195f0280..40db43729 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
@@ -203,6 +203,7 @@ def check_module(mod):
update_mapping = Reloader().update
type_map = {}
+namespace = globals() # our module's __dict__
def init_Shiboken():
diff --git a/sources/shiboken2/shibokenmodule/support/signature/parser.py b/sources/shiboken2/shibokenmodule/support/signature/parser.py
index 5178d9ef9..2f6e6e3f5 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/parser.py
@@ -45,8 +45,7 @@ import warnings
import types
import keyword
import functools
-from signature_loader.mapping import (
- type_map, update_mapping, __dict__ as namespace)
+from signature_loader.mapping import type_map, update_mapping, namespace
_DEBUG = False
LIST_KEYWORDS = False
diff --git a/sources/shiboken2/tests/samplebinding/decisor_test.py b/sources/shiboken2/tests/samplebinding/decisor_test.py
index 9102e2d4e..734c43760 100644
--- a/sources/shiboken2/tests/samplebinding/decisor_test.py
+++ b/sources/shiboken2/tests/samplebinding/decisor_test.py
@@ -43,13 +43,15 @@ class DecisorTest(unittest.TestCase):
This can trigger the bug #262, which means using an argument
not provided by the user.'''
pt = Point()
- self.assertRaises(TypeError, SampleNamespace.forceDecisorSideA, pt)
+ # This exception may move from a TypeError to a ValueError.
+ self.assertRaises((TypeError, ValueError), SampleNamespace.forceDecisorSideA, pt)
def testCallWithInvalidParametersSideB(self):
'''Same as the previous test, but with an integer as first argument,
just to complicate things for the overload method decisor.'''
pt = Point()
- self.assertRaises(TypeError, SampleNamespace.forceDecisorSideB, 1, pt)
+ # This exception may move from a TypeError to a ValueError.
+ self.assertRaises((TypeError, ValueError), SampleNamespace.forceDecisorSideB, 1, pt)
def testDecideCallWithInheritance(self):
'''Call methods overloads that receive parent and inheritor classes' instances.'''