aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--MANIFEST.in40
-rw-r--r--README.md52
-rw-r--r--README.pyside2.md71
-rw-r--r--README.shiboken2-generator.md37
-rw-r--r--README.shiboken2.md13
-rw-r--r--build_history/blacklist.txt3
-rw-r--r--build_scripts/build_scripts.pyqtc18
-rw-r--r--build_scripts/config.py399
-rw-r--r--build_scripts/main.py448
-rw-r--r--build_scripts/options.py106
-rw-r--r--build_scripts/platforms/linux.py136
-rw-r--r--build_scripts/platforms/macos.py119
-rw-r--r--build_scripts/platforms/unix.py272
-rw-r--r--build_scripts/platforms/windows_desktop.py475
-rw-r--r--build_scripts/setup_runner.py167
-rw-r--r--build_scripts/utils.py233
-rw-r--r--coin_build_instructions.py42
-rw-r--r--coin_test_instructions.py17
-rw-r--r--docs/building/options.rst2
-rwxr-xr-xexamples/opengl/hellogl2.py2
-rw-r--r--examples/samplebinding/CMakeLists.txt26
-rw-r--r--examples/scriptableapplication/CMakeLists.txt36
-rw-r--r--examples/scriptableapplication/pyside2.pri40
-rw-r--r--examples/scriptableapplication/scriptableapplication.pro4
-rw-r--r--examples/utils/pyside2_config.py328
-rw-r--r--keyword-errors.lst43
-rw-r--r--popenasync.py360
-rw-r--r--setup.py195
-rw-r--r--sources/cmake_helpers/helpers.cmake78
m---------sources/pyside2-tools0
-rw-r--r--sources/pyside2/CMakeLists.txt111
-rw-r--r--sources/pyside2/PySide2/CMakeLists.txt49
-rw-r--r--sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml33
-rw-r--r--sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml25
-rw-r--r--sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt15
-rw-r--r--sources/pyside2/PySide2/QtCharts/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtCharts/typesystem_charts.xml10
-rw-r--r--sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml2
-rw-r--r--sources/pyside2/PySide2/QtCore/CMakeLists.txt33
-rw-r--r--sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp158
-rw-r--r--sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp227
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml2391
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml8
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_win.xml10
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml8
-rw-r--r--sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml57
-rw-r--r--sources/pyside2/PySide2/QtGui/CMakeLists.txt38
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml1567
-rw-r--r--sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml4
-rw-r--r--sources/pyside2/PySide2/QtHelp/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtHelp/typesystem_help.xml4
-rw-r--r--sources/pyside2/PySide2/QtLocation/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml42
-rw-r--r--sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml8
-rw-r--r--sources/pyside2/PySide2/QtNetwork/CMakeLists.txt82
-rw-r--r--sources/pyside2/PySide2/QtNetwork/typesystem_network.xml108
-rw-r--r--sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml298
-rw-r--r--sources/pyside2/PySide2/QtPositioning/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml18
-rw-r--r--sources/pyside2/PySide2/QtQml/CMakeLists.txt14
-rw-r--r--sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp6
-rw-r--r--sources/pyside2/PySide2/QtQml/typesystem_qml.xml82
-rw-r--r--sources/pyside2/PySide2/QtQuick/CMakeLists.txt14
-rw-r--r--sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp1
-rw-r--r--sources/pyside2/PySide2/QtQuick/typesystem_quick.xml118
-rw-r--r--sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml4
-rw-r--r--sources/pyside2/PySide2/QtScript/CMakeLists.txt18
-rw-r--r--sources/pyside2/PySide2/QtScript/typesystem_script.xml44
-rw-r--r--sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml6
-rw-r--r--sources/pyside2/PySide2/QtScxml/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml8
-rw-r--r--sources/pyside2/PySide2/QtSensors/CMakeLists.txt16
-rw-r--r--sources/pyside2/PySide2/QtSql/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtSql/typesystem_sql.xml65
-rw-r--r--sources/pyside2/PySide2/QtSvg/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtSvg/typesystem_svg.xml4
-rw-r--r--sources/pyside2/PySide2/QtTest/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtTest/typesystem_test.xml4
-rw-r--r--sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml2
-rw-r--r--sources/pyside2/PySide2/QtUiTools/CMakeLists.txt18
-rw-r--r--sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml35
-rw-r--r--sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml4
-rw-r--r--sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml30
-rw-r--r--sources/pyside2/PySide2/QtWebKit/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml105
-rw-r--r--sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml26
-rw-r--r--sources/pyside2/PySide2/QtWidgets/CMakeLists.txt22
-rw-r--r--sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp161
-rw-r--r--sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp104
-rw-r--r--sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml779
-rw-r--r--sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtXml/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtXml/typesystem_xml.xml108
-rw-r--r--sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt13
-rw-r--r--sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml91
-rw-r--r--sources/pyside2/PySide2/__init__.py.in22
-rw-r--r--sources/pyside2/PySide2/_config.py.in13
-rw-r--r--sources/pyside2/PySide2/glue/qtcharts.cpp (renamed from sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp)16
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp1816
-rw-r--r--sources/pyside2/PySide2/glue/qtdatavisualization.cpp (renamed from sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp)16
-rw-r--r--sources/pyside2/PySide2/glue/qtgui.cpp539
-rw-r--r--sources/pyside2/PySide2/glue/qtmultimedia.cpp (renamed from sources/pyside2/PySide2/QtGui/glue/qguiapplication_init.cpp)19
-rw-r--r--sources/pyside2/PySide2/glue/qtnetwork.cpp (renamed from sources/pyside2/PySide2/QtCore/glue/qbytearray_bufferprotocol.cpp)65
-rw-r--r--sources/pyside2/PySide2/glue/qtopengl.cpp (renamed from sources/pyside2/libpyside/globalreceiver.h)68
-rw-r--r--sources/pyside2/PySide2/glue/qtqml.cpp (renamed from sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp)34
-rw-r--r--sources/pyside2/PySide2/glue/qtquick.cpp42
-rw-r--r--sources/pyside2/PySide2/glue/qtscript.cpp74
-rw-r--r--sources/pyside2/PySide2/glue/qtuitools.cpp (renamed from sources/pyside2/PySide2/QtUiTools/glue/uitools_loadui.cpp)31
-rw-r--r--sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp92
-rw-r--r--sources/pyside2/PySide2/glue/qtwidgets.cpp664
-rw-r--r--sources/pyside2/PySide2/glue/qtxml.cpp (renamed from sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp)49
-rw-r--r--sources/pyside2/PySide2/glue/qtxmlpatterns.cpp43
-rw-r--r--sources/pyside2/PySide2/support/__init__.py10
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py351
-rw-r--r--sources/pyside2/PySide2/support/signature/__init__.py8
-rw-r--r--sources/pyside2/PySide2/support/signature/layout.py42
-rw-r--r--sources/pyside2/PySide2/support/signature/lib/__init__.py40
-rw-r--r--sources/pyside2/PySide2/support/signature/lib/enum_sig.py42
-rw-r--r--sources/pyside2/PySide2/support/signature/loader.py110
-rw-r--r--sources/pyside2/PySide2/support/signature/mapping.py159
-rw-r--r--sources/pyside2/PySide2/support/signature/typing.py42
-rw-r--r--sources/pyside2/PySide2/templates/core_common.xml (renamed from sources/pyside2/PySide2/typesystem_templates.xml)365
-rw-r--r--sources/pyside2/PySide2/templates/datavisualization_common.xml (renamed from sources/pyside2/PySide2/QtCore/glue/qbytearray_mgetitem.cpp)83
-rw-r--r--sources/pyside2/PySide2/templates/gui_common.xml312
-rw-r--r--sources/pyside2/PySide2/templates/opengl_common.xml61
-rw-r--r--sources/pyside2/PySide2/templates/webkitwidgets_common.xml (renamed from sources/pyside2/PySide2/QtCore/glue/qobject_findchild.cpp)67
-rw-r--r--sources/pyside2/PySide2/templates/widgets_common.xml91
-rw-r--r--sources/pyside2/PySide2/templates/xml_common.xml58
-rw-r--r--sources/pyside2/cmake/Macros/PySideModules.cmake225
-rw-r--r--sources/pyside2/doc/CMakeLists.txt11
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.cpp)0
-rw-r--r--sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py (renamed from sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.cpp)0
-rw-r--r--sources/pyside2/doc/conf.py.in4
-rw-r--r--sources/pyside2/doc/gettingstarted.rst18
-rw-r--r--sources/pyside2/doc/index.rst3
-rw-r--r--sources/pyside2/doc/pysideapi2.rst7
-rw-r--r--sources/pyside2/doc/pysideversion.rst14
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst84
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/dialog.rst139
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/qml.rst63
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/uifiles.rst166
-rw-r--r--sources/pyside2/doc/tutorials/basictutorial/widgets.rst40
-rw-r--r--sources/pyside2/doc/tutorials/index.rst9
-rw-r--r--sources/pyside2/libpyside/CMakeLists.txt13
-rw-r--r--sources/pyside2/libpyside/PySide2Config-spec.cmake.in1
-rw-r--r--sources/pyside2/libpyside/destroylistener.cpp3
-rw-r--r--sources/pyside2/libpyside/destroylistener.h6
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.cpp991
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject.h45
-rw-r--r--sources/pyside2/libpyside/dynamicqmetaobject_p.h5
-rw-r--r--sources/pyside2/libpyside/globalreceiver.cpp329
-rw-r--r--sources/pyside2/libpyside/globalreceiverv2.cpp48
-rw-r--r--sources/pyside2/libpyside/globalreceiverv2.h26
-rw-r--r--sources/pyside2/libpyside/pyside.cpp90
-rw-r--r--sources/pyside2/libpyside/pyside.h12
-rw-r--r--sources/pyside2/libpyside/pyside2.pc.in1
-rw-r--r--sources/pyside2/libpyside/pyside_p.h71
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo.cpp20
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo.h6
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction.cpp7
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction.h7
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction_p.h4
-rw-r--r--sources/pyside2/libpyside/pysideproperty.cpp33
-rw-r--r--sources/pyside2/libpyside/pysideproperty.h4
-rw-r--r--sources/pyside2/libpyside/pysideqflags.cpp12
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp41
-rw-r--r--sources/pyside2/libpyside/pysidesignal.h13
-rw-r--r--sources/pyside2/libpyside/pysideslot.cpp9
-rw-r--r--sources/pyside2/libpyside/pysideweakref.cpp2
-rw-r--r--sources/pyside2/libpyside/signalmanager.cpp (renamed from sources/pyside2/libpyside/signalmanager.cpp.in)132
-rw-r--r--sources/pyside2/libpyside/signalmanager.h34
-rw-r--r--sources/pyside2/pyside_version.py4
-rw-r--r--sources/pyside2/tests/CMakeLists.txt1
-rw-r--r--sources/pyside2/tests/QtCore/CMakeLists.txt2
-rw-r--r--sources/pyside2/tests/QtCore/bug_826.py4
-rw-r--r--sources/pyside2/tests/QtCore/qabstractitemmodel_test.py4
-rw-r--r--sources/pyside2/tests/QtCore/qcbor_test.py74
-rw-r--r--sources/pyside2/tests/QtCore/qenum_test.py18
-rw-r--r--sources/pyside2/tests/QtCore/qjsondocument_test.py56
-rw-r--r--sources/pyside2/tests/QtCore/qmetaobject_test.py6
-rw-r--r--sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py23
-rw-r--r--sources/pyside2/tests/QtCore/qrandomgenerator_test.py2
-rw-r--r--sources/pyside2/tests/QtGui/qmatrix_test.py17
-rw-r--r--sources/pyside2/tests/QtNetwork/CMakeLists.txt1
-rw-r--r--sources/pyside2/tests/QtNetwork/qpassworddigestor_test.py45
-rw-r--r--sources/pyside2/tests/QtWidgets/bug_493.py8
-rw-r--r--sources/pyside2/tests/QtWidgets/python_properties_test.py2
-rw-r--r--sources/pyside2/tests/QtWidgets/qlabel_test.py9
-rw-r--r--sources/pyside2/tests/QtWidgets/qstandarditemmodel_test.py9
-rw-r--r--sources/pyside2/tests/QtWidgets/qstyle_test.py8
-rw-r--r--sources/pyside2/tests/QtWidgets/qwidget_test.py23
-rw-r--r--sources/pyside2/tests/pysidetest/CMakeLists.txt8
-rw-r--r--sources/pyside2/tests/pysidetest/new_inherited_functions_test.py153
-rw-r--r--sources/pyside2/tests/registry/existence_test.py2
-rw-r--r--sources/pyside2/tests/registry/init_platform.py99
-rw-r--r--sources/pyside2/tests/support/voidptr_test.py4
-rw-r--r--sources/shiboken2/ApiExtractor/CMakeLists.txt1
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp706
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.h14
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h45
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.cpp398
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetalang.h99
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.cpp34
-rw-r--r--sources/shiboken2/ApiExtractor/apiextractor.h3
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp236
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp49
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/clangutils.h14
-rw-r--r--sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp12
-rw-r--r--sources/shiboken2/ApiExtractor/doc/conf.py.in6
-rw-r--r--sources/shiboken2/ApiExtractor/doc/typesystem_conversionrule.rst3
-rw-r--r--sources/shiboken2/ApiExtractor/doc/typesystem_documentation.rst6
-rw-r--r--sources/shiboken2/ApiExtractor/doc/typesystem_manipulating_objects.rst50
-rw-r--r--sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst65
-rw-r--r--sources/shiboken2/ApiExtractor/docparser.cpp79
-rw-r--r--sources/shiboken2/ApiExtractor/docparser.h16
-rw-r--r--sources/shiboken2/ApiExtractor/doxygenparser.cpp30
-rw-r--r--sources/shiboken2/ApiExtractor/fileout.cpp180
-rw-r--r--sources/shiboken2/ApiExtractor/fileout.h15
-rw-r--r--sources/shiboken2/ApiExtractor/include.cpp5
-rw-r--r--sources/shiboken2/ApiExtractor/include.h3
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp446
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h142
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.cpp230
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h57
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel_enums.h13
-rw-r--r--sources/shiboken2/ApiExtractor/parser/enumvalue.h1
-rw-r--r--sources/shiboken2/ApiExtractor/qtdocparser.cpp1
-rw-r--r--sources/shiboken2/ApiExtractor/tests/CMakeLists.txt17
-rw-r--r--sources/shiboken2/ApiExtractor/tests/injectedcode.txt5
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp37
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp45
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.h3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp6
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testenum.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc5
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp99
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp3
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.cpp119
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtemplates.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp49
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testtyperevision.h2
-rw-r--r--sources/shiboken2/ApiExtractor/tests/testutil.h11
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.cpp390
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase.h28
-rw-r--r--sources/shiboken2/ApiExtractor/typedatabase_typedefs.h25
-rw-r--r--sources/shiboken2/ApiExtractor/typeparser.cpp57
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.cpp3913
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem.h381
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_enums.h21
-rw-r--r--sources/shiboken2/ApiExtractor/typesystem_p.h115
-rw-r--r--sources/shiboken2/CMakeLists.txt24
-rw-r--r--sources/shiboken2/data/generatorrunner.16
-rw-r--r--sources/shiboken2/doc/commandlineoptions.rst110
-rw-r--r--sources/shiboken2/doc/conf.py.in8
-rw-r--r--sources/shiboken2/doc/contents.rst4
-rw-r--r--sources/shiboken2/doc/images/icecream.pngbin0 -> 4272 bytes
-rw-r--r--sources/shiboken2/doc/images/qtforpython-underthehood.pngbin0 -> 19144 bytes
-rw-r--r--sources/shiboken2/doc/index.rst28
-rw-r--r--sources/shiboken2/doc/samplebinding.rst250
-rw-r--r--sources/shiboken2/generator/CMakeLists.txt30
-rw-r--r--sources/shiboken2/generator/__init__.py.in2
-rw-r--r--sources/shiboken2/generator/_config.py.in9
-rw-r--r--sources/shiboken2/generator/generator.cpp413
-rw-r--r--sources/shiboken2/generator/generator.h182
-rw-r--r--sources/shiboken2/generator/main.cpp329
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp132
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.h6
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp706
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.h15
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.cpp145
-rw-r--r--sources/shiboken2/generator/shiboken2/headergenerator.h4
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.cpp18
-rw-r--r--sources/shiboken2/generator/shiboken2/overloaddata.h2
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp451
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.h284
-rw-r--r--sources/shiboken2/libshiboken/autodecref.h29
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp360
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.h8
-rw-r--r--sources/shiboken2/libshiboken/basewrapper_p.h106
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.cpp49
-rw-r--r--sources/shiboken2/libshiboken/bindingmanager.h13
-rw-r--r--sources/shiboken2/libshiboken/gilstate.h5
-rw-r--r--sources/shiboken2/libshiboken/helper.cpp26
-rw-r--r--sources/shiboken2/libshiboken/helper.h11
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.cpp49
-rw-r--r--sources/shiboken2/libshiboken/pep384impl.h17
-rw-r--r--sources/shiboken2/libshiboken/pep384impl_doc.rst4
-rw-r--r--sources/shiboken2/libshiboken/qt_attribution.json2
-rw-r--r--sources/shiboken2/libshiboken/sbkconverter.cpp12
-rw-r--r--sources/shiboken2/libshiboken/sbkconverter.h3
-rw-r--r--sources/shiboken2/libshiboken/sbkconverter_p.h36
-rw-r--r--sources/shiboken2/libshiboken/sbkdbg.h5
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp193
-rw-r--r--sources/shiboken2/libshiboken/sbkpython.h58
-rw-r--r--sources/shiboken2/libshiboken/sbkstring.cpp5
-rw-r--r--sources/shiboken2/libshiboken/shibokenbuffer.cpp4
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp820
-rw-r--r--sources/shiboken2/libshiboken/signature.h6
-rw-r--r--sources/shiboken2/libshiboken/threadstatesaver.h8
-rw-r--r--sources/shiboken2/libshiboken/typespec.cpp45
-rw-r--r--sources/shiboken2/libshiboken/typespec.h4
-rw-r--r--sources/shiboken2/libshiboken/voidptr.cpp8
-rwxr-xr-xsources/shiboken2/shiboken_tool.py53
-rw-r--r--sources/shiboken2/shiboken_version.py6
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt54
-rw-r--r--sources/shiboken2/shibokenmodule/__init__.py.in4
-rw-r--r--sources/shiboken2/shibokenmodule/_config.py.in11
-rw-r--r--sources/shiboken2/shibokenmodule/support/__init__.py40
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/PSF-3.7.0.txt (renamed from sources/pyside2/PySide2/support/signature/PSF-3.7.0.txt)0
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/__init__.py47
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py (renamed from sources/pyside2/PySide2/support/signature/backport_inspect.py)4
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py (renamed from sources/pyside2/PySide2/support/signature/fix-complaints.py)2
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/layout.py246
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/lib/__init__.py40
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py168
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/loader.py202
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/mapping.py210
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/parser.py (renamed from sources/pyside2/PySide2/support/signature/parser.py)51
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/qt_attribution.json (renamed from sources/pyside2/PySide2/support/signature/qt_attribution.json)0
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/typing27.py (renamed from sources/pyside2/PySide2/support/signature/typing27.py)117
-rw-r--r--sources/shiboken2/tests/libsample/CMakeLists.txt1
-rw-r--r--sources/shiboken2/tests/libsample/exceptiontest.cpp64
-rw-r--r--sources/shiboken2/tests/libsample/exceptiontest.h48
-rw-r--r--sources/shiboken2/tests/libsample/mapuser.cpp5
-rw-r--r--sources/shiboken2/tests/libsample/mapuser.h2
-rw-r--r--sources/shiboken2/tests/libsample/nontypetemplate.h51
-rw-r--r--sources/shiboken2/tests/libsample/objecttype.cpp1
-rw-r--r--sources/shiboken2/tests/libsample/objecttype.h2
-rw-r--r--sources/shiboken2/tests/libsample/samplenamespace.cpp7
-rw-r--r--sources/shiboken2/tests/libsample/samplenamespace.h6
-rw-r--r--sources/shiboken2/tests/minimalbinding/CMakeLists.txt5
-rw-r--r--sources/shiboken2/tests/otherbinding/CMakeLists.txt5
-rwxr-xr-xsources/shiboken2/tests/otherbinding/extended_multiply_operator_test.py2
-rw-r--r--sources/shiboken2/tests/samplebinding/CMakeLists.txt8
-rw-r--r--sources/shiboken2/tests/samplebinding/exception_test.py78
-rw-r--r--sources/shiboken2/tests/samplebinding/global.h2
-rw-r--r--sources/shiboken2/tests/samplebinding/nontypetemplate_test.py44
-rw-r--r--sources/shiboken2/tests/samplebinding/typesystem_sample.xml9
-rw-r--r--sources/shiboken2/tests/smartbinding/CMakeLists.txt5
-rw-r--r--testing/runner.py34
-rw-r--r--testing/testing.pyqtc9
-rw-r--r--testing/wheel_tester.py295
385 files changed, 21281 insertions, 14223 deletions
diff --git a/.gitignore b/.gitignore
index 6a8b69288..903fc81f3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,6 @@
/build
/dist
/pyside*_build
-/pyside*_package
/pyside*_install
/PySide
/PySide-*.*.*
@@ -13,3 +12,5 @@ distribute-*.egg
distribute-*.tar.gz
explore2
build_history/2*
+*.qdocconf
+*.qdocconf.in
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index dd79b2380..000000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# MANIFEST.in
-#
-# Manifest template for creating the PySide source distribution.
-
-include MANIFEST.in
-include CHANGES.rst
-include README.rst
-include ez_setup.py
-include setup.py
-include popenasync.py
-include qtinfo.py
-include utils.py
-
-# sources
-recursive-include sources/patchelf **
-recursive-include sources/shiboken2 **
-recursive-include sources/pyside2 **
-recursive-include sources/pyside2-tools **
-# ignore .git
-recursive-exclude sources/shiboken2/.git **
-recursive-exclude sources/pyside2/.git **
-recursive-exclude sources/pyside2-tools/.git **
-
-# PySide package
-recursive-include pyside_package/PySide2 **
-recursive-include pyside_package/PySide2/docs **
-recursive-include pyside_package/PySide2/plugins **
-recursive-include pyside_package/PySide2s **
-recursive-include pyside_package/PySide2/translations **
-recursive-include pyside_package/PySide2include **
-recursive-include pyside_package/PySide2/typesystems **
-recursive-include pyside_package/PySide2/examples **
-
-# pysideuic package
-recursive-include pyside_package/pysideuic **
-recursive-include pyside_package/pysideuic/Compiler **
-recursive-include pyside_package/pysideuic/port_v2 **
-recursive-include pyside_package/pysideuic/port_v3 **
-recursive-include pyside_package/pysideuic/widget-plugins **
diff --git a/README.md b/README.md
index cde05940d..fe61136b2 100644
--- a/README.md
+++ b/README.md
@@ -1,53 +1,9 @@
-# PySide2
+# Qt For Python
-### Introduction
-
-PySide is the [Python Qt bindings project](http://wiki.qt.io/PySide2), providing
+Qt For Python is the [Python Qt bindings project](http://wiki.qt.io/PySide2), providing
access to the complete Qt 5.x framework as well as to generator tools for rapidly
generating bindings for any C++ libraries.
-The PySide 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/).
-
-
-PySide 2 supports Qt5. For building, please read about
-[getting started](https://wiki.qt.io/PySide2_GettingStarted).
-Then download the sources by running
-
- git clone https://code.qt.io/pyside/pyside-setup
-
-### Building
-
-#### Dependencies
-
-PySide versions following 5.6 use a C++ parser based on
-[Clang](http://clang.org/). The Clang library (C-bindings), version 3.9 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/).
-
-After unpacking the archive, set the environment variable *LLVM_INSTALL_DIR* to
-point to the folder containing the *include* and *lib* directories of Clang:
-
- 7z x .../libclang-release_39-linux-Rhel7.2-gcc5.3-x86_64.7z
- export LLVM_INSTALL_DIR=$PWD/libclang
-
-On Windows:
-
- 7z x .../libclang-release_39-windows-vs2015_64.7z
- SET LLVM_INSTALL_DIR=%CD%\libclang
-
-#### Build Instructions
-
-You might consider using a virtual environment as described at
-[getting started](https://wiki.qt.io/PySide2_GettingStarted).
-You should be able to build:
-
- cd pyside-setup
- python setup.py install
+shiboken2 is the generator used to build the bindings.
-The setup script will try to find the location of the qmake tool of the Qt
-version to be used and the cmake build tool in the path. Non-standard
-locations can be specified by the *--qmake=path_to_qmake* or
-*--cmake=path_to_cmake* command line options.
+See README.pyside2.md and README.shiboken2.md for details.
diff --git a/README.pyside2.md b/README.pyside2.md
new file mode 100644
index 000000000..53f7bc9d0
--- /dev/null
+++ b/README.pyside2.md
@@ -0,0 +1,71 @@
+# PySide2
+
+### 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.
+
+The PySide 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/).
+
+### Installation
+
+Since the release of the [Technical Preview](https://blog.qt.io/blog/2018/06/13/qt-python-5-11-released/)
+it is possible to install via `pip`, both from Qt's servers
+and [PyPi](https://pypi.org/project/PySide2/):
+
+ pip install PySide2
+
+#### Dependencies
+
+PySide 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/).
+
+After unpacking the archive, set the environment variable *LLVM_INSTALL_DIR* to
+point to the folder containing the *include* and *lib* directories of Clang:
+
+ 7z x .../libclang-release_60-linux-Rhel7.2-gcc5.3-x86_64-clazy.7z
+ export LLVM_INSTALL_DIR=$PWD/libclang
+
+On Windows:
+
+ 7z x .../libclang-release_60-windows-vs2015_64-clazy.7z
+ SET LLVM_INSTALL_DIR=%CD%\libclang
+
+### Building from source
+
+For building PySide2 from scratch, please read about
+[getting started](https://wiki.qt.io/Qt_for_Python/GettingStarted).
+This process will include getting the code:
+
+ git clone https://code.qt.io/pyside/pyside-setup
+ cd pyside-setup
+ git branch --track 5.12 origin/5.12
+ git checkout 5.12
+
+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
+
+You can obtain more information about the options to build PySide
+and Shiboken in [our wiki](https://wiki.qt.io/Qt_for_Python/).
+
+### Documentation and Bugs
+
+You can find more information about the PySide2 module API in the
+[official Qt for Python documentation](https://doc.qt.io/qtforpython/).
+
+If you come across any issue, please file a bug report at our
+[JIRA tracker](https://bugreports.qt.io/projects/PYSIDE) following
+our [guidelines](https://wiki.qt.io/Qt_for_Python/Reporting_Bugs).
+
+### Community
+
+Check *#qt-pyside*, our official IRC channel on FreeNode,
+or contact us via our [mailing list](http://lists.qt-project.org/mailman/listinfo/pyside).
diff --git a/README.shiboken2-generator.md b/README.shiboken2-generator.md
new file mode 100644
index 000000000..f29f40634
--- /dev/null
+++ b/README.shiboken2-generator.md
@@ -0,0 +1,37 @@
+# shiboken2-generator
+
+Shiboken is the generator used by the Qt for Python project.
+It outputs C++ code for CPython extensions, which can be compiled
+and transformed into a Python module.
+
+C++ projects based on Qt can be wrapped, but also projects
+which are not related to Qt.
+
+## How does it work?
+
+Shiboken uses an API Extractor that does most of the job,
+but it requires a typesystem (XML file) to customize how the
+C++ classes/methods will be exposed to Python.
+
+The typesystem allows you to remove arguments from signatures,
+modify return types, inject code and add conversion rules
+from the C++ data types to Python data types, manipulate
+the ownership of the objects, etc.
+
+# Examples
+
+An example related to wrap a C++ library not depending on Qt
+can be found in our [repository](https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/samplebinding).
+
+Additionally, you can find a couple of tests inside the
+[git repository](https://code.qt.io/cgit/pyside/pyside-setup.git/tree/sources/shiboken2/tests).
+
+For a more advanced case regarding extending a Qt/C++ application
+with Python bindings based on the idea of the PySide module,
+you can check the [scriptableapplication](https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/scriptableapplication)
+example in our repository.
+
+# Documentation
+
+You can find more information about Shiboken in our
+[official documentation page](https://doc.qt.io/qtforpython/shiboken2/).
diff --git a/README.shiboken2.md b/README.shiboken2.md
new file mode 100644
index 000000000..d9cd32a40
--- /dev/null
+++ b/README.shiboken2.md
@@ -0,0 +1,13 @@
+# shiboken2 module
+
+The purpose of the shiboken2 Python module 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.
+
+Mostly the idea is to interact with Shiboken objects,
+where one can check if it is valid, or if the generated Python wrapper
+is invalid after the underlying C++ object has been destroyed.
+
+More information on the available functions can be found
+in our [official documentation](https://doc.qt.io/qtforpython/shiboken2/shibokenmodule.html)
diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt
index a228f9e21..c20760c74 100644
--- a/build_history/blacklist.txt
+++ b/build_history/blacklist.txt
@@ -88,3 +88,6 @@
win32
linux
darwin
+
+[QtPositioning::positioning]
+ win32
diff --git a/build_scripts/build_scripts.pyqtc b/build_scripts/build_scripts.pyqtc
new file mode 100644
index 000000000..1fc1c9664
--- /dev/null
+++ b/build_scripts/build_scripts.pyqtc
@@ -0,0 +1,18 @@
+__init__.py
+config.py
+main.py
+options.py
+platforms
+qtinfo.py
+setup_runner.py
+utils.py
+wheel_override.py
+platforms/__init__.py
+platforms/linux.py
+platforms/macos.py
+platforms/unix.py
+platforms/windows_desktop.py
+../setup.py
+../coin_build_instructions.py
+../coin_test_instructions.py
+
diff --git a/build_scripts/config.py b/build_scripts/config.py
new file mode 100644
index 000000000..f47230a6d
--- /dev/null
+++ b/build_scripts/config.py
@@ -0,0 +1,399 @@
+#############################################################################
+##
+## Copyright (C) 2018 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$
+##
+#############################################################################
+
+import sys, os
+import distutils.log as log
+
+
+class Config(object):
+ def __init__(self):
+ # Constants
+ self._build_type_all = "all"
+ self._invocation_type_top_level = "top-level"
+ self._invocation_type_internal = "internal"
+
+ # The keyword arguments which will be given to setuptools.setup
+ self.setup_kwargs = {}
+
+ # The setup.py invocation type.
+ # top-level
+ # internal
+ self.invocation_type = None
+
+ # The type of the top-level build.
+ # all - build shiboken2 module, shiboken2-generator and PySide2
+ # modules
+ # shiboken2 - build only shiboken2 module
+ # shiboken2-generator - build only the shiboken2-generator
+ # pyside2 - build only PySide2 modules
+ self.build_type = None
+
+ # The internal build type, used for internal invocations of
+ # setup.py to build a specific module only.
+ self.internal_build_type = None
+
+ # Options that can be given to --build-type and
+ # --internal-build-type
+ self.shiboken_module_option_name = "shiboken2"
+ self.shiboken_generator_option_name = "shiboken2-generator"
+ self.pyside_option_name = "pyside2"
+
+ # Names to be passed to setuptools.setup() name key,
+ # so not package name, but rather project name as it appears
+ # in the wheel name and on PyPi.
+ self.shiboken_module_st_name = "shiboken2"
+ self.shiboken_generator_st_name = "shiboken2-generator"
+ self.pyside_st_name = "PySide2"
+
+ # Used by check_allowed_python_version to validate the
+ # interpreter version.
+ self.python_version_classifiers = [
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ ]
+
+ self.setup_script_dir = None
+
+ def init_config(self, build_type=None, internal_build_type=None,
+ cmd_class_dict=None, package_version=None,
+ ext_modules=None, setup_script_dir=None,
+ quiet=False):
+ """
+ Sets up the global singleton config which is used in many parts
+ of the setup process.
+ """
+
+ # if --internal-build-type was passed, it means that this is a
+ # sub-invocation to build a specific package.
+ if internal_build_type:
+ self.set_is_internal_invocation()
+ self.set_internal_build_type(internal_build_type)
+ else:
+ self.set_is_top_level_invocation()
+
+ # --build-type was specified explicitly, so set it. Otherwise
+ # default to all.
+ if build_type:
+ self.build_type = build_type
+ else:
+ self.build_type = self._build_type_all
+
+ self.setup_script_dir = setup_script_dir
+
+ setup_kwargs = {}
+ setup_kwargs['long_description'] = self.get_long_description()
+ 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'
+ setup_kwargs['url'] = 'https://www.pyside.org'
+ setup_kwargs['download_url'] = 'https://download.qt.io/official_releases/QtForPython'
+ setup_kwargs['license'] = 'LGPL'
+ setup_kwargs['zip_safe'] = False
+ setup_kwargs['cmdclass'] = cmd_class_dict
+ setup_kwargs['version'] = package_version
+
+ if quiet:
+ # Tells distutils / setuptools to be quiet, and only print warnings or errors.
+ # Makes way less noise in the terminal when building.
+ setup_kwargs['verbose'] = 0
+
+ # Setting these two keys is still a bit of a discussion point.
+ # In general not setting them will allow using "build" and
+ # "bdist_wheel" just fine. What they do, is they specify to the
+ # setuptools.command.build_py command that certain pure python
+ # modules (.py files) exist in the specified package location,
+ # and that they should be copied over to the setuptools build
+ # dir.
+ # But it doesn't really make sense for us, because we copy all
+ # the necessary files to the build dir via prepare_packages()
+ # function anyway.
+ # If we don't set them, the build_py sub-command will be
+ # skipped, but the build command will still be executed, which
+ # is where we run cmake / make.
+ # The only plausible usage of it, is if we will implement a
+ # correctly functioning setup.py develop command (or bdist_egg).
+ # But currently that doesn't seem to work.
+ setup_kwargs['packages'] = self.get_setup_tools_packages_for_current_build()
+ setup_kwargs['package_dir'] = self.get_package_name_to_dir_path_mapping()
+
+ # Add a bogus extension module (will never be built here since
+ # we are overriding the build command to do it using cmake) so
+ # things like bdist_egg will know that there are extension
+ # modules and will name the dist with the full platform info.
+ setup_kwargs['ext_modules'] = ext_modules
+
+ common_classifiers = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Console',
+ 'Environment :: MacOS X',
+ 'Environment :: X11 Applications :: Qt',
+ 'Environment :: Win32 (MS Windows)',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
+ 'Operating System :: MacOS :: MacOS X',
+ 'Operating System :: POSIX',
+ 'Operating System :: POSIX :: Linux',
+ 'Operating System :: Microsoft',
+ 'Operating System :: Microsoft :: Windows',
+ 'Programming Language :: C++']
+ common_classifiers.extend(self.python_version_classifiers)
+ common_classifiers.extend([
+ 'Topic :: Database',
+ 'Topic :: Software Development',
+ 'Topic :: Software Development :: Code Generators',
+ 'Topic :: Software Development :: Libraries :: Application Frameworks',
+ 'Topic :: Software Development :: User Interfaces',
+ 'Topic :: Software Development :: Widget Sets'])
+ setup_kwargs['classifiers'] = common_classifiers
+
+ if self.internal_build_type == self.shiboken_module_option_name:
+ setup_kwargs['name'] = self.shiboken_module_st_name
+ setup_kwargs['description'] = "Python / C++ bindings helper module",
+ setup_kwargs['entry_points'] = {}
+
+ elif self.internal_build_type == self.shiboken_generator_option_name:
+ setup_kwargs['name'] = self.shiboken_generator_st_name
+ setup_kwargs['description'] = "Python / C++ bindings generator",
+ setup_kwargs['install_requires'] = [self.shiboken_module_st_name]
+ setup_kwargs['entry_points'] = {
+ 'console_scripts': [
+ 'shiboken2 = {}.scripts.shiboken_tool:main'.format(self.package_name()),
+ ]
+ }
+
+ 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['install_requires'] = [self.shiboken_module_st_name]
+ setup_kwargs['entry_points'] = {
+ 'console_scripts': [
+ 'pyside2-uic = {}.scripts.uic:main'.format(self.package_name()),
+ 'pyside2-rcc = {}.scripts.pyside_tool:main'.format(self.package_name()),
+ 'pyside2-lupdate = {}.scripts.pyside_tool:main'.format(self.package_name()),
+ ]
+ }
+ self.setup_kwargs = setup_kwargs
+
+ def get_long_description(self):
+ readme_filename = 'README.md'
+ changes_filename = 'CHANGES.rst'
+
+ if self.is_internal_shiboken_module_build():
+ readme_filename = 'README.shiboken2.md'
+ elif self.is_internal_shiboken_generator_build():
+ readme_filename = 'README.shiboken2-generator.md'
+ elif self.is_internal_pyside_build():
+ readme_filename = 'README.pyside2.md'
+
+ content = ''
+ changes = ''
+ try:
+ with open(os.path.join(self.setup_script_dir, readme_filename)) as f:
+ readme = f.read()
+ except Exception as e:
+ log.error("Couldn't read contents of {}.".format(readme_filename))
+ raise
+
+ # Don't include CHANGES.rst for now, because we have not decided
+ # how to handle change files yet.
+ include_changes = False
+ if include_changes:
+ try:
+ with open(os.path.join(self.setup_script_dir, changes_filename)) as f:
+ changes = f.read()
+ except Exception as e:
+ log.error("Couldn't read contents of {}".format(changes_filename))
+ raise
+ content += readme
+
+ if changes:
+ content += "\n\n" + changes
+
+ return content
+
+ def package_name(self):
+ """
+ Returns package name as it appears in Python's site-packages
+ directory.
+
+ Package names can only be delimited by underscores, and not by
+ dashes.
+ """
+ if self.is_internal_shiboken_module_build():
+ return "shiboken2"
+ elif self.is_internal_shiboken_generator_build():
+ return "shiboken2_generator"
+ elif self.is_internal_pyside_build():
+ return "PySide2"
+ else:
+ return None
+
+ def get_setup_tools_packages_for_current_build(self):
+ """
+ Returns a list of packages for setup tools to consider in the
+ build_py command, so that it can copy the pure python files.
+ Not really necessary because it's done in prepare_packages()
+ anyway.
+
+ This is really just to satisfy some checks in setuptools
+ build_py command, and if we ever properly implement the develop
+ command.
+ """
+ if self.internal_build_type == self.pyside_option_name:
+ return [
+ config.package_name(),
+ 'pyside2uic',
+ 'pyside2uic.Compiler',
+ 'pyside2uic.port_v{}'.format(sys.version_info[0])
+ ]
+ elif self.internal_build_type == self.shiboken_module_option_name:
+ return [self.package_name()]
+ else:
+ return []
+
+ def get_package_name_to_dir_path_mapping(self):
+ """
+ Used in setuptools.setup 'package_dir' argument to specify where
+ the actual module packages are located.
+
+ For example when building the shiboken module, setuptools will
+ expect to find the "shiboken2" module sources under
+ "sources/shiboken2/shibokenmodule".
+
+ This is really just to satisfy some checks in setuptools
+ build_py command, and if we ever properly implement the develop
+ command.
+ """
+ if self.is_internal_shiboken_module_build():
+ return {
+ self.package_name(): "sources/shiboken2/shibokenmodule"
+ }
+ elif self.is_internal_shiboken_generator_build():
+ # This is left empty on purpose, because the shiboken
+ # generator doesn't have a python module for now.
+ return {}
+ elif self.is_internal_pyside_build():
+ return {
+ self.package_name(): "sources/pyside2/PySide2",
+ "pyside2uic": "sources/pyside2-tools/pyside2uic"
+ }
+ else:
+ return {}
+
+ def get_buildable_extensions(self):
+ """
+ Used by PysideBuild.run to build the CMake projects.
+ :return: A list of directory names under the sources directory.
+ """
+ if self.is_internal_shiboken_module_build() or self.is_internal_shiboken_generator_build():
+ return ['shiboken2']
+ elif self.is_internal_pyside_build():
+ return ['pyside2', 'pyside2-tools']
+ return None
+
+ def set_is_top_level_invocation(self):
+ self.invocation_type = self._invocation_type_top_level
+
+ def set_is_internal_invocation(self):
+ self.invocation_type = self._invocation_type_internal
+
+ def is_top_level_invocation(self):
+ return self.invocation_type == self._invocation_type_top_level
+
+ def is_internal_invocation(self):
+ return self.invocation_type == self._invocation_type_internal
+
+ def is_top_level_build_all(self):
+ return self.build_type == self._build_type_all
+
+ def is_top_level_build_shiboken_module(self):
+ return self.build_type == self.shiboken_module_option_name
+
+ def is_top_level_build_shiboken_generator(self):
+ return self.build_type == self.shiboken_generator_option_name
+
+ def is_top_level_build_pyside(self):
+ return self.build_type == self.pyside_option_name
+
+ def set_internal_build_type(self, internal_build_type):
+ self.internal_build_type = internal_build_type
+
+ def is_internal_shiboken_module_build(self):
+ return self.internal_build_type == self.shiboken_module_option_name
+
+ def is_internal_shiboken_generator_build(self):
+ return self.internal_build_type == self.shiboken_generator_option_name
+
+ def is_internal_pyside_build(self):
+ return self.internal_build_type == self.pyside_option_name
+
+ def is_internal_shiboken_generator_build_and_part_of_top_level_all(self):
+ """
+ Used to skip certain build rules and output, when we know that
+ the CMake build of shiboken was already done as part of the
+ top-level "all" build when shiboken2-module was built.
+ """
+ return self.is_internal_shiboken_generator_build() and self.is_top_level_build_all()
+
+ def get_allowed_top_level_build_values(self):
+ return [
+ self._build_type_all,
+ self.shiboken_module_option_name,
+ self.shiboken_generator_option_name,
+ self.pyside_option_name
+ ]
+
+ def get_allowed_internal_build_values(self):
+ return [
+ self.shiboken_module_option_name,
+ self.shiboken_generator_option_name,
+ self.pyside_option_name
+ ]
+
+
+config = Config()
diff --git a/build_scripts/main.py b/build_scripts/main.py
index b64d6f1a9..cdc6dce7e 100644
--- a/build_scripts/main.py
+++ b/build_scripts/main.py
@@ -42,6 +42,7 @@ from distutils.version import LooseVersion
import os
import time
+from .config import config
from .utils import memoize, get_python_dict
from .options import *
@@ -49,14 +50,17 @@ setup_script_dir = os.getcwd()
build_scripts_dir = os.path.join(setup_script_dir, 'build_scripts')
setup_py_path = os.path.join(setup_script_dir, "setup.py")
+start_time = int(time.time())
+
+def elapsed():
+ return int(time.time()) - start_time
+
@memoize
def get_package_timestamp():
""" In a Coin CI build the returned timestamp will be the
Coin integration id timestamp. For regular builds it's
just the current timestamp or a user provided one."""
- if OPTION_PACKAGE_TIMESTAMP:
- return OPTION_PACKAGE_TIMESTAMP
- return int(time.time())
+ return OPTION_PACKAGE_TIMESTAMP if OPTION_PACKAGE_TIMESTAMP else start_time
@memoize
def get_package_version():
@@ -90,15 +94,11 @@ def get_setuptools_extension_modules():
extension_modules = [Extension(*extension_args, **extension_kwargs)]
return extension_modules
-# Buildable extensions.
-contained_modules = ['shiboken2', 'pyside2', 'pyside2-tools']
# Git submodules: ["submodule_name",
# "location_relative_to_sources_folder"]
submodules = [["pyside2-tools"]]
-pyside_package_dir_name = "pyside_package"
-
try:
import setuptools
except ImportError:
@@ -108,13 +108,8 @@ except ImportError:
import sys
import platform
import re
-import fnmatch
-import difflib # for a close match of dirname and module
-import functools
-
-from distutils import log
-from distutils.errors import DistutilsOptionError
+import distutils.log as log
from distutils.errors import DistutilsSetupError
from distutils.sysconfig import get_config_var
from distutils.sysconfig import get_python_lib
@@ -123,7 +118,7 @@ from distutils.command.build import build as _build
from distutils.command.build_ext import build_ext as _build_ext
from distutils.util import get_platform
-from setuptools import setup, Extension
+from setuptools import Extension
from setuptools.command.install import install as _install
from setuptools.command.install_lib import install_lib as _install_lib
from setuptools.command.bdist_egg import bdist_egg as _bdist_egg
@@ -132,39 +127,40 @@ from setuptools.command.build_py import build_py as _build_py
from .qtinfo import QtInfo
from .utils import rmtree, detect_clang, copyfile, copydir, run_process_output, run_process
-from .utils import update_env_path, init_msvc_env, filter_match, macos_fix_rpaths_for_library
+from .utils import update_env_path, init_msvc_env, filter_match
+from .utils import macos_fix_rpaths_for_library
+from .utils import linux_fix_rpaths_for_library
from .platforms.unix import prepare_packages_posix
from .platforms.windows_desktop import prepare_packages_win32
from .wheel_override import wheel_module_exists, get_bdist_wheel_override
from textwrap import dedent
-# make sure that setup.py is run with an allowed python version
+
def check_allowed_python_version():
+ """
+ Make sure that setup.py is run with an allowed python version.
+ """
+
import re
- pattern = "'Programming Language :: Python :: (\d+)\.(\d+)'"
+ pattern = r'Programming Language :: Python :: (\d+)\.(\d+)'
supported = []
- with open(setup_py_path) as setup:
- for line in setup.readlines():
- found = re.search(pattern, line)
- if found:
- major = int(found.group(1))
- minor = int(found.group(2))
- supported.append( (major, minor) )
+
+ for line in config.python_version_classifiers:
+ found = re.search(pattern, line)
+ if found:
+ major = int(found.group(1))
+ minor = int(found.group(2))
+ supported.append( (major, minor) )
this_py = sys.version_info[:2]
if this_py not in supported:
- print("only these python versions are supported:", supported)
+ print("Unsupported python version detected. Only these python versions are supported: {}"
+ .format(supported))
sys.exit(1)
-check_allowed_python_version()
qt_src_dir = ''
-# This is used automatically by distutils.command.install object, to
-# specify final installation location.
-OPTION_FINAL_INSTALL_PREFIX = option_value("prefix")
-
-
if OPTION_QT_VERSION is None:
OPTION_QT_VERSION = "5"
if OPTION_QMAKE is None:
@@ -205,20 +201,16 @@ if not os.path.exists(OPTION_CMAKE):
print("'{}' does not exist.".format(OPTION_CMAKE))
sys.exit(1)
-if sys.platform == "win32":
- if OPTION_MAKESPEC is None:
- OPTION_MAKESPEC = "msvc"
- if not OPTION_MAKESPEC in ["msvc", "mingw"]:
- print("Invalid option --make-spec. Available values are {}".format(
- ["msvc", "mingw"]))
- sys.exit(1)
-else:
- if OPTION_MAKESPEC is None:
- OPTION_MAKESPEC = "make"
- if not OPTION_MAKESPEC in ["make"]:
- print("Invalid option --make-spec. Available values are {}".format(
- ["make"]))
- sys.exit(1)
+# First element is default
+available_mkspecs = ["msvc", "mingw", "ninja"] if sys.platform == "win32" else ["make", "ninja"]
+
+if OPTION_MAKESPEC is None:
+ OPTION_MAKESPEC = available_mkspecs[0]
+
+if not OPTION_MAKESPEC in available_mkspecs:
+ print('Invalid option --make-spec "{}". Available values are {}'.format(
+ OPTION_MAKESPEC, available_mkspecs))
+ sys.exit(1)
if OPTION_JOBS:
if sys.platform == 'win32' and OPTION_NO_JOM:
@@ -293,8 +285,7 @@ def get_qt_version():
qt_version = qtinfo.version
if not qt_version:
- log.error("Failed to query the Qt version with qmake {0}".format(
- self.qtinfo.qmake_command))
+ log.error("Failed to query the Qt version with qmake {0}".format(qtinfo.qmake_command))
sys.exit(1)
if LooseVersion(qtinfo.version) < LooseVersion("5.7"):
@@ -304,27 +295,22 @@ def get_qt_version():
return qt_version
+
def prepare_build():
if (os.path.isdir(".git") and not OPTION_IGNOREGIT and
not OPTION_ONLYPACKAGE and not OPTION_REUSE_BUILD):
prepare_sub_modules()
- # Clean up temp and package folders
- for n in [pyside_package_dir_name, "build"]:
+ # Clean up temp build folder.
+ for n in ["build"]:
d = os.path.join(setup_script_dir, n)
if os.path.isdir(d):
- print("Removing {}".format(d))
+ log.info("Removing {}".format(d))
try:
rmtree(d)
except Exception as e:
print('***** problem removing "{}"'.format(d))
print('ignored error: {}'.format(e))
- # Prepare package folders
- ppdn = pyside_package_dir_name
- absolute_paths = [os.path.join(ppdn, "PySide2"),
- os.path.join(ppdn, "pyside2uic")]
- for pkg in absolute_paths:
- pkg_dir = os.path.join(setup_script_dir, pkg)
- os.makedirs(pkg_dir)
+
# locate Qt sources for the documentation
if OPTION_QT_SRC is None:
install_prefix = qtinfo.prefix_dir
@@ -360,7 +346,7 @@ class PysideInstall(_install):
def run(self):
_install.run(self)
- log.info('*** Install completed')
+ print('*** Install completed ({}s)'.format(elapsed()))
class PysideDevelop(_develop):
@@ -389,26 +375,15 @@ class PysideBuildExt(_build_ext):
pass
-
-# pyside_build_py and pyside_install_lib are reimplemented to preserve
-# symlinks when distutils / setuptools copy files to various
-# directories through the different build stages.
class PysideBuildPy(_build_py):
def __init__(self, *args, **kwargs):
_build_py.__init__(self, *args, **kwargs)
- def build_package_data(self):
- """Copies files from pyside_package into build/xxx directory"""
-
- for package, src_dir, build_dir, filenames in self.data_files:
- for filename in filenames:
- target = os.path.join(build_dir, filename)
- self.mkpath(os.path.dirname(target))
- srcfile = os.path.abspath(os.path.join(src_dir, filename))
- # Using our own copyfile makes sure to preserve symlinks.
- copyfile(srcfile, target)
+# _install_lib is reimplemented to preserve
+# symlinks when distutils / setuptools copy files to various
+# directories from the setup tools build dir to the install dir.
class PysideInstallLib(_install_lib):
def __init__(self, *args, **kwargs):
@@ -512,6 +487,9 @@ class PysideBuild(_build):
elif OPTION_MAKESPEC == "mingw":
make_name = "mingw32-make"
make_generator = "MinGW Makefiles"
+ elif OPTION_MAKESPEC == "ninja":
+ make_name = "ninja"
+ make_generator = "Ninja"
else:
raise DistutilsSetupError(
"Invalid option --make-spec.")
@@ -539,10 +517,12 @@ class PysideBuild(_build):
py_prefix = get_config_var("prefix")
if not py_prefix or not os.path.exists(py_prefix):
py_prefix = sys.prefix
+ self.py_prefix = py_prefix
if sys.platform == "win32":
py_scripts_dir = os.path.join(py_prefix, "Scripts")
else:
py_scripts_dir = os.path.join(py_prefix, "bin")
+ self.py_scripts_dir = py_scripts_dir
if py_libdir is None or not os.path.exists(py_libdir):
if sys.platform == "win32":
py_libdir = os.path.join(py_prefix, "libs")
@@ -656,7 +636,7 @@ class PysideBuild(_build):
qt_version = get_qt_version()
# Update the PATH environment variable
- additional_paths = [py_scripts_dir, qt_dir]
+ additional_paths = [self.py_scripts_dir, qt_dir]
# Add Clang to path for Windows.
# Revisit once Clang is bundled with Qt.
@@ -685,19 +665,11 @@ class PysideBuild(_build):
install_dir = os.path.join(script_dir, prefix() + "_install",
"{}".format(build_name))
- # Try to ensure that tools built by this script (such as shiboken2)
- # are found before any that may already be installed on the system.
- update_env_path([os.path.join(install_dir, 'bin')])
-
- # Tell cmake to look here for *.cmake files
- os.environ['CMAKE_PREFIX_PATH'] = install_dir
-
self.make_path = make_path
self.make_generator = make_generator
self.debug = OPTION_DEBUG
self.script_dir = script_dir
- self.pyside_package_dir = os.path.join(self.script_dir,
- pyside_package_dir_name)
+ self.st_build_dir = os.path.join(self.script_dir, self.build_lib)
self.sources_dir = sources_dir
self.build_dir = build_dir
self.install_dir = install_dir
@@ -709,14 +681,61 @@ class PysideBuild(_build):
self.site_packages_dir = get_python_lib(1, 0, prefix=install_dir)
self.build_tests = OPTION_BUILDTESTS
- setuptools_install_prefix = get_python_lib(1)
- if OPTION_FINAL_INSTALL_PREFIX:
- setuptools_install_prefix = OPTION_FINAL_INSTALL_PREFIX
-
# Save the shiboken build dir path for clang deployment
# purposes.
self.shiboken_build_dir = os.path.join(self.build_dir, "shiboken2")
+ self.log_pre_build_info()
+
+ # Prepare folders
+ if not os.path.exists(self.sources_dir):
+ log.info("Creating sources folder {}...".format(self.sources_dir))
+ os.makedirs(self.sources_dir)
+ if not os.path.exists(self.build_dir):
+ log.info("Creating build folder {}...".format(self.build_dir))
+ os.makedirs(self.build_dir)
+ if not os.path.exists(self.install_dir):
+ log.info("Creating install folder {}...".format(self.install_dir))
+ os.makedirs(self.install_dir)
+
+ if not (OPTION_ONLYPACKAGE
+ and not config.is_internal_shiboken_generator_build_and_part_of_top_level_all()):
+ # Build extensions
+ for ext in config.get_buildable_extensions():
+ self.build_extension(ext)
+
+ if OPTION_BUILDTESTS:
+ # we record the latest successful build and note the
+ # build directory for supporting the tests.
+ timestamp = time.strftime('%Y-%m-%d_%H%M%S')
+ build_history = os.path.join(setup_script_dir, 'build_history')
+ unique_dir = os.path.join(build_history, timestamp)
+ os.makedirs(unique_dir)
+ fpath = os.path.join(unique_dir, 'build_dir.txt')
+ with open(fpath, 'w') as f:
+ print(build_dir, file=f)
+ log.info("Created {}".format(build_history))
+
+ if not OPTION_SKIP_PACKAGING:
+ # Build patchelf if needed
+ self.build_patchelf()
+
+ # Prepare packages
+ self.prepare_packages()
+
+ # Build packages
+ _build.run(self)
+ else:
+ log.info("Skipped preparing and building packages.")
+ print('*** Build completed ({}s)'.format(elapsed()))
+
+ def log_pre_build_info(self):
+ if config.is_internal_shiboken_generator_build_and_part_of_top_level_all():
+ return
+
+ setuptools_install_prefix = get_python_lib(1)
+ if OPTION_FINAL_INSTALL_PREFIX:
+ setuptools_install_prefix = OPTION_FINAL_INSTALL_PREFIX
log.info("=" * 30)
log.info("Package version: {}".format(get_package_version()))
log.info("Build type: {}".format(self.build_type))
@@ -726,40 +745,34 @@ class PysideBuild(_build):
log.info("Make generator: {}".format(self.make_generator))
log.info("Make jobs: {}".format(OPTION_JOBS))
log.info("-" * 3)
-
log.info("setup.py directory: {}".format(self.script_dir))
log.info("Build scripts directory: {}".format(build_scripts_dir))
log.info("Sources directory: {}".format(self.sources_dir))
-
log.info(dedent("""
- Building PySide2 will create and touch directories
+ Building {st_package_name} will create and touch directories
in the following order:
make build directory (py*_build/*/*) ->
make install directory (py*_install/*/*) ->
- {} directory (pyside_package/*) ->
setuptools build directory (build/*/*) ->
setuptools install directory
(usually path-installed-python/lib/python*/site-packages/*)
- """).format(pyside_package_dir_name))
-
+ """).format(st_package_name=config.package_name()))
log.info("make build directory: {}".format(self.build_dir))
log.info("make install directory: {}".format(self.install_dir))
- log.info("{} directory: {}".format(pyside_package_dir_name,
- self.pyside_package_dir))
- log.info("setuptools build directory: {}".format(
- os.path.join(self.script_dir, "build")))
- log.info("setuptools install directory: {}".format(
- setuptools_install_prefix))
- log.info("make-installed site-packages directory: {} \n"
- " (only relevant for copying files from "
- "'make install directory' to '{} directory'".format(
- self.site_packages_dir, pyside_package_dir_name))
+ log.info("setuptools build directory: {}".format(self.st_build_dir))
+ log.info("setuptools install directory: {}".format(setuptools_install_prefix))
+ log.info(dedent("""
+ make-installed site-packages directory: {}
+ (only relevant for copying files from 'make install directory'
+ to 'setuptools build directory'
+ """).format(
+ self.site_packages_dir))
log.info("-" * 3)
log.info("Python executable: {}".format(self.py_executable))
log.info("Python includes: {}".format(self.py_include_dir))
log.info("Python library: {}".format(self.py_library))
- log.info("Python prefix: {}".format(py_prefix))
- log.info("Python scripts: {}".format(py_scripts_dir))
+ log.info("Python prefix: {}".format(self.py_prefix))
+ log.info("Python scripts: {}".format(self.py_scripts_dir))
log.info("-" * 3)
log.info("Qt qmake: {}".format(self.qtinfo.qmake_command))
log.info("Qt version: {}".format(self.qtinfo.version))
@@ -772,52 +785,11 @@ class PysideBuild(_build):
if sys.platform == 'darwin':
pyside_macos_deployment_target = (
PysideBuild.macos_pyside_min_deployment_target()
- )
+ )
log.info("MACOSX_DEPLOYMENT_TARGET set to: {}".format(
pyside_macos_deployment_target))
log.info("=" * 30)
- # Prepare folders
- if not os.path.exists(self.sources_dir):
- log.info("Creating sources folder {}...".format(self.sources_dir))
- os.makedirs(self.sources_dir)
- if not os.path.exists(self.build_dir):
- log.info("Creating build folder {}...".format(self.build_dir))
- os.makedirs(self.build_dir)
- if not os.path.exists(self.install_dir):
- log.info("Creating install folder {}...".format(self.install_dir))
- os.makedirs(self.install_dir)
-
- if not OPTION_ONLYPACKAGE:
- # Build extensions
- for ext in contained_modules:
- self.build_extension(ext)
-
- if OPTION_BUILDTESTS:
- # we record the latest successful build and note the
- # build directory for supporting the tests.
- timestamp = time.strftime('%Y-%m-%d_%H%M%S')
- build_history = os.path.join(setup_script_dir, 'build_history')
- unique_dir = os.path.join(build_history, timestamp)
- os.makedirs(unique_dir)
- fpath = os.path.join(unique_dir, 'build_dir.txt')
- with open(fpath, 'w') as f:
- print(build_dir, file=f)
- log.info("Created {}".format(build_history))
-
- if not OPTION_SKIP_PACKAGING:
- # Build patchelf if needed
- self.build_patchelf()
-
- # Prepare packages
- self.prepare_packages()
-
- # Build packages
- _build.run(self)
- else:
- log.info("Skipped preparing and building packages.")
- log.info('*** Build completed')
-
@staticmethod
def macos_qt_min_deployment_target():
target = qtinfo.macos_min_deployment_target
@@ -941,8 +913,17 @@ class PysideBuild(_build):
module_src_dir = os.path.join(self.sources_dir, extension)
# Build module
- cmake_cmd = [
- OPTION_CMAKE,
+ cmake_cmd = [OPTION_CMAKE]
+ if OPTION_QUIET:
+ # Pass a special custom option, to allow printing a lot less information when doing
+ # a quiet build.
+ cmake_cmd.append('-DQUIET_BUILD=1')
+ if self.make_generator == "Unix Makefiles":
+ # Hide progress messages for each built source file.
+ # Doesn't seem to work if set within the cmake files themselves.
+ cmake_cmd.append('-DCMAKE_RULE_MESSAGES=0')
+
+ cmake_cmd += [
"-G", self.make_generator,
"-DBUILD_TESTS={}".format(self.build_tests),
"-DQt5Help_DIR={}".format(self.qtinfo.docs_dir),
@@ -953,6 +934,17 @@ class PysideBuild(_build):
cmake_cmd.append("-DPYTHON_EXECUTABLE={}".format(self.py_executable))
cmake_cmd.append("-DPYTHON_INCLUDE_DIR={}".format(self.py_include_dir))
cmake_cmd.append("-DPYTHON_LIBRARY={}".format(self.py_library))
+
+ # If a custom shiboken cmake config directory path was provided, pass it to CMake.
+ if OPTION_SHIBOKEN_CONFIG_DIR and config.is_internal_pyside_build():
+ if os.path.exists(OPTION_SHIBOKEN_CONFIG_DIR):
+ log.info("Using custom provided shiboken2 installation: {}"
+ .format(OPTION_SHIBOKEN_CONFIG_DIR))
+ cmake_cmd.append("-DShiboken2_DIR={}".format(OPTION_SHIBOKEN_CONFIG_DIR))
+ else:
+ log.info("Custom provided shiboken2 installation not found. Path given: {}"
+ .format(OPTION_SHIBOKEN_CONFIG_DIR))
+
if OPTION_MODULE_SUBSET:
module_sub_set = ''
for m in OPTION_MODULE_SUBSET.split(','):
@@ -1014,20 +1006,20 @@ class PysideBuild(_build):
cmake_cmd.append("-DPYSIDE_QT_CONF_PREFIX={}".format(
pyside_qt_conf_prefix))
- # Pass package version to CMake, so this string can be
- # embedded into _config.py file.
- package_version = get_package_version()
- cmake_cmd.append("-DPYSIDE_SETUP_PY_PACKAGE_VERSION={}".format(
- package_version))
-
- # In case if this is a snapshot build, also pass the
- # timestamp as a separate value, because it the only
- # version component that is actually generated by setup.py.
- timestamp = ''
- if OPTION_SNAPSHOT_BUILD:
- timestamp = get_package_timestamp()
- cmake_cmd.append("-DPYSIDE_SETUP_PY_PACKAGE_TIMESTAMP={}".format(
- timestamp))
+ # Pass package version to CMake, so this string can be
+ # embedded into _config.py file.
+ package_version = get_package_version()
+ cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_VERSION={}".format(
+ package_version))
+
+ # In case if this is a snapshot build, also pass the
+ # timestamp as a separate value, because it is the only
+ # version component that is actually generated by setup.py.
+ timestamp = ''
+ if OPTION_SNAPSHOT_BUILD:
+ timestamp = get_package_timestamp()
+ cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_TIMESTAMP={}".format(
+ timestamp))
if extension.lower() in ["shiboken2", "pyside2-tools"]:
cmake_cmd.append("-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=yes")
@@ -1120,7 +1112,9 @@ class PysideBuild(_build):
log.info("Waiting 1 second, to ensure installation is "
"successful...")
time.sleep(1)
- if run_process([self.make_path, "install/fast"]) != 0:
+ # ninja: error: unknown target 'install/fast'
+ target = 'install/fast' if self.make_generator != 'Ninja' else 'install'
+ if run_process([self.make_path, target]) != 0:
raise DistutilsSetupError("Error pseudo installing {}".format(
extension))
else:
@@ -1129,15 +1123,24 @@ class PysideBuild(_build):
os.chdir(self.script_dir)
def prepare_packages(self):
+ """
+ This will copy all relevant files from the various locations in the "cmake install dir",
+ to the setup tools build dir (which is read from self.build_lib provided by distutils).
+
+ After that setuptools.command.build_py is smart enough to copy everything
+ from the build dir to the install dir (the virtualenv site-packages for example).
+ """
try:
- log.info("Preparing packages...")
+ log.info("\nPreparing setup tools build directory.\n")
vars = {
"site_packages_dir": self.site_packages_dir,
"sources_dir": self.sources_dir,
"install_dir": self.install_dir,
"build_dir": self.build_dir,
"script_dir": self.script_dir,
- "pyside_package_dir": self.pyside_package_dir,
+ "st_build_dir": self.st_build_dir,
+ "cmake_package_name": config.package_name(),
+ "st_package_name": config.package_name(),
"ssl_libs_dir": OPTION_OPENSSL,
"py_version": self.py_version,
"qt_version": self.qtinfo.version,
@@ -1151,6 +1154,12 @@ class PysideBuild(_build):
"qt_qml_dir": self.qtinfo.qml_dir,
"target_arch": self.py_arch,
}
+
+ # Needed for correct file installation in generator build
+ # case.
+ if config.is_internal_shiboken_generator_build():
+ vars['cmake_package_name'] = config.shiboken_module_option_name
+
os.chdir(self.script_dir)
if sys.platform == "win32":
@@ -1170,19 +1179,21 @@ class PysideBuild(_build):
def get_built_pyside_config(self, vars):
# Get config that contains list of built modules, and
# SOVERSIONs of the built libraries.
- pyside_package_dir = vars['pyside_package_dir']
- config_path = os.path.join(pyside_package_dir, "PySide2", "_config.py")
- config = get_python_dict(config_path)
- return config
+ st_build_dir = vars['st_build_dir']
+ config_path = os.path.join(st_build_dir, config.package_name(), "_config.py")
+ temp_config = get_python_dict(config_path)
+ if 'built_modules' not in temp_config:
+ temp_config['built_modules'] = []
+ return temp_config
def is_webengine_built(self, built_modules):
return ('WebEngineWidgets' in built_modules or 'WebEngineCore' in built_modules
or 'WebEngine' in built_modules)
- def prepare_standalone_clang(self, is_win = False):
+ def prepare_standalone_clang(self, is_win=False):
"""
- Copies the libclang library to the pyside package so that
- shiboken executable works.
+ Copies the libclang library to the shiboken2-generator
+ package so that the shiboken executable works.
"""
log.info('Finding path to the libclang shared library.')
cmake_cmd = [
@@ -1205,47 +1216,54 @@ class PysideBuild(_build):
if not clang_lib_path:
raise RuntimeError("Could not find the location of the libclang "
- "library inside the CMake cache file.")
+ "library inside the CMake cache file.")
- target_name = None
if is_win:
# clang_lib_path points to the static import library
# (lib/libclang.lib), whereas we want to copy the shared
# library (bin/libclang.dll).
- clang_lib_path = re.sub(r'lib/libclang.lib$', 'bin/libclang.dll',
- clang_lib_path)
+ clang_lib_path = re.sub(r'lib/libclang.lib$',
+ 'bin/libclang.dll',
+ clang_lib_path)
else:
- if sys.platform != 'darwin' and os.path.islink(clang_lib_path):
- # On Linux, we get "libclang.so" from CMake which is
- # a symlink:
- # libclang.so -> libclang.so.6 -> libclang.so.6.0.
- # shiboken2 links against libclang.so.6. So, we
- # determine the target name by resolving just
- # one symlink (note: os.path.realpath() resolves all).
- target_name = os.readlink(clang_lib_path)
- # We want to resolve any symlink on Linux and macOS, and
- # copy the actual file.
- clang_lib_path = os.path.realpath(clang_lib_path)
-
- if not target_name:
- target_name = os.path.basename(clang_lib_path)
-
- # Path to directory containing libclang.
- clang_lib_dir = os.path.dirname(clang_lib_path)
-
- # The destination will be the package folder near the other
- # extension modules.
- destination_dir = "{}/PySide2".format(os.path.join(self.script_dir,
- 'pyside_package'))
+ # shiboken2 links against libclang.so.6 or a similarly
+ # named library.
+ # If the linked against library is a symlink, resolve
+ # the symlink once (but not all the way to the real
+ # file) on Linux and macOS,
+ # so that we get the path to the "SO version" symlink
+ # (the one used as the install name in the shared library
+ # dependency section).
+ # E.g. On Linux libclang.so -> libclang.so.6 ->
+ # libclang.so.6.0.
+ # "libclang.so.6" is the name we want for the copied file.
+ if os.path.islink(clang_lib_path):
+ link_target = os.readlink(clang_lib_path)
+ if os.path.isabs(link_target):
+ clang_lib_path = link_target
+ else:
+ # link_target is relative, transform to absolute.
+ clang_lib_path = os.path.join(os.path.dirname(clang_lib_path), link_target)
+ clang_lib_path = os.path.abspath(clang_lib_path)
+
+ # The destination will be the shiboken package folder.
+ vars = {}
+ vars['st_build_dir'] = self.st_build_dir
+ vars['st_package_name'] = config.package_name()
+ destination_dir = "{st_build_dir}/{st_package_name}".format(**vars)
+
if os.path.exists(clang_lib_path):
- log.info('Copying libclang shared library {} to the package folder as {}.'.format(
- clang_lib_path, target_name))
basename = os.path.basename(clang_lib_path)
- destination_path = os.path.join(destination_dir, target_name)
+ log.info('Copying libclang shared library {} to the package folder as {}.'.format(
+ clang_lib_path, basename))
+ destination_path = os.path.join(destination_dir, basename)
# Need to modify permissions in case file is not writable
# (a reinstall would cause a permission denied error).
- copyfile(clang_lib_path, destination_path, make_writable_by_owner=True)
+ copyfile(clang_lib_path,
+ destination_path,
+ force_copy_symlink=True,
+ make_writable_by_owner=True)
else:
raise RuntimeError("Error copying libclang library "
"from {} to {}. ".format(
@@ -1265,18 +1283,17 @@ class PysideBuild(_build):
else:
# Add rpath values pointing to $ORIGIN and the
# installed qt lib directory.
- local_rpath = '$ORIGIN/'
- qt_lib_dir = self.qtinfo.libs_dir
+ final_rpath = self.qtinfo.libs_dir
if OPTION_STANDALONE:
- qt_lib_dir = "$ORIGIN/Qt/lib"
- final_rpath = local_rpath + ':' + qt_lib_dir
- cmd = [self._patchelf_path, '--set-rpath', final_rpath, srcpath]
- if run_process(cmd) != 0:
- raise RuntimeError("Error patching rpath in " + srcpath)
+ final_rpath = "$ORIGIN/Qt/lib"
+ override = OPTION_STANDALONE
+ linux_fix_rpaths_for_library(self._patchelf_path, srcpath, final_rpath,
+ override=override)
elif sys.platform == 'darwin':
pyside_libs = [lib for lib in os.listdir(
package_path) if filter_match(lib, ["*.so", "*.dylib"])]
+
def rpath_cmd(srcpath):
final_rpath = ''
# Command line rpath option takes precedence over
@@ -1304,17 +1321,8 @@ class PysideBuild(_build):
if not os.path.exists(srcpath):
continue
rpath_cmd(srcpath)
- print("Patched rpath to '$ORIGIN/' (Linux) or "
- "updated rpath (OS/X) in {}.".format(srcpath))
-
-
-try:
- with open(os.path.join(setup_script_dir, 'README.rst')) as f:
- README = f.read()
- with open(os.path.join(setup_script_dir, 'CHANGES.rst')) as f:
- CHANGES = f.read()
-except IOError:
- README = CHANGES = ''
+ log.info("Patched rpath to '$ORIGIN/' (Linux) or "
+ "updated rpath (OS/X) in {}.".format(srcpath))
cmd_class_dict = {
diff --git a/build_scripts/options.py b/build_scripts/options.py
index fd8b0718e..644649938 100644
--- a/build_scripts/options.py
+++ b/build_scripts/options.py
@@ -38,16 +38,109 @@
#############################################################################
from __future__ import print_function
+import sys
+import os
+import warnings
+
+
+def _warn_multiple_option(option):
+ w = 'Option "{}" occurs multiple times on the command line.'.format(option)
+ warnings.warn(w)
+
+def _warn_deprecated_option(option, replacement=None):
+ w = 'Option "{}" is deprecated and may be removed in a future release.'.format(option)
+ if replacement:
+ w = '{}\nUse "{}" instead.'.format(w, replacement)
+ warnings.warn(w)
+
+class Options(object):
+ def __init__(self):
+
+ # Dictionary containing values of all the possible options.
+ self.dict = {}
+
+ def has_option(self, name, remove=True):
+ """ Returns True if argument '--name' was passed on the command
+ line. """
+ option = '--' + name
+ count = sys.argv.count(option)
+ remove_count = count
+ if not remove and count > 0:
+ remove_count -= 1
+ for i in range(remove_count):
+ sys.argv.remove(option)
+ if count > 1:
+ _warn_multiple_option(option)
+ return count > 0
+
+ def option_value(self, name, short_option_name=None, remove=True):
+ """
+ Returns the value of a command line option or environment
+ variable.
+
+ :param name: The name of the command line option or environment
+ variable.
+
+ :param remove: Whether the option and its value should be
+ removed from sys.argv. Useful when there's a need to query for
+ the value and also pass it along to setuptools for example.
+
+ :return: Either the option value or None.
+ """
+ option = '--' + name
+ short_option = '-' + short_option_name if short_option_name else None
+ single_option_prefix = option + '='
+ value = None
+ for index in reversed(range(len(sys.argv))):
+ arg = sys.argv[index]
+ if arg == option or short_option and arg == short_option:
+ if value:
+ _warn_multiple_option(option)
+ else:
+ if index + 1 >= len(sys.argv):
+ raise RuntimeError("The option {} requires a value".format(option))
+ value = sys.argv[index + 1]
+
+ if remove:
+ sys.argv[index:index + 2] = []
+
+ elif arg.startswith(single_option_prefix):
+ if value:
+ _warn_multiple_option(option)
+ else:
+ value = arg[len(single_option_prefix):]
+
+ if remove:
+ sys.argv[index:index + 1] = []
+
+ if value is None:
+ value = os.getenv(name.upper().replace('-', '_'))
+
+ self.dict[name] = value
+ return value
+
+
+options = Options()
+
+
+def has_option(*args, **kwargs):
+ return options.has_option(*args, **kwargs)
+
+
+def option_value(*args,**kwargs):
+ return options.option_value(*args,**kwargs)
-from .utils import has_option, option_value
# Declare options
+OPTION_BUILD_TYPE = option_value("build-type")
+OPTION_INTERNAL_BUILD_TYPE = option_value("internal-build-type")
OPTION_DEBUG = has_option("debug")
OPTION_RELWITHDEBINFO = has_option('relwithdebinfo')
OPTION_QMAKE = option_value("qmake")
OPTION_QT_VERSION = option_value("qt")
OPTION_CMAKE = option_value("cmake")
OPTION_OPENSSL = option_value("openssl")
+OPTION_SHIBOKEN_CONFIG_DIR = option_value("shiboken-config-dir")
OPTION_ONLYPACKAGE = has_option("only-package")
OPTION_STANDALONE = has_option("standalone")
OPTION_MAKESPEC = option_value("make-spec")
@@ -57,7 +150,11 @@ OPTION_SKIP_DOCS = has_option("skip-docs")
# don't include pyside2-examples
OPTION_NOEXAMPLES = has_option("no-examples")
# number of parallel build jobs
-OPTION_JOBS = option_value('jobs')
+OPTION_JOBS = option_value('parallel', short_option_name='j')
+_deprecated_option_jobs = option_value('jobs')
+if _deprecated_option_jobs:
+ _warn_deprecated_option('jobs', 'parallel')
+ OPTION_JOBS = _deprecated_option_jobs
# Legacy, not used any more.
OPTION_JOM = has_option('jom')
# Do not use jom instead of nmake with msvc
@@ -77,8 +174,13 @@ OPTION_MODULE_SUBSET = option_value("module-subset")
OPTION_RPATH_VALUES = option_value("rpath")
OPTION_QT_CONF_PREFIX = option_value("qt-conf-prefix")
OPTION_QT_SRC = option_value("qt-src-dir")
+OPTION_QUIET = has_option('quiet', remove=False)
OPTION_VERBOSE_BUILD = has_option("verbose-build")
OPTION_SANITIZE_ADDRESS = has_option("sanitize-address")
OPTION_SNAPSHOT_BUILD = has_option("snapshot-build")
OPTION_LIMITED_API = option_value("limited-api")
OPTION_PACKAGE_TIMESTAMP = option_value("package-timestamp")
+
+# This is used automatically by distutils.command.install object, to
+# specify the final installation location.
+OPTION_FINAL_INSTALL_PREFIX = option_value("prefix", remove=False)
diff --git a/build_scripts/platforms/linux.py b/build_scripts/platforms/linux.py
index 4c38fef6c..067179cdc 100644
--- a/build_scripts/platforms/linux.py
+++ b/build_scripts/platforms/linux.py
@@ -37,76 +37,100 @@
##
#############################################################################
-from ..options import *
from ..utils import copydir, copyfile, copy_icu_libs, find_files_using_glob
+from ..config import config
-def prepare_standalone_package_linux(self, executables, vars):
+
+def prepare_standalone_package_linux(self, vars):
built_modules = vars['built_modules']
- # <qt>/lib/* -> <setup>/PySide2/Qt/lib
- destination_lib_dir = "{pyside_package_dir}/PySide2/Qt/lib"
+ constrain_modules = None
+ copy_plugins = True
+ copy_qml = True
+ copy_translations = True
+ copy_qt_conf = True
+ should_copy_icu_libs = True
+
+ if config.is_internal_shiboken_generator_build():
+ constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"]
+ copy_plugins = False
+ copy_qml = False
+ copy_translations = False
+ copy_qt_conf = False
+ should_copy_icu_libs = False
+
+ # <qt>/lib/* -> <setup>/{st_package_name}/Qt/lib
+ destination_lib_dir = "{st_build_dir}/{st_package_name}/Qt/lib"
+
+ accepted_modules = ['libQt5*.so.?']
+ if constrain_modules:
+ accepted_modules = ["libQt5" + module + "*.so.?" for module in constrain_modules]
+ accepted_modules.append("libicu*.so.??")
+
copydir("{qt_lib_dir}", destination_lib_dir,
- filter=[
- "libQt5*.so.?",
- "libicu*.so.??",
- ],
- recursive=False, vars=vars, force_copy_symlinks=True)
-
- # Check if ICU libraries were copied over to the destination
- # Qt libdir.
- resolved_destination_lib_dir = destination_lib_dir.format(**vars)
- maybe_icu_libs = find_files_using_glob(resolved_destination_lib_dir,
- "libicu*")
-
- # If no ICU libraries are present in the Qt libdir (like when
- # Qt is built against system ICU, or in the Coin CI where ICU
- # libs are in a different directory) try to find out / resolve
- # which ICU libs are used by QtCore (if used at all) using a
- # custom written ldd, and copy the ICU libs to the Pyside Qt
- # dir if necessary. We choose the QtCore lib to inspect, by
- # checking which QtCore library the shiboken2 executable uses.
- if not maybe_icu_libs:
- copy_icu_libs(self._patchelf_path, resolved_destination_lib_dir)
+ filter=accepted_modules,
+ recursive=False, vars=vars, force_copy_symlinks=True)
+
+ if should_copy_icu_libs:
+ # Check if ICU libraries were copied over to the destination
+ # Qt libdir.
+ resolved_destination_lib_dir = destination_lib_dir.format(**vars)
+ maybe_icu_libs = find_files_using_glob(resolved_destination_lib_dir,
+ "libicu*")
+
+ # If no ICU libraries are present in the Qt libdir (like when
+ # Qt is built against system ICU, or in the Coin CI where ICU
+ # libs are in a different directory) try to find out / resolve
+ # which ICU libs are used by QtCore (if used at all) using a
+ # custom written ldd, and copy the ICU libs to the Pyside Qt
+ # dir if necessary. We choose the QtCore lib to inspect, by
+ # checking which QtCore library the shiboken2 executable uses.
+ if not maybe_icu_libs:
+ copy_icu_libs(self._patchelf_path, resolved_destination_lib_dir)
if self.is_webengine_built(built_modules):
copydir("{qt_lib_execs_dir}",
- "{pyside_package_dir}/PySide2/Qt/libexec",
+ "{st_build_dir}/{st_package_name}/Qt/libexec",
filter=None,
recursive=False,
vars=vars)
copydir("{qt_prefix_dir}/resources",
- "{pyside_package_dir}/PySide2/Qt/resources",
+ "{st_build_dir}/{st_package_name}/Qt/resources",
filter=None,
recursive=False,
vars=vars)
- # <qt>/plugins/* -> <setup>/PySide2/Qt/plugins
- copydir("{qt_plugins_dir}",
- "{pyside_package_dir}/PySide2/Qt/plugins",
- filter=["*.so"],
- recursive=True,
- vars=vars)
-
- # <qt>/qml/* -> <setup>/PySide2/Qt/qml
- copydir("{qt_qml_dir}",
- "{pyside_package_dir}/PySide2/Qt/qml",
- filter=None,
- force=False,
- recursive=True,
- ignore=["*.so.debug"],
- vars=vars)
-
- # <qt>/translations/* -> <setup>/PySide2/Qt/translations
-
- copydir("{qt_translations_dir}",
- "{pyside_package_dir}/PySide2/Qt/translations",
- filter=["*.qm", "*.pak"],
- force=False,
- vars=vars)
-
- # Copy the qt.conf file to libexec.
- copyfile(
- "{build_dir}/pyside2/PySide2/qt.conf",
- "{pyside_package_dir}/PySide2/Qt/libexec",
- vars=vars)
+ if copy_plugins:
+ # <qt>/plugins/* -> <setup>/{st_package_name}/Qt/plugins
+ copydir("{qt_plugins_dir}",
+ "{st_build_dir}/{st_package_name}/Qt/plugins",
+ filter=["*.so"],
+ recursive=True,
+ vars=vars)
+
+ if copy_qml:
+ # <qt>/qml/* -> <setup>/{st_package_name}/Qt/qml
+ copydir("{qt_qml_dir}",
+ "{st_build_dir}/{st_package_name}/Qt/qml",
+ filter=None,
+ force=False,
+ recursive=True,
+ ignore=["*.so.debug"],
+ vars=vars)
+
+ if copy_translations:
+ # <qt>/translations/* ->
+ # <setup>/{st_package_name}/Qt/translations
+ copydir("{qt_translations_dir}",
+ "{st_build_dir}/{st_package_name}/Qt/translations",
+ filter=["*.qm", "*.pak"],
+ force=False,
+ vars=vars)
+
+ if copy_qt_conf:
+ # Copy the qt.conf file to libexec.
+ copyfile(
+ "{build_dir}/pyside2/{st_package_name}/qt.conf",
+ "{st_build_dir}/{st_package_name}/Qt/libexec",
+ vars=vars)
diff --git a/build_scripts/platforms/macos.py b/build_scripts/platforms/macos.py
index 936f4ca90..49f02754d 100644
--- a/build_scripts/platforms/macos.py
+++ b/build_scripts/platforms/macos.py
@@ -37,12 +37,29 @@
##
#############################################################################
-import fnmatch, os
+import fnmatch
+import os
from ..utils import copydir, copyfile, macos_fix_rpaths_for_library
+from ..config import config
-def prepare_standalone_package_macos(self, executables, vars):
+
+def prepare_standalone_package_macos(self, vars):
built_modules = vars['built_modules']
+ constrain_modules = None
+ copy_plugins = True
+ copy_qml = True
+ copy_translations = True
+ copy_qt_conf = True
+
+ if config.is_internal_shiboken_generator_build():
+ constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"]
+ constrain_frameworks = ['Qt' + name + '.framework' for name in constrain_modules]
+ copy_plugins = False
+ copy_qml = False
+ copy_translations = False
+ copy_qt_conf = False
+
# Directory filter for skipping unnecessary files.
def general_dir_filter(dir_name, parent_full_path, dir_full_path):
if fnmatch.fnmatch(dir_name, "*.dSYM"):
@@ -52,6 +69,7 @@ def prepare_standalone_package_macos(self, executables, vars):
# Filter out debug plugins and qml plugins in the
# debug_and_release config.
no_copy_debug = True
+
def file_variant_filter(file_name, file_full_path):
if self.qtinfo.build_type != 'debug_and_release':
return True
@@ -59,17 +77,16 @@ def prepare_standalone_package_macos(self, executables, vars):
return False
return True
- # <qt>/lib/* -> <setup>/PySide2/Qt/lib
+ # <qt>/lib/* -> <setup>/{st_package_name}/Qt/lib
if self.qt_is_framework_build():
- framework_built_modules = [
- 'Qt' + name + '.framework' for name in built_modules]
-
- def framework_dir_filter(dir_name, parent_full_path,
- dir_full_path):
+ def framework_dir_filter(dir_name, parent_full_path, dir_full_path):
if '.framework' in dir_name:
- if dir_name.startswith('QtWebEngine') and not \
- self.is_webengine_built(built_modules):
+ if (dir_name.startswith('QtWebEngine') and
+ not self.is_webengine_built(built_modules)):
+ return False
+ if constrain_modules and dir_name not in constrain_frameworks:
return False
+
if dir_name in ['Headers', 'fonts']:
return False
if dir_full_path.endswith('Versions/Current'):
@@ -84,6 +101,7 @@ def prepare_standalone_package_macos(self, executables, vars):
# Filter out debug frameworks in the
# debug_and_release config.
no_copy_debug = True
+
def framework_variant_filter(file_name, file_full_path):
if self.qtinfo.build_type != 'debug_and_release':
return True
@@ -93,7 +111,7 @@ def prepare_standalone_package_macos(self, executables, vars):
return False
return True
- copydir("{qt_lib_dir}", "{pyside_package_dir}/PySide2/Qt/lib",
+ copydir("{qt_lib_dir}", "{st_build_dir}/{st_package_name}/Qt/lib",
recursive=True, vars=vars,
ignore=["*.la", "*.a", "*.cmake", "*.pc", "*.prl"],
dir_filter_function=framework_dir_filter,
@@ -104,7 +122,7 @@ def prepare_standalone_package_macos(self, executables, vars):
# from Versions/5/Helpers, thus adding two more levels of
# directory hierarchy.
if self.is_webengine_built(built_modules):
- qt_lib_path = "{pyside_package_dir}/PySide2/Qt/lib".format(
+ qt_lib_path = "{st_build_dir}/{st_package_name}/Qt/lib".format(
**vars)
bundle = "QtWebEngineCore.framework/Helpers/"
bundle += "QtWebEngineProcess.app"
@@ -120,9 +138,11 @@ def prepare_standalone_package_macos(self, executables, vars):
if 'WebKit' not in built_modules:
ignored_modules.extend(['libQt5WebKit*.dylib'])
accepted_modules = ['libQt5*.5.dylib']
+ if constrain_modules:
+ accepted_modules = ["libQt5" + module + "*.5.dylib" for module in constrain_modules]
copydir("{qt_lib_dir}",
- "{pyside_package_dir}/PySide2/Qt/lib",
+ "{st_build_dir}/{st_package_name}/Qt/lib",
filter=accepted_modules,
ignore=ignored_modules,
file_filter_function=file_variant_filter,
@@ -130,53 +150,58 @@ def prepare_standalone_package_macos(self, executables, vars):
if self.is_webengine_built(built_modules):
copydir("{qt_lib_execs_dir}",
- "{pyside_package_dir}/PySide2/Qt/libexec",
+ "{st_build_dir}/{st_package_name}/Qt/libexec",
filter=None,
recursive=False,
vars=vars)
copydir("{qt_prefix_dir}/resources",
- "{pyside_package_dir}/PySide2/Qt/resources",
+ "{st_build_dir}/{st_package_name}/Qt/resources",
filter=None,
recursive=False,
vars=vars)
# Fix rpath for WebEngine process executable.
- pyside_package_dir = vars['pyside_package_dir']
- qt_libexec_path = "{}/PySide2/Qt/libexec".format(pyside_package_dir)
+ qt_libexec_path = "{st_build_dir}/{st_package_name}/Qt/libexec".format(**vars)
binary = "QtWebEngineProcess"
final_path = os.path.join(qt_libexec_path, binary)
rpath = "@loader_path/../lib"
macos_fix_rpaths_for_library(final_path, rpath)
- # Copy the qt.conf file to libexec.
- copyfile(
- "{build_dir}/pyside2/PySide2/qt.conf",
- "{pyside_package_dir}/PySide2/Qt/libexec",
- vars=vars)
+ if copy_qt_conf:
+ # Copy the qt.conf file to libexec.
+ copyfile(
+ "{build_dir}/pyside2/{st_package_name}/qt.conf",
+ "{st_build_dir}/{st_package_name}/Qt/libexec",
+ vars=vars)
+
+ if copy_plugins:
+ # <qt>/plugins/* -> <setup>/{st_package_name}/Qt/plugins
+ copydir("{qt_plugins_dir}",
+ "{st_build_dir}/{st_package_name}/Qt/plugins",
+ filter=["*.dylib"],
+ recursive=True,
+ dir_filter_function=general_dir_filter,
+ file_filter_function=file_variant_filter,
+ vars=vars)
+
- # <qt>/plugins/* -> <setup>/PySide2/Qt/plugins
- copydir("{qt_plugins_dir}",
- "{pyside_package_dir}/PySide2/Qt/plugins",
- filter=["*.dylib"],
- recursive=True,
- dir_filter_function=general_dir_filter,
- file_filter_function=file_variant_filter,
- vars=vars)
-
- # <qt>/qml/* -> <setup>/PySide2/Qt/qml
- copydir("{qt_qml_dir}",
- "{pyside_package_dir}/PySide2/Qt/qml",
- filter=None,
- recursive=True,
- force=False,
- dir_filter_function=general_dir_filter,
- file_filter_function=file_variant_filter,
- vars=vars)
-
- # <qt>/translations/* -> <setup>/PySide2/Qt/translations
- copydir("{qt_translations_dir}",
- "{pyside_package_dir}/PySide2/Qt/translations",
- filter=["*.qm", "*.pak"],
- force=False,
- vars=vars)
+ if copy_qml:
+ # <qt>/qml/* -> <setup>/{st_package_name}/Qt/qml
+ copydir("{qt_qml_dir}",
+ "{st_build_dir}/{st_package_name}/Qt/qml",
+ filter=None,
+ recursive=True,
+ force=False,
+ dir_filter_function=general_dir_filter,
+ file_filter_function=file_variant_filter,
+ vars=vars)
+
+ if copy_translations:
+ # <qt>/translations/* ->
+ # <setup>/{st_package_name}/Qt/translations
+ copydir("{qt_translations_dir}",
+ "{st_build_dir}/{st_package_name}/Qt/translations",
+ filter=["*.qm", "*.pak"],
+ force=False,
+ vars=vars)
diff --git a/build_scripts/platforms/unix.py b/build_scripts/platforms/unix.py
index c93bbbbbe..d3767976f 100644
--- a/build_scripts/platforms/unix.py
+++ b/build_scripts/platforms/unix.py
@@ -37,69 +37,31 @@
##
#############################################################################
-import os, re, sys
+import os
+import sys
from .linux import prepare_standalone_package_linux
from .macos import prepare_standalone_package_macos
+
+from ..config import config
from ..options import *
from ..utils import copydir, copyfile, rmtree, makefile
from ..utils import regenerate_qt_resources
+
def prepare_packages_posix(self, vars):
executables = []
- # <build>/shiboken2/doc/html/* ->
- # <setup>/PySide2/docs/shiboken2
- copydir(
- "{build_dir}/shiboken2/doc/html",
- "{pyside_package_dir}/PySide2/docs/shiboken2",
- force=False, vars=vars)
- # <install>/lib/site-packages/PySide2/* -> <setup>/PySide2
- copydir(
- "{site_packages_dir}/PySide2",
- "{pyside_package_dir}/PySide2",
- vars=vars)
- # <install>/lib/site-packages/shiboken2.so ->
- # <setup>/PySide2/shiboken2.so
- shiboken_module_name = 'shiboken2.so'
- shiboken_src_path = "{site_packages_dir}".format(**vars)
- maybe_shiboken_names = [f for f in os.listdir(shiboken_src_path)
- if re.match(r'shiboken.*\.so', f)]
- if maybe_shiboken_names:
- shiboken_module_name = maybe_shiboken_names[0]
- vars.update({'shiboken_module_name': shiboken_module_name})
- copyfile(
- "{site_packages_dir}/{shiboken_module_name}",
- "{pyside_package_dir}/PySide2/{shiboken_module_name}",
- vars=vars)
- # <install>/lib/site-packages/pyside2uic/* ->
- # <setup>/pyside2uic
+
+ # <install>/lib/site-packages/{st_package_name}/* ->
+ # <setup>/{st_package_name}
+ # This copies the module .so/.dylib files and various .py files
+ # (__init__, config, git version, etc.)
copydir(
- "{site_packages_dir}/pyside2uic",
- "{pyside_package_dir}/pyside2uic",
- force=False, vars=vars)
- if sys.version_info[0] > 2:
- rmtree("{pyside_package_dir}/pyside2uic/port_v2".format(**vars))
- else:
- rmtree("{pyside_package_dir}/pyside2uic/port_v3".format(**vars))
- # <install>/bin/pyside2-uic -> PySide2/scripts/uic.py
- makefile(
- "{pyside_package_dir}/PySide2/scripts/__init__.py",
+ "{site_packages_dir}/{st_package_name}",
+ "{st_build_dir}/{st_package_name}",
vars=vars)
- copyfile(
- "{install_dir}/bin/pyside2-uic",
- "{pyside_package_dir}/PySide2/scripts/uic.py",
- force=False, vars=vars)
- # <install>/bin/* -> PySide2/
- executables.extend(copydir(
- "{install_dir}/bin/",
- "{pyside_package_dir}/PySide2",
- filter=[
- "pyside2-lupdate",
- "pyside2-rcc",
- "shiboken2",
- ],
- recursive=False, vars=vars))
- # <install>/lib/lib* -> PySide2/
- config = self.get_built_pyside_config(vars)
+
+ generated_config = self.get_built_pyside_config(vars)
+
def adjusted_lib_name(name, version):
postfix = ''
if sys.platform.startswith('linux'):
@@ -107,61 +69,159 @@ def prepare_packages_posix(self, vars):
elif sys.platform == 'darwin':
postfix = '.' + version + '.dylib'
return name + postfix
- copydir(
- "{install_dir}/lib/",
- "{pyside_package_dir}/PySide2",
- filter=[
- adjusted_lib_name("libpyside*",
- config['pyside_library_soversion']),
- adjusted_lib_name("libshiboken*",
- config['shiboken_library_soversion']),
- ],
- recursive=False, vars=vars, force_copy_symlinks=True)
- # <install>/share/PySide2/typesystems/* ->
- # <setup>/PySide2/typesystems
- copydir(
- "{install_dir}/share/PySide2/typesystems",
- "{pyside_package_dir}/PySide2/typesystems",
- vars=vars)
- # <install>/include/* -> <setup>/PySide2/include
- copydir(
- "{install_dir}/include",
- "{pyside_package_dir}/PySide2/include",
- vars=vars)
- # <source>/pyside2/PySide2/support/* ->
- # <setup>/PySide2/support/*
- copydir(
- "{build_dir}/pyside2/PySide2/support",
- "{pyside_package_dir}/PySide2/support",
- vars=vars)
- if not OPTION_NOEXAMPLES:
- # examples/* -> <setup>/PySide2/examples
- copydir(os.path.join(self.script_dir, "examples"),
- "{pyside_package_dir}/PySide2/examples",
- force=False, vars=vars)
- # Re-generate examples Qt resource files for Python 3
- # compatibility
- if sys.version_info[0] == 3:
- examples_path = "{pyside_package_dir}/PySide2/examples".format(
- **vars)
- pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format(
- **vars)
- pyside_rcc_options = '-py3'
- regenerate_qt_resources(examples_path, pyside_rcc_path,
- pyside_rcc_options)
+
+ if config.is_internal_shiboken_module_build():
+ # <build>/shiboken2/doc/html/* ->
+ # <setup>/{st_package_name}/docs/shiboken2
+ copydir(
+ "{build_dir}/shiboken2/doc/html",
+ "{st_build_dir}/{st_package_name}/docs/shiboken2",
+ force=False, vars=vars)
+
+ # <install>/lib/lib* -> {st_package_name}/
+ copydir(
+ "{install_dir}/lib/",
+ "{st_build_dir}/{st_package_name}",
+ filter=[
+ adjusted_lib_name("libshiboken*",
+ generated_config['shiboken_library_soversion']),
+ ],
+ recursive=False, vars=vars, force_copy_symlinks=True)
+
+ if config.is_internal_shiboken_generator_build():
+ # <install>/bin/* -> {st_package_name}/
+ executables.extend(copydir(
+ "{install_dir}/bin/",
+ "{st_build_dir}/{st_package_name}",
+ filter=[
+ "shiboken2",
+ ],
+ recursive=False, vars=vars))
+
+ # Used to create scripts directory.
+ makefile(
+ "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py",
+ vars=vars)
+
+ # For setting up setuptools entry points.
+ copyfile(
+ "{install_dir}/bin/shiboken_tool.py",
+ "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py",
+ force=False, vars=vars)
+
+ if config.is_internal_shiboken_generator_build() or config.is_internal_pyside_build():
+ # <install>/include/* -> <setup>/{st_package_name}/include
+ copydir(
+ "{install_dir}/include/{cmake_package_name}",
+ "{st_build_dir}/{st_package_name}/include",
+ vars=vars)
+
+ if config.is_internal_pyside_build():
+ # <install>/lib/site-packages/pyside2uic/* ->
+ # <setup>/pyside2uic
+ copydir(
+ "{site_packages_dir}/pyside2uic",
+ "{st_build_dir}/pyside2uic",
+ force=False, vars=vars)
+ if sys.version_info[0] > 2:
+ rmtree("{st_build_dir}/pyside2uic/port_v2".format(**vars))
+ else:
+ rmtree("{st_build_dir}/pyside2uic/port_v3".format(**vars))
+
+ # <install>/bin/pyside2-uic -> {st_package_name}/scripts/uic.py
+ makefile(
+ "{st_build_dir}/{st_package_name}/scripts/__init__.py",
+ vars=vars)
+ copyfile(
+ "{install_dir}/bin/pyside2-uic",
+ "{st_build_dir}/{st_package_name}/scripts/uic.py",
+ force=False, vars=vars)
+
+ # For setting up setuptools entry points
+ copyfile(
+ "{install_dir}/bin/pyside_tool.py",
+ "{st_build_dir}/{st_package_name}/scripts/pyside_tool.py",
+ force=False, vars=vars)
+
+ # <install>/bin/* -> {st_package_name}/
+ executables.extend(copydir(
+ "{install_dir}/bin/",
+ "{st_build_dir}/{st_package_name}",
+ filter=[
+ "pyside2-lupdate",
+ "pyside2-rcc",
+ ],
+ recursive=False, vars=vars))
+
+ # <install>/lib/lib* -> {st_package_name}/
+ copydir(
+ "{install_dir}/lib/",
+ "{st_build_dir}/{st_package_name}",
+ filter=[
+ adjusted_lib_name("libpyside*",
+ generated_config['pyside_library_soversion']),
+ ],
+ recursive=False, vars=vars, force_copy_symlinks=True)
+
+ # <install>/share/{st_package_name}/typesystems/* ->
+ # <setup>/{st_package_name}/typesystems
+ copydir(
+ "{install_dir}/share/{st_package_name}/typesystems",
+ "{st_build_dir}/{st_package_name}/typesystems",
+ vars=vars)
+
+ # <install>/share/{st_package_name}/glue/* ->
+ # <setup>/{st_package_name}/glue
+ copydir(
+ "{install_dir}/share/{st_package_name}/glue",
+ "{st_build_dir}/{st_package_name}/glue",
+ vars=vars)
+
+ # <source>/pyside2/{st_package_name}/support/* ->
+ # <setup>/{st_package_name}/support/*
+ copydir(
+ "{build_dir}/pyside2/{st_package_name}/support",
+ "{st_build_dir}/{st_package_name}/support",
+ vars=vars)
+
+ # <source>/pyside2/{st_package_name}/*.pyi ->
+ # <setup>/{st_package_name}/*.pyi
+ copydir(
+ "{build_dir}/pyside2/{st_package_name}",
+ "{st_build_dir}/{st_package_name}",
+ filter=["*.pyi"],
+ vars=vars)
+
+ if not OPTION_NOEXAMPLES:
+ # examples/* -> <setup>/{st_package_name}/examples
+ copydir(os.path.join(self.script_dir, "examples"),
+ "{st_build_dir}/{st_package_name}/examples",
+ force=False, vars=vars)
+ # Re-generate examples Qt resource files for Python 3
+ # compatibility
+ if sys.version_info[0] == 3:
+ examples_path = "{st_build_dir}/{st_package_name}/examples".format(
+ **vars)
+ pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format(
+ **vars)
+ pyside_rcc_options = '-py3'
+ regenerate_qt_resources(examples_path, pyside_rcc_path,
+ pyside_rcc_options)
+
# Copy Qt libs to package
if OPTION_STANDALONE:
- vars['built_modules'] = config['built_modules']
- if sys.platform == 'darwin':
- prepare_standalone_package_macos(self, executables, vars)
- else:
- prepare_standalone_package_linux(self, executables, vars)
+ if config.is_internal_pyside_build() or config.is_internal_shiboken_generator_build():
+ vars['built_modules'] = generated_config['built_modules']
+ if sys.platform == 'darwin':
+ prepare_standalone_package_macos(self, vars)
+ else:
+ prepare_standalone_package_linux(self, vars)
- # Copy over clang before rpath patching.
- self.prepare_standalone_clang(is_win=False)
+ if config.is_internal_shiboken_generator_build():
+ # Copy over clang before rpath patching.
+ self.prepare_standalone_clang(is_win=False)
# Update rpath to $ORIGIN
- if (sys.platform.startswith('linux') or
- sys.platform.startswith('darwin')):
- self.update_rpath("{pyside_package_dir}/PySide2".format(**vars),
- executables)
+ if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
+ rpath_path = "{st_build_dir}/{st_package_name}".format(**vars)
+ self.update_rpath(rpath_path, executables)
diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py
index 3bf386a17..c98ef3959 100644
--- a/build_scripts/platforms/windows_desktop.py
+++ b/build_scripts/platforms/windows_desktop.py
@@ -38,147 +38,240 @@
#############################################################################
import functools
-import os, re, sys
+import os
+import sys
+
+from ..config import config
from ..options import *
from ..utils import copydir, copyfile, rmtree, makefile
from ..utils import regenerate_qt_resources, filter_match
from ..utils import download_and_extract_7z
+
def prepare_packages_win32(self, vars):
# For now, debug symbols will not be shipped into the package.
copy_pdbs = False
pdbs = []
if (self.debug or self.build_type == 'RelWithDebInfo') and copy_pdbs:
pdbs = ['*.pdb']
- # <install>/lib/site-packages/PySide2/* -> <setup>/PySide2
+
+ # <install>/lib/site-packages/{st_package_name}/* ->
+ # <setup>/{st_package_name}
+ # This copies the module .pyd files and various .py files
+ # (__init__, config, git version, etc.)
copydir(
- "{site_packages_dir}/PySide2",
- "{pyside_package_dir}/PySide2",
+ "{site_packages_dir}/{st_package_name}",
+ "{st_build_dir}/{st_package_name}",
vars=vars)
- built_modules = self.get_built_pyside_config(vars)['built_modules']
- # <build>/pyside2/PySide2/*.pdb -> <setup>/PySide2
- copydir(
- "{build_dir}/pyside2/PySide2",
- "{pyside_package_dir}/PySide2",
- filter=pdbs,
- recursive=False, vars=vars)
+ if config.is_internal_shiboken_module_build():
+ # <build>/shiboken2/doc/html/* ->
+ # <setup>/{st_package_name}/docs/shiboken2
+ copydir(
+ "{build_dir}/shiboken2/doc/html",
+ "{st_build_dir}/{st_package_name}/docs/shiboken2",
+ force=False, vars=vars)
+
+ # <install>/bin/*.dll -> {st_package_name}/
+ copydir(
+ "{install_dir}/bin/",
+ "{st_build_dir}/{st_package_name}",
+ filter=["shiboken*.dll"],
+ recursive=False, vars=vars)
- # <build>/shiboken2/doc/html/* ->
- # <setup>/PySide2/docs/shiboken2
- copydir(
- "{build_dir}/shiboken2/doc/html",
- "{pyside_package_dir}/PySide2/docs/shiboken2",
- force=False, vars=vars)
-
- # <install>/lib/site-packages/shiboken2.pyd ->
- # <setup>/PySide2/shiboken2.pyd
- shiboken_module_name = 'shiboken2.pyd'
- shiboken_src_path = "{site_packages_dir}".format(**vars)
- maybe_shiboken_names = [f for f in os.listdir(shiboken_src_path)
- if re.match(r'shiboken.*\.pyd', f)]
- if maybe_shiboken_names:
- shiboken_module_name = maybe_shiboken_names[0]
- vars.update({'shiboken_module_name': shiboken_module_name})
- copyfile(
- "{site_packages_dir}/{shiboken_module_name}",
- "{pyside_package_dir}/PySide2/{shiboken_module_name}",
- vars=vars)
- # @TODO: Fix this .pdb file not to overwrite release
- # {shibokengenerator}.pdb file.
- # Task-number: PYSIDE-615
- copydir(
- "{build_dir}/shiboken2/shibokenmodule",
- "{pyside_package_dir}/PySide2",
- filter=pdbs,
- recursive=False, vars=vars)
+ # <install>/lib/*.lib -> {st_package_name}/
+ copydir(
+ "{install_dir}/lib/",
+ "{st_build_dir}/{st_package_name}",
+ filter=["shiboken*.lib"],
+ recursive=False, vars=vars)
- # <install>/lib/site-packages/pyside2uic/* ->
- # <setup>/pyside2uic
- copydir(
- "{site_packages_dir}/pyside2uic",
- "{pyside_package_dir}/pyside2uic",
- force=False, vars=vars)
- if sys.version_info[0] > 2:
- rmtree("{pyside_package_dir}/pyside2uic/port_v2".format(**vars))
- else:
- rmtree("{pyside_package_dir}/pyside2uic/port_v3".format(**vars))
+ # @TODO: Fix this .pdb file not to overwrite release
+ # {shibokengenerator}.pdb file.
+ # Task-number: PYSIDE-615
+ copydir(
+ "{build_dir}/shiboken2/shibokenmodule",
+ "{st_build_dir}/{st_package_name}",
+ filter=pdbs,
+ recursive=False, vars=vars)
- # <install>/bin/pyside2-uic -> PySide2/scripts/uic.py
- makefile(
- "{pyside_package_dir}/PySide2/scripts/__init__.py",
- vars=vars)
- copyfile(
- "{install_dir}/bin/pyside2-uic",
- "{pyside_package_dir}/PySide2/scripts/uic.py",
- force=False, vars=vars)
+ # pdb files for libshiboken and libpyside
+ copydir(
+ "{build_dir}/shiboken2/libshiboken",
+ "{st_build_dir}/{st_package_name}",
+ filter=pdbs,
+ recursive=False, vars=vars)
- # <install>/bin/*.exe,*.dll,*.pdb -> PySide2/
- copydir(
- "{install_dir}/bin/",
- "{pyside_package_dir}/PySide2",
- filter=["*.exe", "*.dll"],
- recursive=False, vars=vars)
- # @TODO: Fix this .pdb file not to overwrite release
- # {shibokenmodule}.pdb file.
- # Task-number: PYSIDE-615
- copydir(
- "{build_dir}/shiboken2/generator",
- "{pyside_package_dir}/PySide2",
- filter=pdbs,
- recursive=False, vars=vars)
+ if config.is_internal_shiboken_generator_build():
+ # <install>/bin/*.dll -> {st_package_name}/
+ copydir(
+ "{install_dir}/bin/",
+ "{st_build_dir}/{st_package_name}",
+ filter=["shiboken*.exe"],
+ recursive=False, vars=vars)
- # <install>/lib/*.lib -> PySide2/
- copydir(
- "{install_dir}/lib/",
- "{pyside_package_dir}/PySide2",
- filter=["*.lib"],
- recursive=False, vars=vars)
+ # Used to create scripts directory.
+ makefile(
+ "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py",
+ vars=vars)
- # <install>/share/PySide2/typesystems/* ->
- # <setup>/PySide2/typesystems
- copydir(
- "{install_dir}/share/PySide2/typesystems",
- "{pyside_package_dir}/PySide2/typesystems",
- vars=vars)
+ # For setting up setuptools entry points.
+ copyfile(
+ "{install_dir}/bin/shiboken_tool.py",
+ "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py",
+ force=False, vars=vars)
+
+ # @TODO: Fix this .pdb file not to overwrite release
+ # {shibokenmodule}.pdb file.
+ # Task-number: PYSIDE-615
+ copydir(
+ "{build_dir}/shiboken2/generator",
+ "{st_build_dir}/{st_package_name}",
+ filter=pdbs,
+ recursive=False, vars=vars)
- # <install>/include/* -> <setup>/PySide2/include
- copydir(
- "{install_dir}/include",
- "{pyside_package_dir}/PySide2/include",
- vars=vars)
+ if config.is_internal_shiboken_generator_build() or config.is_internal_pyside_build():
+ # <install>/include/* -> <setup>/{st_package_name}/include
+ copydir(
+ "{install_dir}/include/{cmake_package_name}",
+ "{st_build_dir}/{st_package_name}/include",
+ vars=vars)
- # <source>/pyside2/PySide2/support/* ->
- # <setup>/PySide2/support/*
- copydir(
- "{build_dir}/pyside2/PySide2/support",
- "{pyside_package_dir}/PySide2/support",
- vars=vars)
+ if config.is_internal_pyside_build():
+ # <build>/pyside2/{st_package_name}/*.pdb ->
+ # <setup>/{st_package_name}
+ copydir(
+ "{build_dir}/pyside2/{st_package_name}",
+ "{st_build_dir}/{st_package_name}",
+ filter=pdbs,
+ recursive=False, vars=vars)
+
+ # <install>/lib/site-packages/pyside2uic/* ->
+ # <setup>/pyside2uic
+ copydir(
+ "{site_packages_dir}/pyside2uic",
+ "{st_build_dir}/pyside2uic",
+ force=False, vars=vars)
+ if sys.version_info[0] > 2:
+ rmtree("{st_build_dir}/pyside2uic/port_v2".format(**vars))
+ else:
+ rmtree("{st_build_dir}/pyside2uic/port_v3".format(**vars))
+
+ # <install>/bin/pyside2-uic -> {st_package_name}/scripts/uic.py
+ makefile(
+ "{st_build_dir}/{st_package_name}/scripts/__init__.py",
+ vars=vars)
+ copyfile(
+ "{install_dir}/bin/pyside2-uic",
+ "{st_build_dir}/{st_package_name}/scripts/uic.py",
+ force=False, vars=vars)
+
+ # For setting up setuptools entry points
+ copyfile(
+ "{install_dir}/bin/pyside_tool.py",
+ "{st_build_dir}/{st_package_name}/scripts/pyside_tool.py",
+ force=False, vars=vars)
+
+ # <install>/bin/*.exe,*.dll -> {st_package_name}/
+ copydir(
+ "{install_dir}/bin/",
+ "{st_build_dir}/{st_package_name}",
+ filter=["pyside*.exe", "pyside*.dll"],
+ recursive=False, vars=vars)
+
+ # <install>/lib/*.lib -> {st_package_name}/
+ copydir(
+ "{install_dir}/lib/",
+ "{st_build_dir}/{st_package_name}",
+ filter=["pyside*.lib"],
+ recursive=False, vars=vars)
- if not OPTION_NOEXAMPLES:
- # examples/* -> <setup>/PySide2/examples
- copydir(os.path.join(self.script_dir, "examples"),
- "{pyside_package_dir}/PySide2/examples",
+ # <install>/share/{st_package_name}/typesystems/* ->
+ # <setup>/{st_package_name}/typesystems
+ copydir(
+ "{install_dir}/share/{st_package_name}/typesystems",
+ "{st_build_dir}/{st_package_name}/typesystems",
+ vars=vars)
+
+ # <install>/share/{st_package_name}/glue/* ->
+ # <setup>/{st_package_name}/glue
+ copydir(
+ "{install_dir}/share/{st_package_name}/glue",
+ "{st_build_dir}/{st_package_name}/glue",
+ vars=vars)
+
+ # <source>/pyside2/{st_package_name}/support/* ->
+ # <setup>/{st_package_name}/support/*
+ copydir(
+ "{build_dir}/pyside2/{st_package_name}/support",
+ "{st_build_dir}/{st_package_name}/support",
+ vars=vars)
+
+ # <source>/pyside2/{st_package_name}/*.pyi ->
+ # <setup>/{st_package_name}/*.pyi
+ copydir(
+ "{build_dir}/pyside2/{st_package_name}",
+ "{st_build_dir}/{st_package_name}",
+ filter=["*.pyi"],
+ vars=vars)
+
+ copydir(
+ "{build_dir}/pyside2/libpyside",
+ "{st_build_dir}/{st_package_name}",
+ filter=pdbs,
+ recursive=False, vars=vars)
+
+ if not OPTION_NOEXAMPLES:
+ # examples/* -> <setup>/{st_package_name}/examples
+ copydir(os.path.join(self.script_dir, "examples"),
+ "{st_build_dir}/{st_package_name}/examples",
+ force=False, vars=vars)
+ # Re-generate examples Qt resource files for Python 3
+ # compatibility
+ if sys.version_info[0] == 3:
+ examples_path = "{st_build_dir}/{st_package_name}/examples".format(
+ **vars)
+ pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format(
+ **vars)
+ pyside_rcc_options = '-py3'
+ regenerate_qt_resources(examples_path, pyside_rcc_path,
+ pyside_rcc_options)
+
+ if vars['ssl_libs_dir']:
+ # <ssl_libs>/* -> <setup>/{st_package_name}/openssl
+ copydir("{ssl_libs_dir}", "{st_build_dir}/{st_package_name}/openssl",
+ filter=[
+ "libeay32.dll",
+ "ssleay32.dll"],
force=False, vars=vars)
- # Re-generate examples Qt resource files for Python 3
- # compatibility
- if sys.version_info[0] == 3:
- examples_path = "{pyside_package_dir}/PySide2/examples".format(
- **vars)
- pyside_rcc_path = "{install_dir}/bin/pyside2-rcc".format(
- **vars)
- pyside_rcc_options = '-py3'
- regenerate_qt_resources(examples_path, pyside_rcc_path,
- pyside_rcc_options)
-
- # <ssl_libs>/* -> <setup>/PySide2/openssl
- copydir("{ssl_libs_dir}", "{pyside_package_dir}/PySide2/openssl",
- filter=[
- "libeay32.dll",
- "ssleay32.dll"],
- force=False, vars=vars)
-
- # <qt>/bin/*.dll and Qt *.exe -> <setup>/PySide2
+
+ if config.is_internal_pyside_build() or config.is_internal_shiboken_generator_build():
+ copy_qt_artifacts(self, copy_pdbs, vars)
+
+
+def copy_qt_artifacts(self, copy_pdbs, vars):
+ built_modules = self.get_built_pyside_config(vars)['built_modules']
+
+ constrain_modules = None
+ copy_plugins = True
+ copy_qml = True
+ copy_translations = True
+ copy_qt_conf = True
+ copy_qt_permanent_artifacts = True
+ copy_msvc_redist = False
+ copy_clang = False
+
+ if config.is_internal_shiboken_generator_build():
+ constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"]
+ copy_plugins = False
+ copy_qml = False
+ copy_translations = False
+ copy_qt_conf = False
+ copy_qt_permanent_artifacts = False
+ copy_msvc_redist = True
+ copy_clang = True
+
+ # <qt>/bin/*.dll and Qt *.exe -> <setup>/{st_package_name}
qt_artifacts_permanent = [
"opengl*.dll",
"d3d*.dll",
@@ -189,6 +282,7 @@ def prepare_packages_win32(self, vars):
"lconvert.exe",
"qtdiag.exe"
]
+
# MSVC redistributable
msvc_redist = [
"concrt140.dll",
@@ -212,8 +306,14 @@ def prepare_packages_win32(self, vars):
else:
egl_suffix = ''
qt_artifacts_egl = [a.format(egl_suffix) for a in qt_artifacts_egl]
- qt_artifacts_permanent += qt_artifacts_egl
- qt_artifacts_permanent += msvc_redist
+
+ artifacts = []
+ if copy_qt_permanent_artifacts:
+ artifacts += qt_artifacts_permanent
+ artifacts += qt_artifacts_egl
+
+ if copy_msvc_redist:
+ artifacts += msvc_redist
# Extract Qt dependency dll's when building on Qt CI
# There is no proper CI env variable, so using agent launch params
@@ -225,15 +325,22 @@ def prepare_packages_win32(self, vars):
zip_file = "pyside_qt_deps_32.7z"
download_and_extract_7z(redist_url + zip_file, "{qt_bin_dir}".format(**vars))
- copydir("{qt_bin_dir}", "{pyside_package_dir}/PySide2",
- filter=qt_artifacts_permanent,
- recursive=False, vars=vars)
+ if artifacts:
+ copydir("{qt_bin_dir}",
+ "{st_build_dir}/{st_package_name}",
+ filter=artifacts, recursive=False, vars=vars)
- # <qt>/bin/*.dll and Qt *.pdbs -> <setup>/PySide2 part two
+ # <qt>/bin/*.dll and Qt *.pdbs -> <setup>/{st_package_name} part two
# File filter to copy only debug or only release files.
- qt_dll_patterns = ["Qt5*{}.dll", "lib*{}.dll"]
- if copy_pdbs:
- qt_dll_patterns += ["Qt5*{}.pdb", "lib*{}.pdb"]
+ if constrain_modules:
+ qt_dll_patterns = ["Qt5" + x + "{}.dll" for x in constrain_modules]
+ if copy_pdbs:
+ qt_dll_patterns += ["Qt5" + x + "{}.pdb" for x in constrain_modules]
+ else:
+ qt_dll_patterns = ["Qt5*{}.dll", "lib*{}.dll"]
+ if copy_pdbs:
+ qt_dll_patterns += ["Qt5*{}.pdb", "lib*{}.pdb"]
+
def qt_build_config_filter(patterns, file_name, file_full_path):
release = [a.format('') for a in patterns]
debug = [a.format('d') for a in patterns]
@@ -283,56 +390,60 @@ def prepare_packages_win32(self, vars):
return False
qt_dll_filter = functools.partial(qt_build_config_filter,
- qt_dll_patterns)
- copydir("{qt_bin_dir}", "{pyside_package_dir}/PySide2",
- file_filter_function=qt_dll_filter,
- recursive=False, vars=vars)
-
- # <qt>/plugins/* -> <setup>/PySide2/plugins
- plugin_dll_patterns = ["*{}.dll"]
- pdb_pattern = "*{}.pdb"
- if copy_pdbs:
- plugin_dll_patterns += [pdb_pattern]
- plugin_dll_filter = functools.partial(qt_build_config_filter,
- plugin_dll_patterns)
- copydir("{qt_plugins_dir}", "{pyside_package_dir}/PySide2/plugins",
- file_filter_function=plugin_dll_filter,
- vars=vars)
+ qt_dll_patterns)
+ copydir("{qt_bin_dir}",
+ "{st_build_dir}/{st_package_name}",
+ file_filter_function=qt_dll_filter,
+ recursive=False, vars=vars)
- # <qt>/translations/* -> <setup>/PySide2/translations
- copydir("{qt_translations_dir}",
- "{pyside_package_dir}/PySide2/translations",
- filter=["*.qm", "*.pak"],
- force=False,
- vars=vars)
+ if copy_plugins:
+ # <qt>/plugins/* -> <setup>/{st_package_name}/plugins
+ plugin_dll_patterns = ["*{}.dll"]
+ pdb_pattern = "*{}.pdb"
+ if copy_pdbs:
+ plugin_dll_patterns += [pdb_pattern]
+ plugin_dll_filter = functools.partial(qt_build_config_filter,
+ plugin_dll_patterns)
+ copydir("{qt_plugins_dir}", "{st_build_dir}/{st_package_name}/plugins",
+ file_filter_function=plugin_dll_filter,
+ vars=vars)
- # <qt>/qml/* -> <setup>/PySide2/qml
- qml_dll_patterns = ["*{}.dll"]
- qml_ignore_patterns = qml_dll_patterns + [pdb_pattern]
- qml_ignore = [a.format('') for a in qml_ignore_patterns]
+ if copy_translations:
+ # <qt>/translations/* -> <setup>/{st_package_name}/translations
+ copydir("{qt_translations_dir}",
+ "{st_build_dir}/{st_package_name}/translations",
+ filter=["*.qm", "*.pak"],
+ force=False,
+ vars=vars)
- # Copy all files that are not dlls and pdbs (.qml, qmldir).
- copydir("{qt_qml_dir}", "{pyside_package_dir}/PySide2/qml",
- ignore=qml_ignore,
- force=False,
- recursive=True,
- vars=vars)
+ if copy_qml:
+ # <qt>/qml/* -> <setup>/{st_package_name}/qml
+ qml_dll_patterns = ["*{}.dll"]
+ qml_ignore_patterns = qml_dll_patterns + [pdb_pattern]
+ qml_ignore = [a.format('') for a in qml_ignore_patterns]
+
+ # Copy all files that are not dlls and pdbs (.qml, qmldir).
+ copydir("{qt_qml_dir}", "{st_build_dir}/{st_package_name}/qml",
+ ignore=qml_ignore,
+ force=False,
+ recursive=True,
+ vars=vars)
- if copy_pdbs:
- qml_dll_patterns += [pdb_pattern]
- qml_dll_filter = functools.partial(qt_build_config_filter,
- qml_dll_patterns)
+ if copy_pdbs:
+ qml_dll_patterns += [pdb_pattern]
+ qml_dll_filter = functools.partial(qt_build_config_filter,
+ qml_dll_patterns)
- # Copy all dlls (and possibly pdbs).
- copydir("{qt_qml_dir}", "{pyside_package_dir}/PySide2/qml",
- file_filter_function=qml_dll_filter,
- force=False,
- recursive=True,
- vars=vars)
+ # Copy all dlls (and possibly pdbs).
+ copydir("{qt_qml_dir}", "{st_build_dir}/{st_package_name}/qml",
+ file_filter_function=qml_dll_filter,
+ force=False,
+ recursive=True,
+ vars=vars)
if self.is_webengine_built(built_modules):
copydir("{qt_prefix_dir}/resources",
- "{pyside_package_dir}/PySide2/resources",
+ "{st_build_dir}/{st_package_name}/resources",
filter=None,
recursive=False,
vars=vars)
@@ -340,26 +451,16 @@ def prepare_packages_win32(self, vars):
filter = 'QtWebEngineProcess{}.exe'.format(
'd' if self.debug else '')
copydir("{qt_bin_dir}",
- "{pyside_package_dir}/PySide2",
+ "{st_build_dir}/{st_package_name}",
filter=[filter],
recursive=False, vars=vars)
- # Copy the qt.conf file to prefix dir.
- copyfile(
- "{build_dir}/pyside2/PySide2/qt.conf",
- "{pyside_package_dir}/PySide2",
- vars=vars)
-
- self.prepare_standalone_clang(is_win=True)
+ if copy_qt_conf:
+ # Copy the qt.conf file to prefix dir.
+ copyfile(
+ "{build_dir}/pyside2/{st_package_name}/qt.conf",
+ "{st_build_dir}/{st_package_name}",
+ vars=vars)
- # pdb files for libshiboken and libpyside
- copydir(
- "{build_dir}/shiboken2/libshiboken",
- "{pyside_package_dir}/PySide2",
- filter=pdbs,
- recursive=False, vars=vars)
- copydir(
- "{build_dir}/pyside2/libpyside",
- "{pyside_package_dir}/PySide2",
- filter=pdbs,
- recursive=False, vars=vars)
+ if copy_clang:
+ self.prepare_standalone_clang(is_win=True)
diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py
new file mode 100644
index 000000000..8efb2883a
--- /dev/null
+++ b/build_scripts/setup_runner.py
@@ -0,0 +1,167 @@
+#############################################################################
+##
+## Copyright (C) 2018 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$
+##
+#############################################################################
+
+import sys, os, textwrap
+
+from build_scripts.config import config
+from build_scripts.main import get_package_version, get_setuptools_extension_modules
+from build_scripts.main import cmd_class_dict
+from build_scripts.options import OPTION_BUILD_TYPE, OPTION_INTERNAL_BUILD_TYPE
+from build_scripts.options import OPTION_QUIET
+from build_scripts.utils import run_process
+
+from setuptools import setup
+
+
+class SetupRunner(object):
+ def __init__(self, orig_argv):
+ self.invocations_list = []
+
+ # Keep the original args around in case we ever need to pass
+ # modified arguments to the sub invocations.
+ self.orig_argv = orig_argv
+ self.sub_argv = list(orig_argv)
+
+ self.setup_script_dir = os.getcwd()
+
+ @staticmethod
+ def cmd_line_argument_is_in_args(argument, args):
+ """ Check if command line argument was passed in args. """
+ return any(arg for arg in list(args) if "--" + argument in arg)
+
+ @staticmethod
+ def remove_cmd_line_argument_in_args(argument, args):
+ """ Remove command line argument from args. """
+ return [arg for arg in list(args) if "--" + argument not in arg]
+
+ @staticmethod
+ def construct_cmd_line_argument(name, value=None):
+ """ Constructs a command line argument given name and value. """
+ if not value:
+ return "--{}".format(name)
+ return "--{}={}".format(name, value)
+
+ @staticmethod
+ def construct_internal_build_type_cmd_line_argument(internal_build_type):
+ return SetupRunner.construct_cmd_line_argument("internal-build-type", internal_build_type)
+
+ def add_setup_internal_invocation(self, build_type, reuse_build=False):
+ """ Enqueues a script sub-invocation to be executed later. """
+ internal_build_type_arg = self.construct_internal_build_type_cmd_line_argument(build_type)
+ setup_cmd = [sys.executable] + self.sub_argv + [internal_build_type_arg]
+
+ # Add --reuse-build option if requested and not already present.
+ if reuse_build and not self.cmd_line_argument_is_in_args("reuse-build", self.sub_argv):
+ setup_cmd.append(self.construct_cmd_line_argument("reuse-build"))
+ self.invocations_list.append(setup_cmd)
+
+ def run_setup(self):
+ """
+ Decide what kind of build is requested and then execute it.
+ In the top-level invocation case, the script
+ will spawn setup.py again (possibly multiple times).
+ In the internal invocation case, the script
+ will run setuptools.setup().
+ """
+
+ # Prepare initial config.
+ config.init_config(build_type=OPTION_BUILD_TYPE,
+ internal_build_type=OPTION_INTERNAL_BUILD_TYPE,
+ cmd_class_dict=cmd_class_dict,
+ package_version=get_package_version(),
+ ext_modules=get_setuptools_extension_modules(),
+ setup_script_dir=self.setup_script_dir,
+ quiet=OPTION_QUIET)
+
+ # This is an internal invocation of setup.py, so start actual
+ # build.
+ if config.is_internal_invocation():
+ if config.internal_build_type not in config.get_allowed_internal_build_values():
+ raise RuntimeError("Invalid '{}' option given to --internal-build-type. "
+ .format(config.internal_build_type))
+ self.run_setuptools_setup()
+ return
+
+ # This is a top-level invocation of setup.py, so figure out what
+ # modules we will build and depending on that, call setup.py
+ # multiple times with different arguments.
+ if config.build_type not in config.get_allowed_top_level_build_values():
+ raise RuntimeError("Invalid '{}' option given to --build-type. "
+ .format(config.build_type))
+
+ # Build everything: shiboken2, shiboken2-generator and PySide2.
+ if config.is_top_level_build_all():
+ self.add_setup_internal_invocation(config.shiboken_module_option_name)
+
+ # Reuse the shiboken build for the generator package instead
+ # of rebuilding it again.
+ self.add_setup_internal_invocation(config.shiboken_generator_option_name,
+ reuse_build=True)
+
+ self.add_setup_internal_invocation(config.pyside_option_name)
+
+ elif config.is_top_level_build_shiboken_module():
+ self.add_setup_internal_invocation(config.shiboken_module_option_name)
+
+ elif config.is_top_level_build_shiboken_generator():
+ self.add_setup_internal_invocation(config.shiboken_generator_option_name)
+
+ elif config.is_top_level_build_pyside():
+ self.add_setup_internal_invocation(config.pyside_option_name)
+
+ for cmd in self.invocations_list:
+ cmd_as_string = " ".join(cmd)
+ print("\nRunning process: {}\n".format(cmd_as_string))
+ exit_code = run_process(cmd, redirect_stderr_to_stdout=False)
+ if exit_code != 0:
+ msg = textwrap.dedent("""
+ setup.py invocation failed with exit code: {}.\n\n
+ setup.py invocation was: {}
+ """).format(exit_code, cmd_as_string)
+ raise RuntimeError(msg)
+
+ @staticmethod
+ def run_setuptools_setup():
+ """
+ Runs setuptools.setup() once in a single setup.py
+ sub-invocation.
+ """
+
+ kwargs = config.setup_kwargs
+ setup(**kwargs)
diff --git a/build_scripts/utils.py b/build_scripts/utils.py
index 4c23a6279..924b698dc 100644
--- a/build_scripts/utils.py
+++ b/build_scripts/utils.py
@@ -39,17 +39,13 @@
import sys
import os
-import stat
import re
import stat
import errno
-import time
import shutil
import subprocess
import fnmatch
-import glob
import itertools
-import popenasync
import glob
# There is no urllib.request in Python2
@@ -58,11 +54,9 @@ try:
except ImportError:
import urllib
-from distutils import log
+import distutils.log as log
from distutils.errors import DistutilsOptionError
from distutils.errors import DistutilsSetupError
-from distutils.spawn import spawn
-from distutils.spawn import DistutilsExecError
try:
WindowsError
@@ -70,32 +64,6 @@ except NameError:
WindowsError = None
-def has_option(name):
- try:
- sys.argv.remove("--{}".format(name))
- return True
- except ValueError:
- pass
- return False
-
-
-def option_value(name):
- for index, option in enumerate(sys.argv):
- if option == '--' + name:
- if index+1 >= len(sys.argv):
- raise DistutilsOptionError("The option {} requires a "
- "value".format(option))
- value = sys.argv[index+1]
- sys.argv[index:index+2] = []
- return value
- if option.startswith('--' + name + '='):
- value = option[len(name)+3:]
- sys.argv[index:index+1] = []
- return value
- env_val = os.getenv(name.upper().replace('-', '_'))
- return env_val
-
-
def filter_match(name, patterns):
for pattern in patterns:
if pattern is None:
@@ -182,7 +150,6 @@ def find_vcdir(version):
"""
from distutils.msvc9compiler import VS_BASE
from distutils.msvc9compiler import Reg
- from distutils import log
vsbase = VS_BASE % version
try:
productdir = Reg.get_value(r"{}\Setup\VC".format(vsbase), "productdir")
@@ -304,7 +271,7 @@ def copyfile(src, dst, force=True, vars=None, force_copy_symlink=False,
if os.path.exists(link_name):
os.remove(link_name)
log.info("Symlinking {} -> {} in {}.".format(link_name,
- link_target, target_dir))
+ link_target, target_dir))
os.symlink(link_target, link_name)
except OSError:
log.error("{} -> {}: Error creating symlink".format(link_name,
@@ -355,8 +322,8 @@ def copydir(src, dst, filter=None, ignore=None, force=True, recursive=True,
"filter={}. ignore={}.".format(src, dst, filter, ignore))
return []
- log.info("Copying tree {} to {}. filter={}. ignore={}.".format(src, dst,
- filter, ignore))
+ log.info("Copying tree {} to {}. filter={}. ignore={}.".format(src,
+ dst, filter, ignore))
names = os.listdir(src)
@@ -416,13 +383,15 @@ def rmtree(dirname, ignore=False):
os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
func(path)
else:
- raise
+ raise IOError
shutil.rmtree(dirname, ignore_errors=ignore, onerror=handle_remove_readonly)
def run_process_output(args, initial_env=None):
if initial_env is None:
initial_env = os.environ
- std_out = subprocess.Popen(args, env = initial_env, universal_newlines = 1,
+ std_out = subprocess.Popen(args,
+ env = initial_env,
+ universal_newlines = 1,
stdout=subprocess.PIPE).stdout
result = []
for raw_line in std_out.readlines():
@@ -430,54 +399,27 @@ def run_process_output(args, initial_env=None):
result.append(line.rstrip())
return result
-def run_process(args, initial_env=None):
- def _log(buffer, check_new_line=False):
- ends_with_new_line = False
- if buffer.endswith('\n'):
- ends_with_new_line = True
- if check_new_line and buffer.find('\n') == -1:
- return buffer
- lines = buffer.splitlines()
- buffer = ''
- if check_new_line and not ends_with_new_line:
- buffer = lines[-1]
- lines = lines[:-1]
- for line in lines:
- log.info(line.rstrip('\r'))
- return buffer
- _log("Running process in {0}: {1}".format(os.getcwd(),
- " ".join([(" " in x and '"{0}"'.format(x) or x) for x in args])))
-
- if sys.platform != "win32":
- try:
- spawn(args)
- return 0
- except DistutilsExecError:
- return -1
-
- shell = False
- if sys.platform == "win32":
- shell = True
+def run_process(args, initial_env=None, redirect_stderr_to_stdout=True):
+ """
+ Run process until completion and return the process exit code.
+ Prints both stdout and stderr to the console.
+ No output is captured.
+ """
+ log.info("Running process in directory {0}: command {1}".format(
+ os.getcwd(),
+ " ".join([(" " in x and '"{0}"'.format(x) or x) for x in args]))
+ )
if initial_env is None:
initial_env = os.environ
- proc = popenasync.Popen(args,
- stdin = subprocess.PIPE,
- stdout = subprocess.PIPE,
- stderr = subprocess.STDOUT,
- universal_newlines = 1,
- shell = shell,
- env = initial_env)
-
- log_buffer = None;
- while proc.poll() is None:
- log_buffer = _log(proc.read_async(wait=0.1, e=0))
- if log_buffer:
- _log(log_buffer)
+ kwargs = {}
+ kwargs['env'] = initial_env
+ if redirect_stderr_to_stdout:
+ kwargs['stderr'] = subprocess.STDOUT
- proc.wait()
- return proc.returncode
+ exit_code = subprocess.call(args, **kwargs)
+ return exit_code
def get_environment_from_batch_command(env_cmd, initial=None):
@@ -552,7 +494,7 @@ def regenerate_qt_resources(src, pyside_rcc_path, pyside_rcc_options):
dstname = '_rc.py'.join(srcname_split)
if os.path.exists(dstname):
log.info('Regenerating {} from {}'.format(dstname,
- os.path.basename(srcname)))
+ os.path.basename(srcname)))
run_process([pyside_rcc_path,
pyside_rcc_options,
srcname, '-o', dstname])
@@ -607,8 +549,7 @@ def back_tick(cmd, ret_err=False):
return out, err.strip(), retcode
-MACOS_OUTNAME_RE = re.compile(r'\(compatibility version [\d.]+, current version '
- '[\d.]+\)')
+MACOS_OUTNAME_RE = re.compile(r'\(compatibility version [\d.]+, current version [\d.]+\)')
def macos_get_install_names(libpath):
"""
@@ -665,6 +606,9 @@ def macos_get_rpaths(libpath):
ctr += 3
return rpaths
+def macos_add_rpath(rpath, library_path):
+ back_tick('install_name_tool -add_rpath {rpath} {library_path}'.format(
+ rpath=rpath, library_path=library_path))
def macos_fix_rpaths_for_library(library_path, qt_lib_dir):
""" Adds required rpath load commands to given library.
@@ -703,8 +647,7 @@ def macos_fix_rpaths_for_library(library_path, qt_lib_dir):
break
if needs_loader_path and "@loader_path" not in existing_rpath_commands:
- back_tick('install_name_tool -add_rpath {rpath} {library_path}'.format(
- rpath="@loader_path", library_path=library_path))
+ macos_add_rpath("@loader_path", library_path)
# If the library depends on a Qt library, add an rpath load comment
# pointing to the Qt lib directory.
@@ -738,8 +681,7 @@ def macos_add_qt_rpath(library_path, qt_lib_dir,
break
if needs_qt_rpath:
- back_tick('install_name_tool -add_rpath {rpath} {library_path}'.format(
- rpath=qt_lib_dir, library_path=library_path))
+ macos_add_rpath(qt_lib_dir, library_path)
# Find an executable specified by a glob pattern ('foo*') in the OS path
def find_glob_in_path(pattern):
@@ -754,7 +696,7 @@ def find_glob_in_path(pattern):
# Locate the most recent version of llvm_config in the path.
def find_llvm_config():
- version_re = re.compile('(\d+)\.(\d+)\.(\d+)')
+ version_re = re.compile(r'(\d+)\.(\d+)\.(\d+)')
result = None
last_version_string = '000000'
for llvm_config in find_glob_in_path('llvm-config*'):
@@ -996,6 +938,17 @@ def copy_icu_libs(patchelf, destination_lib_dir):
new_rpaths_string = ":".join(rpaths)
linux_set_rpaths(patchelf, qt_core_library_path, new_rpaths_string)
+
+def linux_run_read_elf(executable_path):
+ cmd = "readelf -d {}".format(executable_path)
+ (out, err, code) = back_tick(cmd, True)
+ if code != 0:
+ raise RuntimeError("Running `readelf -d {}` failed with error "
+ "output:\n {}. ".format(executable_path, err))
+ lines = split_and_strip(out)
+ return lines
+
+
def linux_set_rpaths(patchelf, executable_path, rpath_string):
""" Patches the `executable_path` with a new rpath string. """
@@ -1005,18 +958,32 @@ def linux_set_rpaths(patchelf, executable_path, rpath_string):
raise RuntimeError("Error patching rpath in {}".format(
executable_path))
+
+def linux_get_dependent_libraries(executable_path):
+ """
+ Returns a list of libraries that executable_path depends on.
+ """
+
+ lines = linux_run_read_elf(executable_path)
+ pattern = re.compile(r"^.+?\(NEEDED\).+?\[(.+?)\]$")
+
+ library_lines = []
+ for line in lines:
+ match = pattern.search(line)
+ if match:
+ library_line = match.group(1)
+ library_lines.append(library_line)
+
+ return library_lines
+
+
def linux_get_rpaths(executable_path):
"""
Returns a list of run path values embedded in the executable or just
an empty list.
"""
- cmd = "readelf -d {}".format(executable_path)
- (out, err, code) = back_tick(cmd, True)
- if code != 0:
- raise RuntimeError("Running `readelf -d {}` failed with error "
- "output:\n {}. ".format(executable_path, err))
- lines = split_and_strip(out)
+ lines = linux_run_read_elf(executable_path)
pattern = re.compile(r"^.+?\(RUNPATH\).+?\[(.+?)\]$")
rpath_line = None
@@ -1033,6 +1000,7 @@ def linux_get_rpaths(executable_path):
return rpaths
+
def rpaths_has_origin(rpaths):
"""
Return True if the specified list of rpaths has an "$ORIGIN" value
@@ -1048,6 +1016,39 @@ def rpaths_has_origin(rpaths):
return True
return False
+
+def linux_needs_qt_rpath(executable_path):
+ """
+ Returns true if library_path depends on Qt libraries.
+ """
+
+ dependencies = linux_get_dependent_libraries(executable_path)
+
+ # Check if any library dependencies are Qt libraries (hacky).
+ needs_qt_rpath = False
+ for dep in dependencies:
+ if 'Qt' in dep:
+ needs_qt_rpath = True
+ break
+ return needs_qt_rpath
+
+
+def linux_fix_rpaths_for_library(patchelf, executable_path, qt_rpath, override=False):
+ """
+ Adds or overrides required rpaths in given executable / library.
+ """
+ rpaths = ['$ORIGIN/']
+ existing_rpaths = []
+ if not override:
+ existing_rpaths = linux_get_rpaths(executable_path)
+ rpaths.extend(existing_rpaths)
+
+ if linux_needs_qt_rpath(executable_path) and qt_rpath not in existing_rpaths:
+ rpaths.append(qt_rpath)
+
+ rpaths_string = ':'.join(rpaths)
+ linux_set_rpaths(patchelf, executable_path, rpaths_string)
+
def memoize(function):
"""
Decorator to wrap a function with a memoizing callable.
@@ -1076,9 +1077,27 @@ def get_python_dict(python_script_path):
"file: {}.".format(python_script_path))
raise
-def install_pip_dependencies(env_pip, packages):
+def install_pip_wheel_package(env_pip):
+ # Need to install an unreleased wheel version, due to a bug that
+ # will generate a wheel which will not be installable.
+ # See https://github.com/pypa/wheel/issues/263
+ wheel_url = "git+https://github.com/pypa/wheel.git@fbf3e3ada64d36ca7bb9c1422f5a1ccdba7e4dcf"
+ install_pip_package_from_url_specifier(env_pip, wheel_url)
+
+def install_pip_package_from_url_specifier(env_pip, url, upgrade=True):
+ args = [env_pip, "install", url]
+ if upgrade:
+ args.append("--upgrade")
+ args.append(url)
+ run_instruction(args, "Failed to install {}".format(url))
+
+def install_pip_dependencies(env_pip, packages, upgrade=True):
for p in packages:
- run_instruction([env_pip, "install", p], "Failed to install " + p)
+ args = [env_pip, "install"]
+ if upgrade:
+ args.append("--upgrade")
+ args.append(p)
+ run_instruction(args, "Failed to install " + p)
def get_qtci_virtualEnv(python_ver, host, hostArch, targetArch):
_pExe = "python"
@@ -1105,16 +1124,18 @@ def get_qtci_virtualEnv(python_ver, host, hostArch, targetArch):
_pExe = "python3"
return(_pExe, _env, env_pip, env_python)
-def run_instruction(instruction, error):
+def run_instruction(instruction, error, initial_env=None):
+ if initial_env is None:
+ initial_env = os.environ
print("Running Coin instruction: " + ' '.join(str(e) for e in instruction))
- result = subprocess.call(instruction)
+ result = subprocess.call(instruction, env=initial_env)
if result != 0:
print("ERROR : " + error)
exit(result)
def acceptCITestConfiguration(hostOS, hostOSVer, targetArch, compiler):
# Disable unsupported CI configs for now
- # NOTE: String must match with QT CI's storagesturct thrift
+ # NOTE: String must match with QT CI's storagestruct thrift
if hostOSVer in ["WinRT_10"]:
print("Disabled " + hostOSVer + " from Coin configuration")
return False
@@ -1124,3 +1145,13 @@ def acceptCITestConfiguration(hostOS, hostOSVer, targetArch, compiler):
print("Disabled " + compiler + " to " + targetArch + " from Coin configuration")
return False
return True
+
+
+def get_ci_qmake_path(ci_install_dir, ci_host_os):
+ qmake_path = "--qmake={}".format(ci_install_dir)
+ if ci_host_os == "MacOS":
+ return qmake_path + "/bin/qmake"
+ elif ci_host_os == "Windows":
+ return qmake_path + "\\bin\\qmake.exe"
+ else:
+ return qmake_path + "/bin/qmake"
diff --git a/coin_build_instructions.py b/coin_build_instructions.py
index aee0bf265..969b9272b 100644
--- a/coin_build_instructions.py
+++ b/coin_build_instructions.py
@@ -36,14 +36,16 @@
## $QT_END_LICENSE$
##
#############################################################################
-from build_scripts.utils import has_option
-from build_scripts.utils import option_value
+from build_scripts.options import has_option
+from build_scripts.options import option_value
from build_scripts.utils import install_pip_dependencies
+from build_scripts.utils import install_pip_wheel_package
from build_scripts.utils import get_qtci_virtualEnv
from build_scripts.utils import run_instruction
from build_scripts.utils import rmtree
from build_scripts.utils import get_python_dict
from build_scripts.utils import acceptCITestConfiguration
+from build_scripts.utils import get_ci_qmake_path
import os
# Values must match COIN thrift
@@ -98,21 +100,19 @@ def call_setup(python_ver):
_pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH)
rmtree(_env, True)
run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv")
- install_pip_dependencies(env_pip, ["six", "wheel"])
- cmd = [env_python, "setup.py"]
+
+ install_pip_dependencies(env_pip, ["six", "setuptools"])
+ install_pip_wheel_package(env_pip)
+
+ cmd = [env_python, "-u", "setup.py"]
if CI_RELEASE_CONF:
cmd += ["bdist_wheel", "--standalone"]
else:
cmd += ["build"]
- if CI_HOST_OS == "MacOS":
- cmd += ["--qmake=" + CI_ENV_INSTALL_DIR + "/bin/qmake"]
- elif CI_HOST_OS == "Windows":
-
- cmd += ["--qmake=" + CI_ENV_INSTALL_DIR + "\\bin\\qmake.exe"]
- else:
- cmd += ["--qmake=" + CI_ENV_INSTALL_DIR + "/bin/qmake"]
+ qmake_path = get_ci_qmake_path(CI_ENV_INSTALL_DIR, CI_HOST_OS)
+ cmd.append(qmake_path)
cmd += ["--build-tests",
- "--jobs=4",
+ "--parallel=4",
"--verbose-build"]
if python_ver == "3":
cmd += ["--limited-api=yes"]
@@ -121,7 +121,23 @@ def call_setup(python_ver):
cmd += ["--package-timestamp=" + CI_INTEGRATION_ID]
- run_instruction(cmd, "Failed to run setup.py")
+ env = os.environ
+ if CI_HOST_OS == "MacOS":
+ # On Python 3, setuptools.dist.handle_display_options does some
+ # weird sys.stdout.detach-ing if the stdout encoding is
+ # different from utf-8. This causes issues when running
+ # subprocess.call() because that access the original stdout
+ # object stored in sys.__stdout__ which was detached, and
+ # results in an exception being thrown.
+ # The Coin macOS locale by default is US-ASCII, and that
+ # triggers the above issue. Set the encoding to UTF-8 which
+ # makes sure to skip over the detach-ing code.
+ # Relevant links to the issue:
+ # https://bugs.python.org/issue15216
+ # https://bitbucket.org/tarek/distribute/issues/334/fix-for-311-breaks-packages-that-use
+ # https://github.com/pypa/virtualenv/issues/359
+ env['LC_CTYPE'] = 'UTF-8'
+ run_instruction(cmd, "Failed to run setup.py", initial_env=env)
def run_build_instructions():
if not acceptCITestConfiguration(CI_HOST_OS, CI_HOST_OS_VER, CI_TARGET_ARCH, CI_COMPILER):
diff --git a/coin_test_instructions.py b/coin_test_instructions.py
index bd65b5b7e..4121bb558 100644
--- a/coin_test_instructions.py
+++ b/coin_test_instructions.py
@@ -36,13 +36,15 @@
## $QT_END_LICENSE$
##
#############################################################################
-from build_scripts.utils import has_option
-from build_scripts.utils import option_value
+from build_scripts.options import has_option
+from build_scripts.options import option_value
from build_scripts.utils import install_pip_dependencies
+from build_scripts.utils import install_pip_wheel_package
from build_scripts.utils import get_qtci_virtualEnv
from build_scripts.utils import run_instruction
from build_scripts.utils import rmtree
from build_scripts.utils import acceptCITestConfiguration
+from build_scripts.utils import get_ci_qmake_path
import os
# Values must match COIN thrift
@@ -66,12 +68,21 @@ def call_testrunner(python_ver, buildnro):
_pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH)
rmtree(_env, True)
run_instruction(["virtualenv", "-p", _pExe, _env], "Failed to create virtualenv")
- install_pip_dependencies(env_pip, ["six", "wheel"])
+ install_pip_dependencies(env_pip, ["six", "setuptools"])
+ install_pip_wheel_package(env_pip)
cmd = [env_python, "testrunner.py", "test",
"--blacklist", "build_history/blacklist.txt",
"--buildno=" + buildnro]
run_instruction(cmd, "Failed to run testrunner.py")
+ qmake_path = get_ci_qmake_path(CI_ENV_INSTALL_DIR, CI_HOST_OS)
+
+ # Try to install built wheels, and build some buildable examples.
+ if CI_RELEASE_CONF:
+ wheel_tester_path = os.path.join("testing", "wheel_tester.py")
+ cmd = [env_python, wheel_tester_path, qmake_path]
+ run_instruction(cmd, "Error while running wheel_tester.py")
+
def run_test_instructions():
if not acceptCITestConfiguration(CI_HOST_OS, CI_HOST_OS_VER, CI_TARGET_ARCH, CI_COMPILER):
exit()
diff --git a/docs/building/options.rst b/docs/building/options.rst
index 71e7f6a57..63489f80a 100644
--- a/docs/building/options.rst
+++ b/docs/building/options.rst
@@ -89,7 +89,7 @@ Options
``--no-examples``
Don't include PySide examples in PySide distribution
-``--jobs``
+``--parallel``
Specify the number of parallel build jobs
``--jom``
diff --git a/examples/opengl/hellogl2.py b/examples/opengl/hellogl2.py
index e1af6f2a6..b8d1c0e7d 100755
--- a/examples/opengl/hellogl2.py
+++ b/examples/opengl/hellogl2.py
@@ -52,7 +52,7 @@ from PySide2.QtGui import (QVector3D, QOpenGLFunctions, QOpenGLVertexArrayObject
QOpenGLShaderProgram, QMatrix4x4, QOpenGLShader, QOpenGLContext, QSurfaceFormat)
from PySide2.QtWidgets import (QApplication, QWidget, QMessageBox, QHBoxLayout, QSlider,
QOpenGLWidget)
-from PySide2.shiboken2 import VoidPtr
+from shiboken2 import VoidPtr
try:
from OpenGL import GL
diff --git a/examples/samplebinding/CMakeLists.txt b/examples/samplebinding/CMakeLists.txt
index 03ab85754..3852ed36f 100644
--- a/examples/samplebinding/CMakeLists.txt
+++ b/examples/samplebinding/CMakeLists.txt
@@ -40,7 +40,11 @@ set(generated_sources
# ================================== Shiboken detection ======================================
-
+# Use provided python interpreter if given.
+if(NOT python_interpreter)
+ find_program(python_interpreter "python")
+endif()
+message(STATUS "Using python interpreter: ${python_interpreter}")
# Macro to get various pyside / python include / link flags and paths.
# Uses the not entirely supported utils/pyside2_config.py file.
@@ -52,7 +56,8 @@ macro(pyside2_config option output_var)
endif()
execute_process(
- COMMAND python "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" ${option}
+ COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py"
+ ${option}
OUTPUT_VARIABLE ${output_var}
OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -64,14 +69,15 @@ macro(pyside2_config option output_var)
endif()
endmacro()
-# Query for the shiboken path, Python path, include paths and linker flags.
-pyside2_config(--pyside2 pyside2_path)
-pyside2_config(--python-include python_include_dir)
-pyside2_config(--shiboken-include shiboken_include_dir 1)
-pyside2_config(--shiboken-shared-libraries-cmake shiboken_shared_libraries 0)
-pyside2_config(--python-link-cmake python_linking_data 0)
+# Query for the shiboken generator path, Python path, include paths and linker flags.
+pyside2_config(--shiboken2-module-path shiboken2_module_path)
+pyside2_config(--shiboken2-generator-path shiboken2_generator_path)
+pyside2_config(--python-include-path python_include_dir)
+pyside2_config(--shiboken2-generator-include-path shiboken_include_dir 1)
+pyside2_config(--shiboken2-module-shared-libraries-cmake shiboken_shared_libraries 0)
+pyside2_config(--python-link-flags-cmake python_linking_data 0)
-set(shiboken_path "${pyside2_path}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}")
+set(shiboken_path "${shiboken2_generator_path}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}")
if(NOT EXISTS ${shiboken_path})
message(FATAL_ERROR "Shiboken executable not found at path: ${shiboken_path}")
endif()
@@ -87,7 +93,7 @@ endif()
# Enable rpaths so that the built shared libraries find their dependencies.
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
-set(CMAKE_INSTALL_RPATH ${pyside2_path} ${CMAKE_CURRENT_SOURCE_DIR})
+set(CMAKE_INSTALL_RPATH ${shiboken2_module_path} ${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# =============================================================================================
# !!! End of dubious section.
diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt
index 4119b6756..999206425 100644
--- a/examples/scriptableapplication/CMakeLists.txt
+++ b/examples/scriptableapplication/CMakeLists.txt
@@ -12,7 +12,13 @@ project(scriptableapplication)
set(CMAKE_CXX_STANDARD 11)
# Find required Qt packages.
-find_package(Qt5 5.9 REQUIRED COMPONENTS Core Gui Widgets)
+find_package(Qt5 5.12 REQUIRED COMPONENTS Core Gui Widgets)
+
+# Use provided python interpreter if given.
+if(NOT python_interpreter)
+ find_program(python_interpreter "python")
+endif()
+message(STATUS "Using python interpreter: ${python_interpreter}")
# Macro to get various pyside / python include / link flags.
macro(pyside2_config option output_var)
@@ -23,7 +29,8 @@ macro(pyside2_config option output_var)
endif()
execute_process(
- COMMAND python "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" ${option}
+ COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py"
+ ${option}
OUTPUT_VARIABLE ${output_var}
OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -35,14 +42,20 @@ macro(pyside2_config option output_var)
endif()
endmacro()
-# Query for the PySide2 path, Python path, include paths and linker flags.
-pyside2_config(--pyside2 PYSIDE2_PATH)
-pyside2_config(--python-include PYTHON_INCLUDE_DIR)
-pyside2_config(--pyside2-include PYSIDE2_INCLUDE_DIR 1)
+# Query for the shiboken2-generator path, PySide2 path, Python path, include paths and linker flags.
+pyside2_config(--shiboken2-module-path SHIBOKEN2_MODULE_PATH)
+pyside2_config(--shiboken2-generator-path SHIBOKEN2_GENERATOR_PATH)
+pyside2_config(--pyside2-path PYSIDE2_PATH)
+
+pyside2_config(--python-include-path PYTHON_INCLUDE_DIR)
+pyside2_config(--shiboken2-generator-include-path SHIBOKEN2_GENERATOR_INCLUDE_DIR 1)
+pyside2_config(--pyside2-include-path PYSIDE2_INCLUDE_DIR 1)
+
+pyside2_config(--python-link-flags-cmake PYTHON_LINKING_DATA 0)
+pyside2_config(--shiboken2-module-shared-libraries-cmake SHIBOKEN2_MODULE_SHARED_LIBRARIES 0)
pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 0)
-pyside2_config(--python-link-cmake PYTHON_LINKING_DATA 0)
-set(SHIBOKEN_PATH "${PYSIDE2_PATH}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}")
+set(SHIBOKEN_PATH "${SHIBOKEN2_GENERATOR_PATH}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}")
if(NOT EXISTS ${SHIBOKEN_PATH})
message(FATAL_ERROR "Shiboken executable not found at path: ${SHIBOKEN_PATH}")
@@ -122,7 +135,7 @@ endforeach()
# Enable rpaths so that the example can be executed from the build dir.
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
-set(CMAKE_INSTALL_RPATH ${PYSIDE2_PATH})
+set(CMAKE_INSTALL_RPATH ${PYSIDE2_PATH} ${SHIBOKEN2_MODULE_PATH})
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# =============================================================================================
# !!! End of dubious section.
@@ -139,11 +152,13 @@ target_sources(${PROJECT_NAME} PUBLIC ${SOURCES})
# Apply relevant include and link flags.
target_include_directories(${PROJECT_NAME} PRIVATE ${PYTHON_INCLUDE_DIR})
+target_include_directories(${PROJECT_NAME} PRIVATE ${SHIBOKEN2_GENERATOR_INCLUDE_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_INCLUDE_DIR})
target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_ADDITIONAL_INCLUDES})
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR})
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets)
+target_link_libraries(${PROJECT_NAME} PRIVATE ${SHIBOKEN2_MODULE_SHARED_LIBRARIES})
target_link_libraries(${PROJECT_NAME} PRIVATE ${PYSIDE2_SHARED_LIBRARIES})
# Find and link to the python library.
@@ -176,7 +191,8 @@ if(WIN32)
# Add custom target to hard link PySide2 shared libraries (just like in qmake example), so you
# don't have to set PATH manually to point to the PySide2 package.
- foreach(LIBRARY_PATH ${PYSIDE2_SHARED_LIBRARIES})
+ set(shared_libraries ${SHIBOKEN2_MODULE_SHARED_LIBRARIES} ${PYSIDE2_SHARED_LIBRARIES})
+ foreach(LIBRARY_PATH ${shared_libraries})
string(REGEX REPLACE ".lib$" ".dll" LIBRARY_PATH ${LIBRARY_PATH})
get_filename_component(BASE_NAME ${LIBRARY_PATH} NAME)
file(TO_NATIVE_PATH ${LIBRARY_PATH} SOURCE_PATH)
diff --git a/examples/scriptableapplication/pyside2.pri b/examples/scriptableapplication/pyside2.pri
index 17be4392f..2da3bc880 100644
--- a/examples/scriptableapplication/pyside2.pri
+++ b/examples/scriptableapplication/pyside2.pri
@@ -1,30 +1,52 @@
PYSIDE_CONFIG = $$PWD/../utils/pyside2_config.py
-PYSIDE2 = $$system(python $$PYSIDE_CONFIG --pyside2)
+# Use provided python interpreter if given.
+isEmpty(python_interpreter) {
+ python_interpreter = python
+}
+message(Using python interpreter: $$python_interpreter)
+
+SHIBOKEN2_GENERATOR = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-generator-path)
+isEmpty(SHIBOKEN2_GENERATOR): error(Unable to locate the shiboken2-generator package location)
+
+SHIBOKEN2_MODULE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-path)
+isEmpty(SHIBOKEN2_MODULE): error(Unable to locate the shiboken2 package location)
+
+PYSIDE2 = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-path)
isEmpty(PYSIDE2): error(Unable to locate the PySide2 package location)
-PYTHON_INCLUDE = $$system(python $$PYSIDE_CONFIG --python-include)
+PYTHON_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --python-include-path)
isEmpty(PYTHON_INCLUDE): error(Unable to locate the Python include headers directory)
-PYTHON_LFLAGS = $$system(python $$PYSIDE_CONFIG --python-link)
+PYTHON_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --python-link-flags-qmake)
isEmpty(PYTHON_LFLAGS): error(Unable to locate the Python library for linking)
-PYSIDE2_INCLUDE = $$system(python $$PYSIDE_CONFIG --pyside2-include)
+SHIBOKEN2_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-generator-include-path)
+isEmpty(SHIBOKEN2_INCLUDE): error(Unable to locate the shiboken include headers directory)
+
+PYSIDE2_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-include-path)
isEmpty(PYSIDE2_INCLUDE): error(Unable to locate the PySide2 include headers directory)
-PYSIDE2_LFLAGS = $$system(python $$PYSIDE_CONFIG --pyside2-link)
+SHIBOKEN2_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-qmake-lflags)
+isEmpty(SHIBOKEN2_LFLAGS): error(Unable to locate the shiboken libraries for linking)
+
+PYSIDE2_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-qmake-lflags)
isEmpty(PYSIDE2_LFLAGS): error(Unable to locate the PySide2 libraries for linking)
-PYSIDE2_SHARED_LIBRARIES = $$system(python $$PYSIDE_CONFIG --pyside2-shared-libraries)
+SHIBOKEN2_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-shared-libraries-qmake)
+isEmpty(SHIBOKEN2_SHARED_LIBRARIES): error(Unable to locate the used shiboken2 module shared libraries)
+
+PYSIDE2_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-shared-libraries-qmake)
isEmpty(PYSIDE2_SHARED_LIBRARIES): error(Unable to locate the used PySide2 shared libraries)
-INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE2_INCLUDE
-LIBS += $$PYTHON_LFLAGS $$PYSIDE2_LFLAGS
+INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE2_INCLUDE $$SHIBOKEN2_INCLUDE
+LIBS += $$PYTHON_LFLAGS $$PYSIDE2_LFLAGS $$SHIBOKEN2_LFLAGS
!build_pass:message(INCLUDEPATH is $$INCLUDEPATH)
!build_pass:message(LIBS are $$LIBS)
!build_pass:message(Using $$PYSIDE2)
!win32 {
- QMAKE_RPATHDIR += $$PYSIDE2
+ !build_pass:message(RPATH will include $$PYSIDE2 and $$SHIBOKEN2_MODULE)
+ QMAKE_RPATHDIR += $$PYSIDE2 $$SHIBOKEN2_MODULE
}
diff --git a/examples/scriptableapplication/scriptableapplication.pro b/examples/scriptableapplication/scriptableapplication.pro
index 8a09b0abf..8ebab9476 100644
--- a/examples/scriptableapplication/scriptableapplication.pro
+++ b/examples/scriptableapplication/scriptableapplication.pro
@@ -23,7 +23,7 @@ SHIBOKEN_OPTIONS = --generator-set=shiboken --enable-parent-ctor-heuristic \
win32:SHIBOKEN_OPTIONS += --avoid-protected-hack
# Prepare the shiboken tool
-QT_TOOL.shiboken.binary = $$system_path($$PYSIDE2/shiboken2)
+QT_TOOL.shiboken.binary = $$system_path($$SHIBOKEN2_GENERATOR/shiboken2)
qtPrepareTool(SHIBOKEN, shiboken)
# Shiboken run that adds the module wrapper to GENERATED_SOURCES
@@ -61,7 +61,7 @@ win32 {
hard_link_libraries.CONFIG = no_link target_predeps explicit_dependencies
hard_link_libraries.output = $$out_dir/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}
hard_link_libraries.commands = mklink /H $$shell_path($$out_dir/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}) $$shell_path(${QMAKE_FILE_IN})
- hard_link_libraries.input = PYSIDE2_SHARED_LIBRARIES
+ hard_link_libraries.input = PYSIDE2_SHARED_LIBRARIES SHIBOKEN2_SHARED_LIBRARIES
}
QMAKE_EXTRA_COMPILERS += shiboken module_wrapper_dummy_command
diff --git a/examples/utils/pyside2_config.py b/examples/utils/pyside2_config.py
index 298d40d5b..c62b38cad 100644
--- a/examples/utils/pyside2_config.py
+++ b/examples/utils/pyside2_config.py
@@ -38,28 +38,106 @@
##
#############################################################################
-import os, glob, re, sys, imp
+import os, glob, re, sys
from distutils import sysconfig
+generic_error = (' Did you forget to activate your virtualenv? Or perhaps'
+ ' you forgot to build / install PySide2 into your currently active Python'
+ ' environment?')
+pyside2_error = 'Unable to locate PySide2.' + generic_error
+shiboken2_module_error = 'Unable to locate shiboken2-module.' + generic_error
+shiboken2_generator_error = 'Unable to locate shiboken2-generator.' + generic_error
+pyside2_libs_error = 'Unable to locate the PySide2 shared libraries.' + generic_error
+python_link_error = 'Unable to locate the Python library for linking.'
+python_include_error = 'Unable to locate the Python include headers directory.'
+
+options = []
+
+# option, function, error, description
+options.append(("--shiboken2-module-path",
+ lambda: find_shiboken2_module(),
+ shiboken2_module_error,
+ "Print shiboken2 module location"))
+options.append(("--shiboken2-generator-path",
+ lambda: find_shiboken2_generator(),
+ shiboken2_generator_error,
+ "Print shiboken2 generator location"))
+options.append(("--pyside2-path", lambda: find_pyside2(), pyside2_error,
+ "Print PySide2 location"))
+
+options.append(("--python-include-path",
+ lambda: get_python_include_path(),
+ python_include_error,
+ "Print Python include path"))
+options.append(("--shiboken2-generator-include-path",
+ lambda: get_package_include_path(Package.shiboken2_generator),
+ pyside2_error,
+ "Print shiboken2 generator include paths"))
+options.append(("--pyside2-include-path",
+ lambda: get_package_include_path(Package.pyside2),
+ pyside2_error,
+ "Print PySide2 include paths"))
+
+options.append(("--python-link-flags-qmake", lambda: python_link_flags_qmake(), python_link_error,
+ "Print python link flags for qmake"))
+options.append(("--python-link-flags-cmake", lambda: python_link_flags_cmake(), python_link_error,
+ "Print python link flags for cmake"))
+
+options.append(("--shiboken2-module-qmake-lflags",
+ lambda: get_package_qmake_lflags(Package.shiboken2_module), pyside2_error,
+ "Print shiboken2 shared library link flags for qmake"))
+options.append(("--pyside2-qmake-lflags",
+ lambda: get_package_qmake_lflags(Package.pyside2), pyside2_error,
+ "Print PySide2 shared library link flags for qmake"))
+
+options.append(("--shiboken2-module-shared-libraries-qmake",
+ lambda: get_shared_libraries_qmake(Package.shiboken2_module), pyside2_libs_error,
+ "Print paths of shiboken2 shared libraries (.so's, .dylib's, .dll's) for qmake"))
+options.append(("--shiboken2-module-shared-libraries-cmake",
+ lambda: get_shared_libraries_cmake(Package.shiboken2_module), pyside2_libs_error,
+ "Print paths of shiboken2 shared libraries (.so's, .dylib's, .dll's) for cmake"))
+
+options.append(("--pyside2-shared-libraries-qmake",
+ lambda: get_shared_libraries_qmake(Package.pyside2), pyside2_libs_error,
+ "Print paths of PySide2 shared libraries (.so's, .dylib's, .dll's) for qmake"))
+options.append(("--pyside2-shared-libraries-cmake",
+ lambda: get_shared_libraries_cmake(Package.pyside2), pyside2_libs_error,
+ "Print paths of PySide2 shared libraries (.so's, .dylib's, .dll's) for cmake"))
+
+options_usage = ''
+for i, (flag, _, _, description) in enumerate(options):
+ options_usage += ' {:<45} {}'.format(flag, description)
+ if i < len(options) - 1:
+ options_usage += '\n'
+
usage = """
-Utility to determine include/link options of PySide2 and Python for qmake
+Utility to determine include/link options of shiboken2/PySide2 and Python for qmake/CMake projects
+that would like to embed or build custom shiboken2/PySide2 bindings.
Usage: pyside2_config.py [option]
Options:
- --python-include Print Python include path
- --python-link Print Python link flags
- --pyside2 Print PySide2 location
- --pyside2-include Print PySide2 include paths
- --pyside2-link Print PySide2 link flags
- --pyside2-shared-libraries Print paths of PySide2 shared libraries (.so's, .dylib's, .dll's)
- -a Print all
- --help/-h Print this help
-"""
-
-def cleanPath(path):
+{}
+ -a Print all options and their values
+ --help/-h Print this help
+""".format(options_usage)
+
+option = sys.argv[1] if len(sys.argv) == 2 else '-a'
+if option == '-h' or option == '--help':
+ print(usage)
+ sys.exit(0)
+
+
+class Package(object):
+ shiboken2_module = 1
+ shiboken2_generator = 2
+ pyside2 = 3
+
+
+def clean_path(path):
return path if sys.platform != 'win32' else path.replace('\\', '/')
-def sharedLibrarySuffix():
+
+def shared_library_suffix():
if sys.platform == 'win32':
return 'lib'
elif sys.platform == 'darwin':
@@ -68,21 +146,41 @@ def sharedLibrarySuffix():
else:
return 'so.*'
-def sharedLibraryGlobPattern():
- glob = '*.' + sharedLibrarySuffix()
+
+def import_suffixes():
+ if (sys.version_info >= (3, 4)):
+ import importlib
+ return importlib.machinery.EXTENSION_SUFFIXES
+ else:
+ import imp
+ result = []
+ for t in imp.get_suffixes():
+ result.append(t[0])
+ return result
+
+
+def is_debug():
+ debug_suffix = '_d.pyd' if sys.platform == 'win32' else '_d.so'
+ return any([s.endswith(debug_suffix) for s in import_suffixes()])
+
+
+def shared_library_glob_pattern():
+ glob = '*.' + shared_library_suffix()
return glob if sys.platform == 'win32' else 'lib' + glob
-def filterPySide2SharedLibraries(list, only_shiboken=False):
- def predicate(item):
- basename = os.path.basename(item)
- if 'shiboken' in basename or ('pyside2' in basename and not only_shiboken):
+
+def filter_shared_libraries(libs_list):
+ def predicate(lib_name):
+ basename = os.path.basename(lib_name)
+ if 'shiboken' in basename or 'pyside2' in basename:
return True
return False
- result = [item for item in list if predicate(item)]
+ result = [lib for lib in libs_list if predicate(lib)]
return result
+
# Return qmake link option for a library file name
-def linkOption(lib):
+def link_option(lib):
# On Linux:
# Since we cannot include symlinks with wheel packages
# we are using an absolute path for the libpyside and libshiboken
@@ -97,24 +195,50 @@ def linkOption(lib):
link += os.path.splitext(baseName)[0]
return link
-# Locate PySide2 via package path
-def findPySide2():
+
+# Locate PySide2 via sys.path package path.
+def find_pyside2():
+ return find_package_path("PySide2")
+
+
+def find_shiboken2_module():
+ return find_package_path("shiboken2")
+
+
+def find_shiboken2_generator():
+ return find_package_path("shiboken2_generator")
+
+
+def find_package(which_package):
+ if which_package == Package.shiboken2_module:
+ return find_shiboken2_module()
+ if which_package == Package.shiboken2_generator:
+ return find_shiboken2_generator()
+ if which_package == Package.pyside2:
+ return find_pyside2()
+ return None
+
+
+def find_package_path(dir_name):
for p in sys.path:
if 'site-' in p:
- pyside2 = os.path.join(p, 'PySide2')
- if os.path.exists(pyside2):
- return cleanPath(os.path.realpath(pyside2))
+ package = os.path.join(p, dir_name)
+ if os.path.exists(package):
+ return clean_path(os.path.realpath(package))
return None
+
# Return version as "3.5"
-def pythonVersion():
+def python_version():
return str(sys.version_info[0]) + '.' + str(sys.version_info[1])
-def pythonInclude():
+
+def get_python_include_path():
return sysconfig.get_python_inc()
-def pythonLinkQmake():
- flags = pythonLinkData()
+
+def python_link_flags_qmake():
+ flags = python_link_data()
if sys.platform == 'win32':
libdir = flags['libdir']
# This will add the "~1" shortcut for directories that
@@ -131,25 +255,27 @@ def pythonLinkQmake():
# Linux and anything else
return '-L{} -l{}'.format(flags['libdir'], flags['lib'])
-def pythonLinkCmake():
- flags = pythonLinkData()
+
+def python_link_flags_cmake():
+ flags = python_link_data()
libdir = flags['libdir']
lib = re.sub(r'.dll$', '.lib', flags['lib'])
return '{};{}'.format(libdir, lib)
-def pythonLinkData():
+
+def python_link_data():
# @TODO Fix to work with static builds of Python
libdir = sysconfig.get_config_var('LIBDIR')
if libdir is None:
libdir = os.path.abspath(os.path.join(
sysconfig.get_config_var('LIBDEST'), "..", "libs"))
- version = pythonVersion()
+ version = python_version()
version_no_dots = version.replace('.', '')
flags = {}
flags['libdir'] = libdir
if sys.platform == 'win32':
- suffix = '_d' if any([tup[0].endswith('_d.pyd') for tup in imp.get_suffixes()]) else ''
+ suffix = '_d' if is_debug() else ''
flags['lib'] = 'python{}{}'.format(version_no_dots, suffix)
elif sys.platform == 'darwin':
@@ -158,42 +284,44 @@ def pythonLinkData():
# Linux and anything else
else:
if sys.version_info[0] < 3:
- suffix = '_d' if any([tup[0].endswith('_d.so') for tup in imp.get_suffixes()]) else ''
+ suffix = '_d' if is_debug() else ''
flags['lib'] = 'python{}{}'.format(version, suffix)
else:
flags['lib'] = 'python{}{}'.format(version, sys.abiflags)
return flags
-def pyside2Include(only_shiboken=False):
- pySide2 = findPySide2()
- if pySide2 is None:
+
+def get_package_include_path(which_package):
+ package_path = find_package(which_package)
+ if package_path is None:
return None
- includes = "{0}/include/shiboken2".format(pySide2)
- if not only_shiboken:
- includes = includes + " {0}/include/PySide2".format(pySide2)
+ includes = "{0}/include".format(package_path)
return includes
-def pyside2Link():
- pySide2 = findPySide2()
- if pySide2 is None:
+
+def get_package_qmake_lflags(which_package):
+ package_path = find_package(which_package)
+ if package_path is None:
return None
- link = "-L{}".format(pySide2)
- glob_result = glob.glob(os.path.join(pySide2, sharedLibraryGlobPattern()))
- for lib in filterPySide2SharedLibraries(glob_result):
+
+ link = "-L{}".format(package_path)
+ glob_result = glob.glob(os.path.join(package_path, shared_library_glob_pattern()))
+ for lib in filter_shared_libraries(glob_result):
link += ' '
- link += linkOption(lib)
+ link += link_option(lib)
return link
-def pyside2SharedLibrariesData(only_shiboken=False):
- pySide2 = findPySide2()
- if pySide2 is None:
+
+def get_shared_libraries_data(which_package):
+ package_path = find_package(which_package)
+ if package_path is None:
return None
- glob_result = glob.glob(os.path.join(pySide2, sharedLibraryGlobPattern()))
- filtered_libs = filterPySide2SharedLibraries(glob_result, only_shiboken)
+ glob_result = glob.glob(os.path.join(package_path, shared_library_glob_pattern()))
+ filtered_libs = filter_shared_libraries(glob_result)
libs = []
if sys.platform == 'win32':
for lib in filtered_libs:
@@ -203,8 +331,9 @@ def pyside2SharedLibrariesData(only_shiboken=False):
libs.append(lib)
return libs
-def pyside2SharedLibraries():
- libs = pyside2SharedLibrariesData()
+
+def get_shared_libraries_qmake(which_package):
+ libs = get_shared_libraries_data(which_package)
if libs is None:
return None
@@ -223,80 +352,21 @@ def pyside2SharedLibraries():
libs_string += lib + ' '
return libs_string
-def pyside2SharedLibrariesCmake(only_shiboken=False):
- libs = pyside2SharedLibrariesData(only_shiboken)
+
+def get_shared_libraries_cmake(which_package):
+ libs = get_shared_libraries_data(which_package)
result = ';'.join(libs)
return result
-option = sys.argv[1] if len(sys.argv) == 2 else '-a'
-if option == '-h' or option == '--help':
- print(usage)
- sys.exit(0)
-generic_error = (' Did you forget to activate your virtualenv? Or perhaps'
- ' you forgot to build / install PySide2 into your currently active Python'
- ' environment?')
-pyside2_error = 'Unable to locate PySide2.' + generic_error
-pyside2_libs_error = 'Unable to locate the PySide2 shared libraries.' + generic_error
-python_link_error = 'Unable to locate the Python library for linking.'
+print_all = option == "-a"
+for argument, handler, error, _ in options:
+ if option == argument or print_all:
+ handler_result = handler()
+ if handler_result is None:
+ sys.exit(error)
-if option == '--pyside2' or option == '-a':
- pySide2 = findPySide2()
- if pySide2 is None:
- sys.exit(pyside2_error)
- print(pySide2)
-
-if option == '--pyside2-link' or option == '-a':
- l = pyside2Link()
- if l is None:
- sys.exit(pyside2_error)
-
- print(l)
-
-if option == '--shiboken-include' or option == '-a':
- i = pyside2Include(only_shiboken=True)
- if i is None:
- sys.exit(pyside2_error)
- print(i)
-
-if option == '--pyside2-include' or option == '-a':
- i = pyside2Include()
- if i is None:
- sys.exit(pyside2_error)
- print(i)
-
-if option == '--python-include' or option == '-a':
- i = pythonInclude()
- if i is None:
- sys.exit('Unable to locate the Python include headers directory.')
- print(i)
-
-if option == '--python-link' or option == '-a':
- l = pythonLinkQmake()
- if l is None:
- sys.exit(python_link_error)
- print(l)
-
-if option == '--python-link-cmake' or option == '-a':
- l = pythonLinkCmake()
- if l is None:
- sys.exit(python_link_error)
- print(l)
-
-if option == '--pyside2-shared-libraries' or option == '-a':
- l = pyside2SharedLibraries()
- if l is None:
- sys.exit(pyside2_libs_error)
- print(l)
-
-if option == '--pyside2-shared-libraries-cmake' or option == '-a':
- l = pyside2SharedLibrariesCmake()
- if l is None:
- sys.exit(pyside2_libs_error)
- print(l)
-
-if option == '--shiboken-shared-libraries-cmake' or option == '-a':
- l = pyside2SharedLibrariesCmake(only_shiboken=True)
- if l is None:
- sys.exit(pyside2_libs_error)
- print(l)
+ line = handler_result
+ if print_all:
+ line = "{:<40}: ".format(argument) + line
+ print(line)
diff --git a/keyword-errors.lst b/keyword-errors.lst
new file mode 100644
index 000000000..af8c581a5
--- /dev/null
+++ b/keyword-errors.lst
@@ -0,0 +1,43 @@
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QAbstractItemModel.changePersistentIndex', 'arglist': 'from:PySide2.QtCore.QModelIndex,to:PySide2.QtCore.QModelIndex', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QAbstractItemModel.changePersistentIndexList', 'arglist': 'from:QModelIndexList,to:QModelIndexList', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QByteArray.indexOf', 'arglist': 'a:PySide2.QtCore.QByteArray,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QByteArray.lastIndexOf', 'arglist': 'a:PySide2.QtCore.QByteArray,from:int=-1', 'returntype': 'int'}
+KEYWORD {'multi': '1', 'funcname': 'PySide2.QtCore.QByteArrayMatcher.indexIn', 'arglist': 'ba:PySide2.QtCore.QByteArray,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': '0', 'funcname': 'PySide2.QtCore.QByteArrayMatcher.indexIn', 'arglist': 'str:str,len:int,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QItemSelection.indexOf', 'arglist': 't:PySide2.QtCore.QItemSelectionRange,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QItemSelection.lastIndexOf', 'arglist': 't:PySide2.QtCore.QItemSelectionRange,from:int=-1', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QItemSelection.move', 'arglist': 'from:int,to:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QTextCodec.convertToUnicode', 'arglist': 'in:str,length:int,state:PySide2.QtCore.QTextCodec.ConverterState', 'returntype': 'QString'}
+KEYWORD {'multi': '0', 'funcname': 'PySide2.QtCore.QTextCodec.toUnicode', 'arglist': 'in:str,length:int,state:PySide2.QtCore.QTextCodec.ConverterState=nullptr', 'returntype': 'QString'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QVariantAnimation.interpolated', 'arglist': 'from:QVariant,to:QVariant,progress:double', 'returntype': 'QVariant'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QXmlStreamAttributes.indexOf', 'arglist': 't:PySide2.QtCore.QXmlStreamAttribute,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QXmlStreamAttributes.lastIndexOf', 'arglist': 't:PySide2.QtCore.QXmlStreamAttribute,from:int=-1', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QXmlStreamAttributes.move', 'arglist': 'from:int,to:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QAbstractTextDocumentLayout.documentChanged', 'arglist': 'from:int,charsRemoved:int,charsAdded:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QIconEngine.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'bool'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QKeySequence.__lshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygon.indexOf', 'arglist': 't:PySide2.QtCore.QPoint,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygon.lastIndexOf', 'arglist': 't:PySide2.QtCore.QPoint,from:int=-1', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygon.move', 'arglist': 'from:int,to:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygonF.indexOf', 'arglist': 't:PySide2.QtCore.QPointF,from:int=0', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygonF.lastIndexOf', 'arglist': 't:PySide2.QtCore.QPointF,from:int=-1', 'returntype': 'int'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygonF.move', 'arglist': 'from:int,to:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QQuaternion.rotationTo', 'arglist': 'from:PySide2.QtGui.QVector3D,to:PySide2.QtGui.QVector3D', 'returntype': 'PySide2.QtGui.QQuaternion'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QStandardItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QStandardItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'}
+KEYWORD {'multi': '4', 'funcname': 'PySide2.QtGui.QTextDocument.find', 'arglist': 'expr:PySide2.QtCore.QRegExp,from:int=0,options:PySide2.QtGui.QTextDocument.FindFlags=QTextDocument.FindFlags()', 'returntype': 'PySide2.QtGui.QTextCursor'}
+KEYWORD {'multi': '2', 'funcname': 'PySide2.QtGui.QTextDocument.find', 'arglist': 'expr:PySide2.QtCore.QRegularExpression,from:int=0,options:PySide2.QtGui.QTextDocument.FindFlags=QTextDocument.FindFlags()', 'returntype': 'PySide2.QtGui.QTextCursor'}
+KEYWORD {'multi': '0', 'funcname': 'PySide2.QtGui.QTextDocument.find', 'arglist': 'subString:QString,from:int=0,options:PySide2.QtGui.QTextDocument.FindFlags=QTextDocument.FindFlags()', 'returntype': 'PySide2.QtGui.QTextCursor'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QTextDocument.markContentsDirty', 'arglist': 'from:int,length:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QHeaderView.moveSection', 'arglist': 'from:int,to:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QLayout.replaceWidget', 'arglist': 'from:PySide2.QtWidgets.QWidget,to:PySide2.QtWidgets.QWidget,options:PySide2.QtCore.Qt.FindChildOptions=Qt.FindChildrenRecursively', 'returntype': 'PySide2.QtWidgets.QLayoutItem'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QListWidgetItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QListWidgetItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QPlainTextDocumentLayout.documentChanged', 'arglist': 'from:int,arg__2:int,charsAdded:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTabBar.moveTab', 'arglist': 'from:int,to:int', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTableWidgetItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTableWidgetItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTreeWidgetItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTreeWidgetItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtMultimedia.QAudio.convertVolume', 'arglist': 'volume:double,from:PySide2.QtMultimedia.QAudio.VolumeScale,to:PySide2.QtMultimedia.QAudio.VolumeScale', 'returntype': 'double'}
+KEYWORD {'multi': None, 'funcname': 'PySide2.QtMultimedia.QMediaPlaylist.moveMedia', 'arglist': 'from:int,to:int', 'returntype': 'bool'}
diff --git a/popenasync.py b/popenasync.py
deleted file mode 100644
index 77faf9e0c..000000000
--- a/popenasync.py
+++ /dev/null
@@ -1,360 +0,0 @@
-#############################################################################
-##
-## Copyright (C) 2017 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$
-##
-#############################################################################
-
-################################################################################
-"""
-
-Modification of http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554
-
-"""
-
-#################################### IMPORTS ###################################
-
-import os
-import subprocess
-import errno
-import time
-import sys
-import unittest
-import tempfile
-
-def geterror ():
- return sys.exc_info()[1]
-
-if sys.version_info >= (3,):
- null_byte = '\x00'.encode('ascii')
-else:
- null_byte = '\x00'
-
-mswindows = (sys.platform == "win32")
-
-if mswindows:
- if sys.version_info >= (3,):
- # Test date should be in ascii.
- def encode(s):
- return s.encode('ascii', 'ignore')
-
- def decode(b):
- return b.decode('ascii', 'ignore')
- else:
- # Strings only; do nothing
- def encode(s):
- return s
-
- def decode(b):
- return b
-
- try:
- import ctypes
- from ctypes.wintypes import DWORD
- kernel32 = ctypes.windll.kernel32
- TerminateProcess = ctypes.windll.kernel32.TerminateProcess
- def WriteFile(handle, data, ol = None):
- c_written = DWORD()
- success = ctypes.windll.kernel32.WriteFile(handle,
- ctypes.create_string_buffer(encode(data)), len(data),
- ctypes.byref(c_written), ol)
- return ctypes.windll.kernel32.GetLastError(), c_written.value
- def ReadFile(handle, desired_bytes, ol = None):
- c_read = DWORD()
- buffer = ctypes.create_string_buffer(desired_bytes+1)
- success = ctypes.windll.kernel32.ReadFile(handle, buffer,
- desired_bytes, ctypes.byref(c_read), ol)
- buffer[c_read.value] = null_byte
- return ctypes.windll.kernel32.GetLastError(), decode(buffer.value)
- def PeekNamedPipe(handle, desired_bytes):
- c_avail = DWORD()
- c_message = DWORD()
- if desired_bytes > 0:
- c_read = DWORD()
- buffer = ctypes.create_string_buffer(desired_bytes+1)
- success = ctypes.windll.kernel32.PeekNamedPipe(handle, buffer,
- desired_bytes, ctypes.byref(c_read), ctypes.byref(c_avail),
- ctypes.byref(c_message))
- buffer[c_read.value] = null_byte
- return decode(buffer.value), c_avail.value, c_message.value
- else:
- success = ctypes.windll.kernel32.PeekNamedPipe(handle, None,
- desired_bytes, None, ctypes.byref(c_avail),
- ctypes.byref(c_message))
- return "", c_avail.value, c_message.value
-
- except ImportError:
- from win32file import ReadFile, WriteFile
- from win32pipe import PeekNamedPipe
- from win32api import TerminateProcess
- import msvcrt
-
-else:
- from signal import SIGINT, SIGTERM, SIGKILL
- import select
- import fcntl
-
-################################### CONSTANTS ##################################
-
-PIPE = subprocess.PIPE
-
-################################################################################
-
-class Popen(subprocess.Popen):
- def __init__(self, *args, **kwargs):
- subprocess.Popen.__init__(self, *args, **kwargs)
-
- def recv(self, maxsize=None):
- return self._recv('stdout', maxsize)
-
- def recv_err(self, maxsize=None):
- return self._recv('stderr', maxsize)
-
- def send_recv(self, input='', maxsize=None):
- return self.send(input), self.recv(maxsize), self.recv_err(maxsize)
-
- def read_async(self, wait=.1, e=1, tr=5, stderr=0):
- if tr < 1:
- tr = 1
- x = time.time()+ wait
- y = []
- r = ''
- pr = self.recv
- if stderr:
- pr = self.recv_err
- while time.time() < x or r:
- r = pr()
- if r is None:
- if e:
- raise Exception("Other end disconnected!")
- else:
- break
- elif r:
- y.append(r)
- else:
- time.sleep(max((x-time.time())/tr, 0))
- return ''.join(y)
-
- def send_all(self, data):
- while len(data):
- sent = self.send(data)
- if sent is None:
- raise Exception("Other end disconnected!")
- data = buffer(data, sent)
-
- def get_conn_maxsize(self, which, maxsize):
- if maxsize is None:
- maxsize = 1024
- elif maxsize < 1:
- maxsize = 1
- return getattr(self, which), maxsize
-
- def _close(self, which):
- conn = getattr(self, which)
- flags = fcntl.fcntl(conn, fcntl.F_GETFL)
- if not conn.closed:
- fcntl.fcntl(conn, fcntl.F_SETFL, flags & ~os.O_NONBLOCK)
- assert conn.read() == ''
- getattr(self, which).close()
- setattr(self, which, None)
-
- if mswindows:
- def kill(self):
- # Recipes
- #http://me.in-berlin.de/doc/python/faq/windows.html#how-do-i-emulate-os-kill-in-windows
- #http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/347462
-
- """kill function for Win32"""
- TerminateProcess(int(self._handle), 0) # returns None
-
- def send(self, input):
- if not self.stdin:
- return None
-
- try:
- x = msvcrt.get_osfhandle(self.stdin.fileno())
- (errCode, written) = WriteFile(x, input)
- except ValueError:
- return self._close('stdin')
- except (subprocess.pywintypes.error, Exception):
- if geterror()[0] in (109, errno.ESHUTDOWN):
- return self._close('stdin')
- raise
-
- return written
-
- def _recv(self, which, maxsize):
- conn, maxsize = self.get_conn_maxsize(which, maxsize)
- if conn is None:
- return None
-
- try:
- x = msvcrt.get_osfhandle(conn.fileno())
- (read, nAvail, nMessage) = PeekNamedPipe(x, 0)
- if maxsize < nAvail:
- nAvail = maxsize
- if nAvail > 0:
- (errCode, read) = ReadFile(x, nAvail, None)
- except ValueError:
- return self._close(which)
- except (subprocess.pywintypes.error, Exception):
- if geterror()[0] in (109, errno.ESHUTDOWN):
- return self._close(which)
- raise
-
- if self.universal_newlines:
- # Translate newlines. For Python 3.x assume read is text.
- # If bytes then another solution is needed.
- read = read.replace("\r\n", "\n").replace("\r", "\n")
- return read
-
- else:
- def kill(self):
- for i, sig in enumerate([SIGTERM, SIGKILL] * 2):
- if i % 2 == 0: os.kill(self.pid, sig)
- time.sleep((i * (i % 2) / 5.0) + 0.01)
-
- killed_pid, stat = os.waitpid(self.pid, os.WNOHANG)
- if killed_pid != 0: return
-
- def send(self, input):
- if not self.stdin:
- return None
-
- if not select.select([], [self.stdin], [], 0)[1]:
- return 0
-
- try:
- written = os.write(self.stdin.fileno(), input)
- except OSError:
- if geterror()[0] == errno.EPIPE: #broken pipe
- return self._close('stdin')
- raise
-
- return written
-
- def _recv(self, which, maxsize):
- conn, maxsize = self.get_conn_maxsize(which, maxsize)
- if conn is None:
- return None
-
- flags = fcntl.fcntl(conn, fcntl.F_GETFL)
- if not conn.closed:
- fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK)
-
- try:
- if not select.select([conn], [], [], 0)[0]:
- return ''
-
- try:
- r = conn.read(maxsize)
- except IOError as e:
- if e.errno == errno.EAGAIN:
- return ''
- raise
- if not r:
- return self._close(which)
-
- if self.universal_newlines:
- r = r.replace("\r\n", "\n").replace("\r", "\n")
- return r
- finally:
- if not conn.closed:
- fcntl.fcntl(conn, fcntl.F_SETFL, flags)
-
-################################################################################
-
-def proc_in_time_or_kill(cmd, time_out, wd = None, env = None):
- proc = Popen (
- cmd, cwd = wd, env = env,
- stdin = subprocess.PIPE, stdout = subprocess.PIPE,
- stderr = subprocess.STDOUT, universal_newlines = 1
- )
-
- ret_code = None
- response = []
-
- t = time.time()
- while ret_code is None and ((time.time() -t) < time_out):
- ret_code = proc.poll()
- response += [proc.read_async(wait=0.1, e=0)]
-
- if ret_code is None:
- ret_code = '"Process timed out (time_out = {} secs) '.format(time_out)
- try:
- proc.kill()
- ret_code += 'and was successfully terminated"'
- except Exception:
- ret_code += ("and termination failed "
- "(exception: {})".format(geterror(),))
-
- return ret_code, ''.join(response)
-
-################################################################################
-
-class AsyncTest(unittest.TestCase):
- def test_proc_in_time_or_kill(self):
- ret_code, response = proc_in_time_or_kill(
- [sys.executable, '-c', 'while 1: pass'], time_out = 1
- )
-
- self.assert_( 'rocess timed out' in ret_code )
- self.assert_( 'successfully terminated' in ret_code )
-
-################################################################################
-
-def _example():
- if sys.platform == 'win32':
- shell, commands, tail = ('cmd', ('echo "hello"', 'echo "HELLO WORLD"'),
- '\r\n')
- else:
- shell, commands, tail = ('sh', ('ls', 'echo HELLO WORLD'), '\n')
-
- a = Popen(shell, stdin=PIPE, stdout=PIPE)
- sys.stdout.write(a.read_async())
- sys.stdout.write(" ")
- for cmd in commands:
- a.send_all(cmd + tail)
- sys.stdout.write(a.read_async())
- sys.stdout.write(" ")
- a.send_all('exit' + tail)
- print (a.read_async(e=0))
- a.wait()
-
-################################################################################
-
-if __name__ == '__main__':
- if 1: unittest.main()
- else: _example()
diff --git a/setup.py b/setup.py
index b218397c1..58bb84b36 100644
--- a/setup.py
+++ b/setup.py
@@ -42,24 +42,61 @@ from __future__ import print_function
"""
This is a distutils setup-script for the Qt for Python project
-To build PySide2 simply execute:
- python setup.py build
+To build both shiboken2 and PySide2 simply execute:
+
+ python setup.py build
+
or
- python setup.py install
+
+ python setup.py install
+
to build and install into your current Python installation.
+The same setup.py script is used to build all the components of the
+project:
+ - shiboken2 (the supporting Python module)
+ - shiboken2-generator (the bindings generation executable)
+ - PySide2
+ - pyside2-tools
+
+Preferably, a Qt (build) environment should be used to automatically
+pick up the associated `qmake`, but optionally one can specify the
+location of `qmake` and `cmake` if it is not in the current PATH with:
-Optionally, one can specify the location of qmake and cmake if it is
-not on the current PATH with:
--qmake=/path/to/qt/bin/qmake
+
and
+
--cmake=/path/to/bin/cmake
+
respectively.
+By default, all of the above is built when no special options are
+passed to the script. You can use the --build-type parameter to specify
+which things should be built:
+
+ --build-type=shiboken2 - build / package only the python module
+ --build-type=shiboken2-generator - build / package the generator
+ executable
+ --build-type=pyside2 - build / package the PySide2 bindings and
+ and pyside2-tools
+ --build-type=all - the implicit default to build all of the above
+
+
+When building PySide2, optionally, one can specify the location of the
+shiboken2 cmake config path if it is not on the current PATH with:
+
+ --shiboken-config-dir=/path/to/shiboken/cmake/config/dir
+
+This is useful if you did a cmake installation of shiboken2 into
+a custom location.
+
For Windows, if OpenSSL support is required, it's necessary to specify
the directory path that contains the OpenSSL shared libraries
"libeay32.dll" and "ssleay32.dll", for example:
- --openssl=C:\OpenSSL-Win64\bin
+
+ --openssl=C:\\OpenSSL-Win64\\bin
+
This will make sure that the libraries are copied into the PySide2
package and are found by the QtNetwork module.
@@ -79,23 +116,23 @@ not specified.
You can use the option `--only-package` if you want to create more
binary packages (bdist_wheel, bdist_egg, ...) without rebuilding the
-entire PySide2 every time:
+entire project every time:
e.g.:
* First, we create a bdist_wheel from a full PySide2 build:
- python setup.py bdist_wheel --qmake=c:\Qt\5.9\bin\qmake.exe
- --cmake=c:\tools\cmake\bin\cmake.exe
- --openssl=c:\libs\OpenSSL32bit\bin
+ python setup.py bdist_wheel --qmake=c:\\Qt\\5.12\\bin\\qmake.exe
+ --cmake=c:\\tools\\cmake\\bin\\cmake.exe
+ --openssl=c:\\libs\\OpenSSL32bit\\bin
-* Then, we create a bdist_egg reusing PySide2 build with option
+* Then, we create a bdist_egg reusing the PySide2 build with option
`--only-package`:
python setup.py bdist_egg --only-package
- --qmake=c:\Qt\5.9\bin\qmake.exe
- --cmake=c:\tools\cmake\bin\cmake.exe
- --openssl=c:\libs\OpenSSL32bit\bin
+ --qmake=c:\\Qt\\5.12\\bin\\qmake.exe
+ --cmake=c:\\tools\\cmake\\bin\\cmake.exe
+ --openssl=c:\\libs\\OpenSSL32bit\\bin
You can use the option `--qt-conf-prefix` to pass a path relative to
the PySide2 installed package, which will be embedded into an
@@ -110,47 +147,47 @@ new environment variable called PYSIDE_DISABLE_INTERNAL_QT_CONF is
introduced.
You should assign the integer "1" to disable the internal `qt.conf`,
-or "0" (or leave empty) to keep usining the internal `qt.conf` file.
+or "0" (or leave empty) to keep using the internal `qt.conf` file.
DEVELOPMENT OPTIONS:
For development purposes the following options might be of use, when
using `setup.py build`:
+ --ignore-git will skip the fetching and checkout steps for
+ supermodule and all submodules.
+ --limited-api=yes|no default yes if applicable
+ Set or clear the limited API flag. Ignored for Python 2.
--module-subset allows for specifying the Qt modules to be built.
A minimal set is: --module-subset=Core,Gui,Test,Widgets
- --skip-modules allows for specifying the Qt modules that will be
- skipped during the build process.
- For example: --skip-modules=WebEngineCore,WebEngineWidgets
+ --package-timestamp allows specifying the timestamp that will be
+ used as part of the version number for a snapshot package.
+ For example given --package-timestamp=1529646276
+ the package version will be 5.x.y.dev1529646276.
--reuse-build option allows recompiling only the modified sources and
- not the whole world, shortening development iteration time,
+ not the whole world, shortening development iteration time.
+ --sanitize-address will build the project with address sanitizer.
--skip-cmake will reuse the already generated Makefiles (or
equivalents), instead of invoking, CMake to update the
Makefiles (note, CMake should be ran at least once to generate
- the files),
+ the files).
+ --skip-docs skip the documentation generation.
--skip-make-install will not run make install (or equivalent) for
- each module built,
+ each module built.
+ --skip-modules allows for specifying the Qt modules that will be
+ skipped during the build process.
+ For example: --skip-modules=WebEngineCore,WebEngineWidgets
--skip-packaging will skip creation of the python package,
- --ignore-git will skip the fetching and checkout steps for
- supermodule and all submodules.
+ enabled (Linux or macOS only).
--verbose-build will output the compiler invocation with command line
arguments, etc.
- --sanitize-address will build the project with address sanitizer
- enabled (Linux or macOS only).
- --skip-docs skip the documentation generation.
- --limited-api=yes|no default yes if applicable
- Set or clear the limited API flag. Ignored for Python 2.
- --package-timestamp allows specifying the timestamp that will be
- used as part of the version number for a snapshot package.
- For example given --package-timestamp=1529646276
- the package version will be 5.x.y.dev1529646276.
REQUIREMENTS:
-* Python: 2.7 and 3.3+ are supported
+* Python: 2.7 and 3.5+ are supported
* CMake: Specify the path to cmake with `--cmake` option or add cmake
to the system path.
-* Qt: 5.9 and 5.11 are supported. Specify the path to qmake with
+* Qt: 5.11+ is supported. Specify the path to qmake with
`--qmake` option or add qmake to the system path.
OPTIONAL:
@@ -166,9 +203,11 @@ OPTIONAL:
You can specify the location of the OpenSSL DLLs with the
following option:
+
--openssl=</path/to/openssl/bin-directory>.
You can download OpenSSL for Windows here:
+
http://slproweb.com/products/Win32OpenSSL.html (*)
Official Qt packages do not link to the SSL library directly, but
@@ -188,11 +227,12 @@ OPTIONAL:
shared libraries, are not currently compatible with
standalone PySide2 packages.
- (*) Revised on 21.06.2018
+ (*) Revised on 2018.10.24
* macOS SDK:
You can specify which macOS SDK should be used for compilation with
the option:
+
--macos-sysroot=</path/to/sdk>.
e.g.: "--macos-sysroot=/Applications/Xcode.app/.../Developer/SDKs/MacOSX10.12.sdk/"
@@ -200,6 +240,7 @@ OPTIONAL:
* macOS minimum deployment target:
You can specify a custom macOS minimum deployment target with the
option:
+
--macos-deployment-target=<value>
e.g.: "--macos-deployment-target=10.10"
@@ -219,7 +260,8 @@ OPTIONAL:
an older OS version.
"""
-import os, sys
+import os
+import sys
# Change the current directory to setup.py's dir.
try:
@@ -230,75 +272,18 @@ this_file = os.path.abspath(this_file)
if os.path.dirname(this_file):
os.chdir(os.path.dirname(this_file))
-from build_scripts.main import get_package_version, get_setuptools_extension_modules
-from build_scripts.main import pyside_package_dir_name
-from build_scripts.main import cmd_class_dict
-from build_scripts.main import README, CHANGES
-from setuptools import setup, Extension
+# Save the original command line arguments to pass them on to the setup
+# mechanism.
+original_argv = list(sys.argv)
+
+from build_scripts.main import get_package_version, check_allowed_python_version
+from build_scripts.setup_runner import SetupRunner
-# The __version__ variable is just for PEP compliancy, and shouldn't be
-# used as a value source.
+# The __version__ variable is just for PEP compliance, and shouldn't be
+# used as a value source. Use get_package_version() instead.
__version__ = get_package_version()
-extension_modules = get_setuptools_extension_modules()
-
-setup(
- name = "PySide2",
- version = get_package_version(),
- description = ("Python bindings for the Qt cross-platform application and "
- "UI framework"),
- long_description = README + "\n\n" + CHANGES,
- long_description_content_type = 'text/markdown',
- classifiers = [
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Console',
- 'Environment :: MacOS X',
- 'Environment :: X11 Applications :: Qt',
- 'Environment :: Win32 (MS Windows)',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
- 'Operating System :: MacOS :: MacOS X',
- 'Operating System :: POSIX',
- 'Operating System :: POSIX :: Linux',
- 'Operating System :: Microsoft',
- 'Operating System :: Microsoft :: Windows',
- 'Programming Language :: C++',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
- 'Programming Language :: Python :: 3.7',
- 'Topic :: Database',
- 'Topic :: Software Development',
- 'Topic :: Software Development :: Code Generators',
- 'Topic :: Software Development :: Libraries :: Application Frameworks',
- 'Topic :: Software Development :: User Interfaces',
- 'Topic :: Software Development :: Widget Sets',
- ],
- keywords = 'Qt',
- author = 'Qt for Python Team',
- author_email = 'pyside@qt-project.org',
- url = 'https://www.pyside.org',
- download_url = 'https://download.qt.io/official_releases/QtForPython/',
- license = 'LGPL',
- packages = ['PySide2', 'pyside2uic',
- 'pyside2uic.Compiler',
- 'pyside2uic.port_v{}'.format(sys.version_info[0]) ],
- package_dir = {'': pyside_package_dir_name},
- include_package_data = True,
- zip_safe = False,
- entry_points = {
- 'console_scripts': [
- 'pyside2-uic = PySide2.scripts.uic:main',
- ]
- },
- cmdclass = cmd_class_dict,
- # Add a bogus extension module (will never be built here since we
- # are overriding the build command to do it using cmake) so things
- # like bdist_egg will know that there are extension modules and
- # will name the dist with the full platform info.
- ext_modules = extension_modules,
- ext_package = 'PySide2',
-)
+check_allowed_python_version()
+
+setup_runner = SetupRunner(original_argv)
+setup_runner.run_setup()
diff --git a/sources/cmake_helpers/helpers.cmake b/sources/cmake_helpers/helpers.cmake
new file mode 100644
index 000000000..e64b8d9d3
--- /dev/null
+++ b/sources/cmake_helpers/helpers.cmake
@@ -0,0 +1,78 @@
+macro(compute_config_py_values
+ full_version_var_name
+ )
+ string(TIMESTAMP PACKAGE_BUILD_DATE "%Y-%m-%dT%H:%M:%S+00:00" UTC)
+ if (PACKAGE_BUILD_DATE)
+ set(PACKAGE_BUILD_DATE "__build_date__ = '${PACKAGE_BUILD_DATE}'")
+ endif()
+
+ if (PACKAGE_SETUP_PY_PACKAGE_VERSION)
+ set(PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT "__setup_py_package_version__ = '${PACKAGE_SETUP_PY_PACKAGE_VERSION}'")
+ set(FINAL_PACKAGE_VERSION ${PACKAGE_SETUP_PY_PACKAGE_VERSION})
+ else()
+ set(FINAL_PACKAGE_VERSION ${${full_version_var_name}})
+ endif()
+
+ if (PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP)
+ set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = '${PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP}'")
+ else()
+ set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "")
+ endif()
+
+ find_package(Git)
+ if(GIT_FOUND)
+ # Check if current source folder is inside a git repo, so that commit information can be
+ # queried.
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
+ OUTPUT_VARIABLE PACKAGE_SOURCE_IS_INSIDE_REPO
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(PACKAGE_SOURCE_IS_INSIDE_REPO)
+ # Force git dates to be UTC-based.
+ set(ENV{TZ} UTC)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} --no-pager show --date=format-local:%Y-%m-%dT%H:%M:%S+00:00 -s --format=%cd HEAD
+ OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_DATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(PACKAGE_BUILD_COMMIT_DATE)
+ set(PACKAGE_BUILD_COMMIT_DATE "__build_commit_date__ = '${PACKAGE_BUILD_COMMIT_DATE}'")
+ endif()
+ unset(ENV{TZ})
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
+ OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(PACKAGE_BUILD_COMMIT_HASH)
+ set(PACKAGE_BUILD_COMMIT_HASH "__build_commit_hash__ = '${PACKAGE_BUILD_COMMIT_HASH}'")
+ endif()
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} describe HEAD
+ OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH_DESCRIBED
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED)
+ set(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED "__build_commit_hash_described__ = '${PACKAGE_BUILD_COMMIT_HASH_DESCRIBED}'")
+ endif()
+
+ endif()
+ endif()
+
+endmacro()
+
+# Creates a new target called "${library_name}_generator" which
+# depends on the mjb_rejected_classes.log file generated by shiboken.
+# This target is added as a dependency to ${library_name} target.
+# This file's timestamp informs cmake when the last generation was
+# done, without force-updating the timestamps of the generated class
+# cpp files.
+# In practical terms this means that changing some injection code in
+# an xml file that modifies only one specific class cpp file, will
+# not force rebuilding all the cpp files, and thus allow for better
+# incremental builds.
+macro(create_generator_target library_name)
+ add_custom_target(${library_name}_generator DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log")
+ add_dependencies(${library_name} ${library_name}_generator)
+endmacro()
diff --git a/sources/pyside2-tools b/sources/pyside2-tools
-Subproject f1b775537e7fbd718516749583b2abf1cb6adbc
+Subproject 9d23904f5d5f13f8e6f72deebefff1d336163ff
diff --git a/sources/pyside2/CMakeLists.txt b/sources/pyside2/CMakeLists.txt
index 358c119ae..1d563fb44 100644
--- a/sources/pyside2/CMakeLists.txt
+++ b/sources/pyside2/CMakeLists.txt
@@ -8,11 +8,32 @@ cmake_policy(SET CMP0046 NEW)
project(pysidebindings)
-set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Macros/
+set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake_helpers/
+ ${CMAKE_SOURCE_DIR}/cmake/Macros/
${CMAKE_MODULE_PATH})
+include(helpers)
option(USE_PYTHON_VERSION "Use specific python version to build pyside2." "")
+# Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
+if (QUIET_BUILD)
+ set(CMAKE_INSTALL_MESSAGE NEVER)
+endif()
+
+# Override message not to display info messages when doing a quiet build.
+if (QUIET_BUILD)
+ function(message)
+ list(GET ARGV 0 MessageType)
+ if (MessageType STREQUAL FATAL_ERROR OR
+ MessageType STREQUAL SEND_ERROR OR
+ MessageType STREQUAL WARNING OR
+ MessageType STREQUAL AUTHOR_WARNING)
+ list(REMOVE_AT ARGV 0)
+ _message(${MessageType} "${ARGV}")
+ endif()
+ endfunction()
+endif()
+
if (USE_PYTHON_VERSION)
find_package(PythonInterp ${USE_PYTHON_VERSION} REQUIRED)
find_package(PythonLibs ${USE_PYTHON_VERSION} REQUIRED)
@@ -244,70 +265,32 @@ else()
CACHE STRING "PySide2 version [full]" FORCE)
endif()
-string(TIMESTAMP PYSIDE_BUILD_DATE "%Y-%m-%dT%H:%M:%S+00:00" UTC)
-if (PYSIDE_BUILD_DATE)
- set(PYSIDE_BUILD_DATE "__build_date__ = '${PYSIDE_BUILD_DATE}'")
-endif()
+compute_config_py_values(BINDING_API_VERSION)
-if (PYSIDE_SETUP_PY_PACKAGE_VERSION)
- set(PYSIDE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT "__setup_py_package_version__ = '${PYSIDE_SETUP_PY_PACKAGE_VERSION}'")
- set(FINAL_PACKAGE_VERSION ${PYSIDE_SETUP_PY_PACKAGE_VERSION})
-else()
- set(FINAL_PACKAGE_VERSION ${BINDING_API_VERSION_FULL})
-endif()
-
-if (PYSIDE_SETUP_PY_PACKAGE_TIMESTAMP)
- set(PYSIDE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = '${PYSIDE_SETUP_PY_PACKAGE_TIMESTAMP}'")
-else()
- set(PYSIDE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = ''")
-endif()
+include(PySideModules)
-find_package(Git)
-if(GIT_FOUND)
- # Check if current source folder is inside a git repo, so that commit information can be
- # queried.
- execute_process(
- COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
- OUTPUT_VARIABLE PYSIDE_SOURCE_IS_INSIDE_REPO
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if(PYSIDE_SOURCE_IS_INSIDE_REPO)
- # Force git dates to be UTC-based.
- set(ENV{TZ} UTC)
- execute_process(
- COMMAND ${GIT_EXECUTABLE} --no-pager show --date=format-local:%Y-%m-%dT%H:%M:%S+00:00 -s --format=%cd HEAD
- OUTPUT_VARIABLE PYSIDE_BUILD_COMMIT_DATE
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if(PYSIDE_BUILD_COMMIT_DATE)
- set(PYSIDE_BUILD_COMMIT_DATE "__build_commit_date__ = '${PYSIDE_BUILD_COMMIT_DATE}'")
- endif()
- unset(ENV{TZ})
-
- execute_process(
- COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
- OUTPUT_VARIABLE PYSIDE_BUILD_COMMIT_HASH
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if(PYSIDE_BUILD_COMMIT_HASH)
- set(PYSIDE_BUILD_COMMIT_HASH "__build_commit_hash__ = '${PYSIDE_BUILD_COMMIT_HASH}'")
- endif()
+macro(COLLECT_MODULE_IF_FOUND shortname)
+ set(name "Qt5${shortname}")
- execute_process(
- COMMAND ${GIT_EXECUTABLE} describe HEAD
- OUTPUT_VARIABLE PYSIDE_BUILD_COMMIT_HASH_DESCRIBED
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if(PYSIDE_BUILD_COMMIT_HASH_DESCRIBED)
- set(PYSIDE_BUILD_COMMIT_HASH_DESCRIBED "__build_commit_hash_described__ = '${PYSIDE_BUILD_COMMIT_HASH_DESCRIBED}'")
+ # Determine essential/optional/missing
+ set(module_state "missing")
+ list(FIND ALL_ESSENTIAL_MODULES "${shortname}" essentialIndex)
+ if(${essentialIndex} EQUAL -1)
+ list(FIND ALL_OPTIONAL_MODULES "${shortname}" optionalIndex)
+ if(NOT ${optionalIndex} EQUAL -1)
+ set(module_state "optional")
endif()
-
+ else()
+ set(module_state "essential")
endif()
-endif()
-include(PySideModules)
+ # Silence warnings when optional packages are not found when doing a quiet build.
+ set(quiet_argument "")
+ if (QUIET_BUILD AND "${module_state}" STREQUAL "optional")
+ set(quiet_argument "QUIET")
+ endif()
-macro(COLLECT_MODULE_IF_FOUND shortname)
- set(name "Qt5${shortname}")
- find_package(${name})
+ find_package(${name} ${quiet_argument})
# If package is found, _name_found will be equal to 1
set(_name_found "${name}_FOUND")
# _name_dir will keep the path to the directory where the CMake rules were found
@@ -331,18 +314,6 @@ macro(COLLECT_MODULE_IF_FOUND shortname)
get_filename_component(_module_dir "${${_name_dir}}" ABSOLUTE)
string(FIND "${_module_dir}" "${_core_abs_dir}" found_basepath)
- # Determine essential/optional/missing
- set(module_state "missing")
- list(FIND ALL_ESSENTIAL_MODULES "${shortname}" essentialIndex)
- if(${essentialIndex} EQUAL -1)
- list(FIND ALL_OPTIONAL_MODULES "${shortname}" optionalIndex)
- if(NOT ${optionalIndex} EQUAL -1)
- set(module_state "optional")
- endif()
- else()
- set(module_state "essential")
- endif()
-
# If the module was found, and also the module path is the same as the
# Qt5Core base path, we will generate the list with the modules to be installed
set(looked_in_message ". Looked in: ${${_name_dir}}")
diff --git a/sources/pyside2/PySide2/CMakeLists.txt b/sources/pyside2/PySide2/CMakeLists.txt
index 0263f7441..ea1a7de16 100644
--- a/sources/pyside2/PySide2/CMakeLists.txt
+++ b/sources/pyside2/PySide2/CMakeLists.txt
@@ -6,9 +6,24 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/global.h.in"
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
"${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY)
-
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/__init__.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/__init__.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/generate_pyi.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/generate_pyi.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/layout.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/layout.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/mapping.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/mapping.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/typing.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/typing.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/lib/__init__.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/lib/__init__.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/lib/enum_sig.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/lib/enum_sig.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in"
- "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY)
+ "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY)
# Use absolute path instead of relative path, to avoid ninja build errors due to
# duplicate file dependency inconsistency.
@@ -38,21 +53,6 @@ endif()
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/loader.py"
- "${CMAKE_CURRENT_BINARY_DIR}/support/signature/loader.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/mapping.py"
- "${CMAKE_CURRENT_BINARY_DIR}/support/signature/mapping.py" COPYONLY)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/parser.py"
- "${CMAKE_CURRENT_BINARY_DIR}/support/signature/parser.py" COPYONLY)
-if (PYTHON_VERSION_MAJOR EQUAL 3)
-else()
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/backport_inspect.py"
- "${CMAKE_CURRENT_BINARY_DIR}/support/signature/backport_inspect.py" COPYONLY)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/typing27.py"
- "${CMAKE_CURRENT_BINARY_DIR}/support/signature/typing.py" COPYONLY)
-endif()
# now compile all modules.
file(READ "${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h" pyside2_global_contents)
@@ -93,8 +93,19 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside2_SUFFIX}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_git_pyside_version.py"
DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside2_SUFFIX}")
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_templates.xml
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/core_common.xml
+ DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/gui_common.xml
+ DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/widgets_common.xml
+ DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/datavisualization_common.xml
+ DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/opengl_common.xml
+ DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/webkitwidgets_common.xml
+ DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/xml_common.xml
DESTINATION share/PySide2${pyside_SUFFIX}/typesystems)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h
DESTINATION include/${BINDING_NAME}${pyside2_SUFFIX})
-
diff --git a/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt
index 9bdf36add..258a011bf 100644
--- a/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt
@@ -45,11 +45,10 @@ set(Qt3DAnimation_libraries pyside2
set(Qt3DAnimation_deps Qt3DRender)
-create_pyside_module(Qt3DAnimation
- Qt3DAnimation_include_dirs
- Qt3DAnimation_libraries
- Qt3DAnimation_deps
- Qt3DAnimation_SOURCE_DIR
- Qt3DAnimation_SRC
- ""
- ${Qt3DAnimation_BINARY_DIR}/typesystem_3danimation.xml)
+create_pyside_module(NAME Qt3DAnimation
+ INCLUDE_DIRS Qt3DAnimation_include_dirs
+ LIBRARIES Qt3DAnimation_libraries
+ DEPS Qt3DAnimation_deps
+ TYPESYSTEM_PATH Qt3DAnimation_SOURCE_DIR
+ SOURCES Qt3DAnimation_SRC
+ TYPESYSTEM_NAME ${Qt3DAnimation_BINARY_DIR}/typesystem_3danimation.xml)
diff --git a/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt
index 53d3cc634..d046f8fc1 100644
--- a/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt
@@ -64,11 +64,10 @@ set(Qt3DCore_libraries pyside2
set(Qt3DCore_deps QtGui QtNetwork)
-create_pyside_module(Qt3DCore
- Qt3DCore_include_dirs
- Qt3DCore_libraries
- Qt3DCore_deps
- Qt3DCore_SOURCE_DIR
- Qt3DCore_SRC
- ""
- ${Qt3DCore_BINARY_DIR}/typesystem_3dcore.xml)
+create_pyside_module(NAME Qt3DCore
+ INCLUDE_DIRS Qt3DCore_include_dirs
+ LIBRARIES Qt3DCore_libraries
+ DEPS Qt3DCore_deps
+ TYPESYSTEM_PATH Qt3DCore_SOURCE_DIR
+ SOURCES Qt3DCore_SRC
+ TYPESYSTEM_NAME ${Qt3DCore_BINARY_DIR}/typesystem_3dcore.xml)
diff --git a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
index fb7a83ba7..013a49165 100644
--- a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
+++ b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml
@@ -45,19 +45,41 @@
<namespace-type name="Qt3DCore">
<enum-type name="ChangeFlag" flags="ChangeFlags"/>
<object-type name="QAbstractAspect"/>
+ <object-type name="QAbstractEngine"/>
<object-type name="QAbstractSkeleton" since="5.10"/>
<object-type name="QArmature" since="5.10"/>
- <object-type name="QAspectEngine"/>
+ <object-type name="QAspectEngine">
+ <modify-function signature="registerAspect(Qt3DCore::QAbstractAspect*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
<object-type name="QAspectJob"/>
<object-type name="QBackendNode">
<enum-type name="Mode"/>
</object-type>
+ <!-- TODO: Solve issues related to windows and a unresolved
+ external symbol
+ <object-type name="QBackendNodeMapper"/>-->
<object-type name="QComponent"/>
<object-type name="QComponentAddedChange"/>
<object-type name="QComponentRemovedChange"/>
<object-type name="QDynamicPropertyUpdatedChange"/>
- <object-type name="QEntity"/>
- <object-type name="QJoint" since="5.10"/>
+ <object-type name="QEntity">
+ <modify-function signature="addComponent(Qt3DCore::QComponent*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <object-type name="QJoint" since="5.10">
+ <modify-function signature="addChildJoint(Qt3DCore::QJoint*)">
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
<object-type name="QNode">
<enum-type name="PropertyTrackingMode"/>
</object-type>
@@ -88,5 +110,10 @@
<!-- Disambiguate from QtGui/qtransform.h -->
<include file-name="Qt3DCore/qtransform.h" location="global"/>
</object-type>
+ <namespace-type name="Quick">
+ <object-type name="QQmlAspectEngine">
+ <enum-type name="Status"/>
+ </object-type>
+ </namespace-type>
</namespace-type>
</typesystem>
diff --git a/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt
index 4bc25d52d..bd750949d 100644
--- a/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt
@@ -71,11 +71,10 @@ set(Qt3DExtras_libraries pyside2
set(Qt3DExtras_deps Qt3DRender)
-create_pyside_module(Qt3DExtras
- Qt3DExtras_include_dirs
- Qt3DExtras_libraries
- Qt3DExtras_deps
- Qt3DExtras_SOURCE_DIR
- Qt3DExtras_SRC
- ""
- ${Qt3DExtras_BINARY_DIR}/typesystem_3dextras.xml)
+create_pyside_module(NAME Qt3DExtras
+ INCLUDE_DIRS Qt3DExtras_include_dirs
+ LIBRARIES Qt3DExtras_libraries
+ DEPS Qt3DExtras_deps
+ TYPESYSTEM_PATH Qt3DExtras_SOURCE_DIR
+ SOURCES Qt3DExtras_SRC
+ TYPESYSTEM_NAME ${Qt3DExtras_BINARY_DIR}/typesystem_3dextras.xml)
diff --git a/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt
index 694f373f8..a3366c9ba 100644
--- a/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt
@@ -46,11 +46,10 @@ set(Qt3DInput_libraries pyside2
set(Qt3DInput_deps Qt3DCore)
-create_pyside_module(Qt3DInput
- Qt3DInput_include_dirs
- Qt3DInput_libraries
- Qt3DInput_deps
- Qt3DInput_SOURCE_DIR
- Qt3DInput_SRC
- ""
- ${Qt3DInput_BINARY_DIR}/typesystem_3dinput.xml)
+create_pyside_module(NAME Qt3DInput
+ INCLUDE_DIRS Qt3DInput_include_dirs
+ LIBRARIES Qt3DInput_libraries
+ DEPS Qt3DInput_deps
+ TYPESYSTEM_PATH Qt3DInput_SOURCE_DIR
+ SOURCES Qt3DInput_SRC
+ TYPESYSTEM_NAME ${Qt3DInput_BINARY_DIR}/typesystem_3dinput.xml)
diff --git a/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml b/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml
index dd72c5c01..ebac94f03 100644
--- a/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml
+++ b/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml
@@ -45,7 +45,9 @@
<namespace-type name="Qt3DInput">
<object-type name="QAbstractActionInput"/>
<object-type name="QAbstractAxisInput"/>
- <object-type name="QAbstractPhysicalDevice"/>
+ <object-type name="QAbstractPhysicalDevice">
+ <enum-type name="DeviceStatus"/>
+ </object-type>
<object-type name="QAction"/>
<object-type name="QActionInput"/>
<object-type name="QAnalogAxisInput"/>
@@ -57,29 +59,34 @@
<object-type name="QButtonAxisInput"/>
<object-type name="QInputAspect"/>
<object-type name="QInputChord"/>
+ <!-- On windows this raises the following error:
+ type 'Qt3DInput::QInputDeviceIntegration' is specified in typesystem, but not defined.
+ This could potentially lead to compilation errors.
+ <object-type name="QInputDeviceIntegration"/>
+ -->
<object-type name="QInputSequence"/>
<object-type name="QInputSettings"/>
+ <object-type name="QKeyboardDevice"/>
<object-type name="QKeyboardHandler"/>
- <object-type name="QKeyEvent">
- <modify-function signature="QKeyEvent(const Qt3DInput::QKeyEvent&amp;)" remove="all"/>
- </object-type>
+ <object-type name="QKeyEvent"/>
<object-type name="QLogicalDevice"/>
- <object-type name="QKeyboardDevice"/>
<object-type name="QMouseDevice">
<enum-type name="Axis"/>
</object-type>
- <!-- Fixme: shiboken2 mistakenly thinks that Qt3DInput::QMouseEvent(::QMouseEvent)
- is a copy constructor of Qt3DInput::QMouseEvent. Work around by suppressing them -->
<object-type name="QMouseEvent">
<enum-type name="Buttons"/>
<enum-type name="Modifiers"/>
- <modify-function signature="QMouseEvent(const Qt3DInput::QMouseEvent&amp;)" remove="all"/>
</object-type>
<object-type name="QWheelEvent">
<enum-type name="Buttons"/>
<enum-type name="Modifiers"/>
- <modify-function signature="QWheelEvent(const Qt3DInput::QWheelEvent&amp;)" remove="all"/>
</object-type>
<object-type name="QMouseHandler"/>
+ <!-- On windows this raise the following error:
+ qt3dinput_module_wrapper.cpp.obj : error LNK2019:
+ unresolved external symbol "void __cdecl init_Qt3DInput_QPhysicalDeviceCreatedChangeBase(struct _object *)"
+ (?init_Qt3DInput_QPhysicalDeviceCreatedChangeBase@@YAXPAU_object@@@Z) referenced in function _PyInit_Qt3DInput
+ <object-type name="QPhysicalDeviceCreatedChangeBase"/>
+ -->
</namespace-type>
</typesystem>
diff --git a/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt
index 23cde8804..8cf4de37f 100644
--- a/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt
@@ -27,11 +27,10 @@ set(Qt3DLogic_libraries pyside2
set(Qt3DLogic_deps Qt3DCore)
-create_pyside_module(Qt3DLogic
- Qt3DLogic_include_dirs
- Qt3DLogic_libraries
- Qt3DLogic_deps
- Qt3DLogic_SOURCE_DIR
- Qt3DLogic_SRC
- ""
- ${Qt3DLogic_BINARY_DIR}/typesystem_3dlogic.xml)
+create_pyside_module(NAME Qt3DLogic
+ INCLUDE_DIRS Qt3DLogic_include_dirs
+ LIBRARIES Qt3DLogic_libraries
+ DEPS Qt3DLogic_deps
+ TYPESYSTEM_PATH Qt3DLogic_SOURCE_DIR
+ SOURCES Qt3DLogic_SRC
+ TYPESYSTEM_NAME ${Qt3DLogic_BINARY_DIR}/typesystem_3dlogic.xml)
diff --git a/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt
index 1b859ca1e..011536cef 100644
--- a/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt
+++ b/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt
@@ -145,11 +145,10 @@ set(Qt3DRender_libraries pyside2
set(Qt3DRender_deps Qt3DCore)
-create_pyside_module(Qt3DRender
- Qt3DRender_include_dirs
- Qt3DRender_libraries
- Qt3DRender_deps
- Qt3DRender_SOURCE_DIR
- Qt3DRender_SRC
- ""
- ${Qt3DRender_BINARY_DIR}/typesystem_3drender.xml)
+create_pyside_module(NAME Qt3DRender
+ INCLUDE_DIRS Qt3DRender_include_dirs
+ LIBRARIES Qt3DRender_libraries
+ DEPS Qt3DRender_deps
+ TYPESYSTEM_PATH Qt3DRender_SOURCE_DIR
+ SOURCES Qt3DRender_SRC
+ TYPESYSTEM_NAME ${Qt3DRender_BINARY_DIR}/typesystem_3drender.xml)
diff --git a/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt b/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt
index a3971786b..6e9492d48 100644
--- a/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt
@@ -36,11 +36,10 @@ set(QtAxContainer_libraries pyside2
set(QtAxContainer_deps QtWidgets)
-create_pyside_module(QtAxContainer
- QtAxContainer_include_dirs
- QtAxContainer_libraries
- QtAxContainer_deps
- QtAxContainer_SOURCE_DIR
- QtAxContainer_SRC
- ""
- ${QtAxContainer_BINARY_DIR}/typesystem_axcontainer.xml)
+create_pyside_module(NAME QtAxContainer
+ INCLUDE_DIRS QtAxContainer_include_dirs
+ LIBRARIES QtAxContainer_libraries
+ DEPS QtAxContainer_deps
+ TYPESYSTEM_PATH QtAxContainer_SOURCE_DIR
+ SOURCES QtAxContainer_SRC
+ TYPESYSTEM_NAME ${QtAxContainer_BINARY_DIR}/typesystem_axcontainer.xml)
diff --git a/sources/pyside2/PySide2/QtCharts/CMakeLists.txt b/sources/pyside2/PySide2/QtCharts/CMakeLists.txt
index fa177300d..c7611edb0 100644
--- a/sources/pyside2/PySide2/QtCharts/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtCharts/CMakeLists.txt
@@ -81,10 +81,9 @@ set(QtCharts_libraries pyside2
set(QtCharts_deps QtCore QtGui QtWidgets)
-create_pyside_module(QtCharts
- QtCharts_include_dirs
- QtCharts_libraries
- QtCharts_deps
- QtCharts_SOURCE_DIR
- QtCharts_SRC
- "")
+create_pyside_module(NAME QtCharts
+ INCLUDE_DIRS QtCharts_include_dirs
+ LIBRARIES QtCharts_libraries
+ DEPS QtCharts_deps
+ TYPESYSTEM_PATH QtCharts_SOURCE_DIR
+ SOURCES QtCharts_SRC)
diff --git a/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml b/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml
index ebcd09b18..14224751c 100644
--- a/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml
+++ b/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml
@@ -40,7 +40,7 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtCharts">
- <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<namespace-type name="QtCharts">
<object-type name="QAbstractAxis" since="5.7">
<enum-type name="AxisType"/>
@@ -164,14 +164,10 @@
</modify-argument>
</modify-function>
<modify-function signature="removeAxis(QtCharts::QAbstractAxis*)">
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtcharts.cpp" snippet="qchart-releaseownership"/>
</modify-function>
<modify-function signature="removeSeries(QtCharts::QAbstractSeries*)">
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtcharts.cpp" snippet="qchart-releaseownership"/>
</modify-function>
</object-type>
<object-type name="QChartView" since="5.7">
diff --git a/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt b/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt
index 4fb62ee99..9bd5c0547 100644
--- a/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt
@@ -22,10 +22,9 @@ set(QtConcurrent_libraries pyside2
)
set(QtConcurrent_deps QtCore)
-create_pyside_module(QtConcurrent
- QtConcurrent_include_dirs
- QtConcurrent_libraries
- QtConcurrent_deps
- QtConcurrent_SOURCE_DIR
- QtConcurrent_SRC
- "")
+create_pyside_module(NAME QtConcurrent
+ INCLUDE_DIRS QtConcurrent_include_dirs
+ LIBRARIES QtConcurrent_libraries
+ DEPS QtConcurrent_deps
+ TYPESYSTEM_PATH QtConcurrent_SOURCE_DIR
+ SOURCES QtConcurrent_SRC)
diff --git a/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml b/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml
index bed947772..bdf4e6fa7 100644
--- a/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml
+++ b/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml
@@ -47,7 +47,7 @@
<namespace-type name="QtConcurrent" target-type="class">
<rejection class="QtConcurrent" enum-name="enum_1"/>
<enum-type name="ReduceOption" flags="ReduceOptions"/>
- <enum-type name="ThreadFunctionResult" />
+ <enum-type name="ThreadFunctionResult"/>
<extra-includes>
<include file-name="qtconcurrentreducekernel.h" location="global"/>
<include file-name="qtconcurrentthreadengine.h" location="global"/>
diff --git a/sources/pyside2/PySide2/QtCore/CMakeLists.txt b/sources/pyside2/PySide2/QtCore/CMakeLists.txt
index 1d0b7d413..25d30e8bb 100644
--- a/sources/pyside2/PySide2/QtCore/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtCore/CMakeLists.txt
@@ -16,6 +16,7 @@ ${QtCore_GEN_DIR}/qabstracteventdispatcher_timerinfo_wrapper.cpp
${QtCore_GEN_DIR}/qabstracteventdispatcher_wrapper.cpp
${QtCore_GEN_DIR}/qabstractitemmodel_wrapper.cpp
${QtCore_GEN_DIR}/qabstractlistmodel_wrapper.cpp
+${QtCore_GEN_DIR}/qabstractnativeeventfilter_wrapper.cpp
${QtCore_GEN_DIR}/qabstractproxymodel_wrapper.cpp
${QtCore_GEN_DIR}/qabstractstate_wrapper.cpp
${QtCore_GEN_DIR}/qabstracttablemodel_wrapper.cpp
@@ -28,6 +29,15 @@ ${QtCore_GEN_DIR}/qbuffer_wrapper.cpp
${QtCore_GEN_DIR}/qbytearray_wrapper.cpp
${QtCore_GEN_DIR}/qbytearraymatcher_wrapper.cpp
${QtCore_GEN_DIR}/qchildevent_wrapper.cpp
+${QtCore_GEN_DIR}/qcborarray_wrapper.cpp
+${QtCore_GEN_DIR}/qcborerror_wrapper.cpp
+${QtCore_GEN_DIR}/qcbormap_wrapper.cpp
+${QtCore_GEN_DIR}/qcborparsererror_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstreamreader_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstringresultstring_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstringresultbytearray_wrapper.cpp
+${QtCore_GEN_DIR}/qcborstreamwriter_wrapper.cpp
+${QtCore_GEN_DIR}/qcborvalue_wrapper.cpp
${QtCore_GEN_DIR}/qcollator_wrapper.cpp
${QtCore_GEN_DIR}/qcollatorsortkey_wrapper.cpp
${QtCore_GEN_DIR}/qcommandlineoption_wrapper.cpp
@@ -170,6 +180,11 @@ ${SPECIFIC_OS_FILES}
${QtCore_GEN_DIR}/qtcore_module_wrapper.cpp
)
+set(QtCore_glue_sources
+ "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp"
+ "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.h"
+)
+
configure_file("${QtCore_SOURCE_DIR}/typesystem_core.xml.in"
"${QtCore_BINARY_DIR}/typesystem_core.xml" @ONLY)
@@ -185,12 +200,14 @@ set(QtCore_libraries pyside2
${SHIBOKEN_LIBRARY}
${Qt5Core_LIBRARIES}
)
-create_pyside_module(QtCore
- QtCore_include_dirs
- QtCore_libraries
- ""
- QtCore_SOURCE_DIR
- QtCore_SRC
- QtCore_gluecode
- ${QtCore_BINARY_DIR}/typesystem_core.xml)
+
+create_pyside_module(NAME QtCore
+ INCLUDE_DIRS QtCore_include_dirs
+ LIBRARIES QtCore_libraries
+ TYPESYSTEM_PATH QtCore_SOURCE_DIR
+ SOURCES QtCore_SRC
+ STATIC_SOURCES QtCore_gluecode
+ TYPESYSTEM_NAME ${QtCore_BINARY_DIR}/typesystem_core.xml
+ GLUE_SOURCES QtCore_glue_sources
+ )
diff --git a/sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp b/sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp
deleted file mode 100644
index 1349f40f1..000000000
--- a/sources/pyside2/PySide2/QtCore/glue/qbytearray_msetitem.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 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$
-**
-****************************************************************************/
-
-if (PyIndex_Check(_key)) {
- Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
- if (_i == -1 && PyErr_Occurred())
- return -1;
-
- if (_i < 0)
- _i += %CPPSELF.count();
-
- if (_i < 0 || _i >= %CPPSELF.size()) {
- PyErr_SetString(PyExc_IndexError, "QByteArray index out of range");
- return -1;
- }
-
- // Provide more specific error message for bytes/str, bytearray, QByteArray respectively
-#ifdef IS_PY3K
- if (PyBytes_Check(_value)) {
- if (Py_SIZE(_value) != 1) {
- PyErr_SetString(PyExc_ValueError, "bytes must be of size 1");
-#else
- if (PyString_CheckExact(_value)) {
- if (Py_SIZE(_value) != 1) {
- PyErr_SetString(PyExc_ValueError, "str must be of size 1");
-#endif
- return -1;
- }
- } else if (PyByteArray_Check(_value)) {
- if (Py_SIZE(_value) != 1) {
- PyErr_SetString(PyExc_ValueError, "bytearray must be of size 1");
- return -1;
- }
- } else if (reinterpret_cast<PyTypeObject *>(Py_TYPE(_value)) == reinterpret_cast<PyTypeObject *>(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX])) {
- if (PyObject_Length(_value) != 1) {
- PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1");
- return -1;
- }
- } else {
-#ifdef IS_PY3K
- PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required");
-#else
- PyErr_SetString(PyExc_ValueError, "a str, bytearray, QByteArray of size 1 is required");
-#endif
- return -1;
- }
-
- // Not support int or long.
- %CPPSELF.remove(_i, 1);
- PyObject *args = Py_BuildValue("(nO)", _i, _value);
- PyObject *result = Sbk_QByteArrayFunc_insert(self, args);
- Py_DECREF(args);
- Py_XDECREF(result);
- return !result ? -1 : 0;
-} else if (PySlice_Check(_key)) {
- Py_ssize_t start, stop, step, slicelength, value_length;
-
-#ifdef IS_PY3K
- PyObject *key = _key;
-#else
- PySliceObject *key = reinterpret_cast<PySliceObject *>(_key);
-#endif
- if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) {
- return -1;
- }
- // The parameter candidates are: bytes/str, bytearray, QByteArray itself.
- // Not support iterable which contains ints between 0~255
-
- // case 1: value is NULL, means delete the items within the range
- // case 2: step is 1, means shrink or expanse
- // case 3: step is not 1, then the number of slots have to equal the number of items in _value
- QByteArray ba;
- if (_value == NULL || _value == Py_None) {
- ba = QByteArray();
- value_length = 0;
- } else if (!(PyBytes_Check(_value) || PyByteArray_Check(_value) || reinterpret_cast<PyTypeObject *>(Py_TYPE(_value)) == reinterpret_cast<PyTypeObject *>(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX]))) {
- PyErr_Format(PyExc_TypeError, "bytes, bytearray or QByteArray is required, not %.200s", Py_TYPE(_value)->tp_name);
- return -1;
- } else {
- value_length = PyObject_Length(_value);
- }
-
- if (step != 1 && value_length != slicelength) {
- PyErr_Format(PyExc_ValueError, "attempt to assign %s of size %d to extended slice of size %d",Py_TYPE(_value)->tp_name, value_length, slicelength);
- return -1;
- }
-
- if (step != 1) {
- int i = start;
- for (int j = 0; j < slicelength; j++) {
- PyObject *item = PyObject_GetItem(_value, PyLong_FromLong(j));
- QByteArray temp;
-#ifdef IS_PY3K
- if (PyLong_Check(item)) {
-#else
- if (PyLong_Check(item) || PyInt_Check(item)) {
-#endif
- int overflow;
- long ival = PyLong_AsLongAndOverflow(item, &overflow);
- // Not suppose to bigger than 255 because only bytes, bytearray, QByteArray were accept
- const char *el = reinterpret_cast<const char*>(&ival);
- temp = QByteArray(el);
- } else {
- temp = %CONVERTTOCPP[QByteArray](item);
- }
-
- %CPPSELF.replace(i, 1, temp);
- i += step;
- }
- return 0;
- } else {
- ba = %CONVERTTOCPP[QByteArray](_value);
- %CPPSELF.replace(start, slicelength, ba);
- return 0;
- }
-} else {
- PyErr_Format(PyExc_TypeError, "QBytearray indices must be integers or slices, not %.200s",
- Py_TYPE(_key)->tp_name);
- return -1;
-}
-
-
diff --git a/sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp b/sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp
deleted file mode 100644
index 20f3720bf..000000000
--- a/sources/pyside2/PySide2/QtCore/glue/qobject_connect.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-static bool isDecorator(PyObject* method, PyObject* self)
-{
- Shiboken::AutoDecRef methodName(PyObject_GetAttrString(method, "__name__"));
- if (!PyObject_HasAttr(self, methodName))
- return true;
- Shiboken::AutoDecRef otherMethod(PyObject_GetAttr(self, methodName));
- return PyMethod_GET_FUNCTION(otherMethod.object()) != PyMethod_GET_FUNCTION(method);
-}
-
-static bool getReceiver(QObject *source, const char* signal, PyObject* callback, QObject** receiver, PyObject** self, QByteArray* callbackSig)
-{
- bool forceGlobalReceiver = false;
- if (PyMethod_Check(callback)) {
- *self = PyMethod_GET_SELF(callback);
- if (%CHECKTYPE[QObject*](*self))
- *receiver = %CONVERTTOCPP[QObject*](*self);
- forceGlobalReceiver = isDecorator(callback, *self);
- } else if (PyCFunction_Check(callback)) {
- *self = PyCFunction_GET_SELF(callback);
- if (*self && %CHECKTYPE[QObject*](*self))
- *receiver = %CONVERTTOCPP[QObject*](*self);
- } else if (PyCallable_Check(callback)) {
- // Ok, just a callable object
- *receiver = 0;
- *self = 0;
- }
-
- bool usingGlobalReceiver = !*receiver || forceGlobalReceiver;
-
- // Check if this callback is a overwrite of a non-virtual Qt slot.
- if (!usingGlobalReceiver && receiver && self) {
- *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1();
- const QMetaObject* metaObject = (*receiver)->metaObject();
- int slotIndex = metaObject->indexOfSlot(callbackSig->constData());
- if (slotIndex != -1 && slotIndex < metaObject->methodOffset() && PyMethod_Check(callback))
- usingGlobalReceiver = true;
- }
-
- if (usingGlobalReceiver) {
- PySide::SignalManager& signalManager = PySide::SignalManager::instance();
- *receiver = signalManager.globalReceiver(source, callback);
- *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1();
- }
-
- return usingGlobalReceiver;
-}
-
-static bool qobjectConnect(QObject* source, const char* signal, QObject* receiver, const char* slot, Qt::ConnectionType type)
-{
- if (!signal || !slot)
- return false;
-
- if (!PySide::Signal::checkQtSignal(signal))
- return false;
- signal++;
-
- if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal))
- return false;
-
- bool isSignal = PySide::Signal::isQtSignal(slot);
- slot++;
- PySide::SignalManager::registerMetaMethod(receiver, slot, isSignal ? QMetaMethod::Signal : QMetaMethod::Slot);
- bool connection;
- Py_BEGIN_ALLOW_THREADS
- connection = QObject::connect(source, signal - 1, receiver, slot - 1, type);
- Py_END_ALLOW_THREADS
- return connection;
-}
-
-static bool qobjectConnect(QObject* source, QMetaMethod signal, QObject* receiver, QMetaMethod slot, Qt::ConnectionType type)
-{
- return qobjectConnect(source, signal.methodSignature(), receiver, slot.methodSignature(), type);
-}
-
-static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject* callback, Qt::ConnectionType type)
-{
- if (!signal || !PySide::Signal::checkQtSignal(signal))
- return false;
- signal++;
-
- int signalIndex = PySide::SignalManager::registerMetaMethodGetIndex(source, signal, QMetaMethod::Signal);
- if (signalIndex == -1)
- return false;
-
- PySide::SignalManager& signalManager = PySide::SignalManager::instance();
-
- // Extract receiver from callback
- QObject* receiver = 0;
- PyObject* self = 0;
- QByteArray callbackSig;
- bool usingGlobalReceiver = getReceiver(source, signal, callback, &receiver, &self, &callbackSig);
- if (receiver == 0 && self == 0)
- return false;
-
- const QMetaObject* metaObject = receiver->metaObject();
- const char* slot = callbackSig.constData();
- int slotIndex = metaObject->indexOfSlot(slot);
- QMetaMethod signalMethod = metaObject->method(signalIndex);
-
- if (slotIndex == -1) {
- if (!usingGlobalReceiver && self && !Shiboken::Object::hasCppWrapper((SbkObject*)self)) {
- qWarning() << "You can't add dynamic slots on an object originated from C++.";
- if (usingGlobalReceiver)
- signalManager.releaseGlobalReceiver(source, receiver);
-
- return false;
- }
-
- if (usingGlobalReceiver)
- slotIndex = signalManager.globalReceiverSlotIndex(receiver, slot);
- else
- slotIndex = PySide::SignalManager::registerMetaMethodGetIndex(receiver, slot, QMetaMethod::Slot);
-
- if (slotIndex == -1) {
- if (usingGlobalReceiver)
- signalManager.releaseGlobalReceiver(source, receiver);
-
- return false;
- }
- }
- bool connection;
- Py_BEGIN_ALLOW_THREADS
- connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type);
- Py_END_ALLOW_THREADS
- if (connection) {
- if (usingGlobalReceiver)
- signalManager.notifyGlobalReceiver(receiver);
- #ifndef AVOID_PROTECTED_HACK
- source->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char*
- #else
- // Need to cast to QObjectWrapper* and call the public version of
- // connectNotify when avoiding the protected hack.
- reinterpret_cast<QObjectWrapper*>(source)->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char*
- #endif
-
- return connection;
- }
-
- if (usingGlobalReceiver)
- signalManager.releaseGlobalReceiver(source, receiver);
-
- return false;
-}
-
-
-static bool qobjectDisconnectCallback(QObject* source, const char* signal, PyObject* callback)
-{
- if (!PySide::Signal::checkQtSignal(signal))
- return false;
-
- PySide::SignalManager& signalManager = PySide::SignalManager::instance();
-
- // Extract receiver from callback
- QObject* receiver = 0;
- PyObject* self = 0;
- QByteArray callbackSig;
- QMetaMethod slotMethod;
- bool usingGlobalReceiver = getReceiver(NULL, signal, callback, &receiver, &self, &callbackSig);
- if (receiver == 0 && self == 0)
- return false;
-
- const QMetaObject* metaObject = receiver->metaObject();
- int signalIndex = source->metaObject()->indexOfSignal(++signal);
- int slotIndex = -1;
-
- slotIndex = metaObject->indexOfSlot(callbackSig);
- slotMethod = metaObject->method(slotIndex);
-
- bool disconnected;
- Py_BEGIN_ALLOW_THREADS
- disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex);
- Py_END_ALLOW_THREADS
-
- if (disconnected) {
- if (usingGlobalReceiver)
- signalManager.releaseGlobalReceiver(source, receiver);
-
- #ifndef AVOID_PROTECTED_HACK
- source->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char*
- #else
- // Need to cast to QObjectWrapper* and call the public version of
- // connectNotify when avoiding the protected hack.
- reinterpret_cast<QObjectWrapper*>(source)->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char*
- #endif
- return true;
- }
- return false;
-}
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 48f234f2b..c70049d8e 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -40,78 +40,59 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtCore">
- <load-typesystem name="typesystem_templates.xml" generate="no"/>
-
- <custom-type name="str" />
- <custom-type name="PyBytes" />
- <custom-type name="PyByteArray" />
- <custom-type name="PyCallable" />
- <custom-type name="PyObject" />
- <custom-type name="PySequence" />
- <custom-type name="PyTypeObject" />
- <custom-type name="PyUnicode" />
- <custom-type name="list of QAbstractAnimation" />
- <custom-type name="list of QAbstractState" />
-
- <function signature="qAcos(qreal)" />
- <function signature="qAsin(qreal)" since="4.6" />
- <function signature="qAtan(qreal)" since="4.6" />
- <function signature="qAtan2(qreal,qreal)" since="4.6" />
- <function signature="qChecksum(const char*,uint)" />
- <function signature="qExp(qreal)" since="4.6" />
- <function signature="qFabs(qreal)" since="4.6" />
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+
+ <custom-type name="str"/>
+ <custom-type name="PyBytes"/>
+ <custom-type name="PyByteArray"/>
+ <custom-type name="PyCallable"/>
+ <custom-type name="PyObject"/>
+ <custom-type name="PySequence"/>
+ <custom-type name="PyTypeObject"/>
+ <custom-type name="PyUnicode"/>
+ <custom-type name="list of QAbstractAnimation"/>
+ <custom-type name="list of QAbstractState"/>
+
+ <function signature="qAcos(qreal)"/>
+ <function signature="qAsin(qreal)" since="4.6"/>
+ <function signature="qAtan(qreal)" since="4.6"/>
+ <function signature="qAtan2(qreal,qreal)" since="4.6"/>
+ <function signature="qChecksum(const char*,uint)"/>
+ <function signature="qExp(qreal)" since="4.6"/>
+ <function signature="qFabs(qreal)" since="4.6"/>
<function signature="qFastCos(qreal)" since="4.6"/>
- <function signature="qFastSin(qreal)" since="4.6" />
- <function signature="qFuzzyCompare(double,double)" />
- <function signature="qFuzzyIsNull(double)" since="4.6" />
- <function signature="qIsFinite(double)" />
- <function signature="qIsInf(double)" />
- <function signature="qIsNaN(double)" />
- <function signature="qIsNull(double)" />
- <!-- Qt5: gone <function signature="qRound(qreal)" /> -->
- <function signature="qTan(qreal)" since="4.6" />
- <function signature="qtTrId(const char*,int)" since="4.6" />
- <function signature="qVersion()" />
- <function signature="qrand()" />
- <function signature="qsrand(uint)" />
+ <function signature="qFastSin(qreal)" since="4.6"/>
+ <function signature="qFuzzyCompare(double,double)"/>
+ <function signature="qFuzzyIsNull(double)" since="4.6"/>
+ <function signature="qIsFinite(double)"/>
+ <function signature="qIsInf(double)"/>
+ <function signature="qIsNaN(double)"/>
+ <function signature="qIsNull(double)"/>
+ <!-- Qt5: gone <function signature="qRound(qreal)"/> -->
+ <function signature="qTan(qreal)" since="4.6"/>
+ <function signature="qtTrId(const char*,int)" since="4.6"/>
+ <function signature="qVersion()"/>
+ <function signature="qrand()"/>
+ <function signature="qsrand(uint)"/>
<function signature="qCompress(const uchar*,int,int)"/>
<function signature="qCompress(const QByteArray&amp;,int)"/>
<function signature="qUncompress(const uchar*,int)"/>
<function signature="qUncompress(const QByteArray&amp;)"/>
- <inject-code class="native" position="beginning">
- #include &lt;pyside.h&gt;
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="include-pyside"/>
- <template name="use_stream_for_format_security">
- // Uses the stream version for security reasons
- // see gcc man page at -Wformat-security
- %FUNCTION_NAME() &lt;&lt; %1;
- </template>
<add-function signature="qDebug(const char*)">
- <inject-code>
- <insert-template name="use_stream_for_format_security" />
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/>
</add-function>
<add-function signature="qCritical(const char*)">
- <inject-code>
- <insert-template name="use_stream_for_format_security" />
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/>
</add-function>
<add-function signature="qFatal(const char*)">
- <inject-code>
- // qFatal doesn't have a stream version, so we do a
- // qWarning call followed by a qFatal() call using a
- // literal.
- qWarning() &lt;&lt; %1;
- qFatal("[A qFatal() call was made from Python code]");
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qfatal"/>
</add-function>
<add-function signature="qWarning(const char*)">
- <inject-code>
- <insert-template name="use_stream_for_format_security" />
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="use-stream-for-format-security"/>
</add-function>
<!-- TODO: We do not support void* or const void* as arg -->
@@ -127,9 +108,9 @@
<rejection class="QChildEvent" field-name="c"/>
<rejection class="QTimerEvent" field-name="id"/>
<rejection class="QEvent" field-name="t"/>
- <rejection class="*" function-name="tr" />
- <rejection class="*" function-name="trUtf8" />
- <rejection class="*" function-name="qt_metacast" />
+ <rejection class="*" function-name="tr"/>
+ <rejection class="*" function-name="trUtf8"/>
+ <rejection class="*" function-name="qt_metacast"/>
<!-- From Qt4.6 -->
<rejection class="*" field-name="d_ptr"/>
<rejection class="*" field-name="staticQtMetaObject"/>
@@ -144,7 +125,7 @@
<rejection class="*" function-name="qReallocAligned"/>
<rejection class="*" function-name="qMallocAligned"/>
<rejection class="*" function-name="qFreeAligned"/>
- <rejection class="QMetaMethod" enum-name="Attributes" />
+ <rejection class="QMetaMethod" enum-name="Attributes"/>
<rejection class="*" argument-type="QByteArrayDataPtr"/>
<rejection class="*" argument-type="^qfloat16&amp;?$"/>
@@ -180,6 +161,8 @@
<enum-type name="QtMsgType"/>
+ <enum-type name="QCborSimpleType" since="5.12"/>
+ <enum-type name="QCborKnownTags" since="5.12"/>
<primitive-type name="qint8"/>
<primitive-type name="qint16"/>
@@ -195,13 +178,13 @@
<primitive-type name="qint64"/>
<primitive-type name="unsigned long long"/>
<primitive-type name="long long"/>
- <primitive-type name="qlonglong" target-lang-api-name="PyLong" />
- <primitive-type name="qulonglong" target-lang-api-name="PyLong" />
+ <primitive-type name="qlonglong" target-lang-api-name="PyLong"/>
+ <primitive-type name="qulonglong" target-lang-api-name="PyLong"/>
<primitive-type name="short"/>
<primitive-type name="signed short"/>
<primitive-type name="signed short int"/>
- <primitive-type name="ushort" target-lang-api-name="PyInt" />
- <primitive-type name="unsigned short int" />
+ <primitive-type name="ushort" target-lang-api-name="PyInt"/>
+ <primitive-type name="unsigned short int"/>
<primitive-type name="unsigned short"/>
<primitive-type name="char"/>
<primitive-type name="signed char"/>
@@ -215,7 +198,7 @@
<primitive-type name="signed long"/>
<primitive-type name="signed long int"/>
<primitive-type name="long"/>
- <primitive-type name="unsigned long int" />
+ <primitive-type name="unsigned long int"/>
<primitive-type name="unsigned long">
<!-- FIXME APIExtractor or shiboken do not support multiple includes by primitive type -->
<include file-name="signalmanager.h" location="global"/>
@@ -223,13 +206,9 @@
<primitive-type name="bool" target-lang-api-name="PyBool">
<conversion-rule>
- <native-to-target>
- return PyBool_FromLong((bool)%in);
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pybool"/>
<target-to-native>
- <add-conversion type="PyBool">
- %out = %OUTTYPE(%in == Py_True);
- </add-conversion>
+ <add-conversion type="PyBool" file="../glue/qtcore.cpp" snippet="conversion-pybool"/>
</target-to-native>
</conversion-rule>
</primitive-type>
@@ -237,453 +216,152 @@
<!-- Qt5: add the new pointer-ish types -->
<primitive-type name="qintptr" target-lang-api-name="PyLong">
<conversion-rule>
- <native-to-target>
- return PyLong_FromLong(%in);
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pylong"/>
<target-to-native>
- <add-conversion type="PyLong">
- %out = %OUTTYPE(PyLong_AsLong(%in));
- </add-conversion>
+ <add-conversion type="PyLong" file="../glue/qtcore.cpp" snippet="conversion-pylong"/>
</target-to-native>
</conversion-rule>
</primitive-type>
<primitive-type name="quintptr" target-lang-api-name="PyLong">
<conversion-rule>
- <native-to-target>
- return PyLong_FromUnsignedLong(%in);
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pylong-unsigned"/>
<target-to-native>
- <add-conversion type="PyLong">
- %out = %OUTTYPE(PyLong_AsUnsignedLong(%in));
- </add-conversion>
+ <add-conversion type="PyLong" file="../glue/qtcore.cpp" snippet="conversion-pylong-unsigned"/>
</target-to-native>
</conversion-rule>
</primitive-type>
<primitive-type name="qptrdiff" target-lang-api-name="PyLong">
<conversion-rule>
- <native-to-target>
- return PyLong_FromLong(%in);
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pylong"/>
<target-to-native>
- <add-conversion type="PyLong">
- %out = %OUTTYPE(PyLong_AsLong(%in));
- </add-conversion>
+ <add-conversion type="PyLong" file="../glue/qtcore.cpp" snippet="conversion-pylong"/>
</target-to-native>
</conversion-rule>
</primitive-type>
- <inject-code class="native" position="beginning">
- bool py2kStrCheck(PyObject *obj)
- {
- #ifdef IS_PY3K
- return false;
- #else
- return PyString_Check(obj);
- #endif
- }
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="pystring-check"/>
<primitive-type name="QString" target-lang-api-name="PyUnicode">
<include file-name="QString" location="global"/>
<conversion-rule>
- <native-to-target>
- QByteArray ba = %in.toUtf8();
- PyObject *%out = PyUnicode_FromStringAndSize(ba.constData(), ba.size());
- return %out;
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode"/>
<target-to-native>
- <add-conversion type="PyUnicode">
- #ifndef Py_LIMITED_API
- Py_UNICODE* unicode = PyUnicode_AS_UNICODE(%in);
- # if defined(Py_UNICODE_WIDE)
- // cast as Py_UNICODE can be a different type
- %out = QString::fromUcs4((const uint*)unicode);
- # else
- %out = QString::fromUtf16((const ushort*)unicode, PyUnicode_GET_SIZE(%in));
- # endif
- #else
- wchar_t *temp = PyUnicode_AsWideCharString(%in, NULL);
- %out = QString::fromWCharArray(temp);
- PyMem_Free(temp);
- #endif
- </add-conversion>
- <add-conversion type="PyString" check="py2kStrCheck(%in)">
- #ifndef IS_PY3K
- const char* str = %CONVERTTOCPP[const char*](%in);
- %out = %OUTTYPE(str);
- #endif
- </add-conversion>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
+ <add-conversion type="PyUnicode" file="../glue/qtcore.cpp" snippet="conversion-pyunicode"/>
+ <add-conversion type="PyString" check="py2kStrCheck(%in)" file="../glue/qtcore.cpp" snippet="conversion-pystring"/>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
</target-to-native>
</conversion-rule>
</primitive-type>
<primitive-type name="QStringRef">
<conversion-rule>
- <native-to-target>
- const int N = %in.toString().length();
- wchar_t *str = new wchar_t[N];
- %in.toString().toWCharArray(str);
- PyObject *%out = PyUnicode_FromWideChar(str, N);
- delete[] str;
- return %out;
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode-qstringref"/>
</conversion-rule>
</primitive-type>
<primitive-type name="QChar">
<conversion-rule>
- <native-to-target>
- wchar_t c = (wchar_t)%in.unicode();
- return PyUnicode_FromWideChar(&amp;c, 1);
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-pyunicode-qchar"/>
<target-to-native>
- <add-conversion type="PyString" check="Shiboken::String::checkChar(%in)">
- char c = %CONVERTTOCPP[char](%in);
- %out = %OUTTYPE(c);
- </add-conversion>
- <add-conversion type="PyInt">
- int i = %CONVERTTOCPP[int](%in);
- %out = %OUTTYPE(i);
- </add-conversion>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
+ <add-conversion type="PyString" check="Shiboken::String::checkChar(%in)" file="../glue/qtcore.cpp" snippet="conversion-pystring-char"/>
+ <add-conversion type="PyInt" file="../glue/qtcore.cpp" snippet="conversion-pyint"/>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
</target-to-native>
</conversion-rule>
</primitive-type>
<primitive-type name="QVariant" target-lang-api-name="PyObject">
<conversion-rule>
- <native-to-target>
- if (!%in.isValid())
- Py_RETURN_NONE;
-
- if (qstrcmp(%in.typeName(), "QVariantList") == 0) {
- QList&lt;QVariant&gt; var = %in.value&lt;QVariantList&gt;();
- return %CONVERTTOPYTHON[QList&lt;QVariant&gt;](var);
- }
-
- if (qstrcmp(%in.typeName(), "QStringList") == 0) {
- QStringList var = %in.value&lt;QStringList&gt;();
- return %CONVERTTOPYTHON[QList&lt;QString&gt;](var);
- }
-
- if (qstrcmp(%in.typeName(), "QVariantMap") == 0) {
- QMap&lt;QString, QVariant&gt; var = %in.value&lt;QVariantMap&gt;();
- return %CONVERTTOPYTHON[QMap&lt;QString, QVariant&gt;](var);
- }
-
- Shiboken::Conversions::SpecificConverter converter(cppInRef.typeName());
- if (converter) {
- void *ptr = cppInRef.data();
- return converter.toPython(ptr);
- }
- PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName());
- return 0;
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qvariant"/>
<target-to-native>
- <add-conversion type="PyBool">
- %out = %OUTTYPE(%in == Py_True);
- </add-conversion>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
- <add-conversion type="QString" check="Shiboken::String::check(%in)">
- QString in = %CONVERTTOCPP[QString](%in);
- %out = %OUTTYPE(in);
- </add-conversion>
- <add-conversion type="QByteArray">
- QByteArray in = %CONVERTTOCPP[QByteArray](%in);
- %out = %OUTTYPE(in);
- </add-conversion>
- <add-conversion type="PyFloat" check="PyFloat_CheckExact(%in)">
- double in = %CONVERTTOCPP[double](%in);
- %out = %OUTTYPE(in);
- </add-conversion>
+ <add-conversion type="PyBool" file="../glue/qtcore.cpp" snippet="conversion-pybool"/>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="QString" check="Shiboken::String::check(%in)" file="../glue/qtcore.cpp" snippet="conversion-qstring"/>
+ <add-conversion type="QByteArray" file="../glue/qtcore.cpp" snippet="conversion-qbytearray"/>
+ <add-conversion type="PyFloat" check="PyFloat_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-pyfloat"/>
<!-- Using PyLong instead of PyInt to support Python2 and 3-->
- <add-conversion type="PyInt" check="PyInt_CheckExact(%in)">
- qlonglong in = %CONVERTTOCPP[qlonglong](%in);
- %out = %OUTTYPE(in);
- </add-conversion>
- <add-conversion type="PyLong" check="PyLong_CheckExact(%in)">
- qlonglong in = %CONVERTTOCPP[qlonglong](%in);
- %out = %OUTTYPE(in);
- </add-conversion>
- <add-conversion type="SbkEnumType">
- int in = %CONVERTTOCPP[int](%in);
- %out = %OUTTYPE(in);
- </add-conversion>
- <add-conversion type="SbkObject">
- // a class supported by QVariant?
- int typeCode;
- const char *typeName = QVariant_resolveMetaType(Py_TYPE(%in), &amp;typeCode);
- if (!typeCode || !typeName)
- return;
- QVariant var(typeCode, (void*)0);
- Shiboken::Conversions::SpecificConverter converter(typeName);
- converter.toCpp(pyIn, var.data());
- %out = var;
- </add-conversion>
- <add-conversion type="PyDict" check="PyDict_CheckExact(%in)">
- QVariant ret = QVariant_convertToVariantMap(%in);
- %out = ret.isValid() ? ret : QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
- </add-conversion>
- <add-conversion type="PyList" check="PyList_Check(%in)">
- QVariant ret = QVariant_convertToVariantList(%in);
- %out = ret.isValid() ? ret : QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
- </add-conversion>
- <add-conversion type="PyObject">
- // Is a shiboken type not known by Qt
- %out = QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
- </add-conversion>
+ <add-conversion type="PyInt" check="PyInt_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-qlonglong"/>
+ <add-conversion type="PyLong" check="PyLong_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-qlonglong"/>
+ <add-conversion type="SbkEnumType" file="../glue/qtcore.cpp" snippet="conversion-pyint"/>
+ <add-conversion type="SbkObject" file="../glue/qtcore.cpp" snippet="conversion-sbkobject"/>
+ <add-conversion type="PyDict" check="PyDict_CheckExact(%in)" file="../glue/qtcore.cpp" snippet="conversion-pydict"/>
+ <add-conversion type="PyList" check="PyList_Check(%in)" file="../glue/qtcore.cpp" snippet="conversion-pylist"/>
+ <add-conversion type="PyObject" file="../glue/qtcore.cpp" snippet="conversion-pyobject"/>
</target-to-native>
</conversion-rule>
</primitive-type>
- <inject-code class="native" position="beginning">
- static const char *QVariant_resolveMetaType(PyTypeObject *type, int *typeId)
- {
- if (PyObject_TypeCheck(type, SbkObjectType_TypeF())) {
- SbkObjectType* sbkType = (SbkObjectType*)type;
- const char* typeName = Shiboken::ObjectType::getOriginalName(sbkType);
- if (!typeName)
- return 0;
- bool valueType = '*' != typeName[qstrlen(typeName) - 1];
- // Do not convert user type of value
- if (valueType &amp;&amp; Shiboken::ObjectType::isUserType(type))
- return 0;
- int obTypeId = QMetaType::type(typeName);
- if (obTypeId) {
- *typeId = obTypeId;
- return typeName;
- }
- // Do not resolve types to value type
- if (valueType)
- return 0;
- // Find in base types. First check tp_bases, and only after check tp_base, because
- // tp_base does not always point to the first base class, but rather to the first
- // that has added any python fields or slots to its object layout.
- // See https://mail.python.org/pipermail/python-list/2009-January/520733.html
- if (type->tp_bases) {
- for (int i = 0; i &lt; PyTuple_GET_SIZE(type->tp_bases); ++i) {
- const char *derivedName = QVariant_resolveMetaType(reinterpret_cast&lt;PyTypeObject *&gt;(PyTuple_GET_ITEM(
- type->tp_bases, i)), typeId);
- if (derivedName)
- return derivedName;
- }
- }
- else if (type->tp_base) {
- return QVariant_resolveMetaType(type->tp_base, typeId);
- }
- }
- *typeId = 0;
- return 0;
- }
- static QVariant QVariant_convertToValueList(PyObject *list)
- {
- if (PySequence_Size(list) &lt; 0) {
- // clear the error if &lt; 0 which means no length at all
- PyErr_Clear();
- return QVariant();
- }
-
- Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
- int typeId;
- const char *typeName = QVariant_resolveMetaType(element.cast&lt;PyTypeObject*&gt;(), &amp;typeId);
- if (typeName) {
- QByteArray listTypeName("QList&lt;");
- listTypeName += typeName;
- listTypeName += '>';
- typeId = QMetaType::type(listTypeName);
- if (typeId &gt; 0) {
- Shiboken::Conversions::SpecificConverter converter(listTypeName);
- if (converter) {
- QVariant var(typeId, (void*)0);
- converter.toCpp(list, &amp;var);
- return var;
- }
- qWarning() &lt;&lt; "Type converter for :" &lt;&lt; listTypeName &lt;&lt; "not registered.";
- }
- }
- return QVariant();
- }
- static bool QVariant_isStringList(PyObject *list)
- {
- bool allString = true;
-
- if (PySequence_Check(list)) {
- if (PySequence_Size(list) &lt; 0) {
- // clear the error if &lt; 0 which means no length at all
- PyErr_Clear();
- return false;
- }
- Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
- Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
- for (int i = 0; i &lt; size; ++i) {
- PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
- if (!%CHECKTYPE[QString](item)) {
- allString = false;
- break;
- }
- }
- } else {
- // If it is not a list or a derived list class
- // we assume that will not be a String list neither.
- allString = false;
- }
- return allString;
- }
- static QVariant QVariant_convertToVariantMap(PyObject *map)
- {
- Py_ssize_t pos = 0;
- Shiboken::AutoDecRef keys(PyDict_Keys(map));
- if (!QVariant_isStringList(keys))
- return QVariant();
- PyObject *key;
- PyObject *value;
- QMap&lt;QString,QVariant&gt; ret;
- while (PyDict_Next(map, &amp;pos, &amp;key, &amp;value)) {
- QString cppKey = %CONVERTTOCPP[QString](key);
- QVariant cppValue = %CONVERTTOCPP[QVariant](value);
- ret.insert(cppKey, cppValue);
- }
- return QVariant(ret);
- }
- static QVariant QVariant_convertToVariantList(PyObject *list)
- {
- if (QVariant_isStringList(list)) {
- QList&lt;QString &gt; lst = %CONVERTTOCPP[QList&lt;QString&gt;](list);
- return QVariant(QStringList(lst));
- }
- QVariant valueList = QVariant_convertToValueList(list);
- if (valueList.isValid())
- return valueList;
-
- if (PySequence_Size(list) &lt; 0) {
- // clear the error if &lt; 0 which means no length at all
- PyErr_Clear();
- return QVariant();
- }
-
- QList&lt;QVariant&gt; lst;
- Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
- Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
- for (int i = 0; i &lt; size; ++i) {
- PyObject *pyItem = PySequence_Fast_GET_ITEM(fast.object(), i);
- QVariant item = %CONVERTTOCPP[QVariant](pyItem);
- lst.append(item);
- }
- return QVariant(lst);
- }
- </inject-code>
-
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qvariant-conversion"/>
<primitive-type name="QVariant::Type" default-constructor="QVariant::Invalid">
<conversion-rule>
- <native-to-target>
- const char *typeName = QVariant::typeToName(%in);
- PyObject *%out;
- PyTypeObject *pyType = nullptr;
- if (typeName)
- pyType = Shiboken::Conversions::getPythonTypeObject(typeName);
- %out = pyType ? (reinterpret_cast&lt;PyObject*&gt;(pyType)) : Py_None;
- Py_INCREF(%out);
- return %out;
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qvariant-type"/>
<target-to-native>
- <add-conversion type="Py_None">
- %out = QVariant::Invalid;
- </add-conversion>
- <add-conversion type="PyTypeObject">
- const char *typeName;
- if (Shiboken::String::checkType(reinterpret_cast&lt;PyTypeObject *&gt;(%in)))
- typeName = "QString";
- else if (%in == reinterpret_cast&lt;PyObject*&gt;(&amp;PyFloat_Type))
- typeName = "double"; // float is a UserType in QVariant.
- else if (%in == reinterpret_cast&lt;PyObject*&gt;(&amp;PyLong_Type))
- typeName = "int"; // long is a UserType in QVariant.
- else if (Py_TYPE(%in) == SbkObjectType_TypeF())
- typeName = Shiboken::ObjectType::getOriginalName((SbkObjectType*)%in);
- else
- typeName = reinterpret_cast&lt;PyTypeObject *&gt;(%in)->tp_name;
- %out = QVariant::nameToType(typeName);
- </add-conversion>
- <add-conversion type="PyString" check="Shiboken::String::check(%in)">
- %out = QVariant::nameToType(Shiboken::String::toCString(%in));
- </add-conversion>
- <add-conversion type="PyDict" check="PyDict_Check(%in) &amp;&amp; QVariantType_checkAllStringKeys(%in)">
- %out = QVariant::nameToType("QVariantMap");
- </add-conversion>
- <add-conversion type="PySequence">
- %out = QVariantType_isStringList(%in) ? QVariant::StringList : QVariant::List;
- </add-conversion>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-qvariant-invalid"/>
+ <add-conversion type="PyTypeObject" file="../glue/qtcore.cpp" snippet="conversion-qvariant-pytypeobject"/>
+ <add-conversion type="PyString" check="Shiboken::String::check(%in)" file="../glue/qtcore.cpp" snippet="conversion-qvariant-pystring"/>
+ <add-conversion type="PyDict" check="PyDict_Check(%in) &amp;&amp; QVariantType_checkAllStringKeys(%in)" file="../glue/qtcore.cpp" snippet="conversion-qvariant-pydict"/>
+ <add-conversion type="PySequence" file="../glue/qtcore.cpp" snippet="conversion-qvariant-pysequence"/>
</target-to-native>
</conversion-rule>
</primitive-type>
<primitive-type name="QVariantMap" target-lang-api-name="PyDict"/>
- <inject-code class="target" position="end">
- Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QMAP_QSTRING_QVARIANT_IDX], "QVariantMap");
- </inject-code>
-
- <inject-code class="native" position="beginning">
- static bool QVariantType_isStringList(PyObject *list)
- {
- bool allString = true;
- Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
- Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
- for (int i=0; i &lt; size; i++) {
- PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
- if (!%CHECKTYPE[QString](item)) {
- allString = false;
- break;
- }
- }
- return allString;
- }
- static bool QVariantType_checkAllStringKeys(PyObject *dict)
- {
- Shiboken::AutoDecRef keys(PyDict_Keys(dict));
- return QVariantType_isStringList(keys);
- }
- </inject-code>
-
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qvariantmap-register"/>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qvariantmap-check"/>
<primitive-type name="QStringList">
<include file-name="QStringList" location="global"/>
<conversion-rule>
<native-to-target>
<insert-template name="cpplist_to_pylist_conversion">
- <replace from="%INTYPE_0" to="QString" />
+ <replace from="%INTYPE_0" to="QString"/>
</insert-template>
</native-to-target>
<target-to-native>
<add-conversion type="PySequence">
<insert-template name="pyseq_to_cpplist_conversion">
- <replace from="%OUTTYPE_0" to="QString" />
+ <replace from="%OUTTYPE_0" to="QString"/>
</insert-template>
</add-conversion>
</target-to-native>
</conversion-rule>
</primitive-type>
+ <value-type name="QCborError" since="5.12">
+ <enum-type name="Code"/>
+ <include file-name="qcborcommon.h" location="global"/>
+ </value-type>
+
+ <value-type name="QCborParserError" since="5.12">
+ <include file-name="qcborvalue.h" location="global"/>
+ </value-type>
+
+ <value-type name="QCborValue" since="5.12">
+ <enum-type name="EncodingOption" flags="EncodingOptions"/>
+ <enum-type name="DiagnosticNotationOption" flags="DiagnosticNotationOptions"/>
+ <enum-type name="Type"/>
+ </value-type>
+ <value-type name="QCborArray" since="5.12"/>
+ <value-type name="QCborMap" since="5.12"/>
+
+ <object-type name="QCborStreamReader" since="5.12">
+ <enum-type name="StringResultCode"/>
+ <enum-type name="Type"/>
+ <include file-name="qcborstream.h" location="global"/>
+ <value-type name="StringResult" generate="no"/>
+ <!-- 64bit (qsizetype = long long) -->
+ <modify-function signature="readStringChunk(char*,long long)" remove="all"/>
+ <!-- 32bit (qsizetype = int) -->
+ <modify-function signature="readStringChunk(char*,int)" remove="all"/>
+ </object-type>
+ <typedef-type name="QCborStringResultString" source="QCborStreamReader::StringResult&lt;QString&gt;" since="5.12"/>
+ <typedef-type name="QCborStringResultByteArray" source="QCborStreamReader::StringResult&lt;QByteArray&gt;" since="5.12"/>
+ <object-type name="QCborStreamWriter" since="5.12">
+ <include file-name="qcborstream.h" location="global"/>
+ </object-type>
+
<primitive-type name="QJsonObject">
<conversion-rule>
- <native-to-target>
- // The QVariantMap returned by QJsonObject seems to cause a segfault, so
- // using QJsonObject.toVariantMap() won't work.
- // Wrapping it in a QJsonValue first allows it to work
- QJsonValue val(%in);
- QVariant ret = val.toVariant();
-
- return %CONVERTTOPYTHON[QVariant](ret);
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qjsonobject"/>
<target-to-native>
- <add-conversion type="PyDict">
- QVariant dict = QVariant_convertToVariantMap(%in);
- QJsonValue val = QJsonValue::fromVariant(dict);
-
- %out = val.toObject();
- </add-conversion>
+ <add-conversion type="PyDict" file="../glue/qtcore.cpp" snippet="conversion-qjsonobject-pydict"/>
</target-to-native>
</conversion-rule>
</primitive-type>
@@ -693,13 +371,13 @@
<conversion-rule>
<native-to-target>
<insert-template name="cpplist_to_pylist_conversion">
- <replace from="%INTYPE_0" to="QModelIndex" />
+ <replace from="%INTYPE_0" to="QModelIndex"/>
</insert-template>
</native-to-target>
<target-to-native>
<add-conversion type="PySequence">
<insert-template name="pyseq_to_cpplist_conversion">
- <replace from="%OUTTYPE_0" to="QModelIndex" />
+ <replace from="%OUTTYPE_0" to="QModelIndex"/>
</insert-template>
</add-conversion>
</target-to-native>
@@ -791,30 +469,6 @@
</conversion-rule>
</container-type>
- <template name="cppmap_to_pymap_conversion">
- PyObject *%out = PyDict_New();
- for (%INTYPE::const_iterator it = %in.begin(), end = %in.end(); it != end; ++it) {
- %INTYPE_0 key = it.key();
- %INTYPE_1 value = it.value();
- PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
- PyObject *pyValue = %CONVERTTOPYTHON[%INTYPE_1](value);
- PyDict_SetItem(%out, pyKey, pyValue);
- Py_DECREF(pyKey);
- Py_DECREF(pyValue);
- }
- return %out;
- </template>
- <template name="pydict_to_cppmap_conversion">
- PyObject *key;
- PyObject *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(%in, &amp;pos, &amp;key, &amp;value)) {
- %OUTTYPE_0 cppKey = %CONVERTTOCPP[%OUTTYPE_0](key);
- %OUTTYPE_1 cppValue = %CONVERTTOCPP[%OUTTYPE_1](value);
- %out.insert(cppKey, cppValue);
- }
- </template>
-
<container-type name="QHash" type="hash">
<include file-name="QHash" location="global"/>
<!-- Include to make enum flags work. -->
@@ -860,17 +514,9 @@
<container-type name="QPair" type="pair">
<include file-name="QPair" location="global"/>
<conversion-rule>
- <native-to-target>
- PyObject *%out = PyTuple_New(2);
- PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first));
- PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second));
- return %out;
- </native-to-target>
+ <native-to-target file="../glue/qtcore.cpp" snippet="return-qpair"/>
<target-to-native>
- <add-conversion type="PySequence">
- %out.first = %CONVERTTOCPP[%OUTTYPE_0](PySequence_Fast_GET_ITEM(%in, 0));
- %out.second = %CONVERTTOCPP[%OUTTYPE_1](PySequence_Fast_GET_ITEM(%in, 1));
- </add-conversion>
+ <add-conversion type="PySequence" file="../glue/qtcore.cpp" snippet="conversion-qpair-pysequence"/>
</target-to-native>
</conversion-rule>
</container-type>
@@ -907,9 +553,6 @@
<rejection class="" enum-name="QtValidLicenseForGuiModule"/>
<rejection class="" enum-name="QtValidLicenseForScriptModule"/>
<rejection class="" enum-name="QtValidLicenseForHelpModule"/>
- <rejection class="QAbstractEventDispatcher" function-name="filterEvent"/>
- <rejection class="QAbstractEventDispatcher" function-name="filterNativeEvent"/>
- <rejection class="QAbstractEventDispatcher" function-name="setEventFilter"/>
<!-- Internal -->
<rejection class="QAbstractFileEngine"/> <!--
<rejection class="QAbstractFileEngine" function-name="endEntryList"/>
@@ -926,8 +569,8 @@
<rejection class="Qt" function-name="qt_getEnumName"/>
<namespace-type name="Qt">
- <enum-type name="AlignmentFlag" flags="Alignment" />
- <enum-type name="AnchorPoint" since="4.6" />
+ <enum-type name="AlignmentFlag" flags="Alignment"/>
+ <enum-type name="AnchorPoint" since="4.6"/>
<enum-type name="ApplicationAttribute"/>
<enum-type name="ApplicationState" flags="ApplicationStates" since="5.1"/>
<enum-type name="ArrowType"/>
@@ -943,10 +586,10 @@
<enum-type name="ContextMenuPolicy"/>
<enum-type name="CoordinateSystem" since="4.6"/>
<enum-type name="Corner"/>
- <enum-type name="CursorShape" />
- <enum-type name="DateFormat" />
+ <enum-type name="CursorShape"/>
+ <enum-type name="DateFormat"/>
<enum-type name="DayOfWeek"/>
- <enum-type name="DockWidgetArea" flags="DockWidgetAreas" />
+ <enum-type name="DockWidgetArea" flags="DockWidgetAreas"/>
<enum-type name="DockWidgetAreaSizes"/>
<enum-type name="DropAction" flags="DropActions"/>
<enum-type name="Edge" flags="Edges" since="5.1"/>
@@ -960,15 +603,15 @@
<enum-type name="GestureType" since="4.6"/>
<enum-type name="GlobalColor"/>
<enum-type name="HitTestAccuracy"/>
- <enum-type name="ImageConversionFlag" flags="ImageConversionFlags" />
+ <enum-type name="ImageConversionFlag" flags="ImageConversionFlags"/>
<enum-type name="InputMethodHint" flags="InputMethodHints" since="4.6"/>
- <enum-type name="InputMethodQuery" flags="InputMethodQueries" />
- <enum-type name="EnterKeyType" since="5.6" />
- <enum-type name="ItemDataRole" force-integer="yes" />
+ <enum-type name="InputMethodQuery" flags="InputMethodQueries"/>
+ <enum-type name="EnterKeyType" since="5.6"/>
+ <enum-type name="ItemDataRole"/>
<enum-type name="ItemFlag" flags="ItemFlags"/>
<enum-type name="ItemSelectionMode"/>
- <enum-type name="ItemSelectionOperation" since="5.5" />
- <enum-type name="Key" />
+ <enum-type name="ItemSelectionOperation" since="5.5"/>
+ <enum-type name="Key"/>
<enum-type name="KeyboardModifier" flags="KeyboardModifiers"/>
<enum-type name="LayoutDirection"/>
<enum-type name="MaskMode"/>
@@ -990,7 +633,7 @@
<enum-type name="SizeHint"/>
<enum-type name="SizeMode"/>
<enum-type name="SortOrder"/>
- <enum-type name="TabFocusBehavior" since="5.5" />
+ <enum-type name="TabFocusBehavior" since="5.5"/>
<enum-type name="TextElideMode"/>
<enum-type name="TextFlag"/>
<enum-type name="TextFormat"/>
@@ -998,155 +641,46 @@
<enum-type name="TileRule" since="4.6"/>
<enum-type name="TimerType" since="5.0"/>
<enum-type name="TimeSpec"/>
- <enum-type name="ToolBarArea" flags="ToolBarAreas" />
+ <enum-type name="ToolBarArea" flags="ToolBarAreas"/>
<enum-type name="ToolBarAreaSizes"/>
<enum-type name="ToolButtonStyle"/>
<enum-type name="TouchPointState" flags="TouchPointStates" since="4.6"/>
<enum-type name="TransformationMode"/>
<enum-type name="UIEffect"/>
- <enum-type name="WhiteSpaceMode" />
- <enum-type name="WidgetAttribute" />
+ <enum-type name="WhiteSpaceMode"/>
+ <enum-type name="WidgetAttribute"/>
<enum-type name="WindowFrameSection"/>
<enum-type name="WindowModality"/>
<enum-type name="WindowState" flags="WindowStates"/>
<enum-type name="WindowType" flags="WindowFlags"/>
<enum-type name="CursorMoveStyle" since="4.8" revision="4800"/>
- <!--### These functions are part of QtGui, not QtCore -->
- <modify-function signature="codecForHtml(const QByteArray&amp;)" remove="all"/>
- <modify-function signature="mightBeRichText(const QString&amp;)" remove="all"/>
- <modify-function signature="convertFromPlainText(const QString&amp;,Qt::WhiteSpaceMode)" remove="all"/>
- <!--### -->
</namespace-type>
<add-function signature="qAbs(double)" return-type="double">
- <inject-code class="target" position="beginning">
- double _abs = qAbs(%1);
- %PYARG_0 = %CONVERTTOPYTHON[double](_abs);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qabs"/>
</add-function>
- <inject-code class="native" position="beginning">
- namespace PySide {
- static QStack&lt;PyObject*&gt; globalPostRoutineFunctions;
- void globalPostRoutineCallback()
- {
- Shiboken::GilState state;
- foreach(PyObject *callback, globalPostRoutineFunctions) {
- Shiboken::AutoDecRef result(PyObject_CallObject(callback, NULL));
- Py_DECREF(callback);
- }
- globalPostRoutineFunctions.clear();
- }
- void addPostRoutine(PyObject *callback)
- {
- if (PyCallable_Check(callback)) {
- globalPostRoutineFunctions &lt;&lt; callback;
- Py_INCREF(callback);
- } else {
- PyErr_SetString(PyExc_TypeError, "qAddPostRoutine: The argument must be a callable object.");
- }
- }
- } // namespace
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qt-postroutine"/>
<add-function signature="qAddPostRoutine(PyObject*)">
- <inject-code class="target" position="beginning">
- PySide::addPostRoutine(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-addpostroutine"/>
</add-function>
- <inject-code class="target" position="end">
- qAddPostRoutine(PySide::globalPostRoutineCallback);
- </inject-code>
-
- <inject-code class="target" position="end">
- QList&lt;QByteArray&gt; version = QByteArray(qVersion()).split('.');
- PyObject *pyQtVersion = PyTuple_New(3);
- for (int i = 0; i &lt; 3; ++i)
- PyTuple_SET_ITEM(pyQtVersion, i, PyInt_FromLong(version[i].toInt()));
- PyModule_AddObject(module, "__version_info__", pyQtVersion);
- PyModule_AddStringConstant(module, "__version__", qVersion());
- </inject-code>
-
- <inject-code class="target" position="end">
- { // Avoid name clash
- Shiboken::AutoDecRef regFunc((PyObject*)NULL);
- Shiboken::AutoDecRef atexit(Shiboken::Module::import("atexit"));
- if (atexit.isNull()) {
- qWarning() &lt;&lt; "Module atexit not found for registering __moduleShutdown";
- PyErr_Clear();
- }else{
- regFunc = PyObject_GetAttrString(atexit, "register");
- if (regFunc.isNull()) {
- qWarning() &lt;&lt; "Function atexit.register not found for registering __moduleShutdown";
- PyErr_Clear();
- }
- }
- if (!atexit.isNull() &amp;&amp; !regFunc.isNull()){
- PyObject *shutDownFunc = PyObject_GetAttrString(module, "__moduleShutdown");
- Shiboken::AutoDecRef args(PyTuple_New(1));
- PyTuple_SET_ITEM(args, 0, shutDownFunc);
- Shiboken::AutoDecRef retval(PyObject_Call(regFunc, args, 0));
- Q_ASSERT(!retval.isNull());
- }
- }
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-qaddpostroutine"/>
+
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-version"/>
+ <!-- WARNING: There is an issue when adding this code to an external file -->
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-module-shutdown"/>
<add-function signature="__moduleShutdown()">
- <inject-code class="target" position="beginning">
- PySide::runCleanupFunctions();
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="moduleshutdown"/>
</add-function>
<!--signal/slot-->
- <inject-code class="target" position="end">
- Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode");
- Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "str");
- Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList");
-
- PySide::registerInternalQtConf();
- PySide::init(module);
- Py_AtExit(QtCoreModuleExit);
- </inject-code>
-
- <inject-code class="native" position="beginning">
- // Define a global variable to handle qInstallMessageHandler callback
- static PyObject *qtmsghandler = nullptr;
-
- static void msgHandlerCallback(QtMsgType type, const QMessageLogContext &amp;ctx, const QString &amp;msg)
- {
- Shiboken::GilState state;
- Shiboken::AutoDecRef arglist(PyTuple_New(3));
- PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QtMsgType](type));
- PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMessageLogContext &amp;](ctx));
- QByteArray array = msg.toLatin1().data();
- char *data = array.data();
- PyTuple_SET_ITEM(arglist, 2, %CONVERTTOPYTHON[char *](data));
- Shiboken::AutoDecRef ret(PyObject_CallObject(qtmsghandler, arglist));
- }
- static void QtCoreModuleExit()
- {
- PySide::SignalManager::instance().clear();
- }
- </inject-code>
- <add-function signature="qInstallMessageHandler(PyObject)" return-type="PyObject">
- <inject-code class="target" position="beginning">
- if (%PYARG_1 == Py_None) {
- qInstallMessageHandler(0);
- %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None;
- qtmsghandler = 0;
- } else if (!PyCallable_Check(%PYARG_1)) {
- PyErr_SetString(PyExc_TypeError, "parameter must be callable");
- } else {
- %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None;
- Py_INCREF(%PYARG_1);
- qtmsghandler = %PYARG_1;
- qInstallMessageHandler(msgHandlerCallback);
- }
-
- if (%PYARG_0 == Py_None)
- Py_INCREF(%PYARG_0);
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qt-pysideinit"/>
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qt-messagehandler"/>
+ <add-function signature="qInstallMessageHandler(PyObject)" return-type="PyObject">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-installmessagehandler"/>
</add-function>
<value-type name="QElapsedTimer" since="4.7">
@@ -1163,8 +697,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i, %i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()" />
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1172,35 +706,29 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="iiii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()" />
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
</insert-template>
</inject-code>
</add-function>
- <inject-code class="native" position="beginning">
- namespace PySide {
- template&lt;&gt; inline uint hash(const QLine &amp;v) {
- return qHash(qMakePair(qMakePair(v.x1(), v.y1()), qMakePair(v.x2(), v.y2())));
- }
- };
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qline-hash"/>
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="iiii" />
- <replace from="%TT_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()" />
+ <replace from="%TT_FORMAT" to="iiii"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
</insert-template>
</inject-code>
</add-function>
</value-type>
<value-type name="QLineF">
- <enum-type name="IntersectType" />
+ <enum-type name="IntersectType"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1208,8 +736,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dddd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()" />
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1217,8 +745,8 @@
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="dddd" />
- <replace from="%TT_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()" />
+ <replace from="%TT_FORMAT" to="dddd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x1(), %CPPSELF.y1(), %CPPSELF.x2(), %CPPSELF.y2()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1227,15 +755,9 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="(intersectType, intersectionPoint)" />
+ <replace-type modified-type="(intersectType, intersectionPoint)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- QPointF p;
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;p);
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QPointF](p));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qlinef-intersect"/>
</modify-function>
</value-type>
<object-type name="QResource">
@@ -1244,74 +766,37 @@
Returns a read only buffer object pointing to the segment of data that this resource represents. If the resource is compressed the data returns is compressed and qUncompress() must be used to access the data. If the resource is a directory None is returned.
</inject-documentation>
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code>
- const void *d = %CPPSELF.%FUNCTION_NAME();
- if (d) {
- %PYARG_0 = Shiboken::Buffer::newObject(d, %CPPSELF.size());
- } else {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qresource-data"/>
</modify-function>
- <template name="QResource_registerResource">
- uchar *ptr = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1));
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast&lt;const uchar*&gt;(ptr), %2);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </template>
<modify-function signature="unregisterResource(const uchar*,const QString&amp;)" rename="unregisterResourceData">
<modify-argument index="1">
<replace-type modified-type="PyBuffer"/>
</modify-argument>
- <inject-code>
- <insert-template name="QResource_registerResource" />
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qresource-registerResource"/>
</modify-function>
<modify-function signature="registerResource(const uchar*,const QString&amp;)" rename="registerResourceData">
<modify-argument index="1">
<replace-type modified-type="PyBuffer"/>
</modify-argument>
- <inject-code>
- <insert-template name="QResource_registerResource" />
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qresource-registerResource"/>
</modify-function>
</object-type>
<value-type name="QBasicTimer"/>
<value-type name="QByteArrayMatcher"/>
<value-type name="QDate" hash-function="PySide::hash" >
- <template name="pydatetime_importandcheck_function">
- #ifdef IS_PY3K
- #define PySideDateTime_IMPORT PyDateTime_IMPORT
- #else
- #define PySideDateTime_IMPORT \
- (PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import((char*)"datetime", \
- (char*)"datetime_CAPI"))
- #endif
- static bool PyDateTime_ImportAndCheck(PyObject *pyIn) {
- if (!PyDateTimeAPI) PySideDateTime_IMPORT;
- return $DATETIMETYPE_Check(pyIn);
- }
- </template>
<inject-code class="native" position="beginning">
<insert-template name="pydatetime_importandcheck_function">
- <replace from="$DATETIMETYPE" to="PyDate" />
+ <replace from="$DATETIMETYPE" to="PyDate"/>
</insert-template>
</inject-code>
<conversion-rule>
<target-to-native>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
- <add-conversion type="PyDate" check="PyDateTime_ImportAndCheck(%in)">
- int day = PyDateTime_GET_DAY(%in);
- int month = PyDateTime_GET_MONTH(%in);
- int year = PyDateTime_GET_YEAR(%in);
- %out = %OUTTYPE(year, month, day);
- </add-conversion>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyDate" check="PyDateTime_ImportAndCheck(%in)" file="../glue/qtcore.cpp" snippet="conversion-qdate-pydate"/>
</target-to-native>
</conversion-rule>
<extra-includes>
@@ -1321,8 +806,8 @@
<add-function signature="__repr__" return-type="PyObject">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()" />
+ <replace from="%REPR_FORMAT" to="%i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1330,17 +815,13 @@
<add-function signature="__reduce__" return-type="PyObject">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="iii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()" />
+ <replace from="%REDUCE_FORMAT" to="iii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="toPython()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- if (!PyDateTimeAPI)
- PySideDateTime_IMPORT;
- %PYARG_0 = PyDate_FromDate(%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day());
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdate-topython"/>
</add-function>
<modify-function signature="getDate(int*,int*,int*)" >
<modify-argument index="1">
@@ -1355,16 +836,7 @@
<modify-argument index="return">
<replace-type modified-type="(year, month, day)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int year, month, day;
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(&amp;year, &amp;month, &amp;day);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(3);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](year));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](month));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](day));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdate-getdate"/>
</modify-function>
<modify-function signature="weekNumber(int*)const" >
<modify-argument index="1">
@@ -1373,38 +845,19 @@
<modify-argument index="return">
<replace-type modified-type="(week, yearNumber)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int yearNumber;
- %BEGIN_ALLOW_THREADS
- int week = %CPPSELF.%FUNCTION_NAME(&amp;yearNumber);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](week));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](yearNumber));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdate-weeknumber"/>
</modify-function>
</value-type>
<value-type name="QDateTime" hash-function="PySide::hash">
<inject-code class="native" position="beginning">
<insert-template name="pydatetime_importandcheck_function">
- <replace from="$DATETIMETYPE" to="PyDateTime" />
+ <replace from="$DATETIMETYPE" to="PyDateTime"/>
</insert-template>
</inject-code>
<conversion-rule>
<target-to-native>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
- <add-conversion type="PyDateTime" check="PyDateTime_ImportAndCheck(%in)">
- int day = PyDateTime_GET_DAY(%in);
- int month = PyDateTime_GET_MONTH(%in);
- int year = PyDateTime_GET_YEAR(%in);
- int hour = PyDateTime_DATE_GET_HOUR(%in);
- int min = PyDateTime_DATE_GET_MINUTE(%in);
- int sec = PyDateTime_DATE_GET_SECOND(%in);
- int usec = PyDateTime_DATE_GET_MICROSECOND(%in);
- %out = %OUTTYPE(QDate(year, month, day), QTime(hour, min, sec, usec/1000));
- </add-conversion>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyDateTime" check="PyDateTime_ImportAndCheck(%in)" file="../glue/qtcore.cpp" snippet="conversion-qdatetime-pydatetime"/>
</target-to-native>
</conversion-rule>
<extra-includes>
@@ -1415,52 +868,39 @@
<modify-argument index="8">
<replace-default-expression with="Qt::LocalTime"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- QDate date(%1, %2, %3);
- QTime time(%4, %5, %6, %7);
- %0 = new %TYPE(date, time, Qt::TimeSpec(%8));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-1"/>
</add-function>
<add-function signature="QDateTime(int,int,int,int,int,int)">
- <inject-code class="target" position="beginning">
- QDate date(%1, %2, %3);
- QTime time(%4, %5, %6);
- %0 = new %TYPE(date, time);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-2"/>
</add-function>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i, %i, %i, %i, %i, %i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.date().year(), %CPPSELF.date().month(), %CPPSELF.date().day(), %CPPSELF.time().hour(), %CPPSELF.time().minute(), %CPPSELF.time().second(), %CPPSELF.time().msec(), (int)%CPPSELF.timeSpec()" />
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i, %i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.date().year(), %CPPSELF.date().month(), %CPPSELF.date().day(), %CPPSELF.time().hour(), %CPPSELF.time().minute(), %CPPSELF.time().second(), %CPPSELF.time().msec(), (int)%CPPSELF.timeSpec()"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="iiiiiiii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.date().year(), %CPPSELF.date().month(), %CPPSELF.date().day(), %CPPSELF.time().hour(), %CPPSELF.time().minute(), %CPPSELF.time().second(), %CPPSELF.time().msec(), (int)%CPPSELF.timeSpec()" />
+ <replace from="%REDUCE_FORMAT" to="iiiiiiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.date().year(), %CPPSELF.date().month(), %CPPSELF.date().day(), %CPPSELF.time().hour(), %CPPSELF.time().minute(), %CPPSELF.time().second(), %CPPSELF.time().msec(), (int)%CPPSELF.timeSpec()"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="toPython()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- QDate date = %CPPSELF.date();
- QTime time = %CPPSELF.time();
- if (!PyDateTimeAPI) PySideDateTime_IMPORT;
- %PYARG_0 = PyDateTime_FromDateAndTime(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.msec()*1000);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qdatetime-topython"/>
</add-function>
</value-type>
<value-type name="QDir">
<enum-type name="Filter" flags="Filters"/>
- <enum-type name="SortFlag" flags="SortFlags" />
+ <enum-type name="SortFlag" flags="SortFlags"/>
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="s" />
- <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.path())" />
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.path())"/>
</insert-template>
</inject-code>
</add-function>
@@ -1470,8 +910,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%REPR_FORMAT" to="%i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1479,24 +919,18 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="ii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%REDUCE_FORMAT" to="ii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
- <inject-code class="native" position="beginning">
- namespace PySide {
- template&lt;&gt; inline uint hash(const QPoint &amp;v) {
- return qHash(qMakePair(v.x(), v.y()));
- }
- };
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qpoint"/>
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="ii" />
- <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%TT_FORMAT" to="ii"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1510,8 +944,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%REPR_FORMAT" to="%f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1519,8 +953,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%REDUCE_FORMAT" to="dd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1528,8 +962,8 @@
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="dd" />
- <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%TT_FORMAT" to="dd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1543,30 +977,24 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i, %i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="iiii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
- <inject-code class="native" position="beginning">
- namespace PySide {
- template&lt;&gt; inline uint hash(const QRect &amp;v) {
- return qHash(qMakePair(qMakePair(v.x(), v.y()), qMakePair(v.width(), v.height())));
- }
- };
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qrect"/>
<modify-function signature="getCoords(int*,int*,int*,int*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument />
@@ -1582,13 +1010,13 @@
</modify-argument>
<inject-code class="target">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getRect(int*,int*,int*,int*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument />
@@ -1604,7 +1032,7 @@
</modify-argument>
<inject-code class="target">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
@@ -1613,8 +1041,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1626,14 +1054,14 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dddd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
<modify-function signature="getCoords(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument />
@@ -1649,13 +1077,13 @@
</modify-argument>
<inject-code class="target">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getRect(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument />
@@ -1671,7 +1099,7 @@
</modify-argument>
<inject-code class="target">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -1680,8 +1108,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REPR_FORMAT" to="%i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1689,24 +1117,18 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="ii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REDUCE_FORMAT" to="ii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
- <inject-code class="native" position="beginning">
- namespace PySide {
- template&lt;&gt; inline uint hash(const QSize &amp;v) {
- return qHash(qMakePair(v.width(), v.height()));
- }
- };
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qsize"/>
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="ii" />
- <replace from="%TT_ARGS" to="%CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%TT_FORMAT" to="ii"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1720,8 +1142,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REPR_FORMAT" to="%f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1729,8 +1151,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%REDUCE_FORMAT" to="dd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
@@ -1738,36 +1160,28 @@
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="dd" />
- <replace from="%TT_ARGS" to="%CPPSELF.width(), %CPPSELF.height()" />
+ <replace from="%TT_FORMAT" to="dd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.width(), %CPPSELF.height()"/>
</insert-template>
</inject-code>
</add-function>
<!--### Functions removed because they return references to Python imutable objects -->
- <modify-function signature="rheight()" remove="all" />
- <modify-function signature="rwidth()" remove="all" />
+ <modify-function signature="rheight()" remove="all"/>
+ <modify-function signature="rwidth()" remove="all"/>
<!--### -->
</value-type>
<value-type name="QTime" hash-function="PySide::hash">
<inject-code class="native" position="beginning">
<insert-template name="pydatetime_importandcheck_function">
- <replace from="$DATETIMETYPE" to="PyTime" />
+ <replace from="$DATETIMETYPE" to="PyTime"/>
</insert-template>
</inject-code>
<conversion-rule>
<target-to-native>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
- <add-conversion type="PyTime" check="PyDateTime_ImportAndCheck(%in)">
- int hour = PyDateTime_TIME_GET_HOUR(%in);
- int min = PyDateTime_TIME_GET_MINUTE(%in);
- int sec = PyDateTime_TIME_GET_SECOND(%in);
- int usec = PyDateTime_TIME_GET_MICROSECOND(%in);
- %out = %OUTTYPE(hour, min, sec, usec/1000);
- </add-conversion>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyTime" check="PyDateTime_ImportAndCheck(%in)" file="../glue/qtcore.cpp" snippet="conversion-qtime-pytime"/>
</target-to-native>
</conversion-rule>
@@ -1778,33 +1192,24 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i, %i, %i" />
- <replace from="%REPR_ARGS" to="%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()" />
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="iiii" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()" />
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="toPython()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- if (!PyDateTimeAPI)
- PySideDateTime_IMPORT;
- %PYARG_0 = PyTime_FromTime(%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()*1000);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtime-topython"/>
</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"/>
@@ -1825,32 +1230,32 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="'%s'" />
- <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.toString())" />
+ <replace from="%REPR_FORMAT" to="'%s'"/>
+ <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.toString())"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="s" />
- <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.toString())" />
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.toString())"/>
</insert-template>
</inject-code>
</add-function>
</value-type>
- <value-type name="QMimeType" since="5.0" />
+ <value-type name="QMimeType" since="5.0"/>
<object-type name="QMimeDatabase" since="5.0">
- <enum-type name="MatchMode" />
+ <enum-type name="MatchMode"/>
</object-type>
<value-type name="QLocale">
- <enum-type name="Country" />
+ <enum-type name="Country"/>
<enum-type name="DataSizeFormat" flags="DataSizeFormats" since="5.10"/>
<enum-type name="FloatingPointPrecisionOption" since="5.7"/>
<enum-type name="FormatType"/>
- <enum-type name="Language" />
+ <enum-type name="Language"/>
<enum-type name="MeasurementSystem"/>
<enum-type name="NumberOption" flags="NumberOptions"/>
<enum-type name="Script" since="4.8" revision="4800"/>
@@ -1866,12 +1271,12 @@
</extra-includes>
<modify-function signature="toTime(QString,QLocale::FormatType)const">
<modify-argument index="2">
- <rename to="format" />
+ <rename to="format"/>
</modify-argument>
</modify-function>
<modify-function signature="toDate(QString,QLocale::FormatType)const">
<modify-argument index="2">
- <rename to="format" />
+ <rename to="format"/>
</modify-argument>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions, int arg is gone -->
@@ -1885,7 +1290,7 @@
<replace-type modified-type="(int, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions, int arg is gone -->
@@ -1899,7 +1304,7 @@
<replace-type modified-type="(int, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions -->
@@ -1913,7 +1318,7 @@
<replace-type modified-type="(float, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions -->
@@ -1927,7 +1332,7 @@
<replace-type modified-type="(float, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions, int arg is gone -->
@@ -1940,7 +1345,7 @@
<replace-type modified-type="(int, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions, int arg is gone -->
@@ -1953,7 +1358,7 @@
<replace-type modified-type="(int, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions, int arg is gone -->
@@ -1966,7 +1371,7 @@
<replace-type modified-type="(int, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- Qt5: ignore the new QStringRef versions, int arg is gone -->
@@ -1979,34 +1384,19 @@
<replace-type modified-type="(int, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
</value-type>
<value-type name="QBitArray" hash-function="qHash" >
<add-function signature="__len__">
- <inject-code class="target" position="beginning">
- return %CPPSELF.size();
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbitarray-len"/>
</add-function>
<add-function signature="__getitem__">
- <inject-code class="target" position="beginning">
- if (_i &lt; 0 || _i >= %CPPSELF.size()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return 0;
- }
- bool ret = %CPPSELF.at(_i);
- return %CONVERTTOPYTHON[bool](ret);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbitarray-getitem"/>
</add-function>
<add-function signature="__setitem__">
- <inject-code class="target" position="beginning">
- PyObject *args = Py_BuildValue("(iiO)", _i, 1, _value);
- PyObject *result = Sbk_QBitArrayFunc_setBit(self, args);
- Py_DECREF(args);
- Py_XDECREF(result);
- return !result ? -1 : 0;
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbitarray-setitem"/>
</add-function>
</value-type>
<object-type name="QLockFile">
@@ -2029,12 +1419,10 @@
<reference-count action="set"/>
</modify-argument>
</modify-function>
- <modify-function signature="relock()" allow-thread="yes" />
- <add-function signature="__enter__()" />
+ <modify-function signature="relock()" allow-thread="yes"/>
+ <add-function signature="__enter__()"/>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
- <inject-code>
- %CPPSELF.unlock();
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
</add-function>
</object-type>
<object-type name="QWriteLocker">
@@ -2043,12 +1431,10 @@
<reference-count action="set"/>
</modify-argument>
</modify-function>
- <modify-function signature="relock()" allow-thread="yes" />
- <add-function signature="__enter__()" />
+ <modify-function signature="relock()" allow-thread="yes"/>
+ <add-function signature="__enter__()"/>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
- <inject-code>
- %CPPSELF.unlock();
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
</add-function>
</object-type>
<object-type name="QDirIterator">
@@ -2057,56 +1443,30 @@
<object-type name="QThread">
<enum-type name="Priority"/>
<modify-function signature="currentThreadId()" remove="all"/>
- <modify-function signature="run()" thread="yes" />
- <modify-function signature="exec()" rename="exec_" allow-thread="yes" />
- <modify-function signature="msleep(unsigned long)" allow-thread="yes" />
- <modify-function signature="sleep(unsigned long)" allow-thread="yes" />
- <modify-function signature="usleep(unsigned long)" allow-thread="yes" />
- <modify-function signature="wait(unsigned long)" allow-thread="yes" />
+ <modify-function signature="run()" thread="yes"/>
+ <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="msleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="sleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="usleep(unsigned long)" allow-thread="yes"/>
+ <modify-function signature="wait(unsigned long)" allow-thread="yes"/>
<modify-function signature="start(QThread::Priority)" allow-thread="yes">
<modify-argument index="1">
<rename to="priority"/>
</modify-argument>
</modify-function>
- <modify-function signature="exit(int)" allow-thread="yes" />
+ <modify-function signature="exit(int)" allow-thread="yes"/>
</object-type>
<object-type name="QAbstractItemModel">
- <enum-type name="CheckIndexOption" flags="CheckIndexOptions" class="yes" 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"/>
+ <enum-type name="CheckIndexOption" flags="CheckIndexOptions" since="5.11"/>
+ <enum-type name="LayoutChangeHint"/>
<!-- 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" />
+ <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">
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, %PYARG_3);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
- <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">
- qRegisterMetaType&lt;QVector&lt;int&gt; &gt;("QVector&lt;int&gt;");
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qabstractitemmodel"/>
<modify-function signature="mimeData(QModelIndexList)const">
<modify-argument index="return">
<define-ownership class="native" owner="c++"/>
@@ -2132,7 +1492,6 @@
<value-type name="QItemSelectionRange" hash-function="qHash">
</value-type>
- <primitive-type name="QModelIndexList"/>
<object-type name="QAbstractProxyModel" polymorphic-id-expression="qobject_cast&lt;QAbstractProxyModel*&gt;(%1)">
<extra-includes>
<include file-name="QItemSelection" location="global"/>
@@ -2141,9 +1500,6 @@
</extra-includes>
</object-type>
<object-type name="QSortFilterProxyModel">
- <!-- ### This reimplementation of "QObject::parent()" is used in C++ only
- when "using QObject::parent;" is not available. It's useless in Python. -->
- <modify-function signature="parent()const" remove="all"/>
<extra-includes>
<include file-name="QItemSelection" location="global"/>
<include file-name="QStringList" location="global"/>
@@ -2165,13 +1521,10 @@
<extra-includes>
<include file-name="QThread" location="global"/>
<include file-name="QCoreApplication" location="global"/>
- <include file-name="signalmanager.h" location="local" />
+ <include file-name="signalmanager.h" location="local"/>
</extra-includes>
<modify-function signature="metaObject()const">
- <inject-code class="target" position="beginning">
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-metaobject"/>
<modify-argument index="return">
<reference-count action="set"/>
</modify-argument>
@@ -2216,92 +1569,57 @@
<modify-argument index="4">
<rename to="type"/>
</modify-argument>
- <inject-code class="target" position="beginning" file="">
- // %FUNCTION_NAME() - disable generation of function call.
- bool %0 = qobjectConnect(%1, %2, %CPPSELF, %3, %4);
- %PYARG_0 = %CONVERTTOPYTHON[bool](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-1"/>
</modify-function>
<!-- static version -->
<modify-function signature="connect(const QObject*,QMetaMethod,const QObject*,QMetaMethod,Qt::ConnectionType)">
<modify-argument index="5">
<rename to="type"/>
</modify-argument>
- <inject-code class="target" position="beginning" file="">
- // %FUNCTION_NAME() - disable generation of function call.
- bool %0 = qobjectConnect(%1, %2, %3, %4, %5);
- %PYARG_0 = %CONVERTTOPYTHON[bool](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-2"/>
</modify-function>
<modify-function signature="connect(const QObject*,const char*,const QObject*,const char*,Qt::ConnectionType)">
<modify-argument index="5">
<rename to="type"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of function call.
- bool %0 = qobjectConnect(%1, %2, %3, %4, %5);
- %PYARG_0 = %CONVERTTOPYTHON[bool](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-3"/>
</modify-function>
- <inject-code class="native" position="beginning" file="glue/qobject_connect.cpp" />
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect"/>
<add-function signature="connect(const QObject*,const char*,PyCallable*,Qt::ConnectionType)" return-type="bool" static="yes">
<modify-argument index="4">
<rename to="type"/>
- <replace-default-expression with="Qt::AutoConnection" />
+ <replace-default-expression with="Qt::AutoConnection"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of function call.
- %RETURN_TYPE %0 = qobjectConnectCallback(%1, %2, %PYARG_3, %4);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-4"/>
</add-function>
<!-- static version -->
<add-function signature="connect(const char*,PyCallable*,Qt::ConnectionType)" return-type="bool">
<modify-argument index="3">
<rename to="type"/>
- <replace-default-expression with="Qt::AutoConnection" />
+ <replace-default-expression with="Qt::AutoConnection"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of function call.
- %RETURN_TYPE %0 = qobjectConnectCallback(%CPPSELF, %1, %PYARG_2, %3);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-5"/>
</add-function>
<add-function signature="connect(const char*,const QObject*,const char*,Qt::ConnectionType)" return-type="bool">
<modify-argument index="4">
<rename to="type"/>
- <replace-default-expression with="Qt::AutoConnection" />
+ <replace-default-expression with="Qt::AutoConnection"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of function call.
- %RETURN_TYPE %0 = qobjectConnect(%CPPSELF, %1, %2, %3, %4);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-connect-6"/>
</add-function>
<add-function signature="emit(const char*,...)" return-type="bool">
- <inject-code class="target" position="beginning">
- %RETURN_TYPE %0 = PySide::SignalManager::instance().emitSignal(%CPPSELF, %1, %PYARG_2);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-emit"/>
</add-function>
<add-function signature="disconnect(const char*,PyCallable*)" return-type="bool">
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of function call.
- %RETURN_TYPE %0 = qobjectDisconnectCallback(%CPPSELF, %1, %2);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-disconnect-1"/>
</add-function>
<add-function signature="disconnect(const QObject*,const char*,PyCallable*)" return-type="bool" static="yes">
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of function call.
- %RETURN_TYPE %0 = qobjectDisconnectCallback(%1, %2, %3);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-disconnect-2"/>
</add-function>
- <inject-code class="native" file="glue/qobject_findchild.cpp"/>
+ <inject-code class="native" file="../glue/qtcore.cpp" snippet="qobject-findchild-1"/>
<add-function signature="findChild(PyTypeObject*,const QString&amp;)" return-type="PyObject*">
<inject-documentation format="target" mode="append">
To find the child of a certain QObject, the first argument of this function should be the child's type, and the second the name of the child:
@@ -2316,37 +1634,28 @@
child2 = parent.findChild(QWidget, "child_widget")
</inject-documentation>
- <inject-code class="target" position="beginning">
- QObject *child = _findChildHelper(%CPPSELF, %2, (PyTypeObject*)%PYARG_1);
- %PYARG_0 = %CONVERTTOPYTHON[QObject*](child);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchild-2"/>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
<modify-argument index="2">
- <replace-default-expression with="QString()" />
+ <replace-default-expression with="QString()"/>
</modify-argument>
</add-function>
<add-function signature="findChildren(PyTypeObject*,const QString&amp;)" return-type="PySequence*" >
<inject-documentation format="target" mode="append">
Like the method *findChild*, the first parameter should be the child's type.
</inject-documentation>
- <inject-code class="target" position="beginning">
- %PYARG_0 = PyList_New(0);
- _findChildrenHelper(%CPPSELF, %2, (PyTypeObject*)%PYARG_1, %PYARG_0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchildren-1"/>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
<modify-argument index="2">
- <replace-default-expression with="QString()" />
+ <replace-default-expression with="QString()"/>
</modify-argument>
</add-function>
<add-function signature="findChildren(PyTypeObject*,const QRegExp&amp;)" return-type="PySequence*" >
- <inject-code class="target" position="beginning">
- %PYARG_0 = PyList_New(0);
- _findChildrenHelper(%CPPSELF, %2, (PyTypeObject*)%PYARG_1, %PYARG_0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-findchildren-2"/>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
@@ -2360,33 +1669,11 @@
<replace-default-expression with="-1"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- QString result;
- if (QCoreApplication::instance()) {
- PyObject *klass = PyObject_GetAttrString(%PYSELF, "__class__");
- PyObject *cname = PyObject_GetAttrString(klass, "__name__");
- result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname),
- /* %1, %2, QCoreApplication::CodecForTr, %3)); */
- %1, %2, %3));
-
- Py_DECREF(klass);
- Py_DECREF(cname);
- } else {
- result = QString(QString::fromLatin1(%1));
- }
- %PYARG_0 = %CONVERTTOPYTHON[QString](result);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-tr"/>
</add-function>
<modify-function signature="receivers(const char*)const">
- <inject-code class="target" position="beginning">
- // Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife
- int ret = %CPPSELF.%FUNCTION_NAME(%1);
- if (ret > 0 &amp;&amp; ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0)))
- ret -= PySide::SignalManager::instance().countConnectionsWith(%CPPSELF);
-
- %PYARG_0 = %CONVERTTOPYTHON[int](ret);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qobject-receivers"/>
</modify-function>
<modify-function signature="destroyed(QObject*)">
@@ -2420,12 +1707,12 @@
<include file-name="QSize" location="global"/>
</extra-includes>
</object-type>
- <value-type name="QUrlQuery" since="5.0" />
+ <value-type name="QUrlQuery" since="5.0"/>
<value-type name="QUrl" hash-function="PySide::hash">
<!-- Qt5: lots of changes -->
<enum-type name="ComponentFormattingOption" flags="ComponentFormattingOptions,FormattingOptions"/>
<!-- note: above duplication of attribute is not by default XML compliant! -->
- <enum-type name="UrlFormattingOption" />
+ <enum-type name="UrlFormattingOption"/>
<enum-type name="UserInputResolutionOption" flags="UserInputResolutionOptions"/>
<enum-type name="ParsingMode"/>
<extra-includes>
@@ -2434,8 +1721,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="'%s'" />
- <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.toString())" />
+ <replace from="%REPR_FORMAT" to="'%s'"/>
+ <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.toString())"/>
</insert-template>
</inject-code>
</add-function>
@@ -2443,8 +1730,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="s" />
- <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.toString())" />
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.toString())"/>
</insert-template>
</inject-code>
</add-function>
@@ -2458,8 +1745,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="'%s', %i, %i" />
- <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.pattern()), (int)%CPPSELF.caseSensitivity(), (int)%CPPSELF.patternSyntax()" />
+ <replace from="%REPR_FORMAT" to="'%s', %i, %i"/>
+ <replace from="%REPR_ARGS" to="qPrintable(%CPPSELF.pattern()), (int)%CPPSELF.caseSensitivity(), (int)%CPPSELF.patternSyntax()"/>
</insert-template>
</inject-code>
</add-function>
@@ -2467,8 +1754,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="sii" />
- <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.pattern()), (int)%CPPSELF.caseSensitivity(), (int)%CPPSELF.patternSyntax()" />
+ <replace from="%REDUCE_FORMAT" to="sii"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.pattern()), (int)%CPPSELF.caseSensitivity(), (int)%CPPSELF.patternSyntax()"/>
</insert-template>
</inject-code>
</add-function>
@@ -2502,10 +1789,7 @@
# t == "A \\emph{bon mot}."
</inject-documentation>
- <inject-code class="target" position="beginning">
- %1.replace(*%CPPSELF, %2);
- %PYARG_0 = %CONVERTTOPYTHON[QString](%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qregexp-replace"/>
</add-function>
</value-type>
@@ -2525,8 +1809,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="s" />
- <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.filePath())" />
+ <replace from="%REDUCE_FORMAT" to="s"/>
+ <replace from="%REDUCE_ARGS" to="qPrintable(%CPPSELF.filePath())"/>
</insert-template>
</inject-code>
</add-function>
@@ -2535,22 +1819,10 @@
<enum-type name="Base64Option" flags="Base64Options" since="5.2"/>
<conversion-rule>
<target-to-native>
- <add-conversion type="Py_None">
- %out = %OUTTYPE();
- </add-conversion>
- <add-conversion type="PyBytes">
- #ifdef IS_PY3K
- %out = %OUTTYPE(PyBytes_AS_STRING(%in), PyBytes_GET_SIZE(%in));
- #else
- %out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in));
- #endif
- </add-conversion>
- <add-conversion type="PyByteArray">
- %out = %OUTTYPE(PyByteArray_AsString(%in), PyByteArray_Size(%in));
- </add-conversion>
- <add-conversion type="PyString" check="Shiboken::String::check(%in) &amp;&amp; !PyUnicode_Check(%in)">
- %out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in));
- </add-conversion>
+ <add-conversion type="Py_None" file="../glue/qtcore.cpp" snippet="conversion-pynone"/>
+ <add-conversion type="PyBytes" file="../glue/qtcore.cpp" snippet="conversion-qbytearray-pybytes"/>
+ <add-conversion type="PyByteArray" file="../glue/qtcore.cpp" snippet="conversion-qbytearray-pybytearray"/>
+ <add-conversion type="PyString" check="Shiboken::String::check(%in) &amp;&amp; !PyUnicode_Check(%in)" file="../glue/qtcore.cpp" snippet="conversion-qbytearray-pystring"/>
</target-to-native>
</conversion-rule>
@@ -2559,204 +1831,118 @@
</extra-includes>
<!-- ### These overloads must be removed accept strings with \x00 in their contents -->
- <modify-function signature="append(const char*,int)" remove="all" />
- <modify-function signature="append(const char*)" remove="all" />
- <modify-function signature="append(QString)" remove="all" />
- <modify-function signature="contains(const char*)const" remove="all" />
- <modify-function signature="count(const char*)const" remove="all" />
- <modify-function signature="endsWith(const char*)const" remove="all" />
- <modify-function signature="indexOf(const char*,int)const" remove="all" />
- <modify-function signature="indexOf(char,int)const" remove="all" />
- <modify-function signature="indexOf(QString,int)const" remove="all" />
- <modify-function signature="insert(int,const char*)" remove="all" />
- <modify-function signature="insert(int,char)" remove="all" />
- <modify-function signature="insert(int,const char*,int)" since="4.6" remove="all" />
- <modify-function signature="insert(int,QString)" remove="all" />
- <modify-function signature="lastIndexOf(const char*,int)const" remove="all" />
- <modify-function signature="lastIndexOf(QString,int)const" remove="all" />
- <modify-function signature="lastIndexOf(char,int)const" remove="all" />
- <modify-function signature="prepend(const char*)" remove="all" />
- <modify-function signature="prepend(const char*,int)" since="4.6" remove="all" />
- <modify-function signature="replace(QByteArray,const char*)" remove="all" />
+ <modify-function signature="append(const char*,int)" remove="all"/>
+ <modify-function signature="append(const char*)" remove="all"/>
+ <modify-function signature="append(QString)" remove="all"/>
+ <modify-function signature="contains(const char*)const" remove="all"/>
+ <modify-function signature="count(const char*)const" remove="all"/>
+ <modify-function signature="endsWith(const char*)const" remove="all"/>
+ <modify-function signature="indexOf(const char*,int)const" remove="all"/>
+ <modify-function signature="indexOf(char,int)const" remove="all"/>
+ <modify-function signature="indexOf(QString,int)const" remove="all"/>
+ <modify-function signature="insert(int,const char*)" remove="all"/>
+ <modify-function signature="insert(int,char)" remove="all"/>
+ <modify-function signature="insert(int,const char*,int)" since="4.6" remove="all"/>
+ <modify-function signature="insert(int,QString)" remove="all"/>
+ <modify-function signature="lastIndexOf(const char*,int)const" remove="all"/>
+ <modify-function signature="lastIndexOf(QString,int)const" remove="all"/>
+ <modify-function signature="lastIndexOf(char,int)const" remove="all"/>
+ <modify-function signature="prepend(const char*)" remove="all"/>
+ <modify-function signature="prepend(const char*,int)" since="4.6" remove="all"/>
+ <modify-function signature="replace(QByteArray,const char*)" remove="all"/>
<modify-function signature="replace(const char*,int,const char*,int)" remove="all"/>
- <modify-function signature="replace(QString,const char*)" remove="all" />
- <modify-function signature="replace(const char*,QByteArray)" remove="all" />
- <modify-function signature="replace(const char*,const char*)" remove="all" />
- <modify-function signature="replace(int,int,const char*)" remove="all" />
- <modify-function signature="replace(int,int,const char*,int)" since="4.6" remove="all" />
- <modify-function signature="replace(char,const char*)" remove="all" />
- <modify-function signature="replace(char,QString)" remove="all" />
- <modify-function signature="startsWith(const char*)const" remove="all" />
- <modify-function signature="operator==(QString)const" remove="all" />
- <modify-function signature="operator==(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator==(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator>(QString)const" remove="all" />
- <modify-function signature="operator>(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator>(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator>=(QString)const" remove="all" />
- <modify-function signature="operator>=(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator>=(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator&lt;(QString)const" remove="all" />
- <modify-function signature="operator&lt;(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator&lt;=(QString)const" remove="all" />
- <modify-function signature="operator&lt;=(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator&lt;=(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator!=(QString)const" remove="all" />
- <modify-function signature="operator!=(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator!=(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator+=(QString)" remove="all" />
- <modify-function signature="operator+=(const char*)" remove="all" />
- <modify-function signature="operator+(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator+(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator+(QByteArray,const char*)" remove="all" />
- <modify-function signature="operator+(QString,QByteArray)" remove="all" />
- <modify-function signature="operator+(QByteArray,QString)" remove="all" />
+ <modify-function signature="replace(QString,const char*)" remove="all"/>
+ <modify-function signature="replace(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="replace(const char*,const char*)" remove="all"/>
+ <modify-function signature="replace(int,int,const char*)" remove="all"/>
+ <modify-function signature="replace(int,int,const char*,int)" since="4.6" remove="all"/>
+ <modify-function signature="replace(char,const char*)" remove="all"/>
+ <modify-function signature="replace(char,QString)" remove="all"/>
+ <modify-function signature="startsWith(const char*)const" remove="all"/>
+ <modify-function signature="operator==(QString)const" remove="all"/>
+ <modify-function signature="operator==(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator==(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator>(QString)const" remove="all"/>
+ <modify-function signature="operator>(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator>=(QString)const" remove="all"/>
+ <modify-function signature="operator>=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>=(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator&lt;(QString)const" remove="all"/>
+ <modify-function signature="operator&lt;(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;=(QString)const" remove="all"/>
+ <modify-function signature="operator&lt;=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;=(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator!=(QString)const" remove="all"/>
+ <modify-function signature="operator!=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator!=(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator+=(QString)" remove="all"/>
+ <modify-function signature="operator+=(const char*)" remove="all"/>
+ <modify-function signature="operator+(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator+(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator+(QByteArray,const char*)" remove="all"/>
+ <modify-function signature="operator+(QString,QByteArray)" remove="all"/>
+ <modify-function signature="operator+(QByteArray,QString)" remove="all"/>
<add-function signature="operator+(PyBytes,QByteArray)">
- <inject-code>
- QByteArray ba = QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)) + *%CPPSELF;
- %PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplus-1"/>
</add-function>
<add-function signature="operator+(PyByteArray, QByteArray)" return-type="QByteArray">
- <inject-code>
- QByteArray ba = QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)) + *%CPPSELF;
- %PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplus-2"/>
</add-function>
<add-function signature="operator+(PyByteArray)" return-type="QByteArray">
- <inject-code>
- QByteArray ba = *%CPPSELF + QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
- %PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplus-3"/>
</add-function>
<add-function signature="operator+=(PyByteArray)" return-type="QByteArray">
- <inject-code>
- *%CPPSELF += QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorplusequal"/>
</add-function>
<add-function signature="operator==(PyUnicode)">
- <inject-code>
- if (PyUnicode_CheckExact(%PYARG_1)) {
- Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
- QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
- bool cppResult = %CPPSELF == ba;
- %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorequalequal"/>
</add-function>
<add-function signature="operator!=(PyUnicode)">
- <inject-code>
- if (PyUnicode_CheckExact(%PYARG_1)) {
- Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
- QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
- bool cppResult = %CPPSELF != ba;
- %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatornotequal"/>
</add-function>
<add-function signature="operator&gt;(PyUnicode)">
- <inject-code>
- if (PyUnicode_CheckExact(%PYARG_1)) {
- Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
- QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
- bool cppResult = %CPPSELF &gt; ba;
- %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorgreater"/>
</add-function>
<add-function signature="operator&gt;=(PyUnicode)">
- <inject-code>
- if (PyUnicode_CheckExact(%PYARG_1)) {
- Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
- QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
- bool cppResult = %CPPSELF &gt;= ba;
- %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorgreaterequal"/>
</add-function>
<add-function signature="operator&lt;(PyUnicode)">
- <inject-code>
- if (PyUnicode_CheckExact(%PYARG_1)) {
- Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
- QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
- bool cppResult = %CPPSELF &lt; ba;
- %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorlower"/>
</add-function>
<add-function signature="operator&lt;=(PyUnicode)">
- <inject-code>
- if (PyUnicode_CheckExact(%PYARG_1)) {
- Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
- QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
- bool cppResult = %CPPSELF &lt;= ba;
- %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qbytearray-operatorlowerequal"/>
</add-function>
<!-- ### -->
<add-function signature="__repr__" return-type="PyObject*">
- <inject-code class="target" position="beginning">
- PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size());
- if (aux == NULL) {
- return NULL;
- }
- QByteArray b(Py_TYPE(%PYSELF)->tp_name);
- #ifdef IS_PY3K
- %PYARG_0 = PyUnicode_FromFormat("%s(%R)", b.constData(), aux);
- #else
- aux = PyObject_Repr(aux);
- b += "(";
- b += QByteArray(PyBytes_AS_STRING(aux), PyBytes_GET_SIZE(aux));
- b += ")";
- %PYARG_0 = Shiboken::String::fromStringAndSize(b.constData(), b.size());
- #endif
- Py_DECREF(aux);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-repr"/>
</add-function>
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="N" />
- <replace from="%REDUCE_ARGS" to="PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size())" />
+ <replace from="%REDUCE_FORMAT" to="N"/>
+ <replace from="%REDUCE_ARGS" to="PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size())"/>
</insert-template>
</inject-code>
</add-function>
<modify-function signature="QByteArray(const char*,int)">
<!-- Keep \x00 bytes passed in python strings -->
- <inject-code class="target" position="beginning">
- if (PyBytes_Check(%PYARG_1)) {
- %0 = new QByteArray(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
- } else if (Shiboken::String::check(%PYARG_1)) {
- %0 = new QByteArray(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1));
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-1"/>
</modify-function>
- <add-function signature="QByteArray(PyByteArray)" allow-thread="yes">>
- <inject-code class="target" position="beginning">
- %0 = new QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
- </inject-code>
+ <add-function signature="QByteArray(PyByteArray)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-2"/>
</add-function>
- <add-function signature="QByteArray(PyBytes)" allow-thread="yes">
- <inject-code class="target" position="beginning">
- %0 = new QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
- </inject-code>
+ <add-function signature="QByteArray(PyBytes)">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-3"/>
</add-function>
<!-- buffer protocol -->
- <inject-code class="native" position="beginning" file="glue/qbytearray_bufferprotocol.cpp" />
- <inject-code class="target" position="end">
- #if PY_VERSION_HEX &lt; 0x03000000
- Shiboken::SbkType&lt;QByteArray>()->tp_as_buffer = &amp;SbkQByteArrayBufferProc;
- Shiboken::SbkType&lt;QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER;
- #endif
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-bufferprotocol"/>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qbytearray-py3"/>
<modify-function signature="data()">
- <inject-code class="target" position="beginning">
- %PYARG_0 = PyBytes_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size());
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-data"/>
</modify-function>
<!-- removed functions -->
@@ -2775,12 +1961,12 @@
<modify-function signature="number(qulonglong,int)" remove="all"/>
<modify-function signature="operator+=(const char*)" remove="all"/>
<modify-function signature="operator+(char,QByteArray)" remove="all"/>
- <modify-function signature="operator==(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator!=(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator&lt;(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator&lt;=(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator>(const char*,QByteArray)" remove="all" />
- <modify-function signature="operator>=(const char*,QByteArray)" remove="all" />
+ <modify-function signature="operator==(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator!=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator&lt;=(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>(const char*,QByteArray)" remove="all"/>
+ <modify-function signature="operator>=(const char*,QByteArray)" remove="all"/>
<modify-function signature="operator[](int)const" remove="all"/>
<modify-function signature="operator[](uint)const" remove="all"/>
<!-- Those types have the same representation in Python, an overload would be useless. -->
@@ -2877,10 +2063,7 @@
<modify-argument index="2">
<remove-argument />
</modify-argument>
- <inject-code class="target">
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qbytearray-fromrawdata"/>
</modify-function>
<modify-function signature="toDouble(bool*)const">
<modify-argument index="1">
@@ -2899,52 +2082,22 @@
</inject-code>
</modify-function>
<add-function signature="__str__" return-type="PyObject*">
- <inject-code class="target" position="beginning">
- PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size());
- if (aux == NULL) {
- return NULL;
- }
- #ifdef IS_PY3K
- %PYARG_0 = PyObject_Repr(aux);
- Py_DECREF(aux);
- #else
- %PYARG_0 = aux;
- #endif
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-str"/>
</add-function>
<add-function signature="__len__">
- <inject-code class="target" position="beginning">
- return %CPPSELF.count();
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-len"/>
</add-function>
<add-function signature="__getitem__">
- <inject-code class="target" position="beginning">
- if (_i &lt; 0 || _i >= %CPPSELF.size()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return 0;
- } else {
- char res[2];
- res[0] = %CPPSELF.at(_i);
- res[1] = 0;
- return PyBytes_FromStringAndSize(res, 1);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-getitem"/>
</add-function>
<add-function signature="__mgetitem__">
- <inject-code class="target" position="beginning" file="glue/qbytearray_mgetitem.cpp" />
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-mgetitem"/>
</add-function>
<add-function signature="__setitem__">
- <inject-code class="target" position="beginning">
- %CPPSELF.remove(_i, 1);
- PyObject *args = Py_BuildValue("(nO)", _i, _value);
- PyObject *result = Sbk_QByteArrayFunc_insert(self, args);
- Py_DECREF(args);
- Py_XDECREF(result);
- return !result ? -1 : 0;
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-setitem"/>
</add-function>
<add-function signature="__msetitem__">
- <inject-code class="target" position="beginning" file="glue/qbytearray_msetitem.cpp" />
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qbytearray-msetitem"/>
</add-function>
</value-type>
<value-type name="QTextBoundaryFinder">
@@ -2956,12 +2109,32 @@
<object-type name="QXmlStreamEntityResolver"/>
<!-- Qt5: had to move QAbstractEventDispatcher into os-specific files because of Windows -->
+ <object-type name="QAbstractNativeEventFilter">
+ <!-- see QWidget::nativeEvent(), QWindow::nativeEvent() -->
+ <modify-function signature="nativeEventFilter(const QByteArray&amp;,void*,long*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion_variables"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code position="end">
+ <insert-template name="return_native_eventfilter"/>
+ </inject-code>
+ </modify-function>
+ </object-type>
<object-type name="QEventLoop">
<enum-type name="ProcessEventsFlag" flags="ProcessEventsFlags"/>
- <modify-function signature="exec(QFlags&lt;QEventLoop::ProcessEventsFlag>)" rename="exec_" allow-thread="yes" />
- <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes" />
- <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>,int)" allow-thread="yes" />
+ <modify-function signature="exec(QFlags&lt;QEventLoop::ProcessEventsFlag>)" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/>
+ <modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>,int)" allow-thread="yes"/>
</object-type>
<object-type name="QFileDevice" since="5.0">
<enum-type name="FileError"/>
@@ -2976,19 +2149,13 @@
<modify-argument index="1">
<replace-type modified-type="PyBuffer"/>
</modify-argument>
- <inject-code>
- uchar *ptr = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1));
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ptr);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qfiledevice-unmap"/>
</modify-function>
<modify-function signature="map(qint64,qint64,QFileDevice::MemoryMapFlags)">
<modify-argument index="return">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code>
- %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1, %2, %3), %2, Shiboken::Buffer::ReadWrite);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qfiledevice-map"/>
</modify-function>
<modify-function signature="flush()" allow-thread="yes"/>
</object-type>
@@ -3003,7 +2170,7 @@
<modify-function signature="rename(const QString&amp;,const QString&amp;)" allow-thread="yes"/>
</object-type>
<object-type name="QSaveFile"/>
- <object-type name="QFileSelector" />
+ <object-type name="QFileSelector"/>
<object-type name="QIODevice">
<enum-type name="OpenModeFlag" flags="OpenMode"/>
@@ -3030,54 +2197,28 @@
<remove-default-expression />
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_char*" />
+ <insert-template name="fix_char*"/>
</inject-code>
</modify-function>
<modify-function signature="readData(char*,qint64)">
- <inject-code class="target">
- QByteArray ba(1 + int(%2), char(0));
- %CPPSELF.%FUNCTION_NAME(ba.data(), int(%2));
- %PYARG_0 = Shiboken::String::fromCString(ba.constData());
- </inject-code>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qiodevice-readData"/>
<modify-argument index="1">
<remove-argument />
</modify-argument>
<modify-argument index="return">
<replace-type modified-type="PyObject"/>
- <conversion-rule class="native">
- %RETURN_TYPE %out = 0;
- if (PyBytes_Check(%PYARG_0)) {
- %out = PyBytes_GET_SIZE((PyObject*)%PYARG_0);
- memcpy(%1, PyBytes_AS_STRING((PyObject*)%PYARG_0), %out);
- } else if (Shiboken::String::check(%PYARG_0)) {
- %out = Shiboken::String::len((PyObject*)%PYARG_0);
- memcpy(%1, Shiboken::String::toCString((PyObject*)%PYARG_0), %out);
- }
- </conversion-rule>
</modify-argument>
+ <inject-code class="native" position="end" file="../glue/qtcore.cpp" snippet="return-readData"/>
</modify-function>
<modify-function signature="readLineData(char*,qint64)">
- <inject-code class="target">
- QByteArray ba(1 + int(%2), char(0));
- %CPPSELF.%FUNCTION_NAME(ba.data(), int(%2));
- %PYARG_0 = Shiboken::String::fromCString(ba.constData());
- </inject-code>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qiodevice-readData"/>
<modify-argument index="1">
<remove-argument />
</modify-argument>
<modify-argument index="return">
<replace-type modified-type="PyObject"/>
- <conversion-rule class="native">
- %RETURN_TYPE %out = 0;
- if (PyBytes_Check(%PYARG_0)) {
- %out = PyBytes_GET_SIZE((PyObject*)%PYARG_0);
- memcpy(%1, PyBytes_AS_STRING((PyObject*)%PYARG_0), %out);
- } else if (Shiboken::String::check(%PYARG_0)) {
- %out = Shiboken::String::len((PyObject*)%PYARG_0);
- memcpy(%1, Shiboken::String::toCString((PyObject*)%PYARG_0), %out);
- }
- </conversion-rule>
</modify-argument>
+ <inject-code class="native" position="end" file="../glue/qtcore.cpp" snippet="return-readData"/>
</modify-function>
</object-type>
<object-type name="QCryptographicHash">
@@ -3086,9 +2227,7 @@
<modify-argument index="2">
<remove-argument />
</modify-argument>
- <inject-code>
- %CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1));
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qcryptographichash-adddata"/>
</modify-function>
</object-type>
<value-type name="QOperatingSystemVersion" since="5.9">
@@ -3109,11 +2248,9 @@
<reference-count action="set"/>
</modify-argument>
</modify-function>
- <add-function signature="__enter__()" />
+ <add-function signature="__enter__()"/>
<add-function signature="__exit__(PyObject*,PyObject*,PyObject*)">
- <inject-code>
- %CPPSELF.unlock();
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="unlock"/>
</add-function>
</object-type>
@@ -3129,7 +2266,7 @@
<modify-function signature="tryLock(int)" allow-thread="yes"/>
</object-type>
<object-type name="QRandomGenerator" since="5.10">
- <modify-function signature="global()" rename="global_" allow-thread="yes" />
+ <modify-function signature="global()" rename="global_" allow-thread="yes"/>
<modify-function signature="operator()()" remove="all"/>
</object-type>
<object-type name="QRandomGenerator64" since="5.10">
@@ -3145,25 +2282,10 @@
<enum-type name="Type"/>
<add-function signature="QSocketNotifier(PyObject*, QSocketNotifier::Type, QObject*)">
<modify-argument index="3">
- <replace-default-expression with="0" />
- <rename to="parent" />
+ <replace-default-expression with="0"/>
+ <rename to="parent"/>
</modify-argument>
- <inject-code>
- Shiboken::AutoDecRef socket(%PYARG_1);
- if (!socket.isNull()) {
- // We use qintptr as PyLong, but we check for int
- // since it is currently an alias to be Python2 compatible.
- // Internally, ints are qlonglongs.
- if (%CHECKTYPE[int](socket)) {
- int cppSocket = %CONVERTTOCPP[int](socket);
- qintptr socket = (qintptr)cppSocket;
- %0 = new %TYPE(socket, %2, %3);
- } else {
- PyErr_SetString(PyExc_TypeError,
- "QSocketNotifier: first argument (socket) must be an int.");
- }
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qsocketnotifier"/>
</add-function>
</object-type>
@@ -3198,19 +2320,19 @@
</modify-argument>
</modify-function>
<!-- fromUnicode(QString) does the job -->
- <modify-function signature="fromUnicode(const QChar*,int,QTextCodec::ConverterState*)const" remove="all" />
- <modify-function signature="convertFromUnicode(const QChar*,int,QTextCodec::ConverterState*)const" remove="all" />
+ <modify-function signature="fromUnicode(const QChar*,int,QTextCodec::ConverterState*)const" remove="all"/>
+ <modify-function signature="convertFromUnicode(const QChar*,int,QTextCodec::ConverterState*)const" remove="all"/>
<!-- this causes a warning that I cannot avoid. See suppressed warning at the end. -->
</object-type>
<object-type name="QTextDecoder">
<!-- ### toUnicode(QByteArray) does the job -->
- <modify-function signature="toUnicode(const char*,int)" remove="all" />
- <modify-function signature="toUnicode(QString*,const char*,int)" remove="all" />
+ <modify-function signature="toUnicode(const char*,int)" remove="all"/>
+ <modify-function signature="toUnicode(QString*,const char*,int)" remove="all"/>
<!-- ### -->
</object-type>
<object-type name="QTextEncoder">
<!-- fromUnicode(QString) does the job -->
- <modify-function signature="fromUnicode(const QChar*,int)" remove="all" />
+ <modify-function signature="fromUnicode(const QChar*,int)" remove="all"/>
</object-type>
<object-type name="QTimeLine">
<enum-type name="CurveShape"/>
@@ -3220,17 +2342,12 @@
<object-type name="QTranslator">
<modify-function signature="load(const uchar*,int,QString)">
<modify-argument index="1">
- <replace-type modified-type="PyBuffer" />
+ <replace-type modified-type="PyBuffer"/>
</modify-argument>
<modify-argument index="2">
<remove-argument />
</modify-argument>
- <inject-code>
- Py_ssize_t size;
- uchar *ptr = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1, &amp;size));
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast&lt;const uchar*&gt;(ptr), size);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qtranslator-load"/>
</modify-function>
</object-type>
<object-type name="QWaitCondition">
@@ -3250,67 +2367,10 @@
</object-type>
<object-type name="QTimer">
<modify-function signature="singleShot(int,const QObject*,const char*)">
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of c++ function call
- (void) %2; // remove warning about unused variable
- Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
- PyObject *pyTimer = reinterpret_cast&lt;PyTypeObject *&gt;(Shiboken::SbkType&lt;QTimer&gt;())->tp_new(Shiboken::SbkType&lt;QTimer&gt;(), emptyTuple, 0);
- reinterpret_cast&lt;PyTypeObject *&gt;(Shiboken::SbkType&lt;QTimer&gt;())->tp_init(pyTimer, emptyTuple, 0);
-
- QTimer* timer = %CONVERTTOCPP[QTimer*](pyTimer);
- Shiboken::AutoDecRef result(
- PyObject_CallMethod(pyTimer,
- const_cast&lt;char*&gt;("connect"),
- const_cast&lt;char*&gt;("OsOs"),
- pyTimer,
- SIGNAL(timeout()),
- %PYARG_2,
- %3)
- );
- Shiboken::Object::releaseOwnership((SbkObject*)pyTimer);
- Py_XDECREF(pyTimer);
- timer->setSingleShot(true);
- timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()));
- timer->start(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtimer-singleshot-1"/>
</modify-function>
<add-function signature="singleShot(int,PyCallable*)" static="yes">
- <inject-code class="target" position="beginning">
- // %FUNCTION_NAME() - disable generation of c++ function call
- Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
- PyObject *pyTimer = reinterpret_cast&lt;PyTypeObject *&gt;(Shiboken::SbkType&lt;QTimer&gt;())->tp_new(Shiboken::SbkType&lt;QTimer&gt;(), emptyTuple, 0);
- reinterpret_cast&lt;PyTypeObject *&gt;(Shiboken::SbkType&lt;QTimer&gt;())->tp_init(pyTimer, emptyTuple, 0);
- QTimer* timer = %CONVERTTOCPP[QTimer*](pyTimer);
- timer->setSingleShot(true);
-
- if (PyObject_TypeCheck(%2, PySideSignalInstanceTypeF())) {
- PySideSignalInstance *signalInstance = reinterpret_cast&lt;PySideSignalInstance*&gt;(%2);
- Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance)));
- Shiboken::AutoDecRef result(
- PyObject_CallMethod(pyTimer,
- const_cast&lt;char*&gt;("connect"),
- const_cast&lt;char*&gt;("OsOO"),
- pyTimer,
- SIGNAL(timeout()),
- PySide::Signal::getObject(signalInstance),
- signalSignature.object())
- );
- } else {
- Shiboken::AutoDecRef result(
- PyObject_CallMethod(pyTimer,
- const_cast&lt;char*&gt;("connect"),
- const_cast&lt;char*&gt;("OsO"),
- pyTimer,
- SIGNAL(timeout()),
- %PYARG_2)
- );
- }
-
- timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()), Qt::DirectConnection);
- Shiboken::Object::releaseOwnership((SbkObject*)pyTimer);
- Py_XDECREF(pyTimer);
- timer->start(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qtimer-singleshot-2"/>
</add-function>
</object-type>
<object-type name="QProcess">
@@ -3335,37 +2395,22 @@
<modify-argument index="return">
<replace-type modified-type="(retval, pid)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- qint64 pid;
- %RETURN_TYPE retval = %TYPE::%FUNCTION_NAME(%1, %2, %3, &amp;pid);
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[qint64](pid));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qprocess-startdetached"/>
</modify-function>
<!-- Function removed because on windows it returns a win32 specific structure -->
- <modify-function signature="pid()const" remove="all" />
+ <modify-function signature="pid()const" remove="all"/>
<add-function signature="pid()" return-type="long">
- <inject-code>
- long result;
- #ifdef WIN32
- _PROCESS_INFORMATION *procInfo = %CPPSELF.%FUNCTION_NAME();
- result = procInfo ? procInfo->dwProcessId : 0;
- #else
- result = %CPPSELF.%FUNCTION_NAME();
- #endif
- %PYARG_0 = %CONVERTTOPYTHON[long](result);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qprocess-pid"/>
</add-function>
<!--### Obsolete in 4.3-->
<modify-function signature="setReadChannelMode(QProcess::ProcessChannelMode)" remove="all"/>
<modify-function signature="readChannelMode()const" remove="all"/>
<!-- ### -->
</object-type>
- <object-type name="QSignalMapper" />
+ <object-type name="QSignalMapper"/>
- <object-type name="QCollatorSortKey" since="5.2" />
- <object-type name="QCollator" since="5.2" />
+ <object-type name="QCollatorSortKey" since="5.2"/>
+ <object-type name="QCollator" since="5.2"/>
<object-type name="QCommandLineOption" since="5.2">
<enum-type name="Flag" flags="Flags" since="5.8"/>
@@ -3376,7 +2421,7 @@
</object-type>
<object-type name="QCoreApplication">
- <!--Qt5: gone <enum-type name="Encoding" /> -->
+ <!--Qt5: gone <enum-type name="Encoding"/> -->
<enum-type identified-by-value="ApplicationFlags" since="4.8" revision="4800"/>
<extra-includes>
<include file-name="QStringList" location="global"/>
@@ -3395,17 +2440,10 @@
method.
</inject-documentation>
<add-function signature="QCoreApplication(QStringList)">
- <inject-code>
- QCoreApplicationConstructor(%PYSELF, args, &amp;%0);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qcoreapplication-1"/>
</add-function>
<add-function signature="QCoreApplication()">
- <inject-code>
- PyObject *empty = PyTuple_New(2);
- if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
- QCoreApplicationConstructor(%PYSELF, empty, &amp;%0);
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qcoreapplication-2"/>
</add-function>
<!-- blocking functions -->
<modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag&gt;,int)" allow-thread="yes"/>
@@ -3414,22 +2452,7 @@
<modify-function signature="sendEvent(QObject*,QEvent*)" allow-thread="yes"/>
<modify-function signature="sendPostedEvents(QObject*,int)" allow-thread="yes"/>
<modify-function signature="instance()">
- <inject-code class="target">
- QCoreApplication *app = QCoreApplication::instance();
- PyObject *pyApp = Py_None;
- if (app) {
- pyApp = reinterpret_cast&lt;PyObject*&gt;(
- Shiboken::BindingManager::instance().retrieveWrapper(app));
- if (!pyApp)
- pyApp = %CONVERTTOPYTHON[QCoreApplication*](app);
- // this will keep app live after python exit (extra ref)
- }
- // PYSIDE-571: make sure that we return the singleton "None"
- if (pyApp == Py_None)
- Py_DECREF(MakeSingletonQAppWrapper(0)); // here qApp and instance() diverge
- %PYARG_0 = pyApp;
- Py_XINCREF(%PYARG_0);
- </inject-code>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qcoreapplication-instance"/>
</modify-function>
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
@@ -3437,37 +2460,12 @@
<modify-argument index="2" invalidate-after-use="yes"/>
</modify-function>
<modify-function signature="QCoreApplication(int &amp;,char **,int)" access="private"/>
- <inject-code class="native" file="glue/qcoreapplication_init.cpp" position="beginning" />
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qcoreapplication-init"/>
<modify-function signature="postEvent(QObject*,QEvent*,int)">
<modify-argument index="2">
<define-ownership owner="c++"/>
</modify-argument>
</modify-function>
- <modify-function signature="winEventFilter(MSG*,long*)">
- <modify-argument index="2">
- <remove-argument />
- <conversion-rule class="native">
- long *%out = new long;
- %out = 0;
- </conversion-rule>
- </modify-argument>
- <modify-argument index="return">
- <replace-type modified-type="PyObject"/>
- <conversion-rule class="native">
- %RETURN_TYPE %out = false;
- if (PySequence_Check(%PYARG_0) &amp;&amp; (PySequence_Size(%PYARG_0) == 2)) {
- Shiboken::AutoDecRef pyResult(PySequence_GetItem(%PYARG_0, 0));
- %out = %CONVERTTOCPP[bool](pyResult);
- }
- </conversion-rule>
- </modify-argument>
- <inject-code position="end">
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[long](*result_out));
- delete result_out;
- </inject-code>
- </modify-function>
</object-type>
<object-type name="QSettings">
<enum-type name="Format"/>
@@ -3492,28 +2490,18 @@
</modify-function>
</object-type>
<object-type name="QEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::None">
- <enum-type name="Type" extensible="yes" />
+ <enum-type name="Type"/>
</object-type>
<object-type name="QChildEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::ChildAdded || %1-&gt;type() == QEvent::ChildPolished || %1-&gt;type() == QEvent::ChildRemoved">
- <modify-field name="c" read="false" write="false"/>
<modify-function signature="child()const">
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
</modify-argument>
</modify-function>
</object-type>
- <object-type name="QTimerEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Timer" />
- <object-type name="QDynamicPropertyChangeEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::DynamicPropertyChange" />
+ <object-type name="QTimerEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Timer"/>
+ <object-type name="QDynamicPropertyChangeEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::DynamicPropertyChange"/>
- <template name="stream_read_method">
- %RETURN_TYPE _cpp_result;
- (*%CPPSELF) &gt;&gt; _cpp_result;
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](_cpp_result);
- </template>
-
- <template name="stream_write_method">
- (*%CPPSELF) &lt;&lt; %1;
- </template>
<object-type name="QDataStream" stream="yes">
<enum-type name="FloatingPointPrecision" since="4.6"/>
@@ -3560,202 +2548,123 @@
<modify-function signature="operator&lt;&lt;(const char*)" remove="all"/>
<!-- ### -->
<add-function signature="operator&lt;&lt;(const QString&amp;)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeQString(const QString&amp;)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="readQString()" return-type="QString">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="writeQChar(const QChar&amp;)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="readQChar()" return-type="QChar">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="writeQStringList(const QStringList&amp;)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="readQStringList()" return-type="QStringList">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="writeQVariant(const QVariant&amp;)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="readQVariant()" return-type="QVariant">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<modify-function signature="readRawData(char*,int)">
<modify-argument index="1">
<remove-argument />
</modify-argument>
- <inject-code class="target">
- QByteArray data;
- data.resize(%2);
- int result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size());
- if (result == -1) {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- } else {
- %PYARG_0 = PyBytes_FromStringAndSize(data.data(), result);
- }
- </inject-code>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qdatastream-readrawdata"/>
</modify-function>
<modify-function signature="writeRawData(const char*,int)">
<modify-argument index="2">
<remove-argument />
</modify-argument>
- <inject-code class="target">
- int r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1));
- %PYARG_0 = %CONVERTTOPYTHON[int](r);
- </inject-code>
+ <inject-code class="target" file="../glue/qtcore.cpp" snippet="qdatastream-writerawdata"/>
</modify-function>
<!-- Extra functions for primitive type handling -->
<add-function signature="readBool()" return-type="bool">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readInt8()" return-type="qint8">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readUInt8()" return-type="quint8">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readUInt16()" return-type="quint16">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readInt16()" return-type="qint16">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readInt32()" return-type="qint32">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readUInt32()" return-type="quint32">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readInt64()" return-type="qint64">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readUInt64()" return-type="quint64">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readFloat()" return-type="float">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readDouble()" return-type="qreal">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="readString()" return-type="QString">
- <inject-code class="target" position="end">
- <insert-template name="stream_read_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-read-method"/>
</add-function>
<add-function signature="writeBool(bool)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeInt8(qint8)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeUInt8(quint8)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeUInt16(quint16)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeInt16(qint16)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeInt32(qint32)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeUInt32(quint32)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeInt64(qint64)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeUInt64(quint64)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeFloat(float)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeDouble(qreal)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<add-function signature="writeString(QString)">
- <inject-code class="target" position="end">
- <insert-template name="stream_write_method"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="stream-write-method"/>
</add-function>
<!-- ### deprecated method -->
<modify-function signature="readBytes(char*&amp;,uint&amp;)" remove="all"/>
- <modify-function signature="writeBytes(const char*,uint)" remove="all" />
+ <modify-function signature="writeBytes(const char*,uint)" remove="all"/>
</object-type>
<value-type name="QTextStreamManipulator" default-constructor="QTextStreamManipulator(0, 0)">
@@ -3804,13 +2713,7 @@
<modify-function signature="operator&gt;&gt;(QString&amp;)" remove="all"/>
<modify-function signature="string()const">
- <modify-argument index="return">
- <!--<replace-type modified-type="QString" />-->
- <conversion-rule class="target">
- QString &amp;res = *%0;
- %PYARG_0 = %CONVERTTOPYTHON[QString](res);
- </conversion-rule>
- </modify-argument>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="return-qstring-ref"/>
</modify-function>
<modify-function signature="flush()" allow-thread="yes"/>
@@ -3830,19 +2733,17 @@
<object-type name="QThreadPool">
<modify-function signature="start(QRunnable*,int)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="tryStart(QRunnable*)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="globalInstance()" >
- <inject-code position="end">
- Shiboken::Object::releaseOwnership(%PYARG_0);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="releaseownership"/>
</modify-function>
</object-type>
<value-type name="QXmlStreamAttribute"/>
@@ -3853,7 +2754,7 @@
<modify-function signature="pop_front()" remove="all"/>
<modify-function signature="toList()const" remove="all"/>
<modify-function signature="fromList(const QList&lt;QXmlStreamAttribute&gt; &amp;)" remove="all"/>
- <modify-function signature="operator+=(QVector&lt;QXmlStreamAttribute&gt;)" remove="all" />
+ <modify-function signature="operator+=(QVector&lt;QXmlStreamAttribute&gt;)" remove="all"/>
</value-type>
<value-type name="QXmlStreamNamespaceDeclaration"/>
<value-type name="QXmlStreamNotationDeclaration"/>
@@ -3865,7 +2766,7 @@
</object-type>
<object-type name="QXmlStreamWriter">
<!-- Removed because it expect QString to be mutable -->
- <modify-function signature="QXmlStreamWriter(QString*)" remove="all" />
+ <modify-function signature="QXmlStreamWriter(QString*)" remove="all"/>
<modify-function signature="codec()const">
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
@@ -3873,11 +2774,6 @@
</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"/>
@@ -3886,40 +2782,40 @@
</value-type>
<value-type name="QGenericArgument">
- <include file-name="qobjectdefs.h" location="global" />
+ <include file-name="qobjectdefs.h" location="global"/>
</value-type>
<value-type name="QGenericReturnArgument">
- <include file-name="qobjectdefs.h" location="global" />
+ <include file-name="qobjectdefs.h" location="global"/>
</value-type>
<object-type name="QMessageLogContext">
- <modify-function signature="copy(const QMessageLogContext &amp;)" remove="all" />
+ <modify-function signature="copy(const QMessageLogContext &amp;)" remove="all"/>
</object-type>
<value-type name="QMetaMethod">
<enum-type name="Access"/>
<enum-type name="MethodType"/>
<!-- This isn't part of Qt public API -->
- <modify-function signature="attributes()const" remove="all" />
- <modify-function signature="getParameterTypes(int*)const" remove="all" />
+ <modify-function signature="attributes()const" remove="all"/>
+ <modify-function signature="getParameterTypes(int*)const" remove="all"/>
</value-type>
<object-type name="QMetaObject">
<enum-type name="Call"/>
- <include file-name="qobjectdefs.h" location="global" />
+ <include file-name="qobjectdefs.h" location="global"/>
<!-- This isn't part of Qt public API -->
- <modify-function signature="connect(const QObject*,int,const QObject*,int,int,int*)" remove="all" />
+ <modify-function signature="connect(const QObject*,int,const QObject*,int,int,int*)" remove="all"/>
</object-type>
<object-type name="QMetaObject::Connection">
- <include file-name="qobjectdefs.h" location="global" />
+ <include file-name="qobjectdefs.h" location="global"/>
</object-type>
<value-type name="QMetaProperty" >
<!-- This isn't part of Qt public API -->
- <modify-function signature="enclosingMetaObject()const" remove="all" />
+ <modify-function signature="enclosingMetaObject()const" remove="all"/>
</value-type>
<value-type name="QMetaClassInfo">
<!-- This isn't part of Qt public API -->
- <modify-function signature="enclosingMetaObject()const" remove="all" />
+ <modify-function signature="enclosingMetaObject()const" remove="all"/>
</value-type>
<value-type name="QMetaEnum">
@@ -3928,7 +2824,7 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_args,bool*"/>
@@ -3939,17 +2835,14 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- This isn't part of Qt public API -->
- <modify-function signature="enclosingMetaObject()const" remove="all" />
- <!-- Qt5.5: "template<typename T> static QMetaEnum fromType()" is not understood by the compiler.
- We therefore ignore this 5.5 addition for now: -->
- <modify-function signature="fromType()" since="5.5" remove="all" />
+ <modify-function signature="enclosingMetaObject()const" remove="all"/>
</value-type>
<!-- From Qt4.6 -->
@@ -3968,7 +2861,7 @@
</object-type>
<object-type name="QAbstractTransition" since="4.6">
- <enum-type name="TransitionType" since="5.5" />
+ <enum-type name="TransitionType" since="5.5"/>
<modify-function signature="QAbstractTransition(QState*)">
<modify-argument index="1">
@@ -3996,19 +2889,19 @@
<modify-function signature="targetState()const">
<modify-argument index="return">
- <reference-count action="set" variable-name="setTargetState(QAbstractState*)1" />
+ <reference-count action="set" variable-name="setTargetState(QAbstractState*)1"/>
</modify-argument>
</modify-function>
<modify-function signature="targetStates()const">
<modify-argument index="return">
- <reference-count action="set" variable-name="setTargetState(QAbstractState*)1" />
+ <reference-count action="set" variable-name="setTargetState(QAbstractState*)1"/>
</modify-argument>
</modify-function>
<modify-function signature="setTargetStates(QList&lt;QAbstractState*&gt;)">
<modify-argument index="1">
- <reference-count action="set" variable-name="setTargetState(QAbstractState*)1" />
+ <reference-count action="set" variable-name="setTargetState(QAbstractState*)1"/>
</modify-argument>
</modify-function>
@@ -4040,42 +2933,25 @@
</modify-function>
<modify-function signature="clear()" >
- <inject-code class="target" position="beginning">
- for (int counter = 0; counter &lt; %CPPSELF.animationCount(); ++counter ) {
- QAbstractAnimation *animation = %CPPSELF.animationAt(counter);
- PyObject *obj = %CONVERTTOPYTHON[QAbstractAnimation*](animation);
- Shiboken::Object::setParent(NULL, obj);
- Py_DECREF(obj);
- }
- %CPPSELF.clear();
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qanimationgroup-clear"/>
</modify-function>
</object-type>
<!-- We will use inject code to implement the function below -->
- <rejection class="QEasingCurve" function-name="setCustomType" />
- <rejection class="QEasingCurve" function-name="customType" />
+ <rejection class="QEasingCurve" function-name="setCustomType"/>
+ <rejection class="QEasingCurve" function-name="customType"/>
<value-type name="QEasingCurve" since="4.6">
<extra-includes>
<include file-name="pysideweakref.h" location="global"/>
<include file-name="glue/qeasingcurve_glue.h" location="local"/>
</extra-includes>
- <inject-code>
- PySideEasingCurveFunctor::init();
- </inject-code>
- <enum-type name="Type" />
+ <inject-code file="../glue/qtcore.cpp" snippet="qeasingcurve"/>
+ <enum-type name="Type"/>
<add-function signature="setCustomType(PyObject*)">
- <inject-code>
- QEasingCurve::EasingFunction func = PySideEasingCurveFunctor::createCustomFuntion(%PYSELF, %PYARG_1);
- if (func)
- %CPPSELF.%FUNCTION_NAME(func);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qeasingcurve-setcustomtype"/>
</add-function>
<add-function signature="customType()" return-type="PyObject">
- <inject-code>
- //%FUNCTION_NAME()
- %PYARG_0 = PySideEasingCurveFunctor::callable(%PYSELF);
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qeasingcurve-customtype"/>
</add-function>
</value-type>
@@ -4086,11 +2962,11 @@
</value-type>
<value-type name="QJsonDocument">
- <enum-type name="DataValidation" />
- <enum-type name="JsonFormat" />
+ <enum-type name="DataValidation"/>
+ <enum-type name="JsonFormat"/>
</value-type>
- <rejection class="QJsonDocument" field-name="BinaryFormatTag" />
+ <rejection class="QJsonDocument" field-name="BinaryFormatTag"/>
<value-type name="QJsonParseError">
<enum-type name="ParseError"/>
@@ -4120,10 +2996,10 @@
</object-type>
- <object-type name="QFinalState" since="4.6" />
+ <object-type name="QFinalState" since="4.6"/>
<object-type name="QHistoryState" since="4.6">
- <enum-type name="HistoryType" />
+ <enum-type name="HistoryType"/>
<modify-documentation xpath='description/code'>
&lt;code>machine = QStateMachine()
@@ -4163,20 +3039,9 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
<object-type name="QSignalTransition" since="4.6">
<add-function signature="QSignalTransition(PyObject*,QState*)" return-type="QSignalTransition*">
<modify-argument index="2">
- <replace-default-expression with="0" />
+ <replace-default-expression with="0"/>
</modify-argument>
- <inject-code>
- if (PyObject_TypeCheck(%1, PySideSignalInstanceTypeF())) {
- PyObject *dataSource = PySide::Signal::getObject((PySideSignalInstance*)%PYARG_1);
- Shiboken::AutoDecRef obType(PyObject_Type(dataSource));
- QObject* sender = %CONVERTTOCPP[QObject*](dataSource);
- if (sender) {
- const char*dataSignature = PySide::Signal::getSignature((PySideSignalInstance*)%PYARG_1);
- QByteArray signature(dataSignature); // Append SIGNAL flag (2)
- %0 = new QSignalTransitionWrapper(sender,"2" + signature,%2);
- }
- }
- </inject-code>
+ <inject-code file="../glue/qtcore.cpp" snippet="qsignaltransition"/>
</add-function>
</object-type>
@@ -4193,16 +3058,7 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- QString signalName(%2);
- if (PySide::SignalManager::registerMetaMethod(%1, signalName.mid(1).toLatin1().data(), QMetaMethod::Signal)) {
- QSignalTransition *%0 = %CPPSELF->addTransition(%1, %2, %3);
- %PYARG_0 = %CONVERTTOPYTHON[QSignalTransition*](%0);
- } else {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qstate-addtransition-1"/>
</modify-function>
<modify-function signature="addTransition(QAbstractState*)">
<modify-argument index="1">
@@ -4217,18 +3073,7 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- // Obviously the label used by the following goto is a very awkward solution,
- // since it refers to a name very tied to the generator implementation.
- // Check bug #362 for more information on this
- // http://bugs.openbossa.org/show_bug.cgi?id=362
- if (!PyObject_TypeCheck(%1, PySideSignalInstanceTypeF()))
- goto Sbk_%TYPEFunc_%FUNCTION_NAME_TypeError;
- PySideSignalInstance *signalInstance = reinterpret_cast&lt;PySideSignalInstance*&gt;(%1);
- QObject* sender = %CONVERTTOCPP[QObject*](PySide::Signal::getObject(signalInstance));
- QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2);
- %PYARG_0 = %CONVERTTOPYTHON[QSignalTransition*](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qstate-addtransition-2"/>
</add-function>
<modify-function signature="removeTransition(QAbstractTransition*)">
@@ -4257,27 +3102,13 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
</modify-function>
<add-function signature="configuration()" return-type="list of QAbstractState" >
- <inject-code class="target" position="beginning">
- %PYARG_0 = PySet_New(0);
- foreach(QAbstractState *abs_state, %CPPSELF.configuration()) {
- Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractState*](abs_state));
- Shiboken::Object::setParent(self, obj);
- PySet_Add(%PYARG_0, obj);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qstatemachine-configuration"/>
</add-function>
<!-- Replaced by a added function -->
<modify-function signature="defaultAnimations()const" remove="all"/>
<add-function signature="defaultAnimations()" return-type="list of QAbstractAnimation" >
- <inject-code class="target" position="beginning">
- %PYARG_0 = PyList_New(0);
- foreach(QAbstractAnimation *abs_anim, %CPPSELF.defaultAnimations()) {
- Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractAnimation*](abs_anim));
- Shiboken::Object::setParent(self, obj);
- PyList_Append(%PYARG_0, obj);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qstatemachine-defaultanimations"/>
</add-function>
</object-type>
@@ -4294,73 +3125,45 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
<!-- From Qt4.6 ^^^ -->
<add-function signature="SIGNAL(const char*)" return-type="str">
- <inject-code class="target" position="beginning">
- %PYARG_0 = Shiboken::String::fromFormat("2%s",QMetaObject::normalizedSignature(%1).constData());
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-signal"/>
</add-function>
<add-function signature="SLOT(const char*)" return-type="str">
- <inject-code class="target" position="beginning">
- %PYARG_0 = Shiboken::String::fromFormat("1%s",QMetaObject::normalizedSignature(%1).constData());
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-slot"/>
</add-function>
<add-function signature="QT_TR_NOOP(PyObject)" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="return_argument"><replace from="#" to="1" /></insert-template>
+ <insert-template name="return_argument"><replace from="#" to="1"/></insert-template>
</inject-code>
</add-function>
<add-function signature="QT_TR_NOOP_UTF8(PyObject)" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="return_argument"><replace from="#" to="1" /></insert-template>
+ <insert-template name="return_argument"><replace from="#" to="1"/></insert-template>
</inject-code>
</add-function>
<add-function signature="QT_TRANSLATE_NOOP(PyObject,PyObject)" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="return_argument"><replace from="#" to="2" /></insert-template>
+ <insert-template name="return_argument"><replace from="#" to="2"/></insert-template>
</inject-code>
</add-function>
<add-function signature="QT_TRANSLATE_NOOP3(PyObject,PyObject,PyObject)" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="return_argument"><replace from="#" to="2" /></insert-template>
+ <insert-template name="return_argument"><replace from="#" to="2"/></insert-template>
</inject-code>
</add-function>
<add-function signature="QT_TRANSLATE_NOOP_UTF8(PyObject)" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="return_argument"><replace from="#" to="1" /></insert-template>
+ <insert-template name="return_argument"><replace from="#" to="1"/></insert-template>
</inject-code>
</add-function>
- <inject-code class="native" position="beginning">
- QT_BEGIN_NAMESPACE
- extern bool
- qRegisterResourceData(int,
- const unsigned char *,
- const unsigned char *,
- const unsigned char *);
-
- extern bool
- qUnregisterResourceData(int,
- const unsigned char *,
- const unsigned char *,
- const unsigned char *);
- QT_END_NAMESPACE
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtcore.cpp" snippet="qt-registerresourcedata"/>
<add-function signature="qRegisterResourceData(int,PyBytes,PyBytes,PyBytes)" return-type="bool">
- <inject-code class="target" position="beginning">
- %RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast&lt;uchar*&gt;(PyBytes_AS_STRING(%PYARG_2)),
- reinterpret_cast&lt;uchar*&gt;(PyBytes_AS_STRING(%PYARG_3)),
- reinterpret_cast&lt;uchar*&gt;(PyBytes_AS_STRING(%PYARG_4)));
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qregisterresourcedata"/>
</add-function>
<add-function signature="qUnregisterResourceData(int,PyBytes,PyBytes,PyBytes)" return-type="bool">
- <inject-code class="target" position="beginning">
- %RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast&lt;uchar*&gt;(PyBytes_AS_STRING(%PYARG_2)),
- reinterpret_cast&lt;uchar*&gt;(PyBytes_AS_STRING(%PYARG_3)),
- reinterpret_cast&lt;uchar*&gt;(PyBytes_AS_STRING(%PYARG_4)));
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qt-qunregisterresourcedata"/>
</add-function>
<object-type name="QFactoryInterface"/>
@@ -4369,9 +3172,9 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
<object-type name="QPluginLoader"/>
<object-type name="QStringListModel"/>
- <suppress-warning text="Unable to decide type of property: 'QLibrary::LoadHints' in class 'QPluginLoader'" />
- <suppress-warning text="enum '_ISalnum' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'Qt::Initialization' does not have a type entry or is not an enum" />
+ <suppress-warning text="Unable to decide type of property: 'QLibrary::LoadHints' in class 'QPluginLoader'"/>
+ <suppress-warning text="enum '_ISalnum' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'Qt::Initialization' does not have a type entry or is not an enum"/>
<suppress-warning text="visibility of function '*' modified in class '*'"/>
<suppress-warning text="hiding of function '*' in class '*'"/>
<suppress-warning text="namespace '*' does not have a type entry"/>
@@ -4390,55 +3193,57 @@ s1.addTransition(button.clicked, s1h)&lt;/code>
<suppress-warning text="unhandled enum value: (sizeof(void*)&lt;&lt;3) in QSysInfo::Sizes"/>
<suppress-warning text="unmatched enum ~0u"/>
<suppress-warning text="unmatched enum (sizeof(void*)&lt;&lt;3)"/>
- <suppress-warning text="signature 'setCustomType(float)' for function modification in 'QEasingCurve' not found. Possible candidates: setCustomType(double) in QEasingCurve"/>
- <suppress-warning text="enum 'enum_4' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'enum_5' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'FP_NORMAL' does not have a type entry or is not an enum" />
- <suppress-warning text="Shadowing: *" />
+ <suppress-warning text="^signature 'setCustomType(float)' for function modification in 'QEasingCurve' not found.*$"/>
+ <suppress-warning text="enum 'enum_4' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'enum_5' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'FP_NORMAL' does not have a type entry or is not an enum"/>
+ <suppress-warning text="Shadowing: *"/>
+ <!-- QCborStreamReader: Suppress warnings about 32/64bit signatures not found depending on qsizetype -->
+ <suppress-warning text="^signature 'readStringChunk\(char.*in 'QCborStreamReader' not found.*$"/>
<!-- this enum is defined on Qt global header but only used in QtGui module -->
- <suppress-warning text="enum 'PM_MessageBoxHeight' does not have a type entry or is not an enum" />
+ <suppress-warning text="enum 'PM_MessageBoxHeight' does not have a type entry or is not an enum"/>
<!-- this function only exists on Windows -->
- <suppress-warning text="signature 'winEventFilter(MSG*,long*)' for function modification in 'QCoreApplication' not found. Possible candidates:*"/>
+ <suppress-warning text="^signature 'winEventFilter(MSG*,long*)' for function modification in 'QCoreApplication' not found.*"/>
<!-- this is necessary to avoid warning on other modules -->
- <suppress-warning text="signature 'operator*(QByteArray,const char*)' for function modification in 'QByteArray' not found. Possible candidates:*"/>
- <suppress-warning text="signature 'operator+(QByteArray,QString)' for function modification in 'QByteArray' not found. Possible candidates:*"/>
+ <suppress-warning text="^signature 'operator*(QByteArray,const char*)' for function modification in 'QByteArray' not found.*"/>
+ <suppress-warning text="^signature 'operator+(QByteArray,QString)' for function modification in 'QByteArray' not found.*"/>
<!-- This enum is intenaly used -->
- <suppress-warning text="enum 'PM_CbaIconHeight' does not have a type entry or is not an enum" />
+ <suppress-warning text="enum 'PM_CbaIconHeight' does not have a type entry or is not an enum"/>
<!-- TODO: this need be removed -->
- <suppress-warning text="skipping function '*', unmatched return type '*'"/>
- <suppress-warning text="skipping function '*', unmatched type '*"/>
+ <suppress-warning text="^skipping function '.*', unmatched return type '.*$"/>
+ <suppress-warning text="^skipping function '.*', unmatched type '.*$"/>
<suppress-warning text="enum 'q_static_assert_result39' does not have a type entry or is not an enum"/>
<suppress-warning text="horribly broken type ''"/>
- <suppress-warning text="Pure virtual method 'QTextCodec::convertFromUnicode(const QChar*,int,QTextCodec::ConverterState*)const' must be implement but was completely removed on type system." />
+ <suppress-warning text="Pure virtual method 'QTextCodec::convertFromUnicode(const QChar*,int,QTextCodec::ConverterState*)const' must be implement but was completely removed on type system."/>
<!-- Qt5.5: No idea how to get rid of the following five enums, which are moved elsewhere since 5.5: -->
- <suppress-warning text="enum 'QLocale::MeasurementSystem' is specified in typesystem, but not declared" />
- <suppress-warning text="enum 'QState::RestorePolicy' is specified in typesystem, but not declared" />
- <!-- <suppress-warning text="enum 'QLocale::FormatType' is specified in typesystem, but not declared" /> -->
- <suppress-warning text="enum 'QAbstractAnimation::DeletionPolicy' is specified in typesystem, but not declared" />
- <!-- <suppress-warning text="enum 'QAbstractAnimation::State' is specified in typesystem, but not declared" /> -->
+ <suppress-warning text="enum 'QLocale::MeasurementSystem' is specified in typesystem, but not declared"/>
+ <suppress-warning text="enum 'QState::RestorePolicy' is specified in typesystem, but not declared"/>
+ <!-- <suppress-warning text="enum 'QLocale::FormatType' is specified in typesystem, but not declared"/> -->
+ <suppress-warning text="enum 'QAbstractAnimation::DeletionPolicy' is specified in typesystem, but not declared"/>
+ <!-- <suppress-warning text="enum 'QAbstractAnimation::State' is specified in typesystem, but not declared"/> -->
<!-- Qt5.5: we also suppress these warnings, instead of adding wrong enums -->
- <suppress-warning text="enum 'InterfaceType' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'TextBoundaryType' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'RelationFlag' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'Role' does not have a type entry or is not an enum" />
+ <suppress-warning text="enum 'InterfaceType' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'TextBoundaryType' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'RelationFlag' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'Role' does not have a type entry or is not an enum"/>
<!-- Anonymous enum in qtbase/src/corelib/global/qtypeinfo.h -->
- <suppress-warning text="enum 'Q_RELOCATABLE_TYPE' does not have a type entry or is not an enum" />
+ <suppress-warning text="Anonymous enum (Q_COMPLEX_TYPE, ... , Q_RELOCATABLE_TYPE) does not have a type entry"/>
<!-- Another anonymous enum / value pair in in qtbase/src/corelib/kernel/qcoreapplication.h -->
- <suppress-warning text="no matching enum 'QT_VERSION'" />
- <suppress-warning text="unhandled enum value: QT_VERSION in QCoreApplication::ApplicationFlags from header 'qcoreapplication.h'" />
- <suppress-warning text="unmatched enum QT_VERSION from header 'qcoreapplication.h'" />
+ <suppress-warning text="no matching enum 'QT_VERSION'"/>
+ <suppress-warning text="unhandled enum value: QT_VERSION in QCoreApplication::ApplicationFlags from header 'qcoreapplication.h'"/>
+ <suppress-warning text="unmatched enum QT_VERSION from header 'qcoreapplication.h'"/>
- <suppress-warning text="skipping field 'QSysInfo::WindowsVersion' with unmatched type 'const QSysInfo::WinVersion'" />
- <suppress-warning text="template baseclass 'QListSpecialMethods&lt;T&gt;' of 'QList' is not known" />
+ <suppress-warning text="skipping field 'QSysInfo::WindowsVersion' with unmatched type 'const QSysInfo::WinVersion'"/>
+ <suppress-warning text="template baseclass 'QListSpecialMethods&lt;T&gt;' of 'QList' is not known"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml
index 583c1c08e..c1a1abcb3 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml
@@ -40,7 +40,7 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtCore">
- <primitive-type name="Qt::HANDLE" target-lang-api-name="PyObject" />
+ <primitive-type name="Qt::HANDLE" target-lang-api-name="PyObject"/>
<!-- Qt5: had to move QAbstractEventDispatcher into os-specific files because of Windows -->
<object-type name="QAbstractEventDispatcher">
<modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/>
@@ -50,8 +50,8 @@
<object-type name="QSysInfo">
<enum-type name="Endian"/>
<enum-type name="Sizes"/>
- <enum-type name="MacVersion" since="5.5" />
+ <enum-type name="MacVersion" since="5.5"/>
</object-type>
- <suppress-warning text="skipping field 'QSysInfo::WindowsVersion' with unmatched type 'QSysInfo::WinVersion'" />
- <suppress-warning text="enum 'QSysInfo::WinVersion' does not have a type entry or is not an enum" />
+ <suppress-warning text="skipping field 'QSysInfo::WindowsVersion' with unmatched type 'QSysInfo::WinVersion'"/>
+ <suppress-warning text="enum 'QSysInfo::WinVersion' does not have a type entry or is not an enum"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml
index 410187281..afd733b35 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml
@@ -43,7 +43,7 @@
<extra-includes>
<include file-name="windows.h" location="global"/>
</extra-includes>
- <primitive-type name="Qt::HANDLE" target-lang-api-name="PyObject" />
+ <primitive-type name="Qt::HANDLE" target-lang-api-name="PyObject"/>
<primitive-type name="HWND">
<!-- Qt5: Add this include there to insert ti in the global qtcore header (needed by qprocess_wrapper) -->
<include file-name="wtypes.h" location="global"/>
@@ -74,7 +74,7 @@
</inject-code>
<!-- Qt5: had to move QAbstractEventDispatcher into os-specific files because of Windows -->
- <object-type name="QWinEventNotifier" />
+ <object-type name="QWinEventNotifier"/>
<object-type name="QAbstractEventDispatcher">
<modify-function signature="processEvents(QFlags&lt;QEventLoop::ProcessEventsFlag>)" allow-thread="yes"/>
<!-- Qt5: had to add this recursive object def. This was crucial to get rid of "pure virtual" -->
@@ -83,8 +83,8 @@
<object-type name="QSysInfo">
<enum-type name="Endian"/>
<enum-type name="Sizes"/>
- <enum-type name="WinVersion" since="5.5" />
+ <enum-type name="WinVersion" since="5.5"/>
</object-type>
- <suppress-warning text="skipping field 'QSysInfo::MacintoshVersion' with unmatched type 'QSysInfo::MacVersion'" />
- <suppress-warning text="enum 'QSysInfo::MacVersion' does not have a type entry or is not an enum" />
+ <suppress-warning text="skipping field 'QSysInfo::MacintoshVersion' with unmatched type 'QSysInfo::MacVersion'"/>
+ <suppress-warning text="enum 'QSysInfo::MacVersion' does not have a type entry or is not an enum"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml
index d5b0bae3b..c3cbd3666 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml
@@ -54,8 +54,8 @@
<enum-type name="Endian"/>
<enum-type name="Sizes"/>
</object-type>
- <suppress-warning text="skipping field 'QSysInfo::MacintoshVersion' with unmatched type 'QSysInfo::MacVersion'" />
- <suppress-warning text="skipping field 'QSysInfo::WindowsVersion' with unmatched type 'QSysInfo::MacVersion'" />
- <suppress-warning text="enum 'QSysInfo::MacVersion' does not have a type entry or is not an enum" />
- <suppress-warning text="enum 'QSysInfo::WinVersion' does not have a type entry or is not an enum" />
+ <suppress-warning text="skipping field 'QSysInfo::MacintoshVersion' with unmatched type 'QSysInfo::MacVersion'"/>
+ <suppress-warning text="skipping field 'QSysInfo::WindowsVersion' with unmatched type 'QSysInfo::MacVersion'"/>
+ <suppress-warning text="enum 'QSysInfo::MacVersion' does not have a type entry or is not an enum"/>
+ <suppress-warning text="enum 'QSysInfo::WinVersion' does not have a type entry or is not an enum"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt b/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt
index e61a70234..59c779fbd 100644
--- a/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt
@@ -61,10 +61,9 @@ set(QtDataVisualization_libraries pyside2
set(QtDataVisualization_deps QtCore QtGui)
-create_pyside_module(QtDataVisualization
- QtDataVisualization_include_dirs
- QtDataVisualization_libraries
- QtDataVisualization_deps
- QtDataVisualization_SOURCE_DIR
- QtDataVisualization_SRC
- "")
+create_pyside_module(NAME QtDataVisualization
+ INCLUDE_DIRS QtDataVisualization_include_dirs
+ LIBRARIES QtDataVisualization_libraries
+ DEPS QtDataVisualization_deps
+ TYPESYSTEM_PATH QtDataVisualization_SOURCE_DIR
+ SOURCES QtDataVisualization_SRC)
diff --git a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
index d2018ffca..94e6f4b88 100644
--- a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
+++ b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml
@@ -41,38 +41,7 @@
-->
<typesystem package="PySide2.QtDataVisualization">
- <template name="cppqlistofptrtoqvectors_to_py_conversion">
- const int rowCount = %in.size();
- PyObject* %out = PyList_New(rowCount);
- for (int r = 0; r &lt; rowCount; ++r) {
- const QVector&lt;%INTYPE_0&gt; *row = %in.at(r);
- const int columnCount = row->size();
- PyObject *pyRow = PyList_New(columnCount);
- for (int c = 0; c &lt; columnCount; ++c) {
- const %INTYPE_0 &amp;cppItem = row->at(c);
- PyList_SET_ITEM(pyRow, c, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
- }
- PyList_SET_ITEM(%out, r, pyRow);
- }
- return %out;
- </template>
- <template name="py_to_cppqlistofptrtoqvectors_conversion">
- const int rowCount = int(PySequence_Size(%in));
- %OUTTYPE &amp;result = %out;
- result.reserve(rowCount);
- for (int r = 0; r &lt; rowCount; ++r) {
- Shiboken::AutoDecRef rowItem(PySequence_GetItem(%in, r));
- const int columnCount = int(PySequence_Size(rowItem));
- QVector&lt;%OUTTYPE_0&gt; *row = new QVector&lt;%OUTTYPE_0&gt;;
- row->reserve(columnCount);
- for (int c = 0; c &lt; columnCount; ++c) {
- Shiboken::AutoDecRef pyItem(PySequence_GetItem(rowItem, c));
- %OUTTYPE_0 v = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
- row->append(v);
- }
- result.append(row);
- }
- </template>
+ <load-typesystem name="templates/datavisualization_common.xml" generate="no" />
<load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
<namespace-type name="QtDataVisualization">
<primitive-type name="QBarDataArray">
@@ -313,9 +282,7 @@
<modify-argument index="1">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
</modify-function>
<modify-function signature="setColumnAxis(QtDataVisualization::QCategory3DAxis*)">
<modify-argument index="1">
@@ -343,9 +310,7 @@
<modify-argument index="1">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
</modify-function>
<modify-function signature="setAxisX(QtDataVisualization::QValue3DAxis*)">
<modify-argument index="1">
@@ -374,9 +339,7 @@
<modify-argument index="1">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
</modify-function>
<modify-function signature="setAxisX(QtDataVisualization::QValue3DAxis*)">
<modify-argument index="1">
@@ -418,25 +381,19 @@
<modify-argument index="1">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
</modify-function>
<modify-function signature="releaseInputHandler(QtDataVisualization::QAbstract3DInputHandler*)">
<modify-argument index="1">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
</modify-function>
<modify-function signature="releaseTheme(QtDataVisualization::Q3DTheme*)">
<modify-argument index="1">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtdatavisualization.cpp" snippet="releaseownership"/>
</modify-function>
<modify-function signature="setActiveInputHandler(QtDataVisualization::QAbstract3DInputHandler*)">
<modify-argument index="1">
diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt
index 1fe743c01..f514ea7c9 100644
--- a/sources/pyside2/PySide2/QtGui/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt
@@ -2,11 +2,9 @@ project(QtGui)
qt5_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h")
-set(QtGui_OPTIONAL_SRC)
set(QtGui_DROPPED_ENTRIES)
-check_qt_class(QtGui QOpenGLTimeMonitor QtGui_OPTIONAL_SRC QtGui_DROPPED_ENTRIES)
-check_qt_class(QtGui QOpenGLTimerQuery QtGui_OPTIONAL_SRC QtGui_DROPPED_ENTRIES)
+get_property(QtGui_enabled_features TARGET Qt5::Gui PROPERTY INTERFACE_QT_ENABLED_FEATURES)
set(QtGui_SRC
${QtGui_GEN_DIR}/qabstractopenglfunctions_wrapper.cpp
@@ -207,11 +205,23 @@ ${QtGui_GEN_DIR}/qwhatsthisclickedevent_wrapper.cpp
${QtGui_GEN_DIR}/qwheelevent_wrapper.cpp
${QtGui_GEN_DIR}/qwindow_wrapper.cpp
${QtGui_GEN_DIR}/qwindowstatechangeevent_wrapper.cpp
-${QtGui_OPTIONAL_SRC}
# module is always needed
${QtGui_GEN_DIR}/qtgui_module_wrapper.cpp
)
+# cf qtbase/src/gui/opengl/opengl.pri
+list(FIND QtGui_enabled_features "opengles2" _opengles2Index)
+# ### fixme: For cmake >= 3.3: if(opengles2 IN_LIST QtGui_enabled_features)
+if(_opengles2Index GREATER -1)
+ list(APPEND QtGui_DROPPED_ENTRIES QOpenGLTimeMonitor QOpenGLTimerQuery)
+ message(STATUS "Qt5Gui: Dropping Desktop OpenGL classes (GLES2)")
+else()
+ list(APPEND QtGui_SRC
+ ${QtGui_GEN_DIR}/qopengltimemonitor_wrapper.cpp
+ ${QtGui_GEN_DIR}/qopengltimerquery_wrapper.cpp)
+ message(STATUS "Qt5Gui: Adding Desktop OpenGL classes")
+endif()
+
configure_file("${QtGui_SOURCE_DIR}/typesystem_gui.xml.in"
"${QtGui_BINARY_DIR}/typesystem_gui.xml" @ONLY)
@@ -234,17 +244,15 @@ set(QtGui_libraries pyside2
${Qt5Gui_LIBRARIES})
set(QtGui_deps QtCore)
-create_pyside_module(QtGui
- QtGui_include_dirs
- QtGui_libraries
- QtGui_deps
- QtGui_SOURCE_DIR
- QtGui_SRC
- QPYTEXTOBJECT_MOC
- ${QtGui_BINARY_DIR}/typesystem_gui.xml
- ""
- ""
- QtGui_DROPPED_ENTRIES)
+create_pyside_module(NAME QtGui
+ INCLUDE_DIRS QtGui_include_dirs
+ LIBRARIES QtGui_libraries
+ DEPS QtGui_deps
+ TYPESYSTEM_PATH QtGui_SOURCE_DIR
+ SOURCES QtGui_SRC
+ STATIC_SOURCES QPYTEXTOBJECT_MOC
+ TYPESYSTEM_NAME ${QtGui_BINARY_DIR}/typesystem_gui.xml
+ DROPPED_ENTRIES QtGui_DROPPED_ENTRIES)
install(FILES ${pyside2_SOURCE_DIR}/qpytextobject.h DESTINATION include/PySide2/QtGui/)
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
index 70fd1692a..2181ff073 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml
@@ -41,36 +41,27 @@
-->
<typesystem package="PySide2.QtGui">
<load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+ <load-typesystem name="templates/gui_common.xml" generate="no"/>
- <template name="QFontCharFix">
- int size = Shiboken::String::len(%PYARG_1);
- if (size == 1) {
- const char *str = Shiboken::String::toCString(%PYARG_1);
- QChar ch(str[0]);
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ch);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- } else {
- PyErr_SetString(PyExc_TypeError, "String must have only one character");
- }
- </template>
<rejection class="^Q.*$" argument-type="^QPlatform.*$"/>
- <function signature="qAlpha(uint)" />
- <function signature="qBlue(uint)" />
- <function signature="qGray(int,int,int)" />
- <function signature="qGray(uint)" />
- <function signature="qGreen(uint)" />
- <function signature="qIsGray(uint)" />
- <function signature="qRed(uint)" />
- <function signature="qRgb(int,int,int)" />
- <function signature="qRgba(int,int,int,int)" />
- <function signature="qFuzzyCompare(QMatrix,QMatrix)" />
- <function signature="qFuzzyCompare(QTransform,QTransform)" />
- <function signature="qFuzzyCompare(QQuaternion,QQuaternion)" />
- <function signature="qFuzzyCompare(QMatrix4x4,QMatrix4x4)" />
- <function signature="qFuzzyCompare(QVector2D,QVector2D)" />
- <function signature="qFuzzyCompare(QVector3D,QVector3D)" />
- <function signature="qFuzzyCompare(QVector4D,QVector4D)" />
+ <function signature="qAlpha(uint)"/>
+ <function signature="qBlue(uint)"/>
+ <function signature="qGray(int,int,int)"/>
+ <function signature="qGray(uint)"/>
+ <function signature="qGreen(uint)"/>
+ <function signature="qIsGray(uint)"/>
+ <function signature="qRed(uint)"/>
+ <function signature="qRgb(int,int,int)"/>
+ <function signature="qRgba(int,int,int,int)"/>
+ <function signature="qFuzzyCompare(QMatrix,QMatrix)"/>
+ <function signature="qFuzzyCompare(QTransform,QTransform)"/>
+ <function signature="qFuzzyCompare(QQuaternion,QQuaternion)"/>
+ <function signature="qFuzzyCompare(QMatrix4x4,QMatrix4x4)"/>
+ <function signature="qFuzzyCompare(QVector2D,QVector2D)"/>
+ <function signature="qFuzzyCompare(QVector3D,QVector3D)"/>
+ <function signature="qFuzzyCompare(QVector4D,QVector4D)"/>
<rejection class="*" function-name="qobject_interface_iid&lt;QStyleFactoryInterface*&gt;"/>
<rejection class="*" function-name="qobject_interface_iid&lt;QAccessibleFactoryInterface*&gt;"/>
<rejection class="*" function-name="qobject_interface_iid&lt;QInputContextFactoryInterface*&gt;"/>
@@ -97,21 +88,21 @@
<rejection class="*" function-name="d_func"/>
<rejection class="*" field-name="d_ptr"/>
<rejection class="*" field-name="d"/>
- <rejection class="^QOpenGL.*$" argument-type="^GLboolean( const)?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?GLboolean ?\*$"/>
<rejection class="^QOpenGL.*$" argument-type="^GLchar\*$"/>
- <rejection class="^QOpenGL.*$" argument-type="GLchar *const const*"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?GLchar ?\*(const)?\*$"/>
<rejection class="^QOpenGL.*$" argument-type="^char\*$"/>
- <rejection class="^QOpenGL.*$" argument-type="^char( const)?\*\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?char ?\*\*$"/>
<rejection class="^QOpenGL.*$" argument-type="GLintptr"/>
<rejection class="^QOpenGL.*$" argument-type="GLsizeiptr"/>
<rejection class="^QOpenGL.*$" argument-type="GLsync"/>
<rejection class="^QOpenGL.*$" argument-type="^GLubyte( const)?\*$"/>
- <rejection class="^QOpenGL.*$" argument-type="^QMatrix.x.( const)?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?QMatrix.x. ?\*$"/>
<rejection class="^QOpenGL.*$" argument-type="qopengl_GLintptr"/>
<rejection class="^QOpenGL.*$" argument-type="qopengl_GLsizeiptr"/>
<rejection class="^QOpenGL.*$" argument-type="QOpenGLTextureHelper*"/>
- <rejection class="^QOpenGL.*$" argument-type="^QVector.D( const)?\*$"/>
- <rejection class="^QOpenGL.*$" argument-type="^void( const)?\*\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?QVector.D ?\*$"/>
+ <rejection class="^QOpenGL.*$" argument-type="^(const )?void ?\*\*$"/>
<!--
Event classes have a lot of non-documented protected fields, those fields
@@ -212,13 +203,9 @@
<primitive-type name="WId" target-lang-api-name="PyLong">
<conversion-rule>
- <native-to-target>
- return PyLong_FromVoidPtr(reinterpret_cast&lt;void *&gt;(%in));
- </native-to-target>
+ <native-to-target file="../glue/qtgui.cpp" snippet="return-pylong-voidptr"/>
<target-to-native>
- <add-conversion type="PyLong">
- %out = reinterpret_cast&lt;%OUTTYPE&gt;(PyLong_AsVoidPtr(%in));
- </add-conversion>
+ <add-conversion type="PyLong" file="../glue/qtgui.cpp" snippet="conversion-pylong"/>
</target-to-native>
</conversion-rule>
</primitive-type>
@@ -257,9 +244,9 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f, %f, %f, %f, %f, %f, %f" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f, %f, %f, %f, %f, %f"/>
<replace from="%REPR_ARGS"
- to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m13(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.m23(), %CPPSELF.m31(), %CPPSELF.m32(), %CPPSELF.m33()" />
+ to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m13(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.m23(), %CPPSELF.m31(), %CPPSELF.m32(), %CPPSELF.m33()"/>
</insert-template>
</inject-code>
</add-function>
@@ -267,16 +254,16 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="ddddddddd" />
+ <replace from="%REDUCE_FORMAT" to="ddddddddd"/>
<replace from="%REDUCE_ARGS"
- to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m13(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.m23(), %CPPSELF.m31(), %CPPSELF.m32(), %CPPSELF.m33()" />
+ to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m13(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.m23(), %CPPSELF.m31(), %CPPSELF.m32(), %CPPSELF.m33()"/>
</insert-template>
</inject-code>
</add-function>
<modify-function signature="map(qreal,qreal,qreal*,qreal*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="3">
<remove-argument/>
@@ -286,7 +273,7 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_args,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -306,38 +293,14 @@
</inject-code>
</modify-function>
<add-function signature="quadToQuad(QPolygonF&amp;,QPolygonF&amp;)" return-type="PyObject*" static="true">
- <inject-code>
- QTransform _result;
- if (QTransform::quadToQuad(%1, %2, _result)) {
- %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
- } else {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- }
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qtransform-quadtoquad"/>
</add-function>
<add-function signature="quadToSquare(QPolygonF &amp;)" return-type="PyObject*" static="true">
- <inject-code>
- QTransform _result;
- if (QTransform::quadToSquare(%1, _result)) {
- %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
- } else {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- }
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qtransform-quadtosquare"/>
</add-function>
<add-function signature="squareToQuad(QPolygonF &amp;)" return-type="PyObject*" static="true">
- <inject-code>
- QTransform _result;
- if (QTransform::squareToQuad(%1, _result)) {
- %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
- } else {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- }
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qtransform-squaretoquad"/>
</add-function>
<!-- Disambiguate from Qt3DCore/qtransform.h -->
<include file-name="QtGui/qtransform.h" location="global"/>
@@ -346,21 +309,17 @@
<value-type name="QStaticText">
<enum-type name="PerformanceHint"/>
</value-type>
- <value-type name="QTextFragment" />
+ <value-type name="QTextFragment"/>
<value-type name="QBitmap" >
<modify-function signature="fromData(QSize,const uchar*,QImage::Format)">
<modify-argument index="2">
<replace-type modified-type="PyBuffer"/>
</modify-argument>
- <inject-code>
- uchar *buffer = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_2));
- QBitmap %0 = QBitmap::fromData(%1, buffer, %3);
- %PYARG_0 = %CONVERTTOPYTHON[QBitmap](%0);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qbitmap-fromdata"/>
</modify-function>
</value-type>
- <value-type name="QTextInlineObject" />
- <value-type name="QTextDocumentFragment" />
+ <value-type name="QTextInlineObject"/>
+ <value-type name="QTextDocumentFragment"/>
<value-type name="QTextOption">
<enum-type name="Flag" flags="Flags"/>
<enum-type name="TabType"/>
@@ -370,19 +329,12 @@
<value-type name="QTextLine" >
<enum-type name="CursorPosition"/>
<enum-type name="Edge"/>
- <modify-function signature="cursorToX(int*,QTextLine::Edge)const" remove="all" />
+ <modify-function signature="cursorToX(int*,QTextLine::Edge)const" remove="all"/>
<modify-function signature="cursorToX(int,QTextLine::Edge)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE %0 = %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;%1, %2);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qtextline-cursortox"/>
</modify-function>
<modify-function signature="xToCursor(qreal,QTextLine::CursorPosition)const">
<modify-argument index="2">
@@ -390,12 +342,11 @@
</modify-argument>
</modify-function>
</value-type>
- <value-type name="QTextTableFormat" />
- <value-type name="QTextImageFormat" />
+ <value-type name="QTextTableFormat"/>
+ <value-type name="QTextImageFormat"/>
<value-type name="QTextFrameFormat" >
<enum-type name="BorderStyle"/>
<enum-type name="Position"/>
- <modify-function signature="isValid()const" access="non-final"/>
</value-type>
<value-type name="QTextLength">
<enum-type name="Type"/>
@@ -403,18 +354,15 @@
<value-type name="QPainterPath">
<enum-type name="ElementType"/>
<value-type name="Element">
- <modify-field name="x" write="false"/>
- <modify-field name="y" write="false"/>
- <modify-field name="type" write="false"/>
<include file-name="QPainterPath" location="global"/>
</value-type>
</value-type>
<value-type name="QPalette">
- <enum-type name="ColorGroup" />
- <enum-type name="ColorRole" />
+ <enum-type name="ColorGroup"/>
+ <enum-type name="ColorRole"/>
</value-type>
<object-type name="QInputMethod">
- <enum-type name="Action" />
+ <enum-type name="Action"/>
</object-type>
<value-type name="QKeySequence">
<enum-type name="SequenceFormat"/>
@@ -424,9 +372,9 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%i, %i, %i, %i" />
+ <replace from="%REPR_FORMAT" to="%i, %i, %i, %i"/>
<replace from="%REPR_ARGS"
- to="(*%CPPSELF)[0], (*%CPPSELF)[1], (*%CPPSELF)[2], (*%CPPSELF)[3]" />
+ to="(*%CPPSELF)[0], (*%CPPSELF)[1], (*%CPPSELF)[2], (*%CPPSELF)[3]"/>
</insert-template>
</inject-code>
</add-function>
@@ -434,22 +382,15 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="iiii" />
- <replace from="%REDUCE_ARGS" to="(*%CPPSELF)[0], (*%CPPSELF)[1], (*%CPPSELF)[2], (*%CPPSELF)[3]" />
+ <replace from="%REDUCE_FORMAT" to="iiii"/>
+ <replace from="%REDUCE_ARGS" to="(*%CPPSELF)[0], (*%CPPSELF)[1], (*%CPPSELF)[2], (*%CPPSELF)[3]"/>
</insert-template>
</inject-code>
</add-function>
<modify-function signature="operator[](uint)const" remove="all"/>
<add-function signature="__getitem__">
- <inject-code class="target" position="beginning">
- if (_i &lt; 0 || _i >= %CPPSELF.count()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return 0;
- }
- int item = (*%CPPSELF)[_i];
- return %CONVERTTOPYTHON[int](item);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qkeysequence-getitem"/>
</add-function>
<!-- ### Not necessary due the PySide QVariant conversion rules -->
@@ -465,25 +406,22 @@
<modify-argument index="return">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code>
- %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.data(), %CPPSELF.size());
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpicture-data"/>
</modify-function>
<modify-function signature="setData(const char*,uint)">
<modify-argument index="1">
<replace-type modified-type="PyBuffer"/>
<conversion-rule class="target">
- PyObject *%out = Shiboken::Buffer::newObject(%in, size);
+ <insert-template name="const_char_pybuffer"/>
</conversion-rule>
<conversion-rule class="native">
- Py_ssize_t bufferLen;
- char *%out = reinterpret_cast&lt;char*&gt;(Shiboken::Buffer::getPointer(%PYARG_1, &amp;bufferLen));
+ <insert-template name="pybuffer_const_char"/>
</conversion-rule>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
<conversion-rule class="native">
- uint %out = bufferLen;
+ <insert-template name="uint_remove"/>
</conversion-rule>
</modify-argument>
</modify-function>
@@ -506,13 +444,13 @@
<!-- ### -->
<add-function signature="__iter__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="__iter__" />
+ <insert-template name="__iter__"/>
</inject-code>
</add-function>
<add-function signature="__next__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="__next__">
- <replace from="%CPPSELF_TYPE" to="QTextBlock::iterator" />
+ <replace from="%CPPSELF_TYPE" to="QTextBlock::iterator"/>
</insert-template>
</inject-code>
</add-function>
@@ -520,48 +458,34 @@
<add-function signature="__iter__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="__iter_parent__">
- <replace from="%CPPSELF_TYPE" to="QTextBlock::iterator" />
+ <replace from="%CPPSELF_TYPE" to="QTextBlock::iterator"/>
</insert-template>
</inject-code>
</add-function>
<modify-function signature="setUserData(QTextBlockUserData*)">
- <inject-code class="target" position="end">
- const QTextDocument *doc = %CPPSELF.document();
- if (doc) {
- Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument*](doc));
- Shiboken::Object::setParent(pyDocument, %PYARG_1);
- }
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qtextblock-setuserdata"/>
</modify-function>
<modify-function signature="userData()const">
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
</modify-argument>
- <inject-code class="target" position="end">
- const QTextDocument *doc = %CPPSELF.document();
- if (doc) {
- Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument*](doc));
- Shiboken::Object::setParent(pyDocument, %PYARG_0);
- }
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qtextblock-userdata"/>
</modify-function>
</value-type>
<value-type name="QTextBlockFormat">
<enum-type name="LineHeightTypes" since="4.8" revision="4800"/>
</value-type>
- <value-type name="QTextTableCellFormat" />
+ <value-type name="QTextTableCellFormat"/>
<value-type name="QTextCharFormat" >
<enum-type name="FontPropertiesInheritanceBehavior"/>
<enum-type name="UnderlineStyle"/>
<enum-type name="VerticalAlignment"/>
- <modify-function signature="isValid()const" access="non-final"/>
</value-type>
<value-type name="QTextFormat" >
<enum-type name="FormatType"/>
<enum-type name="ObjectTypes"/>
<enum-type name="PageBreakFlag" flags="PageBreakFlags"/>
- <enum-type name="Property" />
- <modify-function signature="isValid()const" access="non-final"/>
+ <enum-type name="Property"/>
</value-type>
<value-type name="QTextListFormat">
<enum-type name="Style"/>
@@ -572,17 +496,10 @@
<include file-name="QTransform" location="global"/>
</extra-includes>
<add-function signature="__reduce__" return-type="PyObject*">
- <inject-code class="target" position="beginning">
- PyObject *points = PyList_New(%CPPSELF.count());
- for (int i = 0, max = %CPPSELF.count(); i &lt; max; ++i){
- int x, y;
- %CPPSELF.point(i, &amp;x, &amp;y);
- QPoint pt = QPoint(x, y);
- PyList_SET_ITEM(points, i, %CONVERTTOPYTHON[QPoint](pt));
- }
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qpolygon-reduce">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="N" />
- <replace from="%REDUCE_ARGS" to="points" />
+ <replace from="%REDUCE_FORMAT" to="N"/>
+ <replace from="%REDUCE_ARGS" to="points"/>
</insert-template>
</inject-code>
</add-function>
@@ -592,18 +509,10 @@
<!-- ### A QVector parameter, for no defined type, will generate wrong code. -->
<modify-function signature="operator+=(QVector&lt;QPoint&gt;)" remove="all"/>
<modify-function signature="operator&lt;&lt;(QPoint)">
- <inject-code>
- // %FUNCTION_NAME()
- *%CPPSELF &lt;&lt; %1;
- %PYARG_0 = %CONVERTTOPYTHON[QPolygon*](%CPPSELF);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpolygon-operatorlowerlower"/>
</modify-function>
<modify-function signature="operator&lt;&lt;(QVector&lt;QPoint&gt;)">
- <inject-code>
- // %FUNCTION_NAME()
- *%CPPSELF &lt;&lt; %1;
- %PYARG_0 = %CONVERTTOPYTHON[QPolygon*](%CPPSELF);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpolygon-operatorlowerlower"/>
</modify-function>
<!-- ### -->
</value-type>
@@ -631,26 +540,6 @@
</modify-function>
</value-type>
- <template name="load_xpm">
- Shiboken::AutoDecRef strList(PySequence_Fast(%PYARG_1, "Invalid sequence."));
- int lineCount = PySequence_Fast_GET_SIZE(strList.object());
- for (int line = 0; line &lt; lineCount; ++line) {
- if (!Shiboken::String::check(PySequence_Fast_GET_ITEM(strList.object(), line))) {
- PyErr_SetString(PyExc_TypeError, "The argument must be a sequence of strings.");
- break;
- }
- }
-
- const char **xpm = reinterpret_cast&lt;const char**&gt;(malloc(lineCount * sizeof(const char**)));
- for (int line = 0; line &lt; lineCount; ++line)
- xpm[line] = Shiboken::String::toCString(PySequence_Fast_GET_ITEM(strList.object(), line));
-
- %BEGIN_ALLOW_THREADS
- %0 = new %TYPE(xpm);
- %END_ALLOW_THREADS
-
- free(xpm);
- </template>
<value-type name="QPixmap" >
<!--<conversion-rule>-->
<!--<target-to-native replace="no">-->
@@ -664,16 +553,14 @@
<modify-argument index="1">
<rename to="image"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %0 = new %TYPE(QPixmap::fromImage(%1));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qpixmap"/>
</add-function>
- <modify-function signature="QPixmap(const char*[])">
+ <modify-function signature="QPixmap(const char*const[])">
<modify-argument index="1">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="load_xpm" />
+ <insert-template name="load_xpm"/>
</inject-code>
</modify-function>
@@ -681,16 +568,28 @@
<modify-function signature="operator!()const" remove="all"/>
<modify-function signature="loadFromData(const uchar*,uint,const char*,QFlags&lt;Qt::ImageConversionFlag&gt;)">
+ <inject-documentation format="target" mode="append">
+ This method must be used with an QPixmap object, not the class:
+
+ ::
+
+ # Wrong
+ pixmap = QPixmap.loadFromData(...)
+
+ # Right
+ pixmap = QPixmap().loadFromData(...)
+
+ </inject-documentation>
<modify-argument index="1">
<replace-type modified-type="PyBytes"/>
<conversion-rule class="native">
- const uchar *%out = reinterpret_cast&lt;const uchar*>(PyBytes_AS_STRING(%PYARG_1));
+ <insert-template name="pybytes_const_uchar"/>
</conversion-rule>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
<conversion-rule class="native">
- uint %out = static_cast&lt;uint>(PyBytes_Size(%PYARG_1));
+ <insert-template name="pybytes_uint"/>
</conversion-rule>
</modify-argument>
</modify-function>
@@ -705,7 +604,7 @@
<enum-type name="SelectionType"/>
<modify-function signature="selectedTableCells(int*,int*,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -721,12 +620,12 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
<inject-code class="native" position="end">
<insert-template name="fix_native_return_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
@@ -755,9 +654,9 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f, %f, %f, %f" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f, %f, %f"/>
<replace from="%REPR_ARGS"
- to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.dx(), %CPPSELF.dy()" />
+ to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.dx(), %CPPSELF.dy()"/>
</insert-template>
</inject-code>
</add-function>
@@ -765,18 +664,11 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dddddd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.dx(), %CPPSELF.dy()" />
+ <replace from="%REDUCE_FORMAT" to="dddddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.m11(), %CPPSELF.m12(), %CPPSELF.m21(), %CPPSELF.m22(), %CPPSELF.dx(), %CPPSELF.dy()"/>
</insert-template>
</inject-code>
</add-function>
- <template name="qmatrix_map">
- %ARG1_TYPE a, b;
- %CPPSELF.%FUNCTION_NAME(%1, %2, &amp;a, &amp;b);
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%ARG1_TYPE](a));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](b));
- </template>
<modify-function signature="map(int,int,int*,int*)const">
<modify-argument index="3">
<remove-argument />
@@ -785,7 +677,7 @@
<remove-argument />
</modify-argument>
<inject-code>
- <insert-template name="qmatrix_map" />
+ <insert-template name="qmatrix_map"/>
</inject-code>
</modify-function>
<modify-function signature="map(qreal,qreal,qreal*,qreal*)const">
@@ -796,9 +688,15 @@
<remove-argument />
</modify-argument>
<inject-code>
- <insert-template name="qmatrix_map" />
+ <insert-template name="qmatrix_map"/>
</inject-code>
</modify-function>
+ <modify-function signature="map(const QPoint&amp;)const">
+ <modify-argument index="return">
+ <replace-type modified-type="QPoint"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qmatrix-map-point" />
+ </modify-function>
<modify-function signature="inverted(bool*)const">
<modify-argument index="1">
<remove-argument/>
@@ -812,15 +710,15 @@
</modify-function>
</value-type>
- <value-type name="QConicalGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::ConicalGradient" />
- <value-type name="QFontInfo" />
- <value-type name="QRadialGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::RadialGradient" />
+ <value-type name="QConicalGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::ConicalGradient"/>
+ <value-type name="QFontInfo"/>
+ <value-type name="QRadialGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::RadialGradient"/>
<value-type name="QFont" >
<enum-type name="Capitalization"/>
<enum-type name="SpacingType"/>
<enum-type name="Stretch"/>
<enum-type name="Style"/>
- <enum-type name="StyleHint" />
+ <enum-type name="StyleHint"/>
<enum-type name="StyleStrategy"/>
<enum-type name="Weight"/>
<enum-type name="HintingPreference" since="4.8" revision="4800"/>
@@ -843,7 +741,7 @@
<include file-name="QImage" location="global"/>
</extra-includes>
</function> -->
- <primitive-type name="QImageCleanupFunction" />
+ <primitive-type name="QImageCleanupFunction"/>
<value-type name="QImage">
<enum-type name="Format"/>
<enum-type name="InvertMode"/>
@@ -852,17 +750,13 @@
<include file-name="QMatrix" location="global"/>
</extra-includes>
- <template name="qimage_buffer_constructor">
- uchar *ptr = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1));
- %0 = new %TYPE(ptr, %ARGS);
- </template>
<modify-function signature="QImage(uchar*,int,int,int,QImage::Format,QImageCleanupFunction,void*)">
<modify-argument index="1">
<replace-type modified-type="PyBuffer"/>
</modify-argument>
<inject-code>
<insert-template name="qimage_buffer_constructor">
- <replace from="%ARGS" to="%2, %3, %4, %5" />
+ <replace from="%ARGS" to="%2, %3, %4, %5"/>
</insert-template>
</inject-code>
</modify-function>
@@ -872,7 +766,7 @@
</modify-argument>
<inject-code>
<insert-template name="qimage_buffer_constructor">
- <replace from="%ARGS" to="%2, %3, %4" />
+ <replace from="%ARGS" to="%2, %3, %4"/>
</insert-template>
</inject-code>
</modify-function>
@@ -880,61 +774,52 @@
<add-function signature="QImage(QString&amp;,int,int,int,QImage::Format)">
<inject-code>
<insert-template name="qimage_buffer_constructor">
- <replace from="%ARGS" to="%2, %3, %4, %5" />
+ <replace from="%ARGS" to="%2, %3, %4, %5"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QImage(QString&amp;,int,int,QImage::Format)">
<inject-code>
<insert-template name="qimage_buffer_constructor">
- <replace from="%ARGS" to="%2, %3, %4" />
+ <replace from="%ARGS" to="%2, %3, %4"/>
</insert-template>
</inject-code>
</add-function>
<!-- The non-const versions are already used -->
<modify-function signature="QImage(const uchar*,int,int,int,QImage::Format,QImageCleanupFunction,void*)" remove="all"/>
- <modify-function signature="QImage(const uchar*,int,int,QImage::Format,QImageCleanupFunction,void*)" remove="all" />
+ <modify-function signature="QImage(const uchar*,int,int,QImage::Format,QImageCleanupFunction,void*)" remove="all"/>
<!-- ### -->
- <modify-function signature="QImage(const char*[])">
+ <modify-function signature="QImage(const char*const[])">
<modify-argument index="1">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="load_xpm" />
+ <insert-template name="load_xpm"/>
</inject-code>
</modify-function>
<!-- ### There is already an fromData with a QByteArray type (that is convertible from Python's str) as the first type. -->
<modify-function signature="fromData(const uchar*,int,const char*)" remove="all"/>
<!-- ### There is already an loadFromData with a QByteArray type (that is convertible from Python's str) as the first type. -->
- <modify-function signature="loadFromData(const uchar*,int,const char*)" remove="all" />
+ <modify-function signature="loadFromData(const uchar*,int,const char*)" remove="all"/>
<modify-function signature="constBits()const" since="4.7">
- <inject-code>
- %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.byteCount());
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-constbits"/>
</modify-function>
<modify-function signature="bits()">
- <inject-code>
- // byteCount() is only available on Qt4.7, so we use bytesPerLine * height
- %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.bytesPerLine() * %CPPSELF.height(), Shiboken::Buffer::ReadWrite);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-bits"/>
</modify-function>
<modify-function signature="constScanLine(int)const" since="4.7">
- <inject-code>
- %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine());
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-constscanline"/>
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
</modify-function>
<modify-function signature="scanLine(int)">
- <inject-code>
- %PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine(), Shiboken::Buffer::ReadWrite);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qimage-scanline"/>
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
</modify-function>
<!--
@@ -961,8 +846,8 @@
<extra-includes>
<include file-name="QStringList" location="global"/>
</extra-includes>
- <enum-type name="SystemFont" />
- <enum-type name="WritingSystem" />
+ <enum-type name="SystemFont"/>
+ <enum-type name="WritingSystem"/>
</value-type>
<value-type name="QPen">
<extra-includes>
@@ -975,48 +860,6 @@
</extra-includes>
</value-type>
- <template name="qcolor_repr">
- switch(%CPPSELF.spec()) {
- case QColor::Rgb:
- {
- qreal r, g, b, a;
- %CPPSELF.getRgbF(&amp;r, &amp;g, &amp;b, &amp;a);
- QString repr = QString().sprintf("PySide2.QtGui.QColor.fromRgbF(%.6f, %.6f, %.6f, %.6f)", r, g, b, a);
- %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
- break;
- }
- case QColor::Hsv:
- {
- qreal h, s, v, a;
- %CPPSELF.getHsvF(&amp;h, &amp;s, &amp;v, &amp;a);
- QString repr = QString().sprintf("PySide2.QtGui.QColor.fromHsvF(%.6f, %.6f, %.6f, %.6f)", h, s, v, a);
- %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
- break;
- }
- case QColor::Cmyk:
- {
- qreal c, m, y, k, a;
- %CPPSELF.getCmykF(&amp;c, &amp;m, &amp;y, &amp;k, &amp;a);
- QString repr = QString().sprintf("PySide2.QtGui.QColor.fromCmykF(%.6f, %.6f, %.6f, %.6f, %.6f)", c, m, y, k, a);
- %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
- break;
- }
- #if QT_VERSION >= 0x040600
- case QColor::Hsl:
- {
- qreal h, s, l, a;
- %CPPSELF.getHslF(&amp;h, &amp;s, &amp;l, &amp;a);
- QString repr = QString().sprintf("PySide2.QtGui.QColor.fromHslF(%.6f, %.6f, %.6f, %.6f)", h, s, l, a);
- %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
- break;
- }
- #endif
- default:
- {
- %PYARG_0 = Shiboken::String::fromCString("PySide2.QtGui.QColor()");
- }
- }
- </template>
<value-type name="QColor">
<enum-type name="NameFormat"/>
<enum-type name="Spec"/>
@@ -1025,117 +868,36 @@
</extra-includes>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="qcolor_repr" />
+ <insert-template name="qcolor_repr"/>
</inject-code>
</add-function>
<add-function signature="__str__" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="qcolor_repr" />
+ <insert-template name="qcolor_repr"/>
</inject-code>
</add-function>
<add-function signature="__setstate__(PyObject*)" return-type="PyObject">
- <inject-code>
- Shiboken::AutoDecRef func(PyObject_GetAttr(%PYSELF, PyTuple_GET_ITEM(%1, 0)));
- PyObject *args = PyTuple_GET_ITEM(%1, 1);
- %PYARG_0 = PyObject_Call(func, args, NULL);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qcolor-setstate"/>
</add-function>
<add-function signature="__reduce__" return-type="PyObject">
- <inject-code class="target" position="beginning">
- switch(%CPPSELF.spec()) {
- case QColor::Rgb:
- {
- qreal r, g, b, a;
- %CPPSELF.getRgbF(&amp;r, &amp;g, &amp;b, &amp;a);
- %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setRgbF", (float)r, (float)g, (float)b, (float)a);
- break;
- }
- case QColor::Hsv:
- {
- qreal h, s, v, a;
- %CPPSELF.getHsvF(&amp;h, &amp;s, &amp;v, &amp;a);
- %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setHsvF", (float)h, (float)s, (float)v, (float)a);
- break;
- }
- case QColor::Cmyk:
- {
- qreal c, m, y, k, a;
- %CPPSELF.getCmykF(&amp;c, &amp;m, &amp;y, &amp;k, &amp;a);
- %PYARG_0 = Py_BuildValue("(ON(s(fffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setCmykF", (float)c, (float)m, (float)y, (float)k, (float)a);
- break;
- }
- #if QT_VERSION >= 0x040600
- case QColor::Hsl:
- {
- qreal h, s, l, a;
- %CPPSELF.getHslF(&amp;h, &amp;s, &amp;l, &amp;a);
- %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), "setHslF", (float)h, (float)s, (float)l, (float)a);
- break;
- }
- #endif
- default:
- {
- %PYARG_0 = Py_BuildValue("(N(O))", PyObject_Type(%PYSELF), Py_None);
- }
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qcolor-reduce"/>
</add-function>
<add-function signature="toTuple" return-type="PyObject">
- <inject-code class="target" position="beginning">
- switch(%CPPSELF.spec()) {
- case QColor::Rgb:
- {
- int r, g, b, a;
- %CPPSELF.getRgb(&amp;r, &amp;g, &amp;b, &amp;a);
- %PYARG_0 = Py_BuildValue("iiii", r, g, b, a);
- break;
- }
- case QColor::Hsv:
- {
- int h, s, v, a;
- %CPPSELF.getHsv(&amp;h, &amp;s, &amp;v, &amp;a);
- %PYARG_0 = Py_BuildValue("iiii", h, s, v, a);
- break;
- }
- case QColor::Cmyk:
- {
- int c, m, y, k, a;
- %CPPSELF.getCmyk(&amp;c, &amp;m, &amp;y, &amp;k, &amp;a);
- %PYARG_0 = Py_BuildValue("iiiii", c, m, y, k, a);
- break;
- }
- case QColor::Hsl:
- {
- int h, s, l, a;
- %CPPSELF.getHsl(&amp;h, &amp;s, &amp;l, &amp;a);
- %PYARG_0 = Py_BuildValue("iiii", h, s, l, a);
- break;
- }
- default:
- {
- %PYARG_0 = 0;
- }
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qcolor-totuple"/>
</add-function>
<!-- ### "QColor(QColor::Spec)" is an internal method. -->
<modify-function signature="QColor(QColor::Spec)" remove="all"/>
<!-- ### Constructor removed because we already have an overload using QString. -->
- <modify-function signature="QColor(const char*)" remove="all" />
+ <modify-function signature="QColor(const char*)" remove="all"/>
<!-- ### -->
<add-function signature="QColor(QVariant)">
- <inject-code class="target" position="beginning">
- if (%1.type() == QVariant::Color)
- %0 = new %TYPE(%1.value&lt;QColor>());
- else
- PyErr_SetString(PyExc_TypeError, "QVariant must be holding a QColor");
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qcolor"/>
</add-function>
<!-- get* methods. Inject code -->
<modify-function signature="getCmyk(int*,int*,int*,int*,int*)">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1156,13 +918,13 @@
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getCmykF(qreal*,qreal*,qreal*,qreal*,qreal*)">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1183,13 +945,13 @@
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getHsl(int*,int*,int*,int*)const" since="4.6">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1206,13 +968,13 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getHslF(qreal*,qreal*,qreal*,qreal*)const" since="4.6">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1229,13 +991,13 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getHsv(int*,int*,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1252,13 +1014,13 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getHsvF(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1275,13 +1037,13 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getRgb(int*,int*,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1298,13 +1060,13 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getRgbF(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1321,7 +1083,7 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -1350,56 +1112,14 @@
<modify-argument index="5">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int *array = nullptr;
- bool errorOccurred = false;
-
- if (numArgs == 5) {
- array = Shiboken::sequenceToIntArray(%PYARG_5, true);
- if (PyErr_Occurred()) {
- if (array)
- delete []array;
- errorOccurred = true;
- }
- }
-
- if (!errorOccurred) {
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array);
-
- if (array)
- delete []array;
-
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetricsf-boundingrect"/>
</modify-function>
<modify-function signature="size(int,QString,int,int*)const">
<modify-argument index="4">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int *array = nullptr;
- bool errorOccurred = false;
-
- if (numArgs == 4) {
- array = Shiboken::sequenceToIntArray(%PYARG_4, true);
- if (PyErr_Occurred()) {
- if (array)
- delete []array;
- errorOccurred = true;
- }
- }
-
- if (!errorOccurred) {
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array);
-
- if (array)
- delete []array;
-
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetricsf-size"/>
</modify-function>
</value-type>
<value-type name="QFontMetrics" >
@@ -1426,107 +1146,44 @@
<modify-argument index="8">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int *array = nullptr;
- bool errorOccurred = false;
-
- if (numArgs == 8) {
- array = Shiboken::sequenceToIntArray(%PYARG_8, true);
- if (PyErr_Occurred()) {
- if (array)
- delete []array;
- errorOccurred = true;
- }
- }
-
- if (!errorOccurred) {
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, array);
-
- if (array)
- delete []array;
-
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetrics-boundingrect-1"/>
</modify-function>
<modify-function signature="boundingRect(QRect,int,QString,int,int*)const">
<modify-argument index="5">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int *array = nullptr;
- bool errorOccurred = false;
-
- if (numArgs == 5) {
- array = Shiboken::sequenceToIntArray(%PYARG_5, true);
- if (PyErr_Occurred()) {
- if (array)
- delete []array;
- errorOccurred = true;
- }
- }
-
- if (!errorOccurred) {
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array);
-
- if (array)
- delete []array;
-
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetrics-boundingrect-2"/>
</modify-function>
<modify-function signature="size(int,QString,int,int*)const">
<modify-argument index="4">
<replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int *array = nullptr;
- bool errorOccurred = false;
-
- if (numArgs == 4) {
- array = Shiboken::sequenceToIntArray(%PYARG_4, true);
- if (PyErr_Occurred()) {
- if (array)
- delete []array;
- errorOccurred = true;
- }
- }
-
- if (!errorOccurred) {
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array);
-
- if (array)
- delete []array;
-
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
- }
-
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qfontmetrics-size"/>
</modify-function>
</value-type>
- <value-type name="QGradient" force-abstract="yes" polymorphic-id-expression="%1-&gt;type() == QGradient::NoGradient">
+ <value-type name="QGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::NoGradient">
<enum-type name="CoordinateMode"/>
<enum-type name="InterpolationMode"/>
- <enum-type name="Spread" lower-bound="QGradient.PadSpread" upper-bound="QGradient.RepeatSpread"/>
+ <enum-type name="Preset" since="5.12"/>
+ <enum-type name="Spread"/>
<enum-type name="Type"/>
</value-type>
- <value-type name="QLinearGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::LinearGradient" />
+ <value-type name="QLinearGradient" polymorphic-id-expression="%1-&gt;type() == QGradient::LinearGradient"/>
<object-type name="QPaintDevice">
<enum-type name="PaintDeviceMetric"/>
</object-type>
<object-type name="QPagedPaintDevice">
- <value-type name="Margins" />
- <enum-type name="PageSize" />
+ <value-type name="Margins"/>
+ <enum-type name="PageSize"/>
<enum-type name="PdfVersion" since="5.10"/>
</object-type>
<object-type name="QAbstractTextDocumentLayout">
<value-type name="PaintContext" >
<include file-name="QAbstractTextDocumentLayout" location="global"/>
</value-type>
- <value-type name="Selection" />
+ <value-type name="Selection"/>
<modify-function signature="setPaintDevice(QPaintDevice*)">
<modify-argument index="1">
<parent index="this" action="add"/>
@@ -1539,15 +1196,15 @@
<modify-argument index="1" invalidate-after-use="yes"/>
</modify-function>
</object-type>
- <object-type name="QPyTextObject" />
+ <object-type name="QPyTextObject"/>
- <object-type name="QDesktopServices" since="4.2" />
+ <object-type name="QDesktopServices" since="4.2"/>
<object-type name="QDoubleValidator">
<enum-type name="Notation"/>
</object-type>
<object-type name="QIconEngine">
- <object-type name="AvailableSizesArgument" />
- <enum-type name="IconEngineHook" />
+ <object-type name="AvailableSizesArgument"/>
+ <enum-type name="IconEngineHook"/>
<modify-function signature="paint(QPainter*,QRect,QIcon::Mode,QIcon::State)">
<modify-argument index="1" invalidate-after-use="yes"/>
</modify-function>
@@ -1569,7 +1226,7 @@
</modify-function>
<modify-function signature="write(const QImage&amp;)" allow-thread="yes"/>
</object-type>
- <object-type name="QIntValidator" />
+ <object-type name="QIntValidator"/>
<object-type name="QPainterPathStroker" copyable="false"/>
<object-type name="QPictureIO">
@@ -1582,19 +1239,11 @@
<object-type name="QPixmapCache">
<value-type name="Key"/>
<add-function signature="find(QPixmapCache::Key&amp;)">
- <inject-code>
- QPixmap p;
- if (%CPPSELF.%FUNCTION_NAME(%1, &amp;p)) {
- %PYARG_0 = %CONVERTTOPYTHON[QPixmap](p);
- } else {
- %PYARG_0 = Py_None;
- Py_INCREF(%PYARG_0);
- }
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpixmapcache-find"/>
</add-function>
</object-type>
- <object-type name="QRegExpValidator" />
+ <object-type name="QRegExpValidator"/>
<object-type name="QStandardItem">
<enum-type name="ItemType"/>
@@ -1646,27 +1295,13 @@
</modify-function>
<modify-function signature="setChild(int,int,QStandardItem*)">
- <inject-code class="target" position="beginning">
- // Clear parent from the old child
- QStandardItem *_i = %CPPSELF->child(%1, %2);
- if (_i) {
- PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
- Shiboken::Object::setParent(0, _pyI);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditem-setchild-1"/>
<modify-argument index="3">
<parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="setChild(int,QStandardItem*)">
- <inject-code class="target" position="beginning">
- // Clear parent from the old child
- QStandardItem *_i = %CPPSELF->child(%1);
- if (_i) {
- PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
- Shiboken::Object::setParent(0, _pyI);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditem-setchild-2"/>
<modify-argument index="2">
<parent index="this" action="add"/>
</modify-argument>
@@ -1705,8 +1340,8 @@
</modify-argument>
</modify-function>
</object-type>
- <object-type name="QTextBlockGroup" />
- <object-type name="QTextBlockUserData" />
+ <object-type name="QTextBlockGroup"/>
+ <object-type name="QTextBlockUserData"/>
<object-type name="QTextItem">
<enum-type name="RenderFlag" flags="RenderFlags"/>
</object-type>
@@ -1721,42 +1356,6 @@
</modify-function>
</object-type>
- <template name="validator_conversionrule">
- QValidator::State %out;
-
- if (PySequence_Check(%PYARG_0)) {
- Shiboken::AutoDecRef seq(PySequence_Fast(%PYARG_0, 0));
- int size = PySequence_Fast_GET_SIZE(seq.object());
-
- if (size > 1) {
- if (%ISCONVERTIBLE[QString](PySequence_Fast_GET_ITEM(seq.object(), 1)))
- %1 = %CONVERTTOCPP[QString](PySequence_Fast_GET_ITEM(seq.object(), 1));
- else
- qWarning("%TYPE::%FUNCTION_NAME: Second tuple element is not convertible to unicode.");
- }
-
- if (size > 2) {
- if (%ISCONVERTIBLE[int](PySequence_Fast_GET_ITEM(seq.object(), 2)))
- %2 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(seq.object(), 2));
- else
- qWarning("%TYPE::%FUNCTION_NAME: Second tuple element is not convertible to int.");
- }
- %PYARG_0 = PySequence_Fast_GET_ITEM(seq.object(), 0);
- Py_INCREF(%PYARG_0); // we need to incref, because "%PYARG_0 = ..." will decref the tuple and the tuple will be decrefed again at the end of this scope.
- }
-
- // check retrun value
- if (%ISCONVERTIBLE[QValidator::State](%PYARG_0)) {
- %out = %CONVERTTOCPP[QValidator::State](%PYARG_0);
- } else {
- PyErr_Format(PyExc_TypeError, "Invalid return value in function %s, expected %s, got %s.",
- "QValidator.validate",
- "PySide2.QtGui.QValidator.State, (PySide2.QtGui.QValidator.State,), (PySide2.QtGui.QValidator.State, unicode) or (PySide2.QtGui.QValidator.State, unicode, int)",
- Py_TYPE(pyResult)->tp_name);
- return QValidator::State();
- }
- </template>
-
<object-type name="QValidator">
<enum-type name="State"/>
<modify-function signature="fixup(QString &amp;)const">
@@ -1766,9 +1365,7 @@
<inject-code class="native" position="end">
<insert-template name="return_QString_native"/>
</inject-code>
- <inject-code class="target" position="end">
- <insert-template name="return_QString"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qstring-return"/>
</modify-function>
<modify-function signature="validate(QString &amp;,int &amp;)const">
<modify-argument index="return">
@@ -1783,25 +1380,26 @@
</modify-function>
</object-type>
- <object-type name="QActionEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::ActionAdded || %1-&gt;type() == QEvent::ActionRemoved || %1-&gt;type() == QEvent::ActionChanged" />
+ <object-type name="QActionEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::ActionAdded || %1-&gt;type() == QEvent::ActionRemoved || %1-&gt;type() == QEvent::ActionChanged"/>
<object-type name="QCloseEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Close"/>
<object-type name="QContextMenuEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::ContextMenu">
<enum-type name="Reason"/>
</object-type>
+
<object-type name="QDragEnterEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::DragEnter"/>
<object-type name="QDragLeaveEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::DragLeave"/>
- <object-type name="QDragMoveEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::DragMove" />
+ <object-type name="QDragMoveEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::DragMove"/>
<object-type name="QDropEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Drop">
<modify-function signature="source()const">
<modify-argument index="return">
- <define-ownership class="target" owner="default" />
+ <define-ownership class="target" owner="default"/>
</modify-argument>
</modify-function>
</object-type>
<object-type name="QEnterEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::Enter"/>
- <object-type name="QExposeEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Expose" />
- <object-type name="QFileOpenEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::FileOpen" />
- <object-type name="QFocusEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::FocusIn || %1-&gt;type() == QEvent::FocusOut" />
+ <object-type name="QExposeEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::Expose"/>
+ <object-type name="QFileOpenEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::FileOpen"/>
+ <object-type name="QFocusEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::FocusIn || %1-&gt;type() == QEvent::FocusOut"/>
<object-type name="QHelpEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::ToolTip || %1-&gt;type() == QEvent::WhatsThis"/>
<object-type name="QHideEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::Hide"/>
<object-type name="QHoverEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::HoverEnter || %1-&gt;type() == QEvent::HoverLeave || %1-&gt;type() == QEvent::HoverMove"/>
@@ -1817,7 +1415,7 @@
</object-type>
<object-type name="QInputMethodQueryEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::InputMethodQuery"/>
- <object-type name="QMoveEvent" copyable = "false" polymorphic-id-expression="%1-&gt;type() == QEvent::Move" />
+ <object-type name="QMoveEvent" copyable = "false" polymorphic-id-expression="%1-&gt;type() == QEvent::Move"/>
<object-type name="QNativeGestureEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::NativeGesture"/>
<object-type name="QResizeEvent" copyable = "false" polymorphic-id-expression="%1-&gt;type() == QEvent::Resize"/>
<object-type name="QShortcutEvent" copyable = "false" polymorphic-id-expression="%1-&gt;type() == QEvent::Shortcut">
@@ -1832,18 +1430,13 @@
<object-type name="QWhatsThisClickedEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::WhatsThisClicked"/>
<object-type name="QWheelEvent" copyable= "false" polymorphic-id-expression="%1-&gt;type() == QEvent::Wheel"/>
<!-- Qt5.5: suppress this nameless enum -->
- <suppress-warning text="enum 'QWheelEvent::DefaultDeltasPerStep' does not have a type entry or is not an enum" />
+ <suppress-warning text="enum 'QWheelEvent::DefaultDeltasPerStep' does not have a type entry or is not an enum"/>
<object-type name="QWindowStateChangeEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::WindowStateChange"/>
- <object-type name="QInputEvent" copyable="false">
- <modify-function signature="modifiers()const" access="non-final"/>
- </object-type>
+ <object-type name="QInputEvent" copyable="false"/>
<object-type name="QKeyEvent" copyable= "false" polymorphic-id-expression="%1-&gt;type() == QEvent::KeyPress || %1-&gt;type() == QEvent::KeyRelease || %1-&gt;type() == QEvent::ShortcutOverride">
<add-function signature="operator!=(QKeySequence::StandardKey)">
- <inject-code class="target">
- bool ret = !(&amp;%CPPSELF == %1);
- %PYARG_0 = %CONVERTTOPYTHON[bool](ret);
- </inject-code>
+ <inject-code class="target" file="../glue/qtgui.cpp" snippet="qkeyevent-operatornotequal"/>
</add-function>
</object-type>
<object-type name="QMouseEvent" copyable= "false" polymorphic-id-expression="%1-&gt;type() == QEvent::MouseButtonDblClick || %1-&gt;type() == QEvent::MouseButtonPress || %1-&gt;type() == QEvent::MouseButtonRelease || %1-&gt;type() == QEvent::MouseMove"/>
@@ -1867,13 +1460,13 @@
<!-- ### -->
<add-function signature="__iter__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="__iter__" />
+ <insert-template name="__iter__"/>
</inject-code>
</add-function>
<add-function signature="__next__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="__next__">
- <replace from="%CPPSELF_TYPE" to="QTextFrame::iterator" />
+ <replace from="%CPPSELF_TYPE" to="QTextFrame::iterator"/>
</insert-template>
</inject-code>
</add-function>
@@ -1881,7 +1474,7 @@
<add-function signature="__iter__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="__iter_parent__">
- <replace from="%CPPSELF_TYPE" to="QTextFrame::iterator" />
+ <replace from="%CPPSELF_TYPE" to="QTextFrame::iterator"/>
</insert-template>
</inject-code>
</add-function>
@@ -1891,7 +1484,7 @@
<include file-name="QRect" location="global"/>
</extra-includes>
<enum-type name="ImageOption"/>
- <enum-type name="Transformation" flags="Transformations" since="5.5" />
+ <enum-type name="Transformation" flags="Transformations" since="5.5"/>
<modify-function signature="setDevice(QIODevice*)">
<modify-argument index="1">
<parent index="this" action="add"/>
@@ -1910,7 +1503,7 @@
<enum-type name="ImageReaderError"/>
<!-- ### This method does not make sense in Python.
Update: perhaps it does, but no one is missing it. -->
- <modify-function signature="read(QImage*)" remove="all" />
+ <modify-function signature="read(QImage*)" remove="all"/>
<modify-function signature="setDevice(QIODevice*)">
<modify-argument index="1">
<parent index="this" action="add"/>
@@ -1971,170 +1564,135 @@
</extra-includes>
<modify-function signature="takeItem(int,int)">
<modify-argument index="return">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
<modify-function signature="takeHorizontalHeaderItem(int)">
<modify-argument index="return">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
<modify-function signature="takeVerticalHeaderItem(int)">
<modify-argument index="return">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
<modify-function signature="verticalHeaderItem(int)const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="horizontalHeaderItem(int)const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="invisibleRootItem()const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="item(int,int)const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="itemFromIndex(const QModelIndex&amp;)const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="itemPrototype()const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="appendRow(const QList&lt;QStandardItem*&gt;&amp;)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="appendRow(QStandardItem*)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="insertRow(int,QStandardItem*)">
<modify-argument index="2">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="setHorizontalHeaderItem(int,QStandardItem*)">
<modify-argument index="2">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="setItem(int,int,QStandardItem*)">
- <inject-code class="target" position="beginning">
- // Clear parent from the old child
- QStandardItem *_i = %CPPSELF->item(%1, %2);
- if (_i) {
- PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
- Shiboken::Object::setParent(0, _pyI);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-setitem-1"/>
<modify-argument index="3">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="setItem(int,QStandardItem*)">
- <inject-code class="target" position="beginning">
- // Clear parent from the old child
- QStandardItem *_i = %CPPSELF->item(%1);
- if (_i) {
- PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
- Shiboken::Object::setParent(0, _pyI);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-setitem-2"/>
<modify-argument index="2">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="setItemPrototype(const QStandardItem*)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="setVerticalHeaderItem(int,QStandardItem*)">
- <inject-code class="target" position="beginning">
- // Clear parent from the old child
- QStandardItem *_i = %CPPSELF->verticalHeaderItem(%1);
- if (_i) {
- PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
- Shiboken::Object::setParent(0, _pyI);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-setverticalheaderitem"/>
<modify-argument index="2">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="takeColumn(int)">
<modify-argument index="return">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
<modify-function signature="takeRow(int)">
<modify-argument index="return">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
<modify-function signature="findItems(const QString&amp;,QFlags&lt;Qt::MatchFlag&gt;,int)const">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="insertColumn(int,const QList&lt;QStandardItem*&gt;&amp;)">
<modify-argument index="2">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="insertRow(int,const QList&lt;QStandardItem*&gt;&amp;)">
<modify-argument index="2">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="appendColumn(const QList&lt;QStandardItem*&gt;&amp;)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="clear()">
- <inject-code class="target" position="beginning">
- Shiboken::BindingManager &amp;bm = Shiboken::BindingManager::instance();
- SbkObject *pyRoot = bm.retrieveWrapper(%CPPSELF.invisibleRootItem());
- if (pyRoot) {
- Shiboken::Object::destroy(pyRoot, %CPPSELF.invisibleRootItem());
- }
-
- for (int r=0, r_max = %CPPSELF.rowCount(); r &lt; r_max; r++) {
- QList&lt;QStandardItem *&gt; ri = %CPPSELF.takeRow(0);
-
- PyObject *pyResult = %CONVERTTOPYTHON[QList&lt;QStandardItem * &gt;](ri);
- Shiboken::Object::setParent(Py_None, pyResult);
- Py_XDECREF(pyResult);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qstandarditemmodel-clear"/>
</modify-function>
</object-type>
<object-type name="QClipboard">
@@ -2142,7 +1700,7 @@
<include file-name="QImage" location="global"/>
<include file-name="QPixmap" location="global"/>
</extra-includes>
- <enum-type name="Mode" />
+ <enum-type name="Mode"/>
<modify-function signature="setMimeData(QMimeData*,QClipboard::Mode)">
<modify-argument index="1">
<!-- TODO: maybe this is not the best solution -->
@@ -2156,14 +1714,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, subtype)"/>
</modify-argument>
- <inject-code class="target" position="end">
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtgui.cpp" snippet="qclipboard-text"/>
</modify-function>
</object-type>
<object-type name="QPaintEngineState">
@@ -2210,9 +1761,9 @@
<parent index="this" action="add"/>
</modify-argument>
</modify-function>
- <modify-function signature="print(QPagedPaintDevice*)const" rename="print_" />
+ <modify-function signature="print(QPagedPaintDevice*)const" rename="print_"/>
</object-type>
- <object-type name="QTextDocumentWriter" since="4.5" />
+ <object-type name="QTextDocumentWriter" since="4.5"/>
<object-type name="QTextTable">
<extra-includes>
<include file-name="QTextCursor" location="global"/>
@@ -2237,7 +1788,6 @@
</extra-includes>
<!-- ### "setPaintDevice(QPaintDevice*)" is an internal method. -->
<modify-function signature="setPaintDevice(QPaintDevice*)" remove="all"/>
- <modify-field name="state" read="false" write="false"/>
</object-type>
<object-type name="QPainter">
<extra-includes>
@@ -2254,70 +1804,57 @@
<!-- ### "drawText(...)" is an internal method. -->
<modify-function signature="drawText(const QPointF&amp;,const QString&amp;,int,int)" remove="all"/>
- <template name="qpainter_drawlist">
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%1.data(), %1.size());
- %END_ALLOW_THREADS
- </template>
- <modify-function signature="drawConvexPolygon(const QPoint*,int)" remove="all" />
+ <modify-function signature="drawConvexPolygon(const QPoint*,int)" remove="all"/>
<add-function signature="drawConvexPolygon(QVector&lt;QPoint>)">
<inject-code>
- <insert-template name="qpainter_drawlist" />
+ <insert-template name="qpainter_drawlist"/>
</inject-code>
</add-function>
- <modify-function signature="drawConvexPolygon(const QPointF*,int)" remove="all" />
+ <modify-function signature="drawConvexPolygon(const QPointF*,int)" remove="all"/>
<add-function signature="drawConvexPolygon(QVector&lt;QPointF>)">
<inject-code>
- <insert-template name="qpainter_drawlist" />
+ <insert-template name="qpainter_drawlist"/>
</inject-code>
</add-function>
<!-- ### Overloads using QVector<T> does the job of these methods -->
- <modify-function signature="drawLines(const QLine*,int)" remove="all" />
- <modify-function signature="drawLines(const QLineF*,int)" remove="all" />
- <modify-function signature="drawLines(const QPoint*,int)" remove="all" />
- <modify-function signature="drawLines(const QPointF*,int)" remove="all" />
- <modify-function signature="drawRects(const QRect*,int)" remove="all" />
- <modify-function signature="drawRects(const QRectF*,int)" remove="all" />
+ <modify-function signature="drawLines(const QLine*,int)" remove="all"/>
+ <modify-function signature="drawLines(const QLineF*,int)" remove="all"/>
+ <modify-function signature="drawLines(const QPoint*,int)" remove="all"/>
+ <modify-function signature="drawLines(const QPointF*,int)" remove="all"/>
+ <modify-function signature="drawRects(const QRect*,int)" remove="all"/>
+ <modify-function signature="drawRects(const QRectF*,int)" remove="all"/>
<!-- ### -->
- <modify-function signature="drawPoints(const QPoint*,int)" remove="all" />
+ <modify-function signature="drawPoints(const QPoint*,int)" remove="all"/>
<add-function signature="drawPoints(QVector&lt;QPoint>)">
<inject-code>
- <insert-template name="qpainter_drawlist" />
+ <insert-template name="qpainter_drawlist"/>
</inject-code>
</add-function>
- <modify-function signature="drawPoints(const QPointF*,int)" remove="all" />
+ <modify-function signature="drawPoints(const QPointF*,int)" remove="all"/>
<add-function signature="drawPoints(QVector&lt;QPointF>)">
<inject-code>
- <insert-template name="qpainter_drawlist" />
+ <insert-template name="qpainter_drawlist"/>
</inject-code>
</add-function>
- <modify-function signature="drawPolygon(const QPoint*,int,Qt::FillRule)" remove="all" />
+ <modify-function signature="drawPolygon(const QPoint*,int,Qt::FillRule)" remove="all"/>
<add-function signature="drawPolygon(QVector&lt;QPoint>,Qt::FillRule)">
- <inject-code>
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%1.data(), %1.size(), %2);
- %END_ALLOW_THREADS
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-drawpolygon"/>
</add-function>
- <modify-function signature="drawPolygon(const QPointF*,int,Qt::FillRule)" remove="all" />
+ <modify-function signature="drawPolygon(const QPointF*,int,Qt::FillRule)" remove="all"/>
<add-function signature="drawPolygon(QVector&lt;QPointF>,Qt::FillRule)">
- <inject-code>
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%1.data(), %1.size(), %2);
- %END_ALLOW_THREADS
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qpainter-drawpolygon"/>
</add-function>
- <modify-function signature="drawPolyline(const QPoint*,int)" remove="all" />
+ <modify-function signature="drawPolyline(const QPoint*,int)" remove="all"/>
<add-function signature="drawPolyline(QVector&lt;QPoint>)">
<inject-code>
- <insert-template name="qpainter_drawlist" />
+ <insert-template name="qpainter_drawlist"/>
</inject-code>
</add-function>
- <modify-function signature="drawPolyline(const QPointF*,int)" remove="all" />
+ <modify-function signature="drawPolyline(const QPointF*,int)" remove="all"/>
<add-function signature="drawPolyline(QVector&lt;QPointF>)">
<inject-code>
- <insert-template name="qpainter_drawlist" />
+ <insert-template name="qpainter_drawlist"/>
</inject-code>
</add-function>
<modify-function signature="drawRoundRect(int,int,int,int,int,int)">
@@ -2388,12 +1925,17 @@
</modify-function>
</object-type>
+ <value-type name="QGenericMatrix" generate="no"/>
<value-type name="QMatrix2x2" since="4.6">
+ <modify-function signature="QMatrix2x2(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="4" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="4"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2401,87 +1943,37 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="4" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="4"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix2x2(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="4" />
+ <replace from="%SIZE" to="4"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="4" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="4" />
+ <replace from="%MATRIX_SIZE" to="4"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix2x2" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="operator!=(const QMatrix2x2&amp;)" return-type="bool" />
-
- <template name="inplace_add">
- *%CPPSELF += %1;
- return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
- </template>
- <template name="inplace_sub">
- *%CPPSELF -= %1;
- return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
- </template>
- <template name="inplace_mult">
- *%CPPSELF *= %1;
- return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
- </template>
- <template name="inplace_div">
- *%CPPSELF /= %1;
- return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
- </template>
-
- <add-function signature="operator*=(float)" return-type="QMatrix2x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix2x2&amp;)" return-type="QMatrix2x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix2x2&amp;)" return-type="QMatrix2x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix2x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix2x2&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix2x3" since="4.6">
+ <modify-function signature="QMatrix2x3(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="6" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="6"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2489,69 +1981,37 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="6" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="6"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix2x3(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="6" />
+ <replace from="%SIZE" to="6"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="6" />
+ <replace from="%MATRIX_SIZE" to="6"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="6" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix3x2" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="operator!=(const QMatrix2x3&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix2x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix2x3&amp;)" return-type="QMatrix2x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix2x3&amp;)" return-type="QMatrix2x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix2x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix2x3&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix2x4" since="4.6">
+ <modify-function signature="QMatrix2x4(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="8" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="8"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2559,69 +2019,37 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="8" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="8"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix2x4(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="8" />
+ <replace from="%SIZE" to="8"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="8" />
+ <replace from="%MATRIX_SIZE" to="8"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="8" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix4x2" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="operator!=(const QMatrix2x4&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix2x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix2x4&amp;)" return-type="QMatrix2x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix2x4&amp;)" return-type="QMatrix2x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix2x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix2x4&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix3x2" since="4.6">
+ <modify-function signature="QMatrix3x2(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="6" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="6"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2629,69 +2057,37 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="6" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="6"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix3x2(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="6" />
+ <replace from="%SIZE" to="6"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="6" />
+ <replace from="%MATRIX_SIZE" to="6"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="6" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix2x3" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="operator!=(const QMatrix3x2&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix3x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix3x2&amp;)" return-type="QMatrix3x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix3x2&amp;)" return-type="QMatrix3x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix3x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix3x2&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix3x3" since="4.6">
+ <modify-function signature="QMatrix3x3(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="9" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="9"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2699,69 +2095,37 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="9" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="9"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix3x3(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="9" />
+ <replace from="%SIZE" to="9"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="9" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="9" />
+ <replace from="%MATRIX_SIZE" to="9"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix3x3" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="operator!=(const QMatrix3x3&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix3x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix3x3&amp;)" return-type="QMatrix3x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix3x3&amp;)" return-type="QMatrix3x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix3x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix3x3&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix3x4" since="4.6">
+ <modify-function signature="QMatrix3x4(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="12" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="12"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2769,69 +2133,36 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="12" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="12"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix3x4(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="12" />
+ <replace from="%SIZE" to="12"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="12" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="12" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix4x3" />
+ <replace from="%MATRIX_SIZE" to="12"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="operator!=(const QMatrix3x4&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix3x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix3x4&amp;)" return-type="QMatrix3x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix3x4&amp;)" return-type="QMatrix3x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix3x4" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix3x4&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix4x2" since="4.6">
+ <modify-function signature="QMatrix4x2(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="8" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="8"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2839,69 +2170,37 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="8" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="8"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix4x2(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="8" />
+ <replace from="%SIZE" to="8"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="8" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="8" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix2x4" />
+ <replace from="%MATRIX_SIZE" to="8"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="operator!=(const QMatrix4x2&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix4x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix4x2&amp;)" return-type="QMatrix4x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix4x2&amp;)" return-type="QMatrix4x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix4x2" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix4x2&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix4x3" since="4.6">
+ <modify-function signature="QMatrix4x3(const float*)">
+ <modify-argument index="1"><array/></modify-argument>
+ </modify-function>
+ <modify-function signature="copyDataTo(float*) const" remove="all"/>
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="12" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="12"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -2909,66 +2208,29 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="12" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="12"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="QMatrix4x3(PySequence*)">
<inject-code class="target" position="beginning">
<insert-template name="matrix_constructor">
- <replace from="%SIZE" to="12" />
+ <replace from="%SIZE" to="12"/>
</insert-template>
</inject-code>
</add-function>
<add-function signature="data()" return-type="float">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="12" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="fill(PyObject*)">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_fill_function">
- <replace from="%MATRIX_SIZE" to="12" />
- </insert-template>
- </inject-code>
- </add-function>
- <add-function signature="transposed()" return-type="PyObject">
- <inject-code class="target" position="beginning">
- <insert-template name="matrix_transposed_function">
- <replace from="%TRANSPOSED_TYPE" to="QMatrix3x4" />
+ <replace from="%MATRIX_SIZE" to="12"/>
</insert-template>
</inject-code>
</add-function>
- <add-function signature="operator!=(const QMatrix4x3&amp;)" return-type="bool" />
- <add-function signature="operator*=(float)" return-type="QMatrix4x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_mult"/>
- </inject-code>
- </add-function>
- <add-function signature="operator+=(const QMatrix4x3&amp;)" return-type="QMatrix4x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_add"/>
- </inject-code>
- </add-function>
- <add-function signature="operator-=(const QMatrix4x3&amp;)" return-type="QMatrix4x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_sub"/>
- </inject-code>
- </add-function>
- <add-function signature="operator/=(float)" return-type="QMatrix4x3" >
- <inject-code class="target" position="beginning">
- <insert-template name="inplace_div"/>
- </inject-code>
- </add-function>
- <add-function signature="operator==(const QMatrix4x3&amp;)" return-type="bool" />
</value-type>
<value-type name="QMatrix4x4" since="4.6">
-
<!-- Qt5: HAIRY TRICK ALERT ahead!
Qt5 partially replaced 'qreal' by float.
That had the side effect that all matrix types did not work any longer.
@@ -2977,10 +2239,10 @@
The signature "QList<qreal>" is needed by the __reduce__ methods,
but created by some other object used elsewhere.
- After the matrix type was changed, "QList<float>" was nowhere created.
+ After the matrix type was changed, "QList<float>" was created nowhere.
I don't know an explicit way to produce the right conversion function, so what I did
- was to create a dummy function and immediately dele it again.
+ was to create a dummy function and immediately delete it again.
This has the desired effect of creating the implicitly needed "QList<float>"
conversion, although the dummy function goes away.
@@ -2993,8 +2255,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code_matrix">
- <replace from="%MATRIX_SIZE" to="16" />
- <replace from="%MATRIX_TYPE" to="float" />
+ <replace from="%MATRIX_SIZE" to="16"/>
+ <replace from="%MATRIX_TYPE" to="float"/>
</insert-template>
</inject-code>
</add-function>
@@ -3002,8 +2264,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code_matrix">
- <replace from="%MATRIX_TYPE" to="float" />
- <replace from="%MATRIX_SIZE" to="16" />
+ <replace from="%MATRIX_TYPE" to="float"/>
+ <replace from="%MATRIX_SIZE" to="16"/>
</insert-template>
</inject-code>
</add-function>
@@ -3013,27 +2275,14 @@
<modify-function signature="QMatrix4x4(const float*)">
<modify-argument index="1">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- if (PySequence_Size(%PYARG_1) == 16) {
- float values[16];
- for (int i=0; i &lt; 16; i++) {
- PyObject *pv = PySequence_Fast_GET_ITEM(%PYARG_1, i);
- values[i] = PyFloat_AsDouble(pv);
- }
-
- %0 = new %TYPE(values[0], values[1], values[2], values[3],
- values[4], values[5], values[6], values[7],
- values[8], values[9], values[10], values[11],
- values[12], values[13], values[14], values[15]);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qmatrix4x4"/>
</modify-function>
<modify-function signature="data()">
<inject-code class="target" position="beginning">
<insert-template name="matrix_data_function">
- <replace from="%MATRIX_SIZE" to="16" />
+ <replace from="%MATRIX_SIZE" to="16"/>
</insert-template>
</inject-code>
</modify-function>
@@ -3044,15 +2293,7 @@
<modify-argument index="return">
<replace-type modified-type="PyTupleObject*"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- float values[16];
- %CPPSELF.%FUNCTION_NAME(values);
- %PYARG_0 = PyTuple_New(16);
- for (int i = 0; i &lt; 16; i++) {
- PyObject *v = PyFloat_FromDouble(values[i]);
- PyTuple_SET_ITEM(%PYARG_0, i, v);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtgui.cpp" snippet="qmatrix4x4-copydatato"/>
</modify-function>
<modify-function signature="inverted(bool*)const">
@@ -3074,21 +2315,7 @@
<modify-function signature="operator()(int,int)const" remove="all"/>
<modify-function signature="operator()(int,int)" remove="all"/>
<add-function signature="__mgetitem__" return-type="PyObject*">
- <inject-code>
- if (PySequence_Check(_key)) {
- Shiboken::AutoDecRef key(PySequence_Fast(_key, "Invalid matrix index."));
- if (PySequence_Fast_GET_SIZE(key.object()) == 2) {
- PyObject *posx = PySequence_Fast_GET_ITEM(key.object(), 0);
- PyObject *posy = PySequence_Fast_GET_ITEM(key.object(), 1);
- Py_ssize_t x = PyInt_AsSsize_t(posx);
- Py_ssize_t y = PyInt_AsSsize_t(posy);
- float ret = (*%CPPSELF)(x,y);
- return %CONVERTTOPYTHON[float](ret);
- }
- }
- PyErr_SetString(PyExc_IndexError, "Invalid matrix index.");
- return 0;
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qmatrix4x4-mgetitem"/>
</add-function>
</value-type>
@@ -3098,8 +2325,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.scalar(), %CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.scalar(), %CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3107,16 +2334,16 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dddd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.scalar(), %CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()" />
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.scalar(), %CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
</insert-template>
</inject-code>
</add-function>
<!-- Qt5.5: XXX support the output variables! For now, I just suppressed the new methods. -->
- <modify-function signature="getAxisAndAngle(float*,float*,float*,float*)const" since="5.5" remove="all" />
- <modify-function signature="getAxisAndAngle(QVector3D*,float*)const" since="5.5" remove="all" />
- <modify-function signature="getEulerAngles(float*,float*,float*)const" since="5.5" remove="all" />
+ <modify-function signature="getAxisAndAngle(float*,float*,float*,float*)const" since="5.5" remove="all"/>
+ <modify-function signature="getAxisAndAngle(QVector3D*,float*)const" since="5.5" remove="all"/>
+ <modify-function signature="getEulerAngles(float*,float*,float*)const" since="5.5" remove="all"/>
</value-type>
<object-type name="QTouchEvent" since="4.6">
@@ -3126,16 +2353,16 @@
</object-type>
<object-type name="QTouchDevice">
- <enum-type name="CapabilityFlag" flags="Capabilities" />
- <enum-type name="DeviceType" />
+ <enum-type name="CapabilityFlag" flags="Capabilities"/>
+ <enum-type name="DeviceType"/>
</object-type>
<value-type name="QVector2D" since="4.6">
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%REPR_FORMAT" to="%f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3143,8 +2370,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%REDUCE_FORMAT" to="dd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3152,8 +2379,8 @@
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="dd" />
- <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()" />
+ <replace from="%TT_FORMAT" to="dd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3166,8 +2393,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3175,8 +2402,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="ddd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()" />
+ <replace from="%REDUCE_FORMAT" to="ddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3184,8 +2411,8 @@
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="ddd" />
- <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()" />
+ <replace from="%TT_FORMAT" to="ddd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3198,8 +2425,8 @@
<add-function signature="__repr__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="repr_code">
- <replace from="%REPR_FORMAT" to="%f, %f, %f, %f" />
- <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()" />
+ <replace from="%REPR_FORMAT" to="%f, %f, %f, %f"/>
+ <replace from="%REPR_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3207,8 +2434,8 @@
<add-function signature="__reduce__" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="reduce_code">
- <replace from="%REDUCE_FORMAT" to="dddd" />
- <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()" />
+ <replace from="%REDUCE_FORMAT" to="dddd"/>
+ <replace from="%REDUCE_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3216,8 +2443,8 @@
<add-function signature="toTuple" return-type="PyObject*">
<inject-code class="target" position="beginning">
<insert-template name="to_tuple">
- <replace from="%TT_FORMAT" to="dddd" />
- <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()" />
+ <replace from="%TT_FORMAT" to="dddd"/>
+ <replace from="%TT_ARGS" to="%CPPSELF.x(), %CPPSELF.y(), %CPPSELF.z(), %CPPSELF.w()"/>
</insert-template>
</inject-code>
</add-function>
@@ -3243,7 +2470,7 @@
</object-type>
<!-- This enum is present on QtCore -->
- <suppress-warning text="enum 'QCoreApplication::ApplicationFlags' is specified in typesystem, but not declared" />
+ <suppress-warning text="enum 'QCoreApplication::ApplicationFlags' is specified in typesystem, but not declared"/>
<!-- Qt5: here the new QWindow stuff and what it pulls in -->
<object-type name="QBackingStore"/>
@@ -3266,12 +2493,35 @@
</extra-includes>
</primitive-type>
- <object-type name="QWindow">
+ <object-type name="QWindow" delete-in-main-thread="true">
<enum-type name="AncestorMode"/>
<enum-type name="Visibility"/>
+ <modify-function signature="raise()" rename="raise_"/>
+ <!-- see QWidget::nativeEvent(), QAbstractNativeEventFilter::nativeEventFilter() -->
+ <modify-function signature="nativeEvent(const QByteArray &amp;,void*,long*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion_variables"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code position="end">
+ <insert-template name="return_native_eventfilter"/>
+ </inject-code>
+ </modify-function>
+ <modify-function signature="fromWinId(WId)">
+ <modify-argument index="1">
+ <replace-type modified-type="long"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qwindow-fromWinId"/>
+ </modify-function>
</object-type>
- <!-- Qt5: not sure if this needs support, skipped for now -->
- <rejection class="QWindow" function-name="nativeEvent"/>"
<object-type name="QGuiApplication">
<extra-includes>
@@ -3282,33 +2532,25 @@
<include file-name="QIcon" location="global"/>
<include file-name="QLocale" location="global"/>
</extra-includes>
- <modify-function signature="QGuiApplication(int&amp;,char**,int)" access="private" />
+ <modify-function signature="QGuiApplication(int&amp;,char**,int)" access="private"/>
<add-function signature="QGuiApplication(QStringList)">
- <inject-code>
- QGuiApplicationConstructor(%PYSELF, args, &amp;%0);
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qguiapplication-1"/>
</add-function>
<add-function signature="QGuiApplication()">
- <inject-code>
- PyObject *empty = PyTuple_New(2);
- if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
- QGuiApplicationConstructor(%PYSELF, empty, &amp;%0);
- }
- </inject-code>
+ <inject-code file="../glue/qtgui.cpp" snippet="qguiapplication-2"/>
</add-function>
- <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
- <inject-code class="native" file="glue/qguiapplication_init.cpp" position="beginning" />
+ <inject-code class="native" position="beginning" file="../glue/qtgui.cpp" snippet="qguiapplication-init"/>
</object-type>
<object-type name="QOpenGLBuffer" since="5.0">
- <enum-type name="Access" />
- <enum-type name="RangeAccessFlag" flags="RangeAccessFlags" />
- <enum-type name="Type" />
- <enum-type name="UsagePattern" />
+ <enum-type name="Access"/>
+ <enum-type name="RangeAccessFlag" flags="RangeAccessFlags"/>
+ <enum-type name="Type"/>
+ <enum-type name="UsagePattern"/>
</object-type>
<object-type name="QOpenGLContext">
- <enum-type name="OpenGLModuleType" />
+ <enum-type name="OpenGLModuleType"/>
</object-type>
<object-type name="QOpenGLContextGroup" since="5.0"/>
<object-type name="QOpenGLDebugLogger" since="5.1">
@@ -3320,7 +2562,7 @@
<enum-type name="Severity" flags="Severities"/>
</value-type>
<object-type name="QOpenGLFramebufferObject" since="5.0">
- <enum-type name="Attachment" />
+ <enum-type name="Attachment"/>
<enum-type name="FramebufferRestorePolicy" since="5.7"/>
</object-type>
<value-type name="QOpenGLFramebufferObjectFormat"/>
@@ -3538,11 +2780,9 @@
</modify-function>
<modify-function signature="glGetStringi(unsigned int,unsigned int)">
<modify-argument index="return">
- <replace-type modified-type="QString" />
+ <replace-type modified-type="QString"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="glGetString_return_QString"/>
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qstring-return"/>
</modify-function>
</object-type>
<object-type name="QOpenGLFunctions" since="5.0">
@@ -3599,7 +2839,7 @@
</modify-function>
<modify-function signature="glGetString(unsigned int)">
<modify-argument index="return">
- <replace-type modified-type="QString" />
+ <replace-type modified-type="QString"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="glGetString_return_QString"/>
@@ -3638,7 +2878,7 @@
-->
<value-type name="QOpenGLPixelTransferOptions"/>
<object-type name="QOpenGLShader" since="5.0">
- <enum-type name="ShaderTypeBit" flags="ShaderType" />
+ <enum-type name="ShaderTypeBit" flags="ShaderType"/>
</object-type>
<object-type name="QOpenGLShaderProgram" since="5.0">
<modify-function signature="setAttributeArray(int,const float*,int,int)">
@@ -3737,9 +2977,14 @@
<modify-function signature="glyphIndexesForChars(const QChar*,int,quint32*,int*)const" remove="all"/>
</value-type>
<object-type name="QRasterWindow"/>
- <object-type name="QScreen" />
+ <object-type name="QScreen">
+ <modify-function signature="grabWindow(WId,int,int,int,int)">
+ <modify-argument index="1">
+ <replace-type modified-type="long"/>
+ </modify-argument>
+ <inject-code file="../glue/qtgui.cpp" snippet="qscreen-grabWindow"/>
+ </modify-function>
+ </object-type>
<object-type name="QStyleHints"/>
</typesystem>
-
-
diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml
index 27fb9387f..4d24d5703 100644
--- a/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml
+++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml
@@ -45,6 +45,6 @@
<primitive-type name="Qt::HANDLE" target-lang-api-name="PyObject"/>
- <suppress-warning text="enum 'QSysInfo::Endian' is specified in typesystem, but not declared" />
- <suppress-warning text="type 'QGtkStyle' is specified in typesystem, but not defined. This could potentially lead to compilation errors." />
+ <suppress-warning text="enum 'QSysInfo::Endian' is specified in typesystem, but not declared"/>
+ <suppress-warning text="type 'QGtkStyle' is specified in typesystem, but not defined. This could potentially lead to compilation errors."/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtHelp/CMakeLists.txt b/sources/pyside2/PySide2/QtHelp/CMakeLists.txt
index 342863a4f..102eef91f 100644
--- a/sources/pyside2/PySide2/QtHelp/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtHelp/CMakeLists.txt
@@ -39,10 +39,9 @@ set(QtHelp_libraries pyside2
set(QtHelp_deps QtWidgets)
-create_pyside_module(QtHelp
- QtHelp_include_dirs
- QtHelp_libraries
- QtHelp_deps
- QtHelp_SOURCE_DIR
- QtHelp_SRC
- "")
+create_pyside_module(NAME QtHelp
+ INCLUDE_DIRS QtHelp_include_dirs
+ LIBRARIES QtHelp_libraries
+ DEPS QtHelp_deps
+ TYPESYSTEM_PATH QtHelp_SOURCE_DIR
+ SOURCES QtHelp_SRC)
diff --git a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
index 080fe4240..287d6374e 100644
--- a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
+++ b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml
@@ -41,7 +41,7 @@
-->
<typesystem package="PySide2.QtHelp">
- <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<value-type name="QHelpContentItem">
<modify-function signature="parent()const">
@@ -52,7 +52,7 @@
</value-type>
<object-type name="QHelpContentModel" polymorphic-id-expression="qobject_cast&lt;QHelpContentModel*&gt;(%1)"/>
<object-type name="QHelpContentWidget"/>
- <object-type name="QHelpEngine" />
+ <object-type name="QHelpEngine"/>
<object-type name="QHelpEngineCore"/>
<object-type name="QHelpIndexModel"/>
<object-type name="QHelpIndexWidget"/>
diff --git a/sources/pyside2/PySide2/QtLocation/CMakeLists.txt b/sources/pyside2/PySide2/QtLocation/CMakeLists.txt
index f968d1a1c..b36613256 100644
--- a/sources/pyside2/PySide2/QtLocation/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtLocation/CMakeLists.txt
@@ -69,12 +69,10 @@ set(QtLocation_libraries pyside2
set(QtLocation_deps QtCore QtPositioning)
-create_pyside_module(QtLocation
- QtLocation_include_dirs
- QtLocation_libraries
- QtLocation_deps
- QtLocation_SOURCE_DIR
- QtLocation_SRC
- ""
- ""
- QtLocation_DROPPED_ENTRIES)
+create_pyside_module(NAME QtLocation
+ INCLUDE_DIRS QtLocation_include_dirs
+ LIBRARIES QtLocation_libraries
+ DEPS QtLocation_deps
+ TYPESYSTEM_PATH QtLocation_SOURCE_DIR
+ SOURCES QtLocation_SRC
+ DROPPED_ENTRIES QtLocation_DROPPED_ENTRIES)
diff --git a/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt b/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt
index 6c69a784c..281596185 100644
--- a/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt
@@ -28,10 +28,9 @@ set(QtMacExtras_libraries pyside2
set(QtMacExtras_deps QtCore QtGui)
-create_pyside_module(QtMacExtras
- QtMacExtras_include_dirs
- QtMacExtras_libraries
- QtMacExtras_deps
- QtMacExtras_SOURCE_DIR
- QtMacExtras_SRC
- "")
+create_pyside_module(NAME QtMacExtras
+ INCLUDE_DIRS QtMacExtras_include_dirs
+ LIBRARIES QtMacExtras_libraries
+ DEPS QtMacExtras_deps
+ TYPESYSTEM_PATH QtMacExtras_SOURCE_DIR
+ SOURCES QtMacExtras_SRC)
diff --git a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt
index e9caaa64b..71e575da3 100644
--- a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt
@@ -125,10 +125,9 @@ set(QtMultimedia_libraries pyside2
)
set(QtMultimedia_deps QtCore QtGui QtNetwork)
-create_pyside_module(QtMultimedia
- QtMultimedia_include_dirs
- QtMultimedia_libraries
- QtMultimedia_deps
- QtMultimedia_SOURCE_DIR
- QtMultimedia_SRC
- "")
+create_pyside_module(NAME QtMultimedia
+ INCLUDE_DIRS QtMultimedia_include_dirs
+ LIBRARIES QtMultimedia_libraries
+ DEPS QtMultimedia_deps
+ TYPESYSTEM_PATH QtMultimedia_SOURCE_DIR
+ SOURCES QtMultimedia_SRC)
diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml
index 5486fb157..a976c42fc 100644
--- a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml
+++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml
@@ -40,9 +40,9 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtMultimedia">
- <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
- <load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
- <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no" />
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
<namespace-type name="QAudio">
<enum-type name="Error"/>
@@ -177,25 +177,15 @@
<enum-type name="Status"/>
<modify-function signature="setViewfinder(QVideoWidget*)">
<modify-argument index="1">
- <replace-type modified-type="QObject *" />
+ <replace-type modified-type="QObject *"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %BEGIN_ALLOW_THREADS
- QObject* upcastedArg = %CONVERTTOCPP[QObject*](%PYARG_1);
- %CPPSELF.%FUNCTION_NAME(reinterpret_cast&lt; %ARG1_TYPE &gt;(upcastedArg));
- %END_ALLOW_THREADS
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtmultimedia.cpp" snippet="upcast"/>
</modify-function>
<modify-function signature="setViewfinder(QGraphicsVideoItem*)">
<modify-argument index="1">
- <replace-type modified-type="QObject *" />
+ <replace-type modified-type="QObject *"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %BEGIN_ALLOW_THREADS
- QObject* upcastedArg = %CONVERTTOCPP[QObject*](%PYARG_1);
- %CPPSELF.%FUNCTION_NAME(reinterpret_cast&lt; %ARG1_TYPE &gt;(upcastedArg));
- %END_ALLOW_THREADS
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtmultimedia.cpp" snippet="upcast"/>
</modify-function>
</object-type>
<object-type name="QCameraCaptureBufferFormatControl"/>
@@ -282,25 +272,15 @@
<enum-type name="Error"/>
<modify-function signature="setVideoOutput(QVideoWidget*)">
<modify-argument index="1">
- <replace-type modified-type="QObject *" />
+ <replace-type modified-type="QObject *"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %BEGIN_ALLOW_THREADS
- QObject* upcastedArg = %CONVERTTOCPP[QObject*](%PYARG_1);
- %CPPSELF.%FUNCTION_NAME(reinterpret_cast&lt; %ARG1_TYPE &gt;(upcastedArg));
- %END_ALLOW_THREADS
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtmultimedia.cpp" snippet="upcast"/>
</modify-function>
<modify-function signature="setVideoOutput(QGraphicsVideoItem*)">
<modify-argument index="1">
- <replace-type modified-type="QObject *" />
+ <replace-type modified-type="QObject *"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %BEGIN_ALLOW_THREADS
- QObject* upcastedArg = %CONVERTTOCPP[QObject*](%PYARG_1);
- %CPPSELF.%FUNCTION_NAME(reinterpret_cast&lt; %ARG1_TYPE &gt;(upcastedArg));
- %END_ALLOW_THREADS
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtmultimedia.cpp" snippet="upcast"/>
</modify-function>
</object-type>
<object-type name="QMediaPlayerControl"/>
diff --git a/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt
index abae2ceb7..09c3ce994 100644
--- a/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt
@@ -38,10 +38,9 @@ set(QtMultimediaWidgets_libraries pyside2
set(QtMultimediaWidgets_deps QtCore QtGui QtNetwork QtWidgets QtMultimedia)
-create_pyside_module(QtMultimediaWidgets
- QtMultimediaWidgets_include_dirs
- QtMultimediaWidgets_libraries
- QtMultimediaWidgets_deps
- QtMultimediaWidgets_SOURCE_DIR
- QtMultimediaWidgets_SRC
- "")
+create_pyside_module(NAME QtMultimediaWidgets
+ INCLUDE_DIRS QtMultimediaWidgets_include_dirs
+ LIBRARIES QtMultimediaWidgets_libraries
+ DEPS QtMultimediaWidgets_deps
+ TYPESYSTEM_PATH QtMultimediaWidgets_SOURCE_DIR
+ SOURCES QtMultimediaWidgets_SRC)
diff --git a/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml b/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml
index 16a42d2e3..550ae17eb 100644
--- a/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml
+++ b/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml
@@ -40,10 +40,10 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtMultimediaWidgets">
- <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
- <load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
- <load-typesystem name="QtMultimedia/typesystem_multimedia_common.xml" generate="no" />
- <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtMultimedia/typesystem_multimedia_common.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<object-type name="QCameraViewfinder"/>
<object-type name="QGraphicsVideoItem"/>
diff --git a/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt b/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt
index 0267bfae3..cd9517889 100644
--- a/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt
@@ -1,23 +1,7 @@
project(QtNetwork)
-set(QtNetwork_OPTIONAL_SRC )
set(QtNetwork_DROPPED_ENTRIES )
-check_qt_class(QtNetwork QSslCertificate QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslCertificateExtension QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslCipher QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslConfiguration QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslDiffieHellmanParameters QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-# Problems with operator==(QSslEllipticCurve,QSslEllipticCurve)
-# check_qt_class(QtNetwork QSslEllipticCurve QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslError QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslKey QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslPreSharedKeyAuthenticator QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSslSocket QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-
-check_qt_class(QtNetwork QSctpServer QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-check_qt_class(QtNetwork QSctpSocket QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
-
set(QtNetwork_SRC
${QtNetwork_GEN_DIR}/qabstractnetworkcache_wrapper.cpp
${QtNetwork_GEN_DIR}/qabstractsocket_wrapper.cpp
@@ -52,15 +36,63 @@ ${QtNetwork_GEN_DIR}/qnetworkproxyquery_wrapper.cpp
${QtNetwork_GEN_DIR}/qnetworkreply_wrapper.cpp
${QtNetwork_GEN_DIR}/qnetworkrequest_wrapper.cpp
${QtNetwork_GEN_DIR}/qnetworksession_wrapper.cpp
+${QtNetwork_GEN_DIR}/qpassworddigestor_wrapper.cpp
${QtNetwork_GEN_DIR}/qssl_wrapper.cpp
${QtNetwork_GEN_DIR}/qtcpserver_wrapper.cpp
${QtNetwork_GEN_DIR}/qtcpsocket_wrapper.cpp
${QtNetwork_GEN_DIR}/qudpsocket_wrapper.cpp
-${QtNetwork_OPTIONAL_SRC}
# module is always needed
${QtNetwork_GEN_DIR}/qtnetwork_module_wrapper.cpp
)
+get_property(QtNetwork_enabled_features TARGET Qt5::Network PROPERTY INTERFACE_QT_ENABLED_FEATURES)
+get_property(QtNetwork_disabled_features TARGET Qt5::Network PROPERTY INTERFACE_QT_DISABLED_FEATURES)
+
+# ### fixme: For cmake >= 3.3, use if( needle IN_LIST list)
+list(FIND QtNetwork_enabled_features "ssl" _sslEnabledIndex)
+list(FIND QtNetwork_disabled_features "dtls" _dtlsDisabledIndex)
+list(FIND QtNetwork_disabled_features "sctp" _sctpDisabledIndex)
+
+if(_sslEnabledIndex EQUAL -1)
+ list(APPEND QtNetwork_DROPPED_ENTRIES QSslCertificate QSslCertificateExtension
+ QSslCipher QSslConfiguration QSslDiffieHellmanParameters QSslError
+ QSslKey QSslPreSharedKeyAuthenticator QSslSocket)
+ message(STATUS "Qt5Network: Dropping SSL classes")
+else()
+ # Problems with operator==(QSslEllipticCurve,QSslEllipticCurve)
+ # check_qt_class(QtNetwork QSslEllipticCurve QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES)
+ list(APPEND QtNetwork_SRC
+ ${QtNetwork_GEN_DIR}/qsslcertificate_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslcertificateextension_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslcipher_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslconfiguration_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qssldiffiehellmanparameters_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslerror_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslkey_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslpresharedkeyauthenticator_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsslsocket_wrapper.cpp)
+ message(STATUS "Qt5Network: Adding SSL classes")
+endif()
+
+if(_dtlsDisabledIndex GREATER -1)
+ list(APPEND QtNetwork_DROPPED_ENTRIES QDtls)
+ message(STATUS "Qt5Network: Dropping DTLS classes")
+else()
+ list(APPEND QtNetwork_SRC
+ ${QtNetwork_GEN_DIR}/qdtls_wrapper.cpp)
+ message(STATUS "Qt5Network: Adding DTLS classes")
+endif()
+
+if(_sctpDisabledIndex GREATER -1)
+ list(APPEND QtNetwork_DROPPED_ENTRIES QSctpServer QSctpSocket)
+ message(STATUS "Qt5Network: Dropping SCTP classes")
+else()
+ list(APPEND QtNetwork_SRC
+ ${QtNetwork_GEN_DIR}/qsctpserver_wrapper.cpp
+ ${QtNetwork_GEN_DIR}/qsctpsocket_wrapper.cpp)
+ message(STATUS "Qt5Network: Adding SCTP classes")
+endif()
+
set(QtNetwork_include_dirs ${QtNetwork_SOURCE_DIR}
${QtNetwork_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
@@ -77,12 +109,10 @@ set(QtNetwork_libraries pyside2
set(QtNetwork_deps QtCore)
-create_pyside_module(QtNetwork
- QtNetwork_include_dirs
- QtNetwork_libraries
- QtNetwork_deps
- QtNetwork_SOURCE_DIR
- QtNetwork_SRC
- ""
- ""
- QtNetwork_DROPPED_ENTRIES)
+create_pyside_module(NAME QtNetwork
+ INCLUDE_DIRS QtNetwork_include_dirs
+ LIBRARIES QtNetwork_libraries
+ DEPS QtNetwork_deps
+ TYPESYSTEM_PATH QtNetwork_SOURCE_DIR
+ SOURCES QtNetwork_SRC
+ DROPPED_ENTRIES QtNetwork_DROPPED_ENTRIES)
diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
index e4235e070..3ffd9077e 100644
--- a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
+++ b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml
@@ -42,12 +42,20 @@
<typesystem package="PySide2.QtNetwork">
<load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
+ <enum-type name="QDtlsError" since="5.12"/>
+
+ <namespace-type name="QPasswordDigestor" since="5.12">
+ <extra-includes>
+ <include file-name="qpassworddigestor.h" location="global"/>
+ </extra-includes>
+ </namespace-type>
+
<namespace-type name="QSsl">
<enum-type name="AlternativeNameEntryType"/>
<enum-type name="EncodingFormat"/>
<enum-type name="KeyAlgorithm"/>
<enum-type name="KeyType"/>
- <enum-type name="SslOption" flags="SslOptions" />
+ <enum-type name="SslOption" flags="SslOptions"/>
<enum-type name="SslProtocol"/>
<extra-includes>
<include file-name="qssl.h" location="global"/>
@@ -57,18 +65,18 @@
<rejection class="QIPv6Address" field-name="c"/>
<object-type name="QAbstractSocket">
- <enum-type name="BindFlag" flags="BindMode" />
+ <enum-type name="BindFlag" flags="BindMode"/>
<enum-type name="NetworkLayerProtocol"/>
- <enum-type name="PauseMode" flags="PauseModes" />
+ <enum-type name="PauseMode" flags="PauseModes"/>
<enum-type name="SocketError"/>
<enum-type name="SocketOption" since="4.6"/>
<enum-type name="SocketState"/>
<enum-type name="SocketType"/>
- <modify-function signature="connectToHost(const QString&amp;,quint16,QFlags&lt;QIODevice::OpenModeFlag>,QAbstractSocket::NetworkLayerProtocol)" allow-thread="yes" />
- <modify-function signature="connectToHost(const QHostAddress&amp;,quint16,QFlags&lt;QIODevice::OpenModeFlag>)" allow-thread="yes" />
- <modify-function signature="disconnectFromHost()" allow-thread="yes" />
- <modify-function signature="waitForConnected(int)" allow-thread="yes" />
- <modify-function signature="waitForDisconnected(int)" allow-thread="yes" />
+ <modify-function signature="connectToHost(const QString&amp;,quint16,QFlags&lt;QIODevice::OpenModeFlag>,QAbstractSocket::NetworkLayerProtocol)" allow-thread="yes"/>
+ <modify-function signature="connectToHost(const QHostAddress&amp;,quint16,QFlags&lt;QIODevice::OpenModeFlag>)" allow-thread="yes"/>
+ <modify-function signature="disconnectFromHost()" allow-thread="yes"/>
+ <modify-function signature="waitForConnected(int)" allow-thread="yes"/>
+ <modify-function signature="waitForDisconnected(int)" allow-thread="yes"/>
</object-type>
<value-type name="QDnsDomainNameRecord"/>
@@ -80,6 +88,11 @@
<value-type name="QDnsMailExchangeRecord"/>
<value-type name="QDnsServiceRecord"/>
<value-type name="QDnsTextRecord"/>
+
+ <object-type name="QDtls" since="5.12">
+ <enum-type name="HandshakeState"/>
+ </object-type>
+
<value-type name="QHstsPolicy" since="5.9">
<enum-type name="PolicyFlag" flags="PolicyFlags"/>
</value-type>
@@ -122,19 +135,7 @@
<modify-argument index="return">
<replace-type modified-type="(data, address, port)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- Shiboken::AutoArrayPointer&lt;char&gt; data(%ARGUMENT_NAMES);
- QHostAddress ha;
- quint16 port;
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(data, %ARGUMENT_NAMES, &amp;ha, &amp;port);
- %END_ALLOW_THREADS
- QByteArray ba(data, retval);
- %PYARG_0 = PyTuple_New(3);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QByteArray](ba));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QHostAddress](ha));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[quint16](port));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qudpsocket-readdatagram"/>
</modify-function>
<modify-function signature="writeDatagram(const QByteArray&amp;,const QHostAddress&amp;,quint16)" allow-thread="yes"/>
<!-- ### writeDatagram(QByteArray, ...) does the trick -->
@@ -143,7 +144,7 @@
</object-type>
<object-type name="QLocalServer">
- <enum-type name="SocketOption" flags="SocketOptions" />
+ <enum-type name="SocketOption" flags="SocketOptions"/>
<modify-function signature="waitForNewConnection(int,bool*)" allow-thread="yes">
<!-- FIXME -->
<modify-argument index="1">
@@ -180,7 +181,7 @@
<modify-function signature="post(const QNetworkRequest &amp;,const QByteArray &amp;)" allow-thread="yes"/>
<modify-function signature="put(const QNetworkRequest &amp;,QIODevice*)" allow-thread="yes"/>
<modify-function signature="put(const QNetworkRequest &amp;,const QByteArray &amp;)" allow-thread="yes"/>
- <modify-function signature="sendCustomRequest(const QNetworkRequest &amp;,const QByteArray &amp;,QIODevice*)" allow-thread="yes" since="4.7" />
+ <modify-function signature="sendCustomRequest(const QNetworkRequest &amp;,const QByteArray &amp;,QIODevice*)" allow-thread="yes" since="4.7"/>
<modify-function signature="setCookieJar(QNetworkCookieJar*)">
<modify-argument index="1">
<define-ownership class="target" owner="c++"/>
@@ -197,11 +198,11 @@
<enum-type name="ConversionModeFlag" flags="ConversionMode" since="5.8"/>
<enum-type name="SpecialAddress"/>
<!-- ### QHostAddress(QIPv6Address) does this -->
- <modify-function signature="QHostAddress(quint8*)" remove="all" />
- <modify-function signature="QHostAddress(const quint8*)" remove="all" />
+ <modify-function signature="QHostAddress(quint8*)" remove="all"/>
+ <modify-function signature="QHostAddress(const quint8*)" remove="all"/>
<!-- ### -->
- <modify-function signature="setAddress(quint8*)" remove="all" />
- <modify-function signature="setAddress(const quint8*)" remove="all" />
+ <modify-function signature="setAddress(quint8*)" remove="all"/>
+ <modify-function signature="setAddress(const quint8*)" remove="all"/>
</value-type>
<value-type name="QHostInfo">
@@ -219,55 +220,28 @@
</value-type>
<value-type name="QNetworkProxy">
- <enum-type name="Capability" flags="Capabilities" />
+ <enum-type name="Capability" flags="Capabilities"/>
<enum-type name="ProxyType"/>
</value-type>
- <object-type name="QNetworkProxyFactory" />
+ <object-type name="QNetworkProxyFactory"/>
<value-type name="QNetworkProxyQuery">
- <enum-type name="QueryType" />
+ <enum-type name="QueryType"/>
</value-type>
<value-type name="QIPv6Address">
<add-function signature="__len__">
- <inject-code class="target" position="beginning">
- return 16;
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qipv6address-len"/>
</add-function>
<add-function signature="__getitem__">
- <inject-code class="target" position="beginning">
- if (_i >= 16) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return 0;
- }
- if (_i &lt; 0)
- _i = 16 - qAbs(_i);
-
- uint item = %CPPSELF.c[_i];
- return %CONVERTTOPYTHON[uint](item);
- </inject-code>
- </add-function>
- <add-function signature="__len__">
- <inject-code class="target" position="beginning">
- return 16;
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qipv6address-getitem"/>
</add-function>
<add-function signature="__setitem__">
- <inject-code class="target" position="beginning">
- if (_i >= 16) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return -1;
- }
- if (_i &lt; 0)
- _i = 16 - qAbs(_i);
- quint8 item = %CONVERTTOCPP[quint8](_value);
- %CPPSELF.c[_i] = item;
- return 0;
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtnetwork.cpp" snippet="qipv6address-setitem"/>
</add-function>
</value-type>
- <value-type name="QAuthenticator" />
+ <value-type name="QAuthenticator"/>
<value-type name="QNetworkCookie">
<enum-type name="RawForm"/>
<extra-includes>
@@ -275,7 +249,7 @@
</extra-includes>
</value-type>
<value-type name="QNetworkRequest">
- <enum-type name="Attribute" extensible="yes"/>
+ <enum-type name="Attribute"/>
<enum-type name="LoadControl" since="4.7"/>
<enum-type name="Priority" since="4.7"/>
<enum-type name="CacheLoadControl"/>
@@ -284,7 +258,7 @@
</value-type>
<value-type name="QNetworkConfiguration" since="4.7">
- <enum-type name="BearerType" />
+ <enum-type name="BearerType"/>
<enum-type name="Purpose" since="4.7"/>
<enum-type name="StateFlag" flags="StateFlags" since="4.7"/>
<enum-type name="Type" since="4.7"/>
@@ -295,7 +269,7 @@
<object-type name="QNetworkSession" since="4.7">
<enum-type name="SessionError" since="4.7"/>
<enum-type name="State" since="4.7"/>
- <enum-type name="UsagePolicy" flags="UsagePolicies" />
+ <enum-type name="UsagePolicy" flags="UsagePolicies"/>
</object-type>
<object-type name="QAbstractNetworkCache"/>
@@ -315,7 +289,7 @@
<value-type name="QSslCipher"/>
<value-type name="QSslConfiguration">
- <enum-type name="NextProtocolNegotiationStatus" />
+ <enum-type name="NextProtocolNegotiationStatus"/>
</value-type>
<value-type name="QSslDiffieHellmanParameters" since="5.8">
@@ -334,8 +308,8 @@
<object-type name="QSslSocket">
<enum-type name="SslMode"/>
<enum-type name="PeerVerifyMode"/>
- <modify-function signature="connectToHostEncrypted(const QString&amp;,quint16,QFlags&lt;QIODevice::OpenModeFlag>,QAbstractSocket::NetworkLayerProtocol)" allow-thread="yes" />
- <modify-function signature="waitForEncrypted(int)" allow-thread="yes" />
+ <modify-function signature="connectToHostEncrypted(const QString&amp;,quint16,QFlags&lt;QIODevice::OpenModeFlag>,QAbstractSocket::NetworkLayerProtocol)" allow-thread="yes"/>
+ <modify-function signature="waitForEncrypted(int)" allow-thread="yes"/>
</object-type>
<value-type name="QSslPreSharedKeyAuthenticator"/>
diff --git a/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt b/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt
index 9a8b64050..e23cd36b1 100644
--- a/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt
@@ -37,10 +37,9 @@ set(QtOpenGL_libraries pyside2
${Qt5OpenGL_LIBRARIES})
set(QtOpenGL_deps QtWidgets)
-create_pyside_module(QtOpenGL
- QtOpenGL_include_dirs
- QtOpenGL_libraries
- QtOpenGL_deps
- QtOpenGL_SOURCE_DIR
- QtOpenGL_SRC
- "")
+create_pyside_module(NAME QtOpenGL
+ INCLUDE_DIRS QtOpenGL_include_dirs
+ LIBRARIES QtOpenGL_libraries
+ DEPS QtOpenGL_deps
+ TYPESYSTEM_PATH QtOpenGL_SOURCE_DIR
+ SOURCES QtOpenGL_SRC)
diff --git a/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml b/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml
index ea5c24cd3..a234e95d6 100644
--- a/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml
+++ b/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml
@@ -41,6 +41,7 @@
-->
<typesystem package="PySide2.QtOpenGL">
<load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+ <load-typesystem name="templates/opengl_common.xml" generate="no" />
<primitive-type name="GLbitfield"/>
<primitive-type name="GLboolean"/>
@@ -59,19 +60,19 @@
<rejection class="QGLColormap::QGLColormapData"/>
<rejection class="QGLContext" field-name="currentCtx"/>
- <rejection class="^QGL.*$" argument-type="^GLboolean( const)?\*$"/>
- <rejection class="^QGL.*$" argument-type="^GLchar( const)?\*$"/>
- <rejection class="^QGL.*$" argument-type="GLchar *const const*"/>
- <rejection class="^QGL.*$" argument-type="^GLenum( const)?\*$"/>
- <rejection class="^QGL.*$" argument-type="^GLfloat( const)?\*$"/>
- <rejection class="^QGL.*$" argument-type="^GLfloat( const)?\[.*$"/>
- <rejection class="^QGL.*$" argument-type="^GLdouble( const)?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLboolean ?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLchar ?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLchar ?\*const"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLenum ?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLfloat ?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLfloat ?\[.*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLdouble ?\*$"/>
<rejection class="^QGL.*$" argument-type="GLintptr"/>
- <rejection class="^QGL.*$" argument-type="^GLint64( const)?\*$"/>
- <rejection class="^QGL.*$" argument-type="^GLsizei( const)?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLint64 ?\*$"/>
+ <rejection class="^QGL.*$" argument-type="^(const )?GLsizei ?\*$"/>
<namespace-type name="QGL">
- <enum-type name="FormatOption" flags="FormatOptions" force-integer="yes"/>
+ <enum-type name="FormatOption" flags="FormatOptions"/>
<extra-includes>
<include file-name="qgl.h" location="global"/>
</extra-includes>
@@ -88,7 +89,7 @@
<enum-type name="OpenGLVersionFlag" flags="OpenGLVersionFlags"/>
</value-type>
- <rejection class="QGLContext" field-name="currentCtx" />
+ <rejection class="QGLContext" field-name="currentCtx"/>
<object-type name="QGLContext">
<enum-type name="BindOption" flags="BindOptions" since="4.6"/>
<modify-function signature="chooseContext(const QGLContext*)">
@@ -99,7 +100,7 @@
</modify-function>
<!-- ### Obsolete functions and ctors -->
- <modify-function signature="QGLContext(const QGLFormat&amp;,QPaintDevice*)" remove="all" />
+ <modify-function signature="QGLContext(const QGLFormat&amp;,QPaintDevice*)" remove="all"/>
<!-- ### -->
</object-type>
<object-type name="QGLFramebufferObject">
@@ -124,7 +125,7 @@
</modify-argument>
</modify-function>
<!-- ### Not part of Qt public API -->
- <modify-function signature="setContext(QGLContext*,const QGLContext*,bool)" remove="all" />
+ <modify-function signature="setContext(QGLContext*,const QGLContext*,bool)" remove="all"/>
<!-- ### -->
<!--- ### Obsolete functions -->
<modify-function signature="setFormat(QGLFormat)" remove="all"/>
@@ -136,34 +137,16 @@
<enum-type name="ShaderTypeBit" flags="ShaderType"/>
</object-type>
- <template name="callArrayFunction">
- int _size = PySequence_Size(%PYARG_2);
- if (_size) {
- $ATTR_TYPE *_list = new $ATTR_TYPE[_size];
- if (_size) {
- Shiboken::AutoDecRef fast(PySequence_Fast(%PYARG_2, "Failed to parse sequence with type %VECTOR_TYPE."));
- for(int i=0; i &lt; _size; i++) {
- PyObject* pv = PySequence_Fast_GET_ITEM(fast.object(), i);
- _list[i] = %CONVERTTOCPP[$ATTR_TYPE](pv);
- }
- }
- %CPPSELF.%FUNCTION_NAME(%1, _list, $ARG0);
- delete[] _list;
- } else {
- %CPPSELF.%FUNCTION_NAME(%1, ($ATTR_TYPE*)NULL, $ARG1);
- }
- </template>
-
<object-type name="QGLShaderProgram" since="4.6">
<!-- setAttributeArray -->
<modify-function signature="setAttributeArray(int,const QVector2D*,int)" rename="setAttributeArray2D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="%3" />
- <replace from="$ARG1" to="%3" />
+ <replace from="$ARG0" to="%3"/>
+ <replace from="$ARG1" to="%3"/>
<replace from="$ATTR_TYPE" to="QVector2D"/>
</insert-template>
</inject-code>
@@ -171,12 +154,12 @@
<modify-function signature="setAttributeArray(int,const QVector3D*,int)" rename="setAttributeArray3D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="%3" />
- <replace from="$ARG1" to="%3" />
+ <replace from="$ARG0" to="%3"/>
+ <replace from="$ARG1" to="%3"/>
<replace from="$ATTR_TYPE" to="QVector3D"/>
</insert-template>
</inject-code>
@@ -184,12 +167,12 @@
<modify-function signature="setAttributeArray(int,const QVector4D*,int)" rename="setAttributeArray4D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="%3" />
- <replace from="$ARG1" to="%3" />
+ <replace from="$ARG0" to="%3"/>
+ <replace from="$ARG1" to="%3"/>
<replace from="$ATTR_TYPE" to="QVector4D"/>
</insert-template>
</inject-code>
@@ -197,12 +180,12 @@
<modify-function signature="setAttributeArray(const char*,const QVector2D*,int)" rename="setAttributeArray2D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="%3" />
- <replace from="$ARG1" to="%3" />
+ <replace from="$ARG0" to="%3"/>
+ <replace from="$ARG1" to="%3"/>
<replace from="$ATTR_TYPE" to="QVector2D"/>
</insert-template>
</inject-code>
@@ -210,12 +193,12 @@
<modify-function signature="setAttributeArray(const char*,const QVector3D*,int)" rename="setAttributeArray3D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="%3" />
- <replace from="$ARG1" to="%3" />
+ <replace from="$ARG0" to="%3"/>
+ <replace from="$ARG1" to="%3"/>
<replace from="$ATTR_TYPE" to="QVector3D"/>
</insert-template>
</inject-code>
@@ -223,12 +206,12 @@
<modify-function signature="setAttributeArray(const char*,const QVector4D*,int)" rename="setAttributeArray4D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="%3" />
- <replace from="$ARG1" to="%3" />
+ <replace from="$ARG0" to="%3"/>
+ <replace from="$ARG1" to="%3"/>
<replace from="$ATTR_TYPE" to="QVector4D"/>
</insert-template>
</inject-code>
@@ -237,15 +220,15 @@
<!-- setUniformValueArray -->
<modify-function signature="setUniformValueArray(int,const GLint*,int)" rename="setUniformValueArrayInt">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="GLint"/>
</insert-template>
</inject-code>
@@ -253,15 +236,15 @@
<modify-function signature="setUniformValueArray(int,const GLuint*,int)" rename="setUniformValueArrayUint">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="GLuint"/>
</insert-template>
</inject-code>
@@ -269,15 +252,15 @@
<modify-function signature="setUniformValueArray(int,const QVector2D*,int)" rename="setUniformValueArray2D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QVector2D"/>
</insert-template>
</inject-code>
@@ -285,15 +268,15 @@
<modify-function signature="setUniformValueArray(int,const QVector3D*,int)" rename="setUniformValueArray3D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QVector3D"/>
</insert-template>
</inject-code>
@@ -301,15 +284,15 @@
<modify-function signature="setUniformValueArray(int,const QVector4D*,int)" rename="setUniformValueArray4D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QVector4D"/>
</insert-template>
</inject-code>
@@ -317,15 +300,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix2x2*,int)" rename="setUniformValueArray2x2">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix2x2"/>
</insert-template>
</inject-code>
@@ -333,15 +316,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix2x3*,int)" rename="setUniformValueArray2x3">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix2x3"/>
</insert-template>
</inject-code>
@@ -349,15 +332,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix2x4*,int)" rename="setUniformValueArray2x4">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix2x4"/>
</insert-template>
</inject-code>
@@ -365,15 +348,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix3x2*,int)" rename="setUniformValueArray3x2">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix3x2"/>
</insert-template>
</inject-code>
@@ -381,15 +364,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix3x3*,int)" rename="setUniformValueArray3x3">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix3x3"/>
</insert-template>
</inject-code>
@@ -397,15 +380,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix3x4*,int)" rename="setUniformValueArray3x4">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix3x4"/>
</insert-template>
</inject-code>
@@ -413,15 +396,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix4x2*,int)" rename="setUniformValueArray4x2">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix4x2"/>
</insert-template>
</inject-code>
@@ -429,15 +412,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix4x3*,int)" rename="setUniformValueArray4x3">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix4x3"/>
</insert-template>
</inject-code>
@@ -445,15 +428,15 @@
<modify-function signature="setUniformValueArray(int,const QMatrix4x4*,int)" rename="setUniformValueArray4x4">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix4x4"/>
</insert-template>
</inject-code>
@@ -461,15 +444,15 @@
<modify-function signature="setUniformValueArray(const char*,const GLint*,int)" rename="setUniformValueArrayInt">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="GLint"/>
</insert-template>
</inject-code>
@@ -477,15 +460,15 @@
<modify-function signature="setUniformValueArray(const char*,const GLuint*,int)" rename="setUniformValueArrayUint">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="GLuint"/>
</insert-template>
</inject-code>
@@ -493,15 +476,15 @@
<modify-function signature="setUniformValueArray(const char*,const QVector2D*,int)" rename="setUniformValueArray2D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QVector2D"/>
</insert-template>
</inject-code>
@@ -509,15 +492,15 @@
<modify-function signature="setUniformValueArray(const char*,const QVector3D*,int)" rename="setUniformValueArray3D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QVector3D"/>
</insert-template>
</inject-code>
@@ -525,15 +508,15 @@
<modify-function signature="setUniformValueArray(const char*,const QVector4D*,int)" rename="setUniformValueArray4D">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QVector4D"/>
</insert-template>
</inject-code>
@@ -541,15 +524,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix2x2*,int)" rename="setUniformValueArray2x2">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix2x2"/>
</insert-template>
</inject-code>
@@ -557,15 +540,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix2x3*,int)" rename="setUniformValueArray2x3">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix2x3"/>
</insert-template>
</inject-code>
@@ -573,15 +556,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix2x4*,int)" rename="setUniformValueArray2x4">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix2x4"/>
</insert-template>
</inject-code>
@@ -589,15 +572,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix3x2*,int)" rename="setUniformValueArray3x2">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix3x2"/>
</insert-template>
</inject-code>
@@ -605,15 +588,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix3x3*,int)" rename="setUniformValueArray3x3">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix3x3"/>
</insert-template>
</inject-code>
@@ -621,15 +604,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix3x4*,int)" rename="setUniformValueArray3x4">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix3x4"/>
</insert-template>
</inject-code>
@@ -637,15 +620,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix4x2*,int)" rename="setUniformValueArray4x2">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix4x2"/>
</insert-template>
</inject-code>
@@ -653,15 +636,15 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix4x3*,int)" rename="setUniformValueArray4x3">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix4x3"/>
</insert-template>
</inject-code>
@@ -669,32 +652,23 @@
<modify-function signature="setUniformValueArray(const char*,const QMatrix4x4*,int)" rename="setUniformValueArray4x4">
<modify-argument index="2" >
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
</modify-argument>
<inject-code>
<insert-template name="callArrayFunction">
- <replace from="$ARG0" to="_size" />
- <replace from="$ARG1" to="0" />
+ <replace from="$ARG0" to="_size"/>
+ <replace from="$ARG1" to="0"/>
<replace from="$ATTR_TYPE" to="QMatrix4x4"/>
</insert-template>
</inject-code>
</modify-function>
- <!-- ### TODO: must evaluate if anything other than removal should be done. -->
- <modify-function signature="setAttributeArray(int,const GLfloat*,int,int)" remove="all" />
- <modify-function signature="setAttributeArray(const char*,const GLfloat*,int,int)" remove="all" />
- <modify-function signature="setUniformValueArray(int,const GLfloat*,int,int)" remove="all" />
- <modify-function signature="setUniformValueArray(const char*,const GLfloat*,int,int)" remove="all" />
- <!-- ### -->
-
<!-- ### Use QMatrixZxY overloads -->
- <modify-function signature="setAttributeValue(int,const GLfloat*,int,int)" remove="all" />
- <modify-function signature="setAttributeValue(const char*,const GLfloat*,int,int)" remove="all" />
- <modify-function signature="setAttributeArray(int,GLenum,const void*,int,int)" remove="all" since="4.7" />
- <modify-function signature="setAttributeArray(const char*,GLenum,const void*,int,int)" remove="all" since="4.7" />
+ <modify-function signature="setAttributeArray(int,GLenum,const void*,int,int)" remove="all" since="4.7"/>
+ <modify-function signature="setAttributeArray(const char*,GLenum,const void*,int,int)" remove="all" since="4.7"/>
<!-- ### -->
</object-type>
@@ -710,25 +684,10 @@
<modify-argument index="2">
<replace-default-expression with="-1"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int size = (%2 &lt; 0) ? %1.size() : %2;
- %CPPSELF.allocate((const void*) %1.data(), size);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtopengl.cpp" snippet="qglbuffer-allocate"/>
</modify-function>
<modify-function signature="map(QGLBuffer::Access)">
- <inject-code>
- Py_ssize_t dataSize = %CPPSELF.size();
- void* data = %CPPSELF.map(%1);
-
- if (!data) {
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- } else if (%1 == QGLBuffer::ReadOnly) {
- %PYARG_0 = Shiboken::Buffer::newObject(data, dataSize, Shiboken::Buffer::ReadOnly);
- } else {
- %PYARG_0 = Shiboken::Buffer::newObject(data, dataSize, Shiboken::Buffer::ReadWrite);
- }
- </inject-code>
+ <inject-code file="../glue/qtopengl.cpp" snippet="qglbuffer-map"/>
</modify-function>
<modify-function signature="read(int,void*,int)">
<modify-argument index="2">
@@ -737,17 +696,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, data)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- char *data = new char[%3];
- bool result = %CPPSELF.read(%1, data, %3);
- QByteArray ret;
- if (result)
- ret.append((const char*)data, %3);
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](result));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QByteArray](ret));
- delete[] data;
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtopengl.cpp" snippet="qglbuffer-read"/>
</modify-function>
<modify-function signature="write(int,const void*,int)">
<modify-argument index="2">
@@ -756,10 +705,7 @@
<modify-argument index="3">
<replace-default-expression with="-1"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int size = (%3 &lt; 0) ? %2.size() : %3;
- %CPPSELF.write(%1, (const void*) %2.data(), size);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtopengl.cpp" snippet="qglbuffer-write"/>
</modify-function>
</object-type>
diff --git a/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt b/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt
index 3a2eb9cf5..ecbcd9f78 100644
--- a/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt
@@ -44,12 +44,10 @@ set(QtPositioning_libraries pyside2
set(QtPositioning_deps QtCore)
-create_pyside_module(QtPositioning
- QtPositioning_include_dirs
- QtPositioning_libraries
- QtPositioning_deps
- QtPositioning_SOURCE_DIR
- QtPositioning_SRC
- ""
- ""
- QtPositioning_DROPPED_ENTRIES)
+create_pyside_module(NAME QtPositioning
+ INCLUDE_DIRS QtPositioning_include_dirs
+ LIBRARIES QtPositioning_libraries
+ DEPS QtPositioning_deps
+ TYPESYSTEM_PATH QtPositioning_SOURCE_DIR
+ SOURCES QtPositioning_SRC
+ DROPPED_ENTRIES QtPositioning_DROPPED_ENTRIES)
diff --git a/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt b/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt
index 201dd6d69..31b86290d 100644
--- a/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt
@@ -35,10 +35,9 @@ set(QtPrintSupport_libraries pyside2
${Qt5PrintSupport_LIBRARIES}
)
set(QtPrintSupport_deps QtWidgets)
-create_pyside_module(QtPrintSupport
- QtPrintSupport_include_dirs
- QtPrintSupport_libraries
- QtPrintSupport_deps
- QtPrintSupport_SOURCE_DIR
- QtPrintSupport_SRC
- "")
+create_pyside_module(NAME QtPrintSupport
+ INCLUDE_DIRS QtPrintSupport_include_dirs
+ LIBRARIES QtPrintSupport_libraries
+ DEPS QtPrintSupport_deps
+ TYPESYSTEM_PATH QtPrintSupport_SOURCE_DIR
+ SOURCES QtPrintSupport_SRC)
diff --git a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml
index b6111a0e6..f85aadc79 100644
--- a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml
+++ b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml
@@ -40,24 +40,24 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtPrintSupport">
- <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<object-type name="QPageSetupDialog">
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
</object-type>
<object-type name="QAbstractPrintDialog">
- <enum-type name="PrintDialogOption" flags="PrintDialogOptions" />
- <enum-type name="PrintRange" />
+ <enum-type name="PrintDialogOption" flags="PrintDialogOptions"/>
+ <enum-type name="PrintRange"/>
</object-type>
<object-type name="QPrintDialog">
- <modify-function signature="exec()" rename="exec_" allow-thread="yes" />
+ <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
</object-type>
<object-type name="QPrintEngine">
- <enum-type name="PrintEnginePropertyKey" />
+ <enum-type name="PrintEnginePropertyKey"/>
</object-type>
- <value-type name="QPrinterInfo" />
+ <value-type name="QPrinterInfo"/>
<rejection class="QPrinter" function-name="printerSelectionOption"/>
<rejection class="QPrinter" function-name="setPrinterSelectionOption"/>
@@ -74,7 +74,7 @@
<enum-type name="Unit"/>
<modify-function signature="getPageMargins(qreal*,qreal*,qreal*,qreal*,QPrinter::Unit)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -90,7 +90,7 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*,args">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -111,7 +111,7 @@
<object-type name="QPrintPreviewWidget">
<enum-type name="ViewMode"/>
<enum-type name="ZoomMode"/>
- <modify-function signature="print()" rename="print_" />
+ <modify-function signature="print()" rename="print_"/>
</object-type>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtQml/CMakeLists.txt b/sources/pyside2/PySide2/QtQml/CMakeLists.txt
index fb09443c1..c584c3371 100644
--- a/sources/pyside2/PySide2/QtQml/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtQml/CMakeLists.txt
@@ -56,10 +56,10 @@ set(QtQml_libraries pyside2
set(QtQml_deps QtGui QtNetwork)
-create_pyside_module(QtQml
- QtQml_include_dirs
- QtQml_libraries
- QtQml_deps
- QtQml_SOURCE_DIR
- QtQml_SRC
- QtQml_registerType)
+create_pyside_module(NAME QtQml
+ INCLUDE_DIRS QtQml_include_dirs
+ LIBRARIES QtQml_libraries
+ DEPS QtQml_deps
+ TYPESYSTEM_PATH QtQml_SOURCE_DIR
+ SOURCES QtQml_SRC
+ STATIC_SOURCES QtQml_registerType)
diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
index 1a1f09511..9d9ddc799 100644
--- a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
+++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
@@ -44,6 +44,7 @@
// pyside
#include <pyside.h>
+#include <pyside_p.h>
#include <pysideproperty.h>
// auto generated headers
@@ -126,8 +127,7 @@ int PySide::qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor,
return -1;
}
- QMetaObject *metaObject = reinterpret_cast<QMetaObject *>(
- ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType *>(pyObj)));
+ const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType);
Q_ASSERT(metaObject);
QQmlPrivate::RegisterType type;
@@ -172,13 +172,13 @@ int PySide::qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor,
type.versionMajor = versionMajor;
type.versionMinor = versionMinor;
type.elementName = qmlName;
- type.metaObject = metaObject;
type.extensionObjectCreate = 0;
type.extensionMetaObject = 0;
type.customParser = 0;
++nextType;
}
+ type.metaObject = metaObject; // Snapshot may have changed.
int qmlTypeId = QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type);
if (qmlTypeId == -1) {
diff --git a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
index 9a0d1e0ae..b0bdfaa27 100644
--- a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
+++ b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml
@@ -45,7 +45,7 @@
<load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
<!-- This is to inform the generator that the VolatileBool python type exists -->
- <custom-type name="VolatileBool" />
+ <custom-type name="VolatileBool"/>
<primitive-type name="bool volatile" target-lang-api-name="VolatileBool">
<include file-name="pysideqmlregistertype.h" location="local"/>
<!-- No conversion rules are specified here, because the generator does not handle
@@ -76,10 +76,7 @@
Note that it's perfectly reasonable for a library to register types to older versions than the actual version of the library. Indeed, it is normal for the new library to allow QML written to previous versions to continue to work, even if more advanced versions of some of its types are available.
</inject-documentation>
- <inject-code class="target">
- int %0 = PySide::qmlRegisterType(%ARGUMENT_NAMES);
- %PYARG_0 = %CONVERTTOPYTHON[int](%0);
- </inject-code>
+ <inject-code class="target" file="../glue/qtqml.cpp" snippet="qmlregistertype"/>
</add-function>
<enum-type identified-by-value="QML_HAS_ATTACHED_PROPERTIES">
@@ -89,38 +86,33 @@
</extra-includes>
</enum-type>
- <inject-code class="target" position="end">
- PySide::initQmlSupport(module);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtqml.cpp" snippet="init"/>
<object-type name="QJSEngine">
- <enum-type name="Extension" flags="Extensions" since="5.6" />
+ <enum-type name="Extension" flags="Extensions" since="5.6"/>
<add-function signature="toScriptValue(const QVariant&amp;)" return-type="QJSValue">
- <inject-code class="target" position="end">
- %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1);
- return %CONVERTTOPYTHON[%RETURN_TYPE](retval);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtqml.cpp" snippet="qjsengine-toscriptvalue"/>
</add-function>
</object-type>
<value-type name="QJSValue">
- <enum-type name="SpecialValue" />
+ <enum-type name="SpecialValue"/>
</value-type>
- <object-type name="QJSValueIterator" />
+ <object-type name="QJSValueIterator"/>
<object-type name="QQmlAbstractUrlInterceptor">
- <enum-type name="DataType" />
+ <enum-type name="DataType"/>
</object-type>
- <object-type name="QQmlApplicationEngine" />
+ <object-type name="QQmlApplicationEngine"/>
<object-type name="QQmlComponent">
- <enum-type name="CompilationMode" />
- <enum-type name="Status" />
+ <enum-type name="CompilationMode"/>
+ <enum-type name="Status"/>
</object-type>
- <object-type name="QQmlContext" />
- <value-type name="QQmlError" />
+ <object-type name="QQmlContext"/>
+ <value-type name="QQmlError"/>
<object-type name="QQmlDebuggingEnabler">
- <enum-type name="StartMode" />
+ <enum-type name="StartMode"/>
</object-type>
<object-type name="QQmlEngine">
- <enum-type name="ObjectOwnership" />
+ <enum-type name="ObjectOwnership"/>
<modify-function signature="addImageProvider(const QString&amp;,QQmlImageProviderBase*)">
<modify-argument index="2">
<define-ownership owner="c++"/>
@@ -133,35 +125,35 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_bool*"/>
</inject-code>
</modify-function>
</object-type>
- <interface-type name="QQmlTypesExtensionInterface" />
- <interface-type name="QQmlExtensionInterface" />
- <object-type name="QQmlExtensionPlugin" />
+ <interface-type name="QQmlTypesExtensionInterface"/>
+ <interface-type name="QQmlExtensionInterface"/>
+ <object-type name="QQmlExtensionPlugin"/>
<!-- Possible qRegisterMetaType issues ? -->
<object-type name="QQmlFile">
- <enum-type name="Status" />
+ <enum-type name="Status"/>
</object-type>
- <object-type name="QQmlFileSelector" />
+ <object-type name="QQmlFileSelector"/>
<object-type name="QQmlImageProviderBase">
- <enum-type name="Flag" flags="Flags" />
- <enum-type name="ImageType" />
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="ImageType"/>
</object-type>
<object-type name="QQmlIncubator">
- <enum-type name="IncubationMode" />
- <enum-type name="Status" />
+ <enum-type name="IncubationMode"/>
+ <enum-type name="Status"/>
</object-type>
<object-type name="QQmlIncubationController">
- <modify-function signature="incubateWhile(bool volatile*,int)" allow-thread="yes">
+ <modify-function signature="incubateWhile(volatile bool*,int)" allow-thread="yes">
<modify-argument index="1">
<!-- The replace type is needed to use the VolatileBool_Check macro instead of
a template conversion function with "volatile bool" as argument. -->
- <replace-type modified-type="VolatileBool" />
+ <replace-type modified-type="VolatileBool"/>
<conversion-rule class="native">
volatile bool * %out =
&amp;((reinterpret_cast&lt;QtQml_VolatileBoolObject *&gt;(%PYARG_1))->flag);
@@ -175,22 +167,22 @@
allow instantiating or deriving from the class though, given that a separate custom ListProperty
type is provided by the module. Plus meta type registration would have to be taken into account
for the QML parts.
- <value-type name="QQmlListProperty" />-->
- <value-type name="QQmlListReference" />
- <interface-type name="QQmlParserStatus" />
+ <value-type name="QQmlListProperty"/>-->
+ <value-type name="QQmlListReference"/>
+ <interface-type name="QQmlParserStatus"/>
<value-type name="QQmlProperty">
- <enum-type name="PropertyTypeCategory" />
- <enum-type name="Type" />
+ <enum-type name="PropertyTypeCategory"/>
+ <enum-type name="Type"/>
</value-type>
- <object-type name="QQmlPropertyMap" />
- <object-type name="QQmlPropertyValueSource" />
+ <object-type name="QQmlPropertyMap"/>
+ <object-type name="QQmlPropertyValueSource"/>
<value-type name="QQmlScriptString">
<modify-function signature="numberLiteral(bool*)const" allow-thread="yes">
<modify-argument index="1">
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_bool*"/>
@@ -201,7 +193,7 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_bool*"/>
@@ -216,5 +208,5 @@
</modify-function>
</object-type>
<!-- Suppress anonymous enum warning -->
- <suppress-warning text="enum 'QmlCurrentSingletonTypeRegistrationVersion' does not have a type entry or is not an enum" />
+ <suppress-warning text="Anonymous enum (QmlCurrentSingletonTypeRegistrationVersion) does not have a type entry"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt
index 01e369e7a..788d6d50e 100644
--- a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt
@@ -84,10 +84,10 @@ set(QtQuick_libraries pyside2
set(QtQuick_deps QtGui QtNetwork QtQml)
-create_pyside_module(QtQuick
- QtQuick_include_dirs
- QtQuick_libraries
- QtQuick_deps
- QtQuick_SOURCE_DIR
- QtQuick_SRC
- QtQuick_registerType)
+create_pyside_module(NAME QtQuick
+ INCLUDE_DIRS QtQuick_include_dirs
+ LIBRARIES QtQuick_libraries
+ DEPS QtQuick_deps
+ TYPESYSTEM_PATH QtQuick_SOURCE_DIR
+ SOURCES QtQuick_SRC
+ STATIC_SOURCES QtQuick_registerType)
diff --git a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp
index bf3ff06a2..93a8f281e 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 <shiboken.h>
// Auto generated headers.
#include "qquickitem_wrapper.h"
diff --git a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml
index 7e6b450c9..2dc90b9e0 100644
--- a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml
+++ b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml
@@ -45,130 +45,128 @@
<load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
<load-typesystem name="QtQml/typesystem_qml.xml" generate="no"/>
- <smart-pointer-type name="QSharedPointer" type="shared" getter="data" />
+ <smart-pointer-type name="QSharedPointer" type="shared" getter="data"/>
<extra-includes>
<include file-name="pysidequickregistertype.h" location="local"/>
</extra-includes>
- <inject-code class="target" position="end">
- PySide::initQuickSupport(module);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtquick.cpp" snippet="qtquick"/>
- <object-type name="QQuickAsyncImageProvider" since="5.6" />
+ <object-type name="QQuickAsyncImageProvider" since="5.6"/>
- <object-type name="QQuickFramebufferObject" />
- <object-type name="QQuickFramebufferObject::Renderer" />
+ <object-type name="QQuickFramebufferObject"/>
+ <object-type name="QQuickFramebufferObject::Renderer"/>
- <object-type name="QQuickTextureFactory" />
- <object-type name="QQuickImageProvider" />
- <object-type name="QQuickImageResponse" since="5.6" />
+ <object-type name="QQuickTextureFactory"/>
+ <object-type name="QQuickImageProvider"/>
+ <object-type name="QQuickImageResponse" since="5.6"/>
- <object-type name="QQuickTransform" />
- <object-type name="QQuickItem">
- <value-type name="UpdatePaintNodeData" />
- <enum-type name="Flag" flags="Flags" />
- <enum-type name="ItemChange" />
- <enum-type name="TransformOrigin" />
+ <object-type name="QQuickTransform"/>
+ <object-type name="QQuickItem" delete-in-main-thread="true">
+ <value-type name="UpdatePaintNodeData"/>
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="ItemChange"/>
+ <enum-type name="TransformOrigin"/>
<modify-function signature="itemTransform(QQuickItem*,bool*)const" allow-thread="yes">
<modify-argument index="2">
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<!-- TODO: Find a way to wrap `union ItemChangeData {}` -->
</object-type>
- <object-type name="QQuickItemGrabResult" />
+ <object-type name="QQuickItemGrabResult"/>
<object-type name="QQuickPaintedItem">
- <enum-type name="RenderTarget" />
- <enum-type name="PerformanceHint" flags="PerformanceHints" />
+ <enum-type name="RenderTarget"/>
+ <enum-type name="PerformanceHint" flags="PerformanceHints"/>
</object-type>
- <object-type name="QQuickRenderControl" />
+ <object-type name="QQuickRenderControl"/>
- <object-type name="QQuickTextDocument" />
+ <object-type name="QQuickTextDocument"/>
<object-type name="QQuickView">
- <enum-type name="ResizeMode" />
- <enum-type name="Status" />
+ <enum-type name="ResizeMode"/>
+ <enum-type name="Status"/>
</object-type>
<object-type name="QQuickWindow">
- <enum-type name="CreateTextureOption" flags="CreateTextureOptions" />
- <enum-type name="RenderStage" />
- <enum-type name="SceneGraphError" />
+ <enum-type name="CreateTextureOption" flags="CreateTextureOptions"/>
+ <enum-type name="RenderStage"/>
+ <enum-type name="SceneGraphError"/>
<enum-type name="TextRenderType" since="5.10"/>
</object-type>
<object-type name="QSGAbstractRenderer">
- <enum-type name="ClearModeBit" flags="ClearMode" />
+ <enum-type name="ClearModeBit" flags="ClearMode"/>
</object-type>
- <object-type name="QSGBasicGeometryNode" />
- <object-type name="QSGClipNode" />
- <object-type name="QSGDynamicTexture" />
+ <object-type name="QSGBasicGeometryNode"/>
+ <object-type name="QSGClipNode"/>
+ <object-type name="QSGDynamicTexture"/>
<object-type name="QSGEngine">
- <enum-type name="CreateTextureOption" flags="CreateTextureOptions" />
+ <enum-type name="CreateTextureOption" flags="CreateTextureOptions"/>
</object-type>
- <!-- <object-type name="QSGFlatColorMaterial" /> -->
+ <!-- <object-type name="QSGFlatColorMaterial"/> -->
<object-type name="QSGGeometry">
- <enum-type name="DataPattern" />
+ <enum-type name="DataPattern"/>
<enum-type name="AttributeType" since="5.8"/>
<enum-type name="DrawingMode" since="5.8"/>
<enum-type name="Type" since="5.8"/>
</object-type>
- <value-type name="QSGGeometry::Attribute" />
- <value-type name="QSGGeometry::AttributeSet" />
- <value-type name="QSGGeometry::ColoredPoint2D" />
- <value-type name="QSGGeometry::Point2D" />
- <value-type name="QSGGeometry::TexturedPoint2D" />
- <object-type name="QSGGeometryNode" />
+ <value-type name="QSGGeometry::Attribute"/>
+ <value-type name="QSGGeometry::AttributeSet"/>
+ <value-type name="QSGGeometry::ColoredPoint2D"/>
+ <value-type name="QSGGeometry::Point2D"/>
+ <value-type name="QSGGeometry::TexturedPoint2D"/>
+ <object-type name="QSGGeometryNode"/>
<!-- QSGMaterialShader doesn't compile because of const char * char * types not being recognized
by the C++ parser, nor the generator.
<object-type name="QSGMaterial">
- <enum-type name="Flag" flags="Flags" />
+ <enum-type name="Flag" flags="Flags"/>
</object-type>
- <object-type name="QSGMaterialShader" />
+ <object-type name="QSGMaterialShader"/>
<value-type name="QSGMaterialShader::RenderState">
- <enum-type name="DirtyState" flags="DirtyStates" />
+ <enum-type name="DirtyState" flags="DirtyStates"/>
</value-type>
-->
- <object-type name="QSGMaterialType" />
+ <object-type name="QSGMaterialType"/>
<object-type name="QSGNode">
- <enum-type name="DirtyStateBit" flags="DirtyState" />
- <enum-type name="Flag" flags="Flags" />
- <enum-type name="NodeType" />
+ <enum-type name="DirtyStateBit" flags="DirtyState"/>
+ <enum-type name="Flag" flags="Flags"/>
+ <enum-type name="NodeType"/>
</object-type>
- <object-type name="QSGOpacityNode" />
- <!-- <object-type name="QSGOpaqueTextureMaterial" /> -->
- <object-type name="QSGSimpleRectNode" />
+ <object-type name="QSGOpacityNode"/>
+ <!-- <object-type name="QSGOpaqueTextureMaterial"/> -->
+ <object-type name="QSGSimpleRectNode"/>
<object-type name="QSGSimpleTextureNode">
- <enum-type name="TextureCoordinatesTransformFlag" flags="TextureCoordinatesTransformMode" />
+ <enum-type name="TextureCoordinatesTransformFlag" flags="TextureCoordinatesTransformMode"/>
</object-type>
<object-type name="QSGTexture">
<enum-type name="AnisotropyLevel" since="5.9"/>
- <enum-type name="Filtering" />
- <enum-type name="WrapMode" />
+ <enum-type name="Filtering"/>
+ <enum-type name="WrapMode"/>
</object-type>
- <!-- <object-type name="QSGTextureMaterial" /> -->
- <object-type name="QSGTextureProvider" />
- <object-type name="QSGTransformNode" />
- <!-- <object-type name="QSGVertexColorMaterial" /> -->
+ <!-- <object-type name="QSGTextureMaterial"/> -->
+ <object-type name="QSGTextureProvider"/>
+ <object-type name="QSGTransformNode"/>
+ <!-- <object-type name="QSGVertexColorMaterial"/> -->
<!-- These currently don't work because they are template classes, and the generator chokes on
them. Making these work properly would require fixing the parsing of template classes,
allowing creation of State structures and passing them to the template classes, as well as
implementing some mechanism of registration of the custom template classes, kind of how
it's done for qt quick items.
- <object-type name="QSGSimpleMaterial" />
- <object-type name="QSGSimpleMaterialShader" />
+ <object-type name="QSGSimpleMaterial"/>
+ <object-type name="QSGSimpleMaterialShader"/>
-->
</typesystem>
diff --git a/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt
index 86991208a..76f81870d 100644
--- a/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt
@@ -38,10 +38,9 @@ set(QtQuickWidgets_libraries pyside2
set(QtQuickWidgets_deps QtGui QtQml QtQuick QtWidgets QtNetwork)
-create_pyside_module(QtQuickWidgets
- QtQuickWidgets_include_dirs
- QtQuickWidgets_libraries
- QtQuickWidgets_deps
- QtQuickWidgets_SOURCE_DIR
- QtQuickWidgets_SRC
- "")
+create_pyside_module(NAME QtQuickWidgets
+ INCLUDE_DIRS QtQuickWidgets_include_dirs
+ LIBRARIES QtQuickWidgets_libraries
+ DEPS QtQuickWidgets_deps
+ TYPESYSTEM_PATH QtQuickWidgets_SOURCE_DIR
+ SOURCES QtQuickWidgets_SRC)
diff --git a/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml b/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml
index 03230187e..e44ef8e6d 100644
--- a/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml
+++ b/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml
@@ -48,7 +48,7 @@
<object-type name="QQuickWidget">
- <enum-type name="ResizeMode" />
- <enum-type name="Status" />
+ <enum-type name="ResizeMode"/>
+ <enum-type name="Status"/>
</object-type>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtScript/CMakeLists.txt b/sources/pyside2/PySide2/QtScript/CMakeLists.txt
index 1e06c4644..dfcb80789 100644
--- a/sources/pyside2/PySide2/QtScript/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtScript/CMakeLists.txt
@@ -18,6 +18,10 @@ ${QtScript_GEN_DIR}/qscriptvalueiterator_wrapper.cpp
${QtScript_GEN_DIR}/qtscript_module_wrapper.cpp
)
+set(QtScript_glue_sources
+ "${QtScript_SOURCE_DIR}/qscript_value_iterator_glue.cpp"
+)
+
set(QtScript_include_dirs ${QtScript_SOURCE_DIR}
${QtScript_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
@@ -33,10 +37,10 @@ set(QtScript_libraries pyside2
${Qt5Core_LIBRARIES}
${Qt5Script_LIBRARIES})
set(QtScript_deps QtCore)
-create_pyside_module(QtScript
- QtScript_include_dirs
- QtScript_libraries
- QtScript_deps
- QtScript_SOURCE_DIR
- QtScript_SRC
- "")
+create_pyside_module(NAME QtScript
+ INCLUDE_DIRS QtScript_include_dirs
+ LIBRARIES QtScript_libraries
+ DEPS QtScript_deps
+ TYPESYSTEM_PATH QtScript_SOURCE_DIR
+ SOURCES QtScript_SRC
+ GLUE_SOURCES QtScript_glue_sources)
diff --git a/sources/pyside2/PySide2/QtScript/typesystem_script.xml b/sources/pyside2/PySide2/QtScript/typesystem_script.xml
index d2d3e3182..f87e4cfdf 100644
--- a/sources/pyside2/PySide2/QtScript/typesystem_script.xml
+++ b/sources/pyside2/PySide2/QtScript/typesystem_script.xml
@@ -40,7 +40,7 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtScript">
- <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
<object-type name="QScriptable"/>
<object-type name="QScriptClass">
@@ -62,7 +62,7 @@
<enum-type name="QObjectWrapOption" flags="QObjectWrapOptions"/>
<enum-type name="ValueOwnership"/>
<!-- Not supported BUG #957-->
- <modify-function signature="scriptValueFromQMetaObject()" remove="all" />
+ <modify-function signature="scriptValueFromQMetaObject()" remove="all"/>
</object-type>
<object-type name="QScriptExtensionInterface"/>
<object-type name="QScriptExtensionPlugin"/>
@@ -82,53 +82,23 @@
<enum-type name="ResolveFlag" flags="ResolveFlags"/>
<enum-type name="SpecialValue"/>
<add-function signature="__repr__" return-type="PyObject*">
- <inject-code class="target" position="beginning">
- if (%CPPSELF.isVariant() || %CPPSELF.isString()) {
- QString format = QString().sprintf("%s(\"%s\")",
- Py_TYPE(%PYSELF)->tp_name,
- qPrintable(%CPPSELF.toString()));
- %PYARG_0 = Shiboken::String::fromCString(qPrintable(format));
- } else {
- %PYARG_0 = Shiboken::String::fromCString(Py_TYPE(%PYSELF)->tp_name);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtscript.cpp" snippet="qscriptvalue-repr"/>
</add-function>
<add-function signature="__mgetitem__">
- <inject-code>
- Shiboken::AutoDecRef key(PyObject_Str(_key));
- QVariant res = %CPPSELF.property(Shiboken::String::toCString(key.object())).toVariant();
- if (res.isValid()) {
- return %CONVERTTOPYTHON[QVariant](res);
- } else {
- PyObject* errorType = PyInt_Check(_key) ? PyExc_IndexError : PyExc_KeyError;
- PyErr_SetString(errorType, "Key not found.");
- return 0;
- }
- </inject-code>
+ <inject-code file="../glue/qtscript.cpp" snippet="qscriptvalue-mgetitem"/>
</add-function>
<add-function signature="__iter__()" return-type="PyObject*">
- <inject-code file="qscript_value_iterator_glue.cpp" />
+ <inject-code file="qscript_value_iterator_glue.cpp"/>
</add-function>
</value-type>
<object-type name="QScriptValueIterator">
<add-function signature="__iter__()" return-type="PyObject*">
<inject-code>
- <insert-template name="__iter__" />
+ <insert-template name="__iter__"/>
</inject-code>
</add-function>
<add-function signature="__next__()" return-type="PyObject*">
- <inject-code>
- if (%CPPSELF.hasNext()) {
- %CPPSELF.next();
- QString name = %CPPSELF.name();
- QVariant value = %CPPSELF.value().toVariant();
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QString](name));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QVariant](value));
- } else {
- PyErr_SetNone(PyExc_StopIteration);
- }
- </inject-code>
+ <inject-code file="../glue/qtscript.cpp" snippet="qscriptvalueiterator-next"/>
</add-function>
</object-type>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt b/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt
index 92bf1a545..39bb0adc6 100644
--- a/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt
@@ -32,10 +32,9 @@ set(QtScriptTools_libraries pyside2
set(QtScriptTools_deps QtCore QtScript QtGui QtWidgets)
-create_pyside_module(QtScriptTools
- QtScriptTools_include_dirs
- QtScriptTools_libraries
- QtScriptTools_deps
- QtScriptTools_SOURCE_DIR
- QtScriptTools_SRC
- "")
+create_pyside_module(NAME QtScriptTools
+ INCLUDE_DIRS QtScriptTools_include_dirs
+ LIBRARIES QtScriptTools_libraries
+ DEPS QtScriptTools_deps
+ TYPESYSTEM_PATH QtScriptTools_SOURCE_DIR
+ SOURCES QtScriptTools_SRC)
diff --git a/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml b/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml
index 81a4048b5..770a2f25f 100644
--- a/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml
+++ b/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml
@@ -40,9 +40,9 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtScriptTools">
- <load-typesystem name="QtScript/typesystem_script.xml" generate="no" />
- <load-typesystem name="QtGui/typesystem_gui.xml" generate="no" />
- <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
+ <load-typesystem name="QtScript/typesystem_script.xml" generate="no"/>
+ <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<object-type name="QScriptEngineDebugger">
<enum-type name="DebuggerAction"/>
diff --git a/sources/pyside2/PySide2/QtScxml/CMakeLists.txt b/sources/pyside2/PySide2/QtScxml/CMakeLists.txt
index 0a75ffce6..35ca46427 100644
--- a/sources/pyside2/PySide2/QtScxml/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtScxml/CMakeLists.txt
@@ -49,12 +49,10 @@ set(QtScxml_libraries pyside2
set(QtScxml_deps QtCore)
-create_pyside_module(QtScxml
- QtScxml_include_dirs
- QtScxml_libraries
- QtScxml_deps
- QtScxml_SOURCE_DIR
- QtScxml_SRC
- ""
- ""
- QtScxml_DROPPED_ENTRIES)
+create_pyside_module(NAME QtScxml
+ INCLUDE_DIRS QtScxml_include_dirs
+ LIBRARIES QtScxml_libraries
+ DEPS QtScxml_deps
+ TYPESYSTEM_PATH QtScxml_SOURCE_DIR
+ SOURCES QtScxml_SRC
+ DROPPED_ENTRIES QtScxml_DROPPED_ENTRIES)
diff --git a/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml b/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml
index 67a0cc4b7..616a5a782 100644
--- a/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml
+++ b/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml
@@ -52,7 +52,13 @@
<object-type name="QScxmlInvokableService"/>
<object-type name="QScxmlInvokableServiceFactory"/>
<object-type name="QScxmlStaticScxmlServiceFactory"/>
- <object-type name="QScxmlStateMachine"/>
+ <object-type name="QScxmlStateMachine">
+ <modify-function signature="submitEvent(QScxmlEvent*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
<object-type name="QScxmlTableData"/>
<object-type name="QScxmlDataModel" since="5.12">
<!-- Needs to have exports fixed -->
diff --git a/sources/pyside2/PySide2/QtSensors/CMakeLists.txt b/sources/pyside2/PySide2/QtSensors/CMakeLists.txt
index 226625443..933c266c0 100644
--- a/sources/pyside2/PySide2/QtSensors/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtSensors/CMakeLists.txt
@@ -95,12 +95,10 @@ set(QtSensors_libraries pyside2
set(QtSensors_deps QtCore)
-create_pyside_module(QtSensors
- QtSensors_include_dirs
- QtSensors_libraries
- QtSensors_deps
- QtSensors_SOURCE_DIR
- QtSensors_SRC
- ""
- ""
- QtSensors_DROPPED_ENTRIES)
+create_pyside_module(NAME QtSensors
+ INCLUDE_DIRS QtSensors_include_dirs
+ LIBRARIES QtSensors_libraries
+ DEPS QtSensors_deps
+ TYPESYSTEM_PATH QtSensors_SOURCE_DIR
+ SOURCES QtSensors_SRC
+ DROPPED_ENTRIES QtSensors_DROPPED_ENTRIES)
diff --git a/sources/pyside2/PySide2/QtSql/CMakeLists.txt b/sources/pyside2/PySide2/QtSql/CMakeLists.txt
index 0573ab5cd..a72d06118 100644
--- a/sources/pyside2/PySide2/QtSql/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtSql/CMakeLists.txt
@@ -45,10 +45,9 @@ set(QtSql_libraries pyside2
${Qt5Sql_LIBRARIES})
set(QtSql_deps QtWidgets)
-create_pyside_module(QtSql
- QtSql_include_dirs
- QtSql_libraries
- QtSql_deps
- QtSql_SOURCE_DIR
- QtSql_SRC
- "")
+create_pyside_module(NAME QtSql
+ INCLUDE_DIRS QtSql_include_dirs
+ LIBRARIES QtSql_libraries
+ DEPS QtSql_deps
+ TYPESYSTEM_PATH QtSql_SOURCE_DIR
+ SOURCES QtSql_SRC)
diff --git a/sources/pyside2/PySide2/QtSql/typesystem_sql.xml b/sources/pyside2/PySide2/QtSql/typesystem_sql.xml
index 1b6baa15f..c8a56a213 100644
--- a/sources/pyside2/PySide2/QtSql/typesystem_sql.xml
+++ b/sources/pyside2/PySide2/QtSql/typesystem_sql.xml
@@ -65,12 +65,12 @@
<include file-name="QStringList" location="global"/>
<include file-name="QSize" location="global"/>
</extra-includes>
- <modify-function signature="exec(QString)const" rename="exec_" allow-thread="yes" />
- <modify-function signature="open()" allow-thread="yes" />
- <modify-function signature="open(const QString&amp;, const QString&amp;)" allow-thread="yes" />
- <modify-function signature="commit()" allow-thread="yes" />
- <modify-function signature="rollback()" allow-thread="yes" />
- <modify-function signature="transaction()" allow-thread="yes" />
+ <modify-function signature="exec(QString)const" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="open()" allow-thread="yes"/>
+ <modify-function signature="open(const QString&amp;, const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="commit()" allow-thread="yes"/>
+ <modify-function signature="rollback()" allow-thread="yes"/>
+ <modify-function signature="transaction()" allow-thread="yes"/>
<modify-function signature="registerSqlDriver(const QString&amp;,QSqlDriverCreatorBase*)">
<modify-argument index="2">
<define-ownership owner="c++"/>
@@ -86,29 +86,28 @@
<include file-name="QStringList" location="global"/>
<include file-name="QSize" location="global"/>
</extra-includes>
- <modify-function signature="exec()" rename="exec_" allow-thread="yes" />
- <modify-function signature="exec(const QString&amp;)" rename="exec_" allow-thread="yes" />
- <modify-function signature="prepare(const QString&amp;)" allow-thread="yes" />
- <modify-function signature="clear()" allow-thread="yes" />
- <modify-function signature="last()" allow-thread="yes" />
- <modify-function signature="first()" allow-thread="yes" />
- <modify-function signature="previous()" allow-thread="yes" />
- <modify-function signature="next()" allow-thread="yes" />
- <modify-function signature="seek(int,bool)" allow-thread="yes" />
+ <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="exec(const QString&amp;)" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="prepare(const QString&amp;)" allow-thread="yes"/>
+ <modify-function signature="clear()" allow-thread="yes"/>
+ <modify-function signature="last()" allow-thread="yes"/>
+ <modify-function signature="first()" allow-thread="yes"/>
+ <modify-function signature="previous()" allow-thread="yes"/>
+ <modify-function signature="next()" allow-thread="yes"/>
+ <modify-function signature="seek(int,bool)" allow-thread="yes"/>
</value-type>
<value-type name="QSqlRecord">
<extra-includes>
<include file-name="QSqlField" location="global"/>
</extra-includes>
- <modify-function signature="append(QSqlField)" access="non-final"/>
</value-type>
<value-type name="QSqlError">
<enum-type name="ErrorType"/>
</value-type>
- <value-type name="QSqlIndex" />
+ <value-type name="QSqlIndex"/>
<value-type name="QSqlRelation"/>
@@ -119,10 +118,10 @@
</value-type>
<object-type name="QSqlDriver">
- <enum-type name="DbmsType" />
+ <enum-type name="DbmsType"/>
<enum-type name="DriverFeature"/>
<enum-type name="IdentifierType"/>
- <enum-type name="NotificationSource" />
+ <enum-type name="NotificationSource"/>
<enum-type name="StatementType"/>
<extra-includes>
<include file-name="QSqlQuery" location="global"/>
@@ -132,18 +131,16 @@
<include file-name="QStringList" location="global"/>
<include file-name="QSize" location="global"/>
</extra-includes>
- <modify-function signature="beginTransaction()" allow-thread="yes" />
- <modify-function signature="commitTransaction()" allow-thread="yes" />
- <modify-function signature="rollbackTransaction()" allow-thread="yes" />
- <modify-function signature="open(const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,const QString&amp;)" allow-thread="yes" />
+ <modify-function signature="beginTransaction()" allow-thread="yes"/>
+ <modify-function signature="commitTransaction()" allow-thread="yes"/>
+ <modify-function signature="rollbackTransaction()" allow-thread="yes"/>
+ <modify-function signature="open(const QString&amp;,const QString&amp;,const QString&amp;,const QString&amp;,int,const QString&amp;)" allow-thread="yes"/>
<!-- ### This is too low level for Python, and pointer would be useless for the Python programmer -->
<modify-function signature="handle()const" remove="all"/>
<!-- ### -->
</object-type>
<object-type name="QSqlQueryModel">
- <modify-function signature="indexInQuery(QModelIndex)const" access="non-final"/>
- <modify-function signature="setQuery(QSqlQuery)" access="non-final"/>
<extra-includes>
<include file-name="QSqlError" location="global"/>
<include file-name="QSqlQuery" location="global"/>
@@ -153,7 +150,7 @@
</extra-includes>
</object-type>
<object-type name="QSqlRelationalTableModel">
- <enum-type name="JoinMode" />
+ <enum-type name="JoinMode"/>
<extra-includes>
<include file-name="QStringList" location="global"/>
<include file-name="QSize" location="global"/>
@@ -170,15 +167,15 @@
<include file-name="QSize" location="global"/>
</extra-includes>
<!-- ### This isn't part of Qt public API -->
- <modify-function signature="virtual_hook(int,void*)" remove="all" />
+ <modify-function signature="virtual_hook(int,void*)" remove="all"/>
<!-- ### -->
- <modify-function signature="exec()" rename="exec_" allow-thread="yes" />
- <modify-function signature="fetchLast()" allow-thread="yes" />
- <modify-function signature="fetchFirst()" allow-thread="yes" />
- <modify-function signature="fetchNext()" allow-thread="yes" />
- <modify-function signature="fetchPrevious()" allow-thread="yes" />
- <modify-function signature="fetch(int)" allow-thread="yes" />
- <modify-function signature="prepare(QString)" allow-thread="yes" />
+ <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="fetchLast()" allow-thread="yes"/>
+ <modify-function signature="fetchFirst()" allow-thread="yes"/>
+ <modify-function signature="fetchNext()" allow-thread="yes"/>
+ <modify-function signature="fetchPrevious()" allow-thread="yes"/>
+ <modify-function signature="fetch(int)" allow-thread="yes"/>
+ <modify-function signature="prepare(QString)" allow-thread="yes"/>
</object-type>
<object-type name="QSqlTableModel">
<enum-type name="EditStrategy"/>
diff --git a/sources/pyside2/PySide2/QtSvg/CMakeLists.txt b/sources/pyside2/PySide2/QtSvg/CMakeLists.txt
index 72914b188..9cc2539b1 100644
--- a/sources/pyside2/PySide2/QtSvg/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtSvg/CMakeLists.txt
@@ -32,10 +32,9 @@ set(QtSvg_libraries pyside2
)
set(QtSvg_deps QtWidgets)
-create_pyside_module(QtSvg
- QtSvg_include_dirs
- QtSvg_libraries
- QtSvg_deps
- QtSvg_SOURCE_DIR
- QtSvg_SRC
- "")
+create_pyside_module(NAME QtSvg
+ INCLUDE_DIRS QtSvg_include_dirs
+ LIBRARIES QtSvg_libraries
+ DEPS QtSvg_deps
+ TYPESYSTEM_PATH QtSvg_SOURCE_DIR
+ SOURCES QtSvg_SRC)
diff --git a/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml b/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml
index 5c4fcb7a8..6523ce541 100644
--- a/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml
+++ b/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml
@@ -42,8 +42,8 @@
<typesystem package="PySide2.QtSvg">
<load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
- <object-type name="QSvgRenderer" />
- <object-type name="QSvgWidget" />
+ <object-type name="QSvgRenderer"/>
+ <object-type name="QSvgWidget"/>
<object-type name="QSvgGenerator">
<modify-function signature="setOutputDevice(QIODevice*)">
diff --git a/sources/pyside2/PySide2/QtTest/CMakeLists.txt b/sources/pyside2/PySide2/QtTest/CMakeLists.txt
index 6d2630f10..ac325ed95 100644
--- a/sources/pyside2/PySide2/QtTest/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtTest/CMakeLists.txt
@@ -36,10 +36,9 @@ set(QtTest_libraries pyside2
)
set(QtTest_deps QtWidgets)
-create_pyside_module(QtTest
- QtTest_include_dirs
- QtTest_libraries
- QtTest_deps
- QtTest_SOURCE_DIR
- QtTest_SRC
- "")
+create_pyside_module(NAME QtTest
+ INCLUDE_DIRS QtTest_include_dirs
+ LIBRARIES QtTest_libraries
+ DEPS QtTest_deps
+ TYPESYSTEM_PATH QtTest_SOURCE_DIR
+ SOURCES QtTest_SRC)
diff --git a/sources/pyside2/PySide2/QtTest/typesystem_test.xml b/sources/pyside2/PySide2/QtTest/typesystem_test.xml
index 86c12f888..ea231f2ee 100644
--- a/sources/pyside2/PySide2/QtTest/typesystem_test.xml
+++ b/sources/pyside2/PySide2/QtTest/typesystem_test.xml
@@ -97,8 +97,8 @@
a simply missing type name in the argument list leads to this message.
<object-type name="QTouchDevice">
- <enum-type name="CapabilityFlag" flags="Capabilities" />
- <enum-type name="DeviceType" />
+ <enum-type name="CapabilityFlag" flags="Capabilities"/>
+ <enum-type name="DeviceType"/>
</object-type>
^^^ this is now moved into QtGui -->
diff --git a/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt
index 63b5a3669..d9e827c0e 100644
--- a/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt
@@ -26,10 +26,9 @@ set(QtTextToSpeech_libraries pyside2
set(QtTextToSpeech_deps QtCore QtMultimedia)
-create_pyside_module(QtTextToSpeech
- QtTextToSpeech_include_dirs
- QtTextToSpeech_libraries
- QtTextToSpeech_deps
- QtTextToSpeech_SOURCE_DIR
- QtTextToSpeech_SRC
- "")
+create_pyside_module(NAME QtTextToSpeech
+ INCLUDE_DIRS QtTextToSpeech_include_dirs
+ LIBRARIES QtTextToSpeech_libraries
+ DEPS QtTextToSpeech_deps
+ TYPESYSTEM_PATH QtTextToSpeech_SOURCE_DIR
+ SOURCES QtTextToSpeech_SRC)
diff --git a/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml
index 9e553ec5b..fee04f444 100644
--- a/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml
+++ b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml
@@ -40,7 +40,7 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtTextToSpeech">
- <load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
+ <load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
<object-type name="QTextToSpeech">
<enum-type name="State"/>
diff --git a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt
index e4de03f49..fc034ec1b 100644
--- a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt
@@ -6,6 +6,10 @@ ${QtUiTools_GEN_DIR}/quiloader_wrapper.cpp
${QtUiTools_GEN_DIR}/qtuitools_module_wrapper.cpp
)
+set(QtUiTools_glue_sources
+ "${QtUiTools_SOURCE_DIR}/glue/plugins.h"
+)
+
set(QtUiTools_include_dirs ${QtUiTools_SOURCE_DIR}
${QtUiTools_BINARY_DIR}
${Qt5Core_INCLUDE_DIRS}
@@ -32,10 +36,10 @@ set(QtUiTools_libraries pyside2
${Qt5Widgets_LIBRARIES}
)
set(QtUiTools_deps QtWidgets QtXml)
-create_pyside_module(QtUiTools
- QtUiTools_include_dirs
- QtUiTools_libraries
- QtUiTools_deps
- QtUiTools_SOURCE_DIR
- QtUiTools_SRC
- "")
+create_pyside_module(NAME QtUiTools
+ INCLUDE_DIRS QtUiTools_include_dirs
+ LIBRARIES QtUiTools_libraries
+ DEPS QtUiTools_deps
+ TYPESYSTEM_PATH QtUiTools_SOURCE_DIR
+ SOURCES QtUiTools_SRC
+ GLUE_SOURCES QtUiTools_glue_sources)
diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
index 4fded3479..8086da01e 100644
--- a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
+++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml
@@ -41,20 +41,18 @@
-->
<typesystem package="PySide2.QtUiTools">
- <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no" />
- <load-typesystem name="QtXml/typesystem_xml.xml" generate="no" />
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
+ <load-typesystem name="QtXml/typesystem_xml.xml" generate="no"/>
<object-type name="QUiLoader">
<extra-includes>
<include file-name="glue/plugins.h" location="local"/>
</extra-includes>
- <inject-code class="native" position="beginning" file="glue/uitools_loadui.cpp"/>
- <inject-code>
- Q_IMPORT_PLUGIN(PyCustomWidgets);
- </inject-code>
+ <inject-code class="native" position="beginning" file="../glue/qtuitools.cpp" snippet="uitools-loadui"/>
+ <inject-code file="../glue/qtuitools.cpp" snippet="quiloader"/>
<add-function signature="registerCustomWidget(PyObject*)" return-type="void">
<modify-argument index="1">
- <rename to="customWidgetType" />
+ <rename to="customWidgetType"/>
</modify-argument>
<inject-documentation format="target" mode="append">
Registers a Python created custom widget to QUiLoader, so it can be recognized when
@@ -87,10 +85,7 @@
# ...
</inject-documentation>
- <inject-code class="target" position="beginning">
- registerCustomWidget(%PYARG_1);
- %CPPSELF.addPluginPath(""); // force reload widgets
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtuitools.cpp" snippet="quiloader-registercustomwidget"/>
</add-function>
<modify-function signature="createAction(QObject*,const QString&amp;)">
<modify-argument index="return">
@@ -119,31 +114,25 @@
<modify-function signature="load(QIODevice*,QWidget*)">
<modify-argument index="2">
- <replace-default-expression with="0" />
- <rename to="parentWidget" />
+ <replace-default-expression with="0"/>
+ <rename to="parentWidget"/>
</modify-argument>
<modify-argument index="return">
<define-ownership class="target" owner="target"/>
</modify-argument>
- <inject-code>
- // Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
- %PYARG_0 = QUiLoadedLoadUiFromDevice(%CPPSELF, %1, %2);
- </inject-code>
+ <inject-code file="../glue/qtuitools.cpp" snippet="quiloader-load-1"/>
</modify-function>
<!-- Syntax sugar -->
<add-function signature="load(QString,QWidget*)" return-type="QWidget*">
<modify-argument index="2">
- <replace-default-expression with="0" />
- <rename to="parentWidget" />
+ <replace-default-expression with="0"/>
+ <rename to="parentWidget"/>
</modify-argument>
<modify-argument index="return">
<define-ownership class="target" owner="target"/>
</modify-argument>
- <inject-code>
- // Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
- %PYARG_0 = QUiLoaderLoadUiFromFileName(%CPPSELF, %1, %2);
- </inject-code>
+ <inject-code file="../glue/qtuitools.cpp" snippet="quiloader-load-2"/>
</add-function>
</object-type>
diff --git a/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt b/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt
index b7fee0d17..c06c690ac 100644
--- a/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt
@@ -24,10 +24,9 @@ set(QtWebChannel_libraries pyside2
)
set(QtWebChannel_deps QtCore)
-create_pyside_module(QtWebChannel
- QtWebChannel_include_dirs
- QtWebChannel_libraries
- QtWebChannel_deps
- QtWebChannel_SOURCE_DIR
- QtWebChannel_SRC
- "")
+create_pyside_module(NAME QtWebChannel
+ INCLUDE_DIRS QtWebChannel_include_dirs
+ LIBRARIES QtWebChannel_libraries
+ DEPS QtWebChannel_deps
+ TYPESYSTEM_PATH QtWebChannel_SOURCE_DIR
+ SOURCES QtWebChannel_SRC)
diff --git a/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml b/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml
index 874924d25..a1cfb91f2 100644
--- a/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml
+++ b/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml
@@ -42,7 +42,7 @@
<typesystem package="PySide2.QtWebChannel">
<load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
- <object-type name="QWebChannel" />
+ <object-type name="QWebChannel"/>
<object-type name="QWebChannelAbstractTransport">
<extra-includes>
<include file-name="QJsonObject" location="global"/>
@@ -50,6 +50,6 @@
</object-type>
<!-- Not sure if this will be useful, but commented out for now because
the QML module is not yet wrapped.
- <object-type name="QQmlWebChannel" /> -->
+ <object-type name="QQmlWebChannel"/> -->
</typesystem>
diff --git a/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt
index 9029509ee..dc673ad06 100644
--- a/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt
@@ -22,11 +22,10 @@ set(QtWebEngine_libraries pyside2
${Qt5Core_LIBRARIES}
)
set(QtWebEngine_deps QtCore)
-create_pyside_module(QtWebEngine
- QtWebEngine_include_dirs
- QtWebEngine_libraries
- QtWebEngine_deps
- QtWebEngine_SOURCE_DIR
- QtWebEngine_SRC
- "")
+create_pyside_module(NAME QtWebEngine
+ INCLUDE_DIRS QtWebEngine_include_dirs
+ LIBRARIES QtWebEngine_libraries
+ DEPS QtWebEngine_deps
+ TYPESYSTEM_PATH QtWebEngine_SOURCE_DIR
+ SOURCES QtWebEngine_SRC)
diff --git a/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt
index 109b9f208..fe660aa7b 100644
--- a/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt
@@ -27,11 +27,10 @@ set(QtWebEngineCore_libraries pyside2
${Qt5Core_LIBRARIES}
)
set(QtWebEngineCore_deps QtCore)
-create_pyside_module(QtWebEngineCore
- QtWebEngineCore_include_dirs
- QtWebEngineCore_libraries
- QtWebEngineCore_deps
- QtWebEngineCore_SOURCE_DIR
- QtWebEngineCore_SRC
- "")
+create_pyside_module(NAME QtWebEngineCore
+ INCLUDE_DIRS QtWebEngineCore_include_dirs
+ LIBRARIES QtWebEngineCore_libraries
+ DEPS QtWebEngineCore_deps
+ TYPESYSTEM_PATH QtWebEngineCore_SOURCE_DIR
+ SOURCES QtWebEngineCore_SRC)
diff --git a/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt
index e0648c491..7711aecbc 100644
--- a/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt
@@ -48,11 +48,10 @@ set(QtWebEngineWidgets_libraries pyside2
${Qt5Core_LIBRARIES}
)
set(QtWebEngineWidgets_deps QtGui QtWidgets QtNetwork QtWebChannel)
-create_pyside_module(QtWebEngineWidgets
- QtWebEngineWidgets_include_dirs
- QtWebEngineWidgets_libraries
- QtWebEngineWidgets_deps
- QtWebEngineWidgets_SOURCE_DIR
- QtWebEngineWidgets_SRC
- "")
+create_pyside_module(NAME QtWebEngineWidgets
+ INCLUDE_DIRS QtWebEngineWidgets_include_dirs
+ LIBRARIES QtWebEngineWidgets_libraries
+ DEPS QtWebEngineWidgets_deps
+ TYPESYSTEM_PATH QtWebEngineWidgets_SOURCE_DIR
+ SOURCES QtWebEngineWidgets_SRC)
diff --git a/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml b/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml
index 6e7418426..b8546d824 100644
--- a/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml
+++ b/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml
@@ -54,35 +54,35 @@
<object-type name="QWebEngineDownloadItem">
<enum-type name="DownloadInterruptReason"/>
- <enum-type name="DownloadState" />
+ <enum-type name="DownloadState"/>
<enum-type name="SavePageFormat"/>
</object-type>
<!-- TODO: Deal with private constructor
- <value-type name="QWebEngineHistory" /> -->
+ <value-type name="QWebEngineHistory"/> -->
- <object-type name="QWebEngineHistoryItem" />
+ <object-type name="QWebEngineHistoryItem"/>
<object-type name="QWebEnginePage">
- <enum-type name="WebAction" />
+ <enum-type name="WebAction"/>
<enum-type name="FindFlag" flags="FindFlags"/>
- <enum-type name="WebWindowType" />
- <enum-type name="PermissionPolicy" />
- <enum-type name="NavigationType" />
- <enum-type name="Feature" />
- <enum-type name="FileSelectionMode" />
- <enum-type name="JavaScriptConsoleMessageLevel" />
+ <enum-type name="WebWindowType"/>
+ <enum-type name="PermissionPolicy"/>
+ <enum-type name="NavigationType"/>
+ <enum-type name="Feature"/>
+ <enum-type name="FileSelectionMode"/>
+ <enum-type name="JavaScriptConsoleMessageLevel"/>
<enum-type name="RenderProcessTerminationStatus"/>
</object-type>
<object-type name="QWebEngineProfile">
- <enum-type name="HttpCacheType" />
- <enum-type name="PersistentCookiesPolicy" />
+ <enum-type name="HttpCacheType"/>
+ <enum-type name="PersistentCookiesPolicy"/>
</object-type>
<value-type name="QWebEngineScript">
- <enum-type name="InjectionPoint" />
- <enum-type name="ScriptWorldId" />
+ <enum-type name="InjectionPoint"/>
+ <enum-type name="ScriptWorldId"/>
</value-type>
<object-type name="QWebEngineScriptCollection"/>
@@ -94,7 +94,7 @@
<enum-type name="WebAttribute"/>
</object-type>
- <object-type name="QWebEngineView" />
+ <object-type name="QWebEngineView"/>
<value-type name="QWebEngineContextMenuData">
<enum-type name="EditFlag" flags="EditFlags" since="5.11"/>
diff --git a/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt b/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt
index 78f865cac..76f647450 100644
--- a/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt
@@ -29,11 +29,10 @@ set(QtWebKit_libraries pyside2
${Qt5Core_LIBRARIES}
)
set(QtWebKit_deps QtGui QtNetwork)
-create_pyside_module(QtWebKit
- QtWebKit_include_dirs
- QtWebKit_libraries
- QtWebKit_deps
- QtWebKit_SOURCE_DIR
- QtWebKit_SRC
- "")
+create_pyside_module(NAME QtWebKit
+ INCLUDE_DIRS QtWebKit_include_dirs
+ LIBRARIES QtWebKit_libraries
+ DEPS QtWebKit_deps
+ TYPESYSTEM_PATH QtWebKit_SOURCE_DIR
+ SOURCES QtWebKit_SRC)
diff --git a/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt
index cd7aa32dd..7422a05da 100644
--- a/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt
@@ -60,11 +60,10 @@ set(QtWebKitWidgets_libraries pyside2
${Qt5Core_LIBRARIES}
)
set(QtWebKitWidgets_deps QtWidgets QtPrintSupport QtNetwork)
-create_pyside_module(QtWebKitWidgets
- QtWebKitWidgets_include_dirs
- QtWebKitWidgets_libraries
- QtWebKitWidgets_deps
- QtWebKitWidgets_SOURCE_DIR
- QtWebKitWidgets_SRC
- "")
+create_pyside_module(NAME QtWebKitWidgets
+ INCLUDE_DIRS QtWebKitWidgets_include_dirs
+ LIBRARIES QtWebKitWidgets_libraries
+ DEPS QtWebKitWidgets_deps
+ TYPESYSTEM_PATH QtWebKitWidgets_SOURCE_DIR
+ SOURCES QtWebKitWidgets_SRC)
diff --git a/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml b/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml
index 74a96250a..dfabff81d 100644
--- a/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml
+++ b/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml
@@ -46,6 +46,7 @@
<load-typesystem name="QtWebKit/typesystem_webkit.xml" generate="no"/>
<load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
<load-typesystem name="QtPrintSupport/typesystem_printsupport.xml" generate="no"/>
+ <load-typesystem name="templates/webkitwidgets_common.xml" generate="no"/>
<value-type name="QWebDatabase"/>
@@ -66,13 +67,13 @@
<value-type name="QWebHistoryItem"/>
<value-type name="QWebSecurityOrigin">
- <enum-type name="SubdomainSetting" />
+ <enum-type name="SubdomainSetting"/>
</value-type>
<object-type name="QWebSettings">
<enum-type name="FontFamily"/>
<enum-type name="FontSize"/>
- <enum-type name="ThirdPartyCookiePolicy" />
+ <enum-type name="ThirdPartyCookiePolicy"/>
<enum-type name="WebAttribute"/>
<enum-type name="WebGraphic"/>
</object-type>
@@ -87,13 +88,9 @@
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
</modify-argument>
- <inject-code position="end">
- SbkObject* _pyReturn = reinterpret_cast&lt;SbkObject*&gt;(%PYARG_0);
- if (!Shiboken::Object::hasParentInfo(_pyReturn))
- Shiboken::Object::setParent(%PYSELF, %PYARG_0);
- </inject-code>
+ <inject-code position="end" file="../glue/qtwebkitwidgets.cpp" snippet="qwebview-page"/>
</modify-function>
- <modify-function signature="print(QPrinter*)const" rename="print_" />
+ <modify-function signature="print(QPrinter*)const" rename="print_"/>
</object-type>
<value-type name="QWebElement" since="4.6">
@@ -102,43 +99,27 @@
<value-type name="QWebElementCollection" since="4.6">
<add-function signature="__len__">
- <inject-code>
- return %CPPSELF.count();
- </inject-code>
+ <inject-code file="../glue/qtwebkitwidgets.cpp" snippet="qwebelementcollection-len"/>
</add-function>
<add-function signature="__getitem__">
- <inject-code>
- if (_i &lt; 0 || _i >= %CPPSELF.count()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return 0;
- }
- QWebElement element = %CPPSELF.at(_i);
- return %CONVERTTOPYTHON[QWebElement](element);
- </inject-code>
+ <inject-code file="../glue/qtwebkitwidgets.cpp" snippet="qwebelementcollection-getitem"/>
</add-function>
</value-type>
<object-type name="QWebFrame">
<enum-type name="RenderLayer" flags="RenderLayers" since="4.6"/>
- <enum-type name="ValueOwnership" />
+ <enum-type name="ValueOwnership"/>
<modify-function signature="addToJavaScriptWindowObject(QString,QObject*,QWebFrame::ValueOwnership)">
<modify-argument index="2">
<parent index="this" action="add"/>
</modify-argument>
</modify-function>
- <modify-function signature="print(QPrinter*)const" rename="print_" />
+ <modify-function signature="print(QPrinter*)const" rename="print_"/>
<modify-function signature="metaData()const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
- <inject-code position="end">
- <insert-template name="convertFromMultiMap">
- <replace from="%MAP_NAME" to="%0"/>
- <replace from="%RETURN_NAME" to="%PYARG_0"/>
- <replace from="%KEY_TYPE" to="QString"/>
- <replace from="%VALUE_TYPE" to="QString"/>
- </insert-template>
- </inject-code>
+ <inject-code position="end" file="../glue/qtwebkitwidgets.cpp" snippet="qwebframe-metadata" />
</modify-function>
</object-type>
@@ -149,33 +130,20 @@
<enum-type name="FindFlag" flags="FindFlags"/>
<enum-type name="LinkDelegationPolicy"/>
<enum-type name="NavigationType"/>
- <enum-type name="PermissionPolicy" since="4.8" revision="4800" />
- <enum-type name="VisibilityState" />
+ <enum-type name="PermissionPolicy" since="4.8" revision="4800"/>
+ <enum-type name="VisibilityState"/>
<enum-type name="WebAction"/>
<enum-type name="WebWindowType"/>
- <value-type name="ChooseMultipleFilesExtensionOption" />
- <value-type name="ChooseMultipleFilesExtensionReturn" />
- <value-type name="ErrorPageExtensionOption" since="4.6" />
- <value-type name="ErrorPageExtensionReturn" since="4.6" />
- <value-type name="ExtensionOption" />
- <value-type name="ExtensionReturn" />
- <value-type name="ViewportAttributes" />
+ <value-type name="ChooseMultipleFilesExtensionOption"/>
+ <value-type name="ChooseMultipleFilesExtensionReturn"/>
+ <value-type name="ErrorPageExtensionOption" since="4.6"/>
+ <value-type name="ErrorPageExtensionReturn" since="4.6"/>
+ <value-type name="ExtensionOption"/>
+ <value-type name="ExtensionReturn"/>
+ <value-type name="ViewportAttributes"/>
<modify-function signature="extension(QWebPage::Extension,const QWebPage::ExtensionOption*,QWebPage::ExtensionReturn*)">
- <template name="qwebpage_extension_argument_conversion">
- PyObject* %out = 0;
- // Cast the parameters according to the extension type
- if (extension == QWebPage::ChooseMultipleFilesExtension) {
- const ChooseMultipleFilesExtension$TYPE_SUFFIX* _in = reinterpret_cast&lt;const ChooseMultipleFilesExtension$TYPE_SUFFIX*>(%in);
- %out = %CONVERTTOPYTHON[const QWebPage::ChooseMultipleFilesExtension$TYPE_SUFFIX*](_in);
- #if QT_VERSION >= 0x040600
- } else if (extension == QWebPage::ErrorPageExtension) {
- const ErrorPageExtension$TYPE_SUFFIX* _in = reinterpret_cast&lt;const ErrorPageExtension$TYPE_SUFFIX*>(%in);
- %out = %CONVERTTOPYTHON[const QWebPage::ErrorPageExtension$TYPE_SUFFIX*](_in);
- #endif
- }
- </template>
<modify-argument index="2" invalidate-after-use="yes">
<conversion-rule class="target">
<insert-template name="qwebpage_extension_argument_conversion">
@@ -199,7 +167,7 @@
</modify-function>
<modify-function signature="networkAccessManager()const">
<modify-argument index="return">
- <reference-count action="set" variable-name="setNetworkAccessManager(QNetworkAccessManager*)1" />
+ <reference-count action="set" variable-name="setNetworkAccessManager(QNetworkAccessManager*)1"/>
</modify-argument>
</modify-function>
<modify-function signature="view()const">
@@ -217,45 +185,22 @@
<modify-argument index="4">
<remove-argument />
<conversion-rule class="native">
- QString _local;
- QString* %4 = &amp;_local;
+ <insert-template name="qstring_remove"/>
</conversion-rule>
</modify-argument>
<modify-argument index="return">
<replace-type modified-type="PySequence"/>
<conversion-rule class="native">
- Shiboken::AutoDecRef pyRes(PySequence_GetItem(%PYARG_0, 0));
- Shiboken::AutoDecRef pyStr(PySequence_GetItem(%PYARG_0, 1));
- %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](pyRes);
- *%4 = %CONVERTTOCPP[QString](pyStr);
+ <insert-template name="pysequence_qstring"/>
</conversion-rule>
<conversion-rule class="target">
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](*%4));
+ <insert-template name="qstring_pytuple"/>
</conversion-rule>
</modify-argument>
</modify-function>
<add-function signature="qt_metacall()">
- <inject-code class="native">
- static int _signalIndex = -1;
- static QMetaMethod _m;
-
- if (_signalIndex == -1) {
- _signalIndex = QWebPage::staticMetaObject.indexOfSlot("shouldInterruptJavaScript()");
- _m = QWebPage::staticMetaObject.method(_signalIndex);
- }
-
- if (_signalIndex == id) {
- Shiboken::GilState gil;
- PyObject* self = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(this);
- if (self) {
- Shiboken::AutoDecRef _pyMethod(PyObject_GetAttrString(self, "shouldInterruptJavaScript"));
- return PySide::SignalManager::callPythonMetaMethod(_m, args, _pyMethod, false);
- }
- }
- </inject-code>
+ <inject-code class="native" file="../glue/qtwebkitwidgets.cpp" snippet="qwebpage-qt-metacall"/>
</add-function>
</object-type>
diff --git a/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt
index 495fd4e7b..98f85f9ab 100644
--- a/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt
@@ -32,10 +32,9 @@ set(QtWebSockets_libraries pyside2
set(QtWebSockets_deps QtNetwork)
-create_pyside_module(QtWebSockets
- QtWebSockets_include_dirs
- QtWebSockets_libraries
- QtWebSockets_deps
- QtWebSockets_SOURCE_DIR
- QtWebSockets_SRC
- "")
+create_pyside_module(NAME QtWebSockets
+ INCLUDE_DIRS QtWebSockets_include_dirs
+ LIBRARIES QtWebSockets_libraries
+ DEPS QtWebSockets_deps
+ TYPESYSTEM_PATH QtWebSockets_SOURCE_DIR
+ SOURCES QtWebSockets_SRC)
diff --git a/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml b/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml
index 6b26ccd76..cd81439cb 100644
--- a/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml
+++ b/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml
@@ -43,7 +43,7 @@
<load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
<load-typesystem name="QtNetwork/typesystem_network.xml" generate="no"/>
- <object-type name="QMaskGenerator" />
+ <object-type name="QMaskGenerator"/>
<object-type name="QWebSocket">
<extra-includes>
@@ -51,7 +51,7 @@
</extra-includes>
</object-type>
- <object-type name="QWebSocketCorsAuthenticator" />
+ <object-type name="QWebSocketCorsAuthenticator"/>
<namespace-type name="QWebSocketProtocol">
<enum-type name="Version"/>
@@ -59,20 +59,20 @@
</namespace-type>
<object-type name="QWebSocketServer">
- <enum-type name="SslMode" />
+ <enum-type name="SslMode"/>
<extra-includes>
- <include file-name="QWebSocketCorsAuthenticator" location="global" />
+ <include file-name="QWebSocketCorsAuthenticator" location="global"/>
</extra-includes>
</object-type>
<!-- TODO: Gracefully handle the lack of SSL support -->
- <rejection class="QWebSocket" function-name="ignoreSslErrors" />
- <rejection class="QWebSocket" function-name="setSslConfiguration" />
- <rejection class="QWebSocket" function-name="sslConfiguration" />
- <rejection class="QWebSocket" function-name="ignoreSslErrors" />
- <rejection class="QWebSocket" function-name="sslErrors" />
- <rejection class="QWebSocketServer" function-name="setSslConfiguration" />
- <rejection class="QWebSocketServer" function-name="sslConfiguration" />
- <rejection class="QWebSocketServer" function-name="peerVerifyError" />
- <rejection class="QWebSocketServer" function-name="sslErrors" />
+ <rejection class="QWebSocket" function-name="ignoreSslErrors"/>
+ <rejection class="QWebSocket" function-name="setSslConfiguration"/>
+ <rejection class="QWebSocket" function-name="sslConfiguration"/>
+ <rejection class="QWebSocket" function-name="ignoreSslErrors"/>
+ <rejection class="QWebSocket" function-name="sslErrors"/>
+ <rejection class="QWebSocketServer" function-name="setSslConfiguration"/>
+ <rejection class="QWebSocketServer" function-name="sslConfiguration"/>
+ <rejection class="QWebSocketServer" function-name="peerVerifyError"/>
+ <rejection class="QWebSocketServer" function-name="sslErrors"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt
index dee79744f..4267c1160 100644
--- a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt
@@ -1,12 +1,5 @@
project(QtWidgets)
-
-set(QtWidgets_OPTIONAL_SRC )
-set(QtWidgets_DROPPED_ENTRIES )
-## XXX check if these conditionals need to be done elsewhere
-check_qt_class(QtWidgets QGtkStyle QtWidgets_OPTIONAL_SRC QtWidgets_DROPPED_ENTRIES)
-check_qt_class(QtWidgets QMacStyle QtWidgets_OPTIONAL_SRC QtWidgets_DROPPED_ENTRIES)
-
set(QtWidgets_SRC
${QtWidgets_GEN_DIR}/qaccessiblewidget_wrapper.cpp
${QtWidgets_GEN_DIR}/qabstractbutton_wrapper.cpp
@@ -238,11 +231,10 @@ set(QtWidgets_libraries pyside2
)
set(QtWidgets_deps QtGui)
-create_pyside_module(QtWidgets
- QtWidgets_include_dirs
- QtWidgets_libraries
- QtWidgets_deps
- QtWidgets_SOURCE_DIR
- QtWidgets_SRC
- ""
- ${QtWidgets_BINARY_DIR}/typesystem_widgets.xml)
+create_pyside_module(NAME QtWidgets
+ INCLUDE_DIRS QtWidgets_include_dirs
+ LIBRARIES QtWidgets_libraries
+ DEPS QtWidgets_deps
+ TYPESYSTEM_PATH QtWidgets_SOURCE_DIR
+ SOURCES QtWidgets_SRC
+ TYPESYSTEM_NAME ${QtWidgets_BINARY_DIR}/typesystem_widgets.xml)
diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp
deleted file mode 100644
index d542b881c..000000000
--- a/sources/pyside2/PySide2/QtWidgets/glue/qlayout_help_functions.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-void addLayoutOwnership(QLayout* layout, QLayoutItem* item);
-void removeLayoutOwnership(QLayout* layout, QWidget* widget);
-
-inline QByteArray retrieveObjectName(PyObject* obj)
-{
- Shiboken::AutoDecRef objName(PyObject_Str(obj));
- return Shiboken::String::toCString(objName);
-}
-
-inline void addLayoutOwnership(QLayout* layout, QWidget* widget)
-{
- //transfer ownership to parent widget
- QWidget *lw = layout->parentWidget();
- QWidget *pw = widget->parentWidget();
-
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget));
-
- //Transfer parent to layout widget
- if (pw && lw && pw != lw)
- Shiboken::Object::setParent(0, pyChild);
-
- if (!lw && !pw) {
- //keep the reference while the layout is orphan
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout));
- Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true);
- } else {
- if (!lw)
- lw = pw;
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](lw));
- Shiboken::Object::setParent(pyParent, pyChild);
- }
-}
-
-inline void addLayoutOwnership(QLayout* layout, QLayout* other)
-{
- //transfer all children widgets from other to layout parent widget
- QWidget* parent = layout->parentWidget();
- if (!parent) {
- //keep the reference while the layout is orphan
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout));
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other));
- Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true);
- return;
- }
-
- for (int i=0, i_max=other->count(); i < i_max; i++) {
- QLayoutItem* item = other->itemAt(i);
- if (PyErr_Occurred() || !item)
- return;
- addLayoutOwnership(layout, item);
- }
-
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout));
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other));
- Shiboken::Object::setParent(pyParent, pyChild);
-}
-
-inline void addLayoutOwnership(QLayout* layout, QLayoutItem* item)
-{
- if (!item)
- return;
-
- QWidget* w = item->widget();
- if (w)
- addLayoutOwnership(layout, w);
- else {
- QLayout* l = item->layout();
- if (l)
- addLayoutOwnership(layout, l);
- }
-
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout));
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item));
- Shiboken::Object::setParent(pyParent, pyChild);
-}
-
-static void removeWidgetFromLayout(QLayout* layout, QWidget* widget)
-{
- QWidget* parent = widget->parentWidget();
-
- if (!parent) {
- //remove reference on layout
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout));
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget));
- Shiboken::Object::removeReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild);
- } else {
- //give the ownership to parent
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent));
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget));
- Shiboken::Object::setParent(pyParent, pyChild);
- }
-}
-
-inline void removeLayoutOwnership(QLayout* layout, QLayoutItem* item)
-{
- QWidget* w = item->widget();
- if (w)
- removeWidgetFromLayout(layout, w);
- else {
- QLayout* l = item->layout();
- if (l && item != l)
- removeLayoutOwnership(layout, l);
- }
-
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item));
- Shiboken::Object::invalidate(pyChild);
- Shiboken::Object::setParent(0, pyChild);
-}
-
-inline void removeLayoutOwnership(QLayout* layout, QWidget* widget)
-{
- if (!widget)
- return;
-
- for (int i=0, i_max=layout->count(); i < i_max; i++) {
- QLayoutItem* item = layout->itemAt(i);
- if (PyErr_Occurred() || !item)
- return;
- if (item->widget() == widget)
- removeLayoutOwnership(layout, item);
- }
-}
diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp b/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp
deleted file mode 100644
index 674e34cfe..000000000
--- a/sources/pyside2/PySide2/QtWidgets/glue/qwidget_glue.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-static QString retrieveObjectName(PyObject *obj)
-{
- Shiboken::AutoDecRef objName(PyObject_Str(obj));
- return QString(Shiboken::String::toCString(objName));
-}
-
-
-/**
- * Tranfer objects ownership from layout to widget
- **/
-static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout)
-{
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent));
-
- for (int i=0; i < layout->count(); i++) {
- QLayoutItem* item = layout->itemAt(i);
- if (PyErr_Occurred() || !item)
- return;
-
- QWidget* w = item->widget();
- if (w) {
- QWidget* pw = w->parentWidget();
- if (pw != parent) {
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](w));
- Shiboken::Object::setParent(pyParent, pyChild);
- }
- } else {
- QLayout* l = item->layout();
- if (l)
- qwidgetReparentLayout(parent, l);
- }
- }
-
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](layout));
- Shiboken::Object::setParent(pyParent, pyChild);
- //remove previous references
- Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None);
-}
-
-static inline void qwidgetSetLayout(QWidget *self, QLayout *layout)
-{
- if (!layout || self->layout())
- return;
-
- QObject* oldParent = layout->parent();
- if (oldParent && oldParent != self) {
- if (oldParent->isWidgetType()) {
- // remove old parent policy
- Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout*](layout));
- Shiboken::Object::setParent(Py_None, pyLayout);
- } else {
- PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
- qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName()));
- return;
- }
- }
-
- if (oldParent != self) {
- qwidgetReparentLayout(self, layout);
- if (PyErr_Occurred())
- return;
-
- self->setLayout(layout);
- }
-}
diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
index 76b3dd1f1..dba6c268d 100644
--- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
+++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml
@@ -40,7 +40,8 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtWidgets">
- <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
+ <load-typesystem name="templates/core_common.xml" generate="no"/>
+ <load-typesystem name="templates/widgets_common.xml" generate="no"/>
@@ -74,7 +75,7 @@
-->
<object-type name="QStyleOption" polymorphic-id-expression="%1-&gt;type == QStyleOption::SO_Default">
- <enum-type name="OptionType" extensible="yes"/>
+ <enum-type name="OptionType"/>
<enum-type name="StyleOptionType"/>
<enum-type name="StyleOptionVersion"/>
</object-type>
@@ -180,7 +181,7 @@
<object-type name="QStyleOptionToolButton" polymorphic-id-expression="%1-&gt;type == QStyleOptionToolButton::Type &amp;&amp; %1-&gt;version == QStyleOptionToolButton::Version">
<enum-type name="StyleOptionType"/>
<enum-type name="StyleOptionVersion"/>
- <enum-type name="ToolButtonFeature" flags="ToolButtonFeatures" />
+ <enum-type name="ToolButtonFeature" flags="ToolButtonFeatures"/>
</object-type>
<value-type name="QStyleOptionViewItem" polymorphic-id-expression="%1-&gt;type == QStyleOptionViewItem::Type &amp;&amp; %1-&gt;version == QStyleOptionViewItem::Version">
<enum-type name="Position"/>
@@ -204,30 +205,21 @@
<value-type name="QTreeWidgetItemIterator" >
<modify-function signature="QTreeWidgetItemIterator(QTreeWidget*,QFlags&lt;QTreeWidgetItemIterator::IteratorFlag&gt;)">
<modify-argument index="this">
- <parent index="1" action="add" />
+ <parent index="1" action="add"/>
</modify-argument>
</modify-function>
<add-function signature="__iter__()" return-type="PyObject*">
<inject-code class="target" position="beginning">
- <insert-template name="__iter__" />
+ <insert-template name="__iter__"/>
</inject-code>
</add-function>
<add-function signature="__next__()" return-type="PyObject*">
- <inject-code class="target" position="beginning">
- if (**%CPPSELF) {
- QTreeWidgetItemIterator *%0 = new QTreeWidgetItemIterator((*%CPPSELF)++);
- %PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItemIterator*](%0);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtreewidgetitemiterator-next"/>
</add-function>
<add-function signature="value()" return-type="QTreeWidgetItem*">
- <inject-code>
- QTreeWidgetItem *%0 = %CPPSELF.operator*();
- %PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItem*](%0);
- Shiboken::Object::releaseOwnership(%PYARG_0);
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtreewidgetitemiterator-value"/>
</add-function>
<enum-type name="IteratorFlag" flags="IteratorFlags"/>
<!-- ### See bug 778 -->
@@ -267,26 +259,14 @@
<enum-type name="GraphicsItemChange"/>
<enum-type name="GraphicsItemFlag" flags="GraphicsItemFlags"/>
<enum-type name="PanelModality" since="4.6"/>
- <inject-code class="target" position="end">
- PyObject *userTypeConstant = PyInt_FromLong(QGraphicsItem::UserType);
- PyDict_SetItemString(reinterpret_cast&lt;PyTypeObject *&gt;(Sbk_QGraphicsItem_TypeF())->tp_dict, "UserType", userTypeConstant);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem"/>
<modify-function signature="setParentItem(QGraphicsItem*)">
<modify-argument index="this">
<parent index="1" action="add"/>
</modify-argument>
</modify-function>
- <template name="scene_return_parenting">
- if (%0) {
- QObject *parent = %0->parent();
- Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QObject*](parent));
- Shiboken::Object::setParent(pyParent, %PYARG_0);
- }
- </template>
<modify-function signature="scene()const">
- <inject-code position="end">
- <insert-template name="scene_return_parenting"/>
- </inject-code>
+ <inject-code position="end" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem-scene-return-parenting"/>
<modify-argument index="this">
<parent index="return" action="add"/>
</modify-argument>
@@ -354,13 +334,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, blockingPanel)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- QGraphicsItem *item_ = NULL;
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;item_);
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QGraphicsItem*](item_));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qgraphicsitem-isblockedbymodalpanel"/>
</modify-function>
<modify-function signature="itemTransform(const QGraphicsItem*,bool*)const">
<modify-argument index="2">
@@ -371,7 +345,7 @@
<replace-type modified-type="(QTransform, bool ok)"/>
</modify-argument>
<inject-code class="target" position="beginning">
- <insert-template name="fix_args,bool*" />
+ <insert-template name="fix_args,bool*"/>
</inject-code>
</modify-function>
<modify-function signature="isObscuredBy(const QGraphicsItem*)const">
@@ -453,7 +427,7 @@
</modify-function>
<modify-function signature="viewOptions()const">
<modify-argument index="return">
- <replace-default-expression with="QStyleOptionViewItem()" />
+ <replace-default-expression with="QStyleOptionViewItem()"/>
</modify-argument>
</modify-function>
<modify-function signature="model()const">
@@ -537,7 +511,7 @@
<object-type name="QDialogButtonBox">
<enum-type name="ButtonLayout"/>
<enum-type name="ButtonRole"/>
- <enum-type name="StandardButton" flags="StandardButtons" />
+ <enum-type name="StandardButton" flags="StandardButtons"/>
<modify-function signature="addButton(QAbstractButton*,QDialogButtonBox::ButtonRole)">
<modify-argument index="1">
<parent index="this" action="add"/>
@@ -562,7 +536,7 @@
<enum-type name="Option" flags="Options"/>
</object-type>
<object-type name="QWizard">
- <enum-type name="WizardButton" />
+ <enum-type name="WizardButton"/>
<enum-type name="WizardOption" flags="WizardOptions"/>
<enum-type name="WizardPixmap"/>
<enum-type name="WizardStyle"/>
@@ -602,7 +576,7 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="bool*_fix,arg"/>
@@ -613,15 +587,14 @@
<remove-argument />
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PyTuple" />
+ <replace-type modified-type="PyTuple"/>
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="bool*_fix,arg,arg,arg,arg"/>
</inject-code>
</modify-function>
</object-type>
- <object-type name="QGraphicsEllipseItem">
- </object-type>
+ <object-type name="QGraphicsEllipseItem"/>
<object-type name="QGraphicsItemAnimation">
<modify-function signature="setItem(QGraphicsItem*)">
<modify-argument index="1">
@@ -638,24 +611,24 @@
</extra-includes>
</object-type>
<object-type name="QGraphicsItemGroup"/>
- <object-type name="QGraphicsLineItem" />
- <object-type name="QGraphicsPathItem" />
+ <object-type name="QGraphicsLineItem"/>
+ <object-type name="QGraphicsPathItem"/>
<object-type name="QGraphicsPixmapItem">
<enum-type name="ShapeMode"/>
</object-type>
<object-type name="QGraphicsPolygonItem"/>
- <object-type name="QGraphicsRectItem" />
- <object-type name="QGraphicsSimpleTextItem" />
+ <object-type name="QGraphicsRectItem"/>
+ <object-type name="QGraphicsSimpleTextItem"/>
<object-type name="QHBoxLayout"/>
<object-type name="QHeaderView">
- <enum-type name="ResizeMode" />
+ <enum-type name="ResizeMode"/>
<modify-function signature="paintSection(QPainter*,QRect,int)const">
<modify-argument index="1" invalidate-after-use="yes"/>
</modify-function>
</object-type>
<object-type name="QItemDelegate">
<!-- ### "doLayout(...)" is an internal method. -->
- <modify-function signature="doLayout(QStyleOptionViewItem,QRect*,QRect*,QRect*,bool)const" remove="all" />
+ <modify-function signature="doLayout(QStyleOptionViewItem,QRect*,QRect*,QRect*,bool)const" remove="all"/>
<!-- ### "selected(QPixmap,QPalette,bool)" is an internal method. -->
<modify-function signature="selected(QPixmap,QPalette,bool)const" remove="all"/>
<!-- ### -->
@@ -687,24 +660,13 @@
<modify-argument index="2">
<reference-count action="set"/>
</modify-argument>
- <inject-code>
- Shiboken::Object::releaseOwnership(%PYARG_2);
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qitemeditorfactory-registerEditor"/>
</modify-function>
<modify-function signature="setDefaultFactory(QItemEditorFactory*)">
<modify-argument index="1">
<define-ownership owner="c++"/>
</modify-argument>
- <inject-code>
- //this function is static we need keep ref to default value, to be able to call python virtual functions
- static PyObject* _defaultValue = 0;
- %CPPSELF.%FUNCTION_NAME(%1);
- Py_INCREF(%PYARG_1);
- if (_defaultValue)
- Py_DECREF(_defaultValue);
-
- _defaultValue = %PYARG_1;
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qitemeditorfactory-setdefaultfactory"/>
</modify-function>
</object-type>
<object-type name="QListView">
@@ -726,10 +688,10 @@
<modify-function signature="setCentralWidget(QWidget*)">
<inject-code class="target" position="beginning">
<insert-template name="replace_child">
- <replace from="$FUNCTION_GET_OLD" to="centralWidget" />
- <replace from="$CHILD_TYPE" to="QWidget" />
- <replace from="$PYARG" to="%PYARG_1" />
- <replace from="$CPPARG" to="%1" />
+ <replace from="$FUNCTION_GET_OLD" to="centralWidget"/>
+ <replace from="$CHILD_TYPE" to="QWidget"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
</insert-template>
</inject-code>
</modify-function>
@@ -737,10 +699,10 @@
<modify-function signature="setMenuBar(QMenuBar*)">
<inject-code class="target" position="beginning">
<insert-template name="replace_child">
- <replace from="$FUNCTION_GET_OLD" to="menuBar" />
- <replace from="$CHILD_TYPE" to="QMenuBar" />
- <replace from="$PYARG" to="%PYARG_1" />
- <replace from="$CPPARG" to="%1" />
+ <replace from="$FUNCTION_GET_OLD" to="menuBar"/>
+ <replace from="$CHILD_TYPE" to="QMenuBar"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
</insert-template>
</inject-code>
</modify-function>
@@ -748,10 +710,10 @@
<modify-function signature="setMenuWidget(QWidget*)">
<inject-code class="target" position="beginning">
<insert-template name="replace_child">
- <replace from="$FUNCTION_GET_OLD" to="menuWidget" />
- <replace from="$CHILD_TYPE" to="QWidget" />
- <replace from="$PYARG" to="%PYARG_1" />
- <replace from="$CPPARG" to="%1" />
+ <replace from="$FUNCTION_GET_OLD" to="menuWidget"/>
+ <replace from="$CHILD_TYPE" to="QWidget"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
</insert-template>
</inject-code>
</modify-function>
@@ -759,10 +721,10 @@
<modify-function signature="setStatusBar(QStatusBar*)">
<inject-code class="target" position="beginning">
<insert-template name="replace_child">
- <replace from="$FUNCTION_GET_OLD" to="statusBar" />
- <replace from="$CHILD_TYPE" to="QStatusBar" />
- <replace from="$PYARG" to="%PYARG_1" />
- <replace from="$CPPARG" to="%1" />
+ <replace from="$FUNCTION_GET_OLD" to="statusBar"/>
+ <replace from="$CHILD_TYPE" to="QStatusBar"/>
+ <replace from="$PYARG" to="%PYARG_1"/>
+ <replace from="$CPPARG" to="%1"/>
</insert-template>
</inject-code>
</modify-function>
@@ -838,11 +800,11 @@
</modify-function>
</object-type>
<object-type name="QMenu">
- <inject-code class="native" position="beginning" file="glue/qmenu_glue.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-glue"/>
- <modify-function signature="exec()" rename="exec_" allow-thread="yes" />
- <modify-function signature="exec(const QPoint&amp;,QAction*)" rename="exec_" allow-thread="yes" />
- <modify-function signature="exec(QList&lt;QAction*>,const QPoint&amp;,QAction*,QWidget*)" rename="exec_" allow-thread="yes" />
+ <modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="exec(const QPoint&amp;,QAction*)" rename="exec_" allow-thread="yes"/>
+ <modify-function signature="exec(QList&lt;QAction*>,const QPoint&amp;,QAction*,QWidget*)" rename="exec_" allow-thread="yes"/>
<modify-function signature="addAction(const QString&amp;)">
<modify-argument index="return">
<parent index="this" action="add"/>
@@ -885,59 +847,42 @@
</modify-argument>
</modify-function>
<!-- ### "setNoReplayFor(QWidget*)" is an internal method. -->
- <modify-function signature="setNoReplayFor(QWidget*)" remove="all" />
+ <modify-function signature="setNoReplayFor(QWidget*)" remove="all"/>
<add-function signature="addAction(QString&amp;,PyObject*,QKeySequence&amp;)">
<modify-argument index="3">
- <replace-default-expression with="0" />
+ <replace-default-expression with="0"/>
</modify-argument>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %PYARG_0 = addActionWithPyObject(%CPPSELF, QIcon(), %1, %2, %3);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-addaction-1"/>
</add-function>
<add-function signature="addAction(QIcon&amp;,QString&amp;,PyObject*,QKeySequence&amp;)">
<modify-argument index="4">
- <replace-default-expression with="0" />
+ <replace-default-expression with="0"/>
</modify-argument>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2, %3, %4);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-addaction-2"/>
</add-function>
<add-function signature="addAction(QAction*)">
- <inject-code class="target" position="beginning">
- %CPPSELF.addAction(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenu-addaction-3"/>
</add-function>
<modify-function signature="clear()">
- <inject-code>
- Shiboken::BindingManager&amp; bm = Shiboken::BindingManager::instance();
- PyObject* pyObj;
- foreach(QAction* act, %CPPSELF.actions()) {
- if ((pyObj = (PyObject*)bm.retrieveWrapper(act)) != 0) {
- Py_INCREF(pyObj);
- Shiboken::Object::setParent(NULL, pyObj);
- Shiboken::Object::invalidate(pyObj);
- Py_DECREF(pyObj);
- }
- }
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenu-clear"/>
</modify-function>
</object-type>
<object-type name="QMenuBar">
- <inject-code class="native" position="beginning" file="glue/qmenubar_glue.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenubar-glue"/>
<modify-function signature="addAction(const QString&amp;)">
<modify-argument index="return">
<parent index="this" action="add"/>
@@ -949,9 +894,7 @@
</modify-argument>
</modify-function>
<add-function signature="addAction(const QString&amp;,PyObject*)">
- <inject-code class="target" position="beginning">
- %PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenubar-addaction-1"/>
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
@@ -983,19 +926,11 @@
</modify-argument>
</modify-function>
<modify-function signature="clear()">
- <inject-code>
- foreach(QAction *act, %CPPSELF.actions()) {
- Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act));
- Shiboken::Object::setParent(NULL, pyAct);
- Shiboken::Object::invalidate(pyAct);
- }
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qmenubar-clear"/>
</modify-function>
<add-function signature="addAction(QAction*)">
- <inject-code class="target" position="beginning">
- %CPPSELF.addAction(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qmenubar-addaction-2"/>
</add-function>
</object-type>
@@ -1009,7 +944,7 @@
</modify-argument>
</modify-function>
</object-type>
- <object-type name="QPushButton" />
+ <object-type name="QPushButton"/>
<object-type name="QScrollArea">
<modify-function signature="setWidget(QWidget*)">
<modify-argument index="1">
@@ -1023,18 +958,8 @@
<modify-argument index="4">
<replace-default-expression with="Qt::WindowShortcut"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- %0 = new %TYPE(%1, %2);
- </inject-code>
- <inject-code class="target" position="end">
- Shiboken::AutoDecRef result(PyObject_CallMethod(%PYSELF,
- const_cast&lt;char *&gt;("connect"),
- const_cast&lt;char *&gt;("OsO"),
- %PYSELF, SIGNAL(activated()), %PYARG_3)
- );
- if (!result.isNull())
- Shiboken::Object::setParent(%PYARG_2, %PYSELF);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qshortcut-1"/>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qshortcut-2"/>
</add-function>
</object-type>
<object-type name="QSpacerItem"/>
@@ -1080,7 +1005,7 @@
<enum-type name="StyleOptionType"/>
<enum-type name="StyleOptionVersion"/>
</object-type>
- <object-type name="QStylePainter" />
+ <object-type name="QStylePainter"/>
<object-type name="QTableView">
<modify-function signature="setHorizontalHeader(QHeaderView*)">
<modify-argument index="1">
@@ -1116,13 +1041,7 @@
</modify-argument>
</modify-function>
<modify-function signature="removeItem(int)">
- <inject-code class="target" position="beginning">
- QWidget *_widget = %CPPSELF.widget(%1);
- if (_widget) {
- Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget*](_widget));
- Shiboken::Object::setParent(0, pyWidget);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtoolbox-removeitem"/>
</modify-function>
</object-type>
<object-type name="QToolButton">
@@ -1211,16 +1130,16 @@
<object-type name="QWidgetAction">
<modify-function signature="setDefaultWidget(QWidget*)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="releaseWidget(QWidget*)">
<modify-argument index="1">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
</object-type>
- <object-type name="QWidgetItem" polymorphic-id-expression="%1-&gt;widget()" />
+ <object-type name="QWidgetItem" polymorphic-id-expression="%1-&gt;widget()"/>
<object-type name="QGraphicsSceneContextMenuEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneContextMenu">
<enum-type name="Reason"/>
@@ -1236,10 +1155,10 @@
<!-- ### "setWidget(QWidget*)" is an internal method. -->
<modify-function signature="setWidget(QWidget*)" remove="all"/>
</object-type>
- <object-type name="QGraphicsSceneMoveEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneMove" />
- <object-type name="QGraphicsSceneResizeEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneResize" />
- <object-type name="QGraphicsSceneHelpEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneHelp" />
- <object-type name="QGraphicsSceneHoverEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneHoverEnter || %1-&gt;type() == QEvent::GraphicsSceneHoverLeave || %1-&gt;type() == QEvent::GraphicsSceneHoverMove" />
+ <object-type name="QGraphicsSceneMoveEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneMove"/>
+ <object-type name="QGraphicsSceneResizeEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneResize"/>
+ <object-type name="QGraphicsSceneHelpEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneHelp"/>
+ <object-type name="QGraphicsSceneHoverEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneHoverEnter || %1-&gt;type() == QEvent::GraphicsSceneHoverLeave || %1-&gt;type() == QEvent::GraphicsSceneHoverMove"/>
<object-type name="QGraphicsSceneMouseEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneMouseDoubleClick || %1-&gt;type() == QEvent::GraphicsSceneMouseMove || %1-&gt;type() == QEvent::GraphicsSceneMousePress || %1-&gt;type() == QEvent::GraphicsSceneMouseRelease"/>
<object-type name="QGraphicsSceneWheelEvent" copyable="false" polymorphic-id-expression="%1-&gt;type() == QEvent::GraphicsSceneWheel"/>
@@ -1272,42 +1191,42 @@
</object-type>
<object-type name="QAbstractButton"/>
<object-type name="QStyle">
- <enum-type name="ComplexControl" extensible="yes"/>
- <enum-type name="ContentsType" extensible="yes"/>
- <enum-type name="ControlElement" extensible="yes"/>
- <enum-type name="PixelMetric" extensible="yes" />
- <enum-type name="PrimitiveElement" extensible="yes" />
+ <enum-type name="ComplexControl"/>
+ <enum-type name="ContentsType"/>
+ <enum-type name="ControlElement"/>
+ <enum-type name="PixelMetric"/>
+ <enum-type name="PrimitiveElement"/>
<enum-type name="RequestSoftwareInputPanel" since="4.6"/>
- <enum-type name="StandardPixmap" extensible="yes"/>
+ <enum-type name="StandardPixmap"/>
<enum-type name="StateFlag" flags="State"/>
- <enum-type name="StyleHint" extensible="yes" />
- <enum-type name="SubControl" flags="SubControls" extensible="yes" force-integer="yes"/>
- <enum-type name="SubElement" extensible="yes" />
+ <enum-type name="StyleHint"/>
+ <enum-type name="SubControl" flags="SubControls"/>
+ <enum-type name="SubElement"/>
<modify-function signature="drawComplexControl(QStyle::ComplexControl,const QStyleOptionComplex*,QPainter*,const QWidget*)const">
<modify-argument index="3" invalidate-after-use="yes"/>
<modify-argument index="4">
<replace-default-expression with="0"/>
- <rename to="widget" />
+ <rename to="widget"/>
</modify-argument>
</modify-function>
<modify-function signature="drawControl(QStyle::ControlElement,const QStyleOption*,QPainter*,const QWidget*)const">
<modify-argument index="3" invalidate-after-use="yes"/>
<modify-argument index="4">
<replace-default-expression with="0"/>
- <rename to="widget" />
+ <rename to="widget"/>
</modify-argument>
</modify-function>
<modify-function signature="drawPrimitive(QStyle::PrimitiveElement,const QStyleOption*,QPainter*,const QWidget*)const">
<modify-argument index="3" invalidate-after-use="yes"/>
<modify-argument index="4">
<replace-default-expression with="0"/>
- <rename to="widget" />
+ <rename to="widget"/>
</modify-argument>
</modify-function>
<modify-function signature="hitTestComplexControl(QStyle::ComplexControl,const QStyleOptionComplex*,const QPoint&amp;,const QWidget*)const">
<modify-argument index="4">
<replace-default-expression with="0"/>
- <rename to="widget" />
+ <rename to="widget"/>
</modify-argument>
</modify-function>
<modify-function signature="styleHint(QStyle::StyleHint,const QStyleOption*,const QWidget*,QStyleHintReturn*)const">
@@ -1322,13 +1241,13 @@
</object-type>
<object-type name="QColorDialog">
<enum-type name="ColorDialogOption" flags="ColorDialogOptions"/>
- <modify-function signature="getColor(const QColor&amp;,QWidget*,const QString&amp;,QFlags&lt;QColorDialog::ColorDialogOption>)" allow-thread="yes" />
+ <modify-function signature="getColor(const QColor&amp;,QWidget*,const QString&amp;,QFlags&lt;QColorDialog::ColorDialogOption>)" allow-thread="yes"/>
<!-- Qt5: obsolete -->
- <modify-function signature="getRgba(unsigned int,bool*,QWidget*)" remove="all" />
+ <modify-function signature="getRgba(unsigned int,bool*,QWidget*)" remove="all"/>
</object-type>
<object-type name="QLayout">
- <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
<enum-type name="SizeConstraint"/>
@@ -1336,20 +1255,14 @@
<modify-argument index="return">
<define-ownership owner="default"/>
</modify-argument>
- <inject-code class="target" position="end">
- addLayoutOwnership(%CPPSELF, %0);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="addownership-0"/>
</modify-function>
<modify-function signature="removeWidget(QWidget*)">
- <inject-code class="target" position="beginning">
- removeLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="removeownership-1"/>
</modify-function>
<modify-function signature="removeItem(QLayoutItem*)">
- <inject-code class="target" position="beginning">
- removeLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="removeownership-1"/>
</modify-function>
<modify-function signature="parentWidget()const">
@@ -1368,35 +1281,25 @@
</modify-function>
<modify-function signature="addItem(QLayoutItem*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addWidget(QWidget*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addChildWidget(QWidget*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addChildLayout(QLayout*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="setMenuBar(QWidget*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="getContentsMargins(int*,int*,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -1412,119 +1315,91 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
<inject-code class="native" position="end">
<insert-template name="fix_native_return_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<add-function signature="setAlignment(QFlags&lt;Qt::AlignmentFlag&gt;)">
- <inject-code class="target" position="beginning">
- %CPPSELF.setAlignment(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-setalignment"/>
</add-function>
</object-type>
<object-type name="QStackedLayout">
- <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
<enum-type name="StackingMode"/>
<modify-function signature="insertWidget(int,QWidget*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %2);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
</modify-function>
</object-type>
<object-type name="QBoxLayout">
- <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
- <enum-type name="Direction" />
+ <enum-type name="Direction"/>
<modify-function signature="addWidget(QWidget*,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addLayout(QLayout*,int)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="insertWidget(int,QWidget*,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %2);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
</modify-function>
<modify-function signature="insertLayout(int,QLayout*,int)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %2);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
</modify-function>
<modify-function signature="insertItem(int,QLayoutItem*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %2);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
</modify-function>
<modify-function signature="addSpacerItem(QSpacerItem*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="insertSpacerItem(int,QSpacerItem*)">
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %2);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-2"/>
</modify-function>
</object-type>
<object-type name="QGridLayout">
- <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
<modify-function signature="itemAtPosition (int,int)const">
<modify-argument index="return">
<define-ownership owner="default"/>
</modify-argument>
- <inject-code class="target" position="end">
- addLayoutOwnership(%CPPSELF, %0);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="addownership-0"/>
</modify-function>
<modify-function signature="addWidget(QWidget*,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
<modify-argument index="4">
<rename to="alignment"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addWidget(QWidget*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
<modify-argument index="6">
<rename to="alignment"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addLayout(QLayout*,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
<modify-argument index="4">
<rename to="alignment"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addLayout(QLayout*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
<modify-argument index="6">
<rename to="alignment"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="addItem(QLayoutItem*,int,int,int,int,QFlags&lt;Qt::AlignmentFlag&gt;)">
<modify-argument index="4">
@@ -1536,13 +1411,11 @@
<modify-argument index="6">
<rename to="alignment"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- addLayoutOwnership(%CPPSELF, %1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="addownership-1"/>
</modify-function>
<modify-function signature="getItemPosition(int,int*,int*,int*,int*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject*" />
+ <replace-type modified-type="PyObject*"/>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
@@ -1557,15 +1430,7 @@
<remove-argument/>
<remove-default-expression/>
</modify-argument>
- <inject-code class="target" position="beginning">
- int a, b, c, d;
- %CPPSELF.%FUNCTION_NAME(%1, &amp;a, &amp;b, &amp;c, &amp;d);
- %PYARG_0 = PyTuple_New(4);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](a));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](b));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](c));
- PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](d));
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qgridlayout-getitemposition"/>
</modify-function>
</object-type>
@@ -1579,7 +1444,6 @@
<enum-type name="OptimizationFlag" flags="OptimizationFlags"/>
<enum-type name="ViewportAnchor"/>
<enum-type name="ViewportUpdateMode"/>
- <modify-function signature="setupViewport(QWidget*)" access="non-final"/>
<modify-function signature="setScene(QGraphicsScene*)">
<modify-argument index="1">
<reference-count action="set"/>
@@ -1587,7 +1451,7 @@
</modify-function>
<modify-function signature="scene()const">
<inject-code position="end">
- <insert-template name="scene_return_parenting"/>
+ <insert-template name="scene-return-parenting"/>
</inject-code>
<modify-argument index="return">
<define-ownership owner="default"/>
@@ -1615,46 +1479,29 @@
<modify-argument index="2">
<remove-argument/>
<conversion-rule class="native">
- int %out = PySequence_Size(%PYARG_1);
+ <insert-template name="pysequencesize_int"/>
</conversion-rule>
</modify-argument>
<modify-argument index="3">
<replace-type modified-type="PySequence"/>
<conversion-rule class="native">
- int numItems = PySequence_Size(%PYARG_1);
- Shiboken::AutoArrayPointer&lt;QGraphicsItem*&gt; %out(numItems);
- for (int i=0; i &lt; numItems; i++) {
- %out[i] = %CONVERTTOCPP[QGraphicsItem*](PySequence_Fast_GET_ITEM(%PYARG_1, i));
- }
+ <insert-template name="qgraphicsitem_pysequence"/>
</conversion-rule>
<conversion-rule class="target">
- Shiboken::AutoDecRef object(PyList_New(0));
- for (int i=0, max=numItems; i &lt; max; i++) {
- PyList_Append(object, %CONVERTTOPYTHON[QGraphicsItem*](%in[i]));
- }
- PyObject *%out = object.object();
+ <insert-template name="qgraphicsitem_pyobject"/>
</conversion-rule>
</modify-argument>
<modify-argument index="4">
<replace-type modified-type="PySequence"/>
<conversion-rule class="target">
- Shiboken::AutoDecRef option_object(PyList_New(0));
- for (int i=0, max=numItems; i &lt; max; i++) {
- const QStyleOptionGraphicsItem* item = &amp;%in[i];
- PyList_Append(option_object, %CONVERTTOPYTHON[QStyleOptionGraphicsItem](item));
- }
- PyObject* %out = option_object.object();
+ <insert-template name="qstyleoptiongraphicsitem_pyobject"/>
</conversion-rule>
<conversion-rule class="native">
- int numOptions = PySequence_Size(%PYARG_2);
- Shiboken::AutoArrayPointer&lt;QStyleOptionGraphicsItem&gt; %out(numOptions);
- for (int i=0; i &lt; numOptions; i++) {
- %out[i] = %CONVERTTOCPP[QStyleOptionGraphicsItem](PySequence_Fast_GET_ITEM(%PYARG_1, i));
- }
+ <insert-template name="pysequence_qstyleoptiongraphicsitem"/>
</conversion-rule>
</modify-argument>
</modify-function>
@@ -1723,11 +1570,11 @@
<enum-type name="SceneLayer" flags="SceneLayers"/>
<!-- Qt5: note: this was called 'obsolete'. Is that true? -->
- <modify-function signature="drawItems(QPainter*,int,QGraphicsItem*[],const QStyleOptionGraphicsItem[],QWidget*)" remove="all" />
+ <modify-function signature="drawItems(QPainter*,int,QGraphicsItem*[],const QStyleOptionGraphicsItem[],QWidget*)" remove="all"/>
<modify-function signature="createItemGroup(const QList&lt;QGraphicsItem*&gt;&amp;)">
<modify-argument index="1">
- <parent index="return" action="add" />
+ <parent index="return" action="add"/>
</modify-argument>
<modify-argument index="return">
<define-ownership owner="default"/>
@@ -1735,17 +1582,7 @@
</modify-function>
<modify-function signature="destroyItemGroup(QGraphicsItemGroup*)">
- <inject-code>
- QGraphicsItem* parentItem = %1->parentItem();
- Shiboken::AutoDecRef parent(%CONVERTTOPYTHON[QGraphicsItem*](parentItem));
- foreach (QGraphicsItem* item, %1->childItems())
- Shiboken::Object::setParent(parent, %CONVERTTOPYTHON[QGraphicsItem*](item));
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%1);
- %END_ALLOW_THREADS
- // the arg was destroyed by Qt.
- Shiboken::Object::invalidate(%PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsscene-destroyitemgroup"/>
</modify-function>
<modify-function signature="contextMenuEvent(QGraphicsSceneContextMenuEvent*)">
@@ -1804,104 +1641,81 @@
</modify-function>
<modify-function signature="addItem(QGraphicsItem*)">
<modify-argument index="1">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addEllipse(const QRectF&amp;,const QPen&amp;,const QBrush&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addEllipse(qreal,qreal,qreal,qreal,const QPen&amp;,const QBrush&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addLine(const QLineF&amp;,const QPen&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addLine(qreal,qreal,qreal,qreal,const QPen&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addPath(const QPainterPath&amp;,const QPen&amp;,const QBrush&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addPixmap(const QPixmap&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addPolygon(const QPolygonF&amp;,const QPen&amp;,const QBrush&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addRect(const QRectF&amp;,const QPen&amp;,const QBrush&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addRect(qreal,qreal,qreal,qreal,const QPen&amp;,const QBrush&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addText(const QString&amp;,const QFont&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addSimpleText(const QString&amp;,const QFont&amp;)">
<modify-argument index="return">
- <parent index="this" action="add" />
+ <parent index="this" action="add"/>
</modify-argument>
</modify-function>
<modify-function signature="addWidget(QWidget*,QFlags&lt;Qt::WindowType&gt;)">
<!-- TODO: Add a keeper attribute to reference-count tag to do what this inject code do. -->
- <inject-code>
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2);
- %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
- Shiboken::Object::keepReference((SbkObject*)%PYARG_0, "setWidget(QWidget*)1", %PYARG_1);
- </inject-code>
- </modify-function>
-
- <!-- use glue code -->
- <modify-function signature="drawItems(QPainter*,int,QGraphicsItem**,const QStyleOptionGraphicsItem*,QWidget*)">
- <modify-argument index="2">
- <remove-argument/>
- </modify-argument>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsscene-addwidget"/>
</modify-function>
<modify-function signature="clear()">
- <inject-code>
- const QList&lt;QGraphicsItem*> items = %CPPSELF.items();
- Shiboken::BindingManager&amp; bm = Shiboken::BindingManager::instance();
- foreach (QGraphicsItem* item, items) {
- SbkObject* obj = bm.retrieveWrapper(item);
- if (obj) {
- if (reinterpret_cast&lt;PyObject*&gt;(obj)->ob_refcnt > 1) // If the refcnt is 1 the object will vannish anyway.
- Shiboken::Object::invalidate(obj);
- Shiboken::Object::removeParent(obj);
- }
- }
- %CPPSELF.%FUNCTION_NAME();
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsscene-clear"/>
</modify-function>
<modify-function signature="removeItem(QGraphicsItem*)">
<modify-argument index="1">
- <parent index="this" action="remove" />
+ <parent index="this" action="remove"/>
</modify-argument>
</modify-function>
@@ -1969,16 +1783,7 @@
</modify-argument>
</modify-function>
<modify-function signature="clear()">
- <inject-code>
- QTreeWidgetItem *rootItem = %CPPSELF.invisibleRootItem();
- Shiboken::BindingManager &amp;bm = Shiboken::BindingManager::instance();
- for (int i = 0; i &lt; rootItem->childCount(); ++i) {
- QTreeWidgetItem *item = rootItem->child(i);
- SbkObject* wrapper = bm.retrieveWrapper(item);
- if (wrapper)
- Shiboken::Object::setParent(0, reinterpret_cast&lt;PyObject*&gt;(wrapper));
- }
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtreewidget-clear"/>
</modify-function>
</object-type>
<object-type name="QAbstractItemDelegate">
@@ -2144,23 +1949,13 @@
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
</modify-argument>
- <inject-code class="target" position="end">
- // Only call the parent function if this return some value
- // the parent can be the TreeWidget
- if (%0)
- Shiboken::Object::setParent(%PYARG_0, %PYSELF);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qtreewidgetitem"/>
</modify-function>
<modify-function signature="treeWidget()const">
<modify-argument index="return">
<define-ownership class="target" owner="default"/>
</modify-argument>
- <inject-code class="target" position="end">
- // Only call the parent function if this return some value
- // the parent can be the TreeWidgetItem
- if (%0)
- Shiboken::Object::setParent(%PYARG_0, %PYSELF);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qtreewidgetitem"/>
</modify-function>
</object-type>
@@ -2187,33 +1982,36 @@
</modify-argument>
</modify-function>
<modify-function signature="clear()">
- <inject-code class="target" position="beginning">
- Shiboken::BindingManager &amp;bm = Shiboken::BindingManager::instance();
- PyObject *pyObj;
- for (int i = 0; i &lt; %CPPSELF.count(); i++) {
- QListWidgetItem *item = %CPPSELF.item(i);
- if ((pyObj = reinterpret_cast&lt;PyObject*&gt;(bm.retrieveWrapper(item))) != 0) {
- Py_INCREF(pyObj);
- Shiboken::Object::setParent(NULL, pyObj);
- Shiboken::Object::invalidate(pyObj);
- Py_DECREF(pyObj);
- }
- }
- %CPPSELF.%FUNCTION_NAME();
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlistwidget-clear"/>
</modify-function>
</object-type>
- <object-type name="QWidget">
- <!-- Qt5: remove native event for now -->
- <modify-function signature="nativeEvent(const QByteArray &amp;,void*,long*)" remove="all" />
+ <object-type name="QWidget" delete-in-main-thread="true">
+ <!-- see QWindow::nativeEvent(), QAbstractNativeEventFilter::nativeEventFilter() -->
+ <modify-function signature="nativeEvent(const QByteArray &amp;,void*,long*)">
+ <modify-argument index="3">
+ <remove-argument/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion_variables"/>
+ </conversion-rule>
+ </modify-argument>
+ <modify-argument index="return">
+ <replace-type modified-type="PyObject"/>
+ <conversion-rule class="native">
+ <insert-template name="return_native_eventfilter_conversion"/>
+ </conversion-rule>
+ </modify-argument>
+ <inject-code position="end">
+ <insert-template name="return_native_eventfilter"/>
+ </inject-code>
+ </modify-function>
<extra-includes>
<include file-name="QIcon" location="global"/>
<include file-name="QMessageBox" location="global"/>
</extra-includes>
- <inject-code class="native" file="glue/qwidget_glue.cpp" position="beginning" />
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-glue"/>
<enum-type name="RenderFlag" flags="RenderFlags"/>
@@ -2370,25 +2168,10 @@
</modify-function>
<modify-function signature="setStyle(QStyle*)">
- <inject-code class="target" position="end">
- Shiboken::Object::keepReference(reinterpret_cast&lt;SbkObject*&gt;(%PYSELF), "__style__", %PYARG_1);
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qwidget-setstyle"/>
</modify-function>
<modify-function signature="style()const">
- <inject-code class="target" position="end">
- QStyle* myStyle = %CPPSELF->style();
- if (myStyle &amp;&amp; qApp) {
- %PYARG_0 = %CONVERTTOPYTHON[QStyle*](myStyle);
- QStyle *appStyle = qApp->style();
- if (appStyle == myStyle) {
- Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication*](qApp));
- Shiboken::Object::setParent(pyApp, %PYARG_0);
- Shiboken::Object::releaseOwnership(%PYARG_0);
- } else {
- Shiboken::Object::keepReference(reinterpret_cast&lt;SbkObject*&gt;(%PYSELF), "__style__", %PYARG_0);
- }
- }
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qwidget-style"/>
<modify-argument index="return">
<define-ownership owner="default"/>
</modify-argument>
@@ -2408,7 +2191,7 @@
<modify-function signature="getContentsMargins(int*,int*,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -2424,12 +2207,12 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
<inject-code class="native" position="end">
<insert-template name="fix_native_return_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
@@ -2440,12 +2223,9 @@
</modify-function>
<modify-function signature="setLayout(QLayout*)">
- <inject-code class="target" position="beginning">
- qwidgetSetLayout(%CPPSELF, %1);
- // %FUNCTION_NAME() - disable generation of function call.
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qwidget-setlayout"/>
</modify-function>
- <modify-function signature="raise()" rename="raise_" />
+ <modify-function signature="raise()" rename="raise_"/>
<modify-function signature="setParent(QWidget*,QFlags&lt;Qt::WindowType>)">
<modify-argument index="this">
<parent index="1" action="add"/>
@@ -2462,7 +2242,7 @@
<object-type name="QMessageBox">
<enum-type name="ButtonRole"/>
<enum-type name="Icon"/>
- <enum-type name="StandardButton" flags="StandardButtons" />
+ <enum-type name="StandardButton" flags="StandardButtons"/>
<modify-function signature="removeButton(QAbstractButton*)">
<modify-argument index="1">
<parent index="this" action="add"/>
@@ -2491,6 +2271,7 @@
<enum-type name="ButtonSymbols"/>
<enum-type name="CorrectionMode"/>
<enum-type name="StepEnabledFlag" flags="StepEnabled"/>
+ <enum-type name="StepType" since="5.12"/>
<modify-function signature="setLineEdit(QLineEdit*)">
<modify-argument index="1">
<parent index="this" action="add"/>
@@ -2500,9 +2281,7 @@
<modify-argument index="return">
<replace-type modified-type="QString"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_QString"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtcore.cpp" snippet="qstring-return"/>
</modify-function>
<modify-function signature="validate(QString &amp;,int &amp;)const">
<modify-argument index="return">
@@ -2553,26 +2332,10 @@
<!-- This function need be re-implemented in inject code -->
<modify-function signature="removeTab(int)">
- <inject-code class="target" position="beginning">
- QWidget* tab = %CPPSELF.widget(%1);
- if (tab) {
- Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget*](tab));
- %CPPSELF.%FUNCTION_NAME(%1);
- }
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtabwidget-removetab"/>
</modify-function>
<modify-function signature="clear()">
- <inject-code class="target" position="beginning">
- Shiboken::BindingManager&amp; bm = Shiboken::BindingManager::instance();
- for (int i = 0; i &lt; %CPPSELF.count(); i++) {
- QWidget* widget = %CPPSELF.widget(i);
- if (bm.hasWrapper(widget)) {
- Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget*](widget));
- Shiboken::Object::releaseOwnership(pyWidget);
- }
- }
- %CPPSELF.%FUNCTION_NAME();
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtabwidget-clear"/>
</modify-function>
</object-type>
<object-type name="QDateTimeEdit">
@@ -2584,7 +2347,7 @@
</modify-function>
</object-type>
<object-type name="QSlider">
- <enum-type name="TickPosition" />
+ <enum-type name="TickPosition"/>
</object-type>
<object-type name="QProgressDialog">
<modify-function signature="setBar(QProgressBar*)">
@@ -2645,8 +2408,8 @@
</modify-argument>
</modify-function>
- <modify-function signature="getExistingDirectory(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QFileDialog::Option>)" allow-thread="yes" />
- <modify-function signature="getExistingDirectoryUrl(QWidget*,const QString&amp;,const QUrl&amp;,QFlags&lt;QFileDialog::Option>,const QStringList&amp;)" />
+ <modify-function signature="getExistingDirectory(QWidget*,const QString&amp;,const QString&amp;,QFlags&lt;QFileDialog::Option>)" allow-thread="yes"/>
+ <modify-function signature="getExistingDirectoryUrl(QWidget*,const QString&amp;,const QUrl&amp;,QFlags&lt;QFileDialog::Option>,const QStringList&amp;)"/>
<modify-function signature="getOpenFileName(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;)" allow-thread="yes">
<modify-argument index="return">
<replace-type modified-type="(fileName, selectedFilter)"/>
@@ -2655,9 +2418,7 @@
<replace-type modified-type="QString"/>
<replace-default-expression with="QString()"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_for_QFileDialog"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
</modify-function>
<modify-function signature="getOpenFileNames(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;)" allow-thread="yes">
<modify-argument index="return">
@@ -2667,9 +2428,7 @@
<replace-type modified-type="QString"/>
<replace-default-expression with="QString()"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_for_QFileDialog"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
</modify-function>
<modify-function signature="getOpenFileUrl(QWidget*,const QString&amp;,const QUrl&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;,const QStringList&amp;)" allow-thread="yes">
@@ -2680,9 +2439,7 @@
<replace-type modified-type="QString"/>
<replace-default-expression with="QString()"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_for_QFileDialog"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
</modify-function>
<modify-function signature="getOpenFileUrls(QWidget*,const QString&amp;,const QUrl&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;,const QStringList&amp;)" allow-thread="yes">
@@ -2693,9 +2450,7 @@
<replace-type modified-type="QString"/>
<replace-default-expression with="QString()"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_for_QFileDialog"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
</modify-function>
<modify-function signature="getSaveFileName(QWidget*,const QString&amp;,const QString&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;)" allow-thread="yes">
@@ -2706,9 +2461,7 @@
<replace-type modified-type="QString"/>
<replace-default-expression with="QString()"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_for_QFileDialog"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
</modify-function>
<modify-function signature="getSaveFileUrl(QWidget*,const QString&amp;,const QUrl&amp;,const QString&amp;,QString*,QFlags&lt;QFileDialog::Option&gt;,const QStringList&amp;)" allow-thread="yes">
@@ -2719,9 +2472,7 @@
<replace-type modified-type="QString"/>
<replace-default-expression with="QString()"/>
</modify-argument>
- <inject-code class="target" position="end">
- <insert-template name="return_for_QFileDialog"/>
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qfiledialog-return" />
</modify-function>
</object-type>
@@ -2735,8 +2486,8 @@
<enum-type name="SelectionBehavior"/>
<enum-type name="ButtonPosition"/>
</object-type>
- <object-type name="QRadioButton" />
- <object-type name="QScrollBar" />
+ <object-type name="QRadioButton"/>
+ <object-type name="QScrollBar"/>
<object-type name="QAbstractScrollArea">
<enum-type name="SizeAdjustPolicy"/>
<modify-function signature="setViewport(QWidget*)">
@@ -2844,7 +2595,7 @@
<object-type name="QSplitter">
<modify-function signature="getRange(int,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
@@ -2854,7 +2605,7 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_args,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
@@ -2869,7 +2620,7 @@
</modify-argument>
</modify-function>
</object-type>
- <object-type name="QGroupBox" />
+ <object-type name="QGroupBox"/>
<object-type name="QStackedWidget">
<modify-function signature="addWidget(QWidget*)">
<modify-argument index="1">
@@ -2893,7 +2644,7 @@
</modify-function>
</object-type>
<object-type name="QSplitterHandle"/>
- <object-type name="QDial" />
+ <object-type name="QDial"/>
<object-type name="QKeySequenceEdit"/>
<object-type name="QLineEdit">
<enum-type name="ActionPosition"/>
@@ -2908,10 +2659,10 @@
<parent index="this" action="add"/>
</modify-argument>
</modify-function>
- <modify-function signature="del()" rename="del_" />
+ <modify-function signature="del()" rename="del_"/>
<modify-function signature="getTextMargins(int*,int*,int*,int*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject *" />
+ <replace-type modified-type="PyObject *"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -2927,15 +2678,13 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="int" />
+ <replace from="$TYPE" to="int"/>
</insert-template>
</inject-code>
</modify-function>
<add-function signature="addAction(QAction*)">
- <inject-code class="target" position="beginning">
- %CPPSELF.addAction(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlineedit-addaction"/>
</add-function>
</object-type>
@@ -2968,7 +2717,7 @@
</object-type>
<object-type name="QDesktopWidget"/>
<object-type name="QFrame">
- <enum-type name="Shadow" extensible="yes"/>
+ <enum-type name="Shadow"/>
<enum-type name="Shape"/>
<enum-type name="StyleMask"/>
</object-type>
@@ -3026,7 +2775,7 @@
<object-type name="QToolBar">
<modify-function signature="addAction(QIcon,QString,const QObject*,const char*)">
<modify-argument index="3">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="4">
<remove-argument />
@@ -3034,20 +2783,11 @@
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
-
- <inject-code>
- QAction *action = %CPPSELF.addAction(%1, %2);
- %PYARG_0 = %CONVERTTOPYTHON[QAction*](action);
- Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0,
- const_cast&lt;char *&gt;("connect"),
- const_cast&lt;char *&gt;("OsO"),
- %PYARG_0, SIGNAL(triggered()), %PYARG_3)
- );
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtoolbar-addaction-1"/>
</modify-function>
<modify-function signature="addAction(QString,const QObject*,const char*)">
<modify-argument index="2">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="3">
<remove-argument />
@@ -3055,15 +2795,7 @@
<modify-argument index="return">
<parent index="this" action="add"/>
</modify-argument>
- <inject-code>
- QAction *action = %CPPSELF.addAction(%1);
- %PYARG_0 = %CONVERTTOPYTHON[QAction*](action);
- Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0,
- const_cast&lt;char *&gt;("connect"),
- const_cast&lt;char *&gt;("OsO"),
- %PYARG_0, SIGNAL(triggered()), %PYARG_2)
- );
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtoolbar-addaction-2"/>
</modify-function>
<modify-function signature="addAction(const QString&amp;)">
<modify-argument index="return">
@@ -3076,9 +2808,7 @@
</modify-argument>
</modify-function>
<add-function signature="addAction(QAction*)">
- <inject-code class="target" position="beginning">
- %CPPSELF.addAction(%1);
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qtoolbar-addaction-3"/>
</add-function>
<modify-function signature="addSeparator()">
<modify-argument index="return">
@@ -3107,30 +2837,7 @@
</modify-argument>
</modify-function>
<modify-function signature="clear()">
- <inject-code>
- QList&lt;PyObject* &gt; lst;
- Shiboken::BindingManager&amp; bm = Shiboken::BindingManager::instance();
- foreach(QToolButton* child, %CPPSELF.findChildren&lt;QToolButton*&gt;()) {
- if (bm.hasWrapper(child)) {
- PyObject* pyChild = %CONVERTTOPYTHON[QToolButton*](child);
- Shiboken::Object::setParent(0, pyChild);
- lst &lt;&lt; pyChild;
- }
- }
-
- //Remove actions
- foreach(QAction *act, %CPPSELF.actions()) {
- Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act));
- Shiboken::Object::setParent(NULL, pyAct);
- Shiboken::Object::invalidate(pyAct);
- }
-
- %CPPSELF.clear();
- foreach(PyObject* obj, lst) {
- Shiboken::Object::invalidate(reinterpret_cast&lt;SbkObject* &gt;(obj));
- Py_XDECREF(obj);
- }
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qtoolbar-clear"/>
</modify-function>
</object-type>
<object-type name="QComboBox">
@@ -3212,22 +2919,18 @@
<include file-name="QLocale" location="global"/>
<include file-name="QStyle" location="global"/>
</extra-includes>
- <modify-function signature="QApplication(int&amp;,char**,int)" access="private" />
+ <modify-function signature="QApplication(int&amp;,char**,int)" access="private"/>
<add-function signature="QApplication(QStringList)">
- <inject-code>
- QApplicationConstructor(%PYSELF, args, &amp;%0);
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qapplication-1"/>
</add-function>
<add-function signature="QApplication()">
- <inject-code>
- PyObject *empty = PyTuple_New(2);
- if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
- QApplicationConstructor(%PYSELF, empty, &amp;%0);
- }
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qapplication-2"/>
</add-function>
+ <modify-function signature="setStyle(QStyle*)">
+ <inject-code class="target" position="end" file="../glue/qtwidgets.cpp" snippet="qapplication-setStyle"/>
+ </modify-function>
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
- <inject-code class="native" file="glue/qapplication_init.cpp" position="beginning" />
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qapplication-init"/>
</object-type>
<object-type name="QCommandLinkButton"/>
@@ -3240,26 +2943,16 @@
</modify-function>
</object-type>
<object-type name="QFormLayout">
- <inject-code class="native" position="beginning" file="glue/qlayout_help_functions.cpp"/>
+ <inject-code class="native" position="beginning" file="../glue/qtwidgets.cpp" snippet="qlayout-help-functions"/>
<enum-type name="FieldGrowthPolicy"/>
<enum-type name="ItemRole"/>
<enum-type name="RowWrapPolicy"/>
- <template name="fix_args,int*,ItemRole*">
- int _row;
- QFormLayout::ItemRole _role;
- %BEGIN_ALLOW_THREADS
- %CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;_row, &amp;_role);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role));
- </template>
<modify-function signature="getLayoutPosition(QLayout*,int*,QFormLayout::ItemRole*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
@@ -3267,13 +2960,11 @@
<modify-argument index="3">
<remove-argument/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="fix_args,int*,ItemRole*"/>
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qformlayout-fix-args" />
</modify-function>
<modify-function signature="getWidgetPosition(QWidget*,int*,QFormLayout::ItemRole*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
@@ -3281,13 +2972,11 @@
<modify-argument index="3">
<remove-argument/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="fix_args,int*,ItemRole*"/>
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qformlayout-fix-args" />
</modify-function>
<modify-function signature="getItemPosition(int,int*,QFormLayout::ItemRole*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="2">
<remove-argument/>
@@ -3295,9 +2984,7 @@
<modify-argument index="3">
<remove-argument/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="fix_args,int*,ItemRole*"/>
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtwidgets.cpp" snippet="qformlayout-fix-args" />
</modify-function>
<modify-function signature="addRow(QWidget*,QWidget*)">
@@ -3408,7 +3095,7 @@
<object-type name="QGraphicsLayout">
<modify-function signature="getContentsMargins(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -3424,12 +3111,12 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
<inject-code class="native" position="end">
<insert-template name="fix_native_return_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -3440,7 +3127,7 @@
<object-type name="QGraphicsLayoutItem" copyable="false">
<modify-function signature="getContentsMargins(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="0">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -3456,12 +3143,12 @@
</modify-argument>
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
<inject-code class="native" position="end">
<insert-template name="fix_native_return_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -3515,20 +3202,14 @@
</modify-argument>
</modify-function>
<modify-function signature="setWidget(QWidget*)">
- <inject-code>
- QWidget* _old = %CPPSELF.widget();
- if (_old)
- Shiboken::Object::setParent(NULL, %CONVERTTOPYTHON[QWidget*](_old));
- %CPPSELF.%FUNCTION_NAME(%1);
- Shiboken::Object::setParent(%PYSELF, %PYARG_1);
- </inject-code>
+ <inject-code file="../glue/qtwidgets.cpp" snippet="qgraphicsproxywidget-setwidget"/>
</modify-function>
</object-type>
<!-- a QObject so main-thread delete redundant -->
<object-type name="QGraphicsWidget">
<modify-function signature="getContentsMargins(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -3545,13 +3226,13 @@
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
<modify-function signature="getWindowFrameMargins(qreal*,qreal*,qreal*,qreal*)const">
<modify-argument index="return">
- <replace-type modified-type="PyObject" />
+ <replace-type modified-type="PyObject"/>
</modify-argument>
<modify-argument index="1">
<remove-argument/>
@@ -3568,7 +3249,7 @@
<inject-code class="target" position="beginning">
<insert-template name="fix_number*,number*,number*,number*">
- <replace from="$TYPE" to="qreal" />
+ <replace from="$TYPE" to="qreal"/>
</insert-template>
</inject-code>
</modify-function>
@@ -3640,7 +3321,7 @@
<parent index="this" action="add"/>
</modify-argument>
</modify-function>
- <modify-function signature="print(QPagedPaintDevice*)const" rename="print_" />
+ <modify-function signature="print(QPagedPaintDevice*)const" rename="print_"/>
</object-type>
<object-type name="QStyledItemDelegate">
<modify-function signature="setItemEditorFactory(QItemEditorFactory*)">
@@ -3724,7 +3405,7 @@
<!-- The above entries may be present in the system or not. Keep this section organized. -->
<!-- This enum is present on QtCore -->
- <suppress-warning text="enum 'QCoreApplication::ApplicationFlags' is specified in typesystem, but not declared" />
+ <suppress-warning text="enum 'QCoreApplication::ApplicationFlags' is specified in typesystem, but not declared"/>
<suppress-warning text="QGraphicsEllipseItem::Type' does not have a type entry or is not an enum"/>
<suppress-warning text="QGraphicsItemGroup::Type' does not have a type entry or is not an enum"/>
<suppress-warning text="QGraphicsItem::UserType' does not have a type entry or is not an enum"/>
diff --git a/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt b/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt
index 5932792e9..9729d319a 100644
--- a/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt
@@ -36,10 +36,9 @@ set(QtWinExtras_libraries pyside2
set(QtWinExtras_deps QtCore QtGui)
-create_pyside_module(QtWinExtras
- QtWinExtras_include_dirs
- QtWinExtras_libraries
- QtWinExtras_deps
- QtWinExtras_SOURCE_DIR
- QtWinExtras_SRC
- "")
+create_pyside_module(NAME QtWinExtras
+ INCLUDE_DIRS QtWinExtras_include_dirs
+ LIBRARIES QtWinExtras_libraries
+ DEPS QtWinExtras_deps
+ TYPESYSTEM_PATH QtWinExtras_SOURCE_DIR
+ SOURCES QtWinExtras_SRC)
diff --git a/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt b/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt
index 4f0111905..fc0b21f1f 100644
--- a/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt
@@ -28,10 +28,9 @@ set(QtX11Extras_libraries pyside2
set(QtX11Extras_deps QtCore QtGui)
-create_pyside_module(QtX11Extras
- QtX11Extras_include_dirs
- QtX11Extras_libraries
- QtX11Extras_deps
- QtX11Extras_SOURCE_DIR
- QtX11Extras_SRC
- "")
+create_pyside_module(NAME QtX11Extras
+ INCLUDE_DIRS QtX11Extras_include_dirs
+ LIBRARIES QtX11Extras_libraries
+ DEPS QtX11Extras_deps
+ TYPESYSTEM_PATH QtX11Extras_SOURCE_DIR
+ SOURCES QtX11Extras_SRC)
diff --git a/sources/pyside2/PySide2/QtXml/CMakeLists.txt b/sources/pyside2/PySide2/QtXml/CMakeLists.txt
index 9c724cffb..7a6a707b7 100644
--- a/sources/pyside2/PySide2/QtXml/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtXml/CMakeLists.txt
@@ -52,10 +52,9 @@ set(QtXml_libraries pyside2
${Qt5Xml_LIBRARIES})
set(QtXml_deps QtCore)
-create_pyside_module(QtXml
- QtXml_include_dirs
- QtXml_libraries
- QtXml_deps
- QtXml_SOURCE_DIR
- QtXml_SRC
- "")
+create_pyside_module(NAME QtXml
+ INCLUDE_DIRS QtXml_include_dirs
+ LIBRARIES QtXml_libraries
+ DEPS QtXml_deps
+ TYPESYSTEM_PATH QtXml_SOURCE_DIR
+ SOURCES QtXml_SRC)
diff --git a/sources/pyside2/PySide2/QtXml/typesystem_xml.xml b/sources/pyside2/PySide2/QtXml/typesystem_xml.xml
index 3bfd7c662..59343543a 100644
--- a/sources/pyside2/PySide2/QtXml/typesystem_xml.xml
+++ b/sources/pyside2/PySide2/QtXml/typesystem_xml.xml
@@ -40,32 +40,20 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtXml">
- <load-typesystem name="typesystem_templates.xml" generate="no" />
<load-typesystem name="QtCore/typesystem_core.xml" generate="no" />
+ <load-typesystem name="templates/core_common.xml" generate="no" />
+ <load-typesystem name="templates/xml_common.xml" generate="no" />
<rejection class="QXmlAttributes::Attribute"/>
<rejection class="QDomNode" field-name="impl"/>
<rejection class="QXmlInputSource" field-name="EndOfData"/>
<rejection class="QXmlInputSource" field-name="EndOfDocument"/>
- <value-type name="QDomAttr" />
- <value-type name="QDomCDATASection" />
- <value-type name="QDomCharacterData" />
- <value-type name="QDomComment" />
+ <value-type name="QDomAttr"/>
+ <value-type name="QDomCDATASection"/>
+ <value-type name="QDomCharacterData"/>
+ <value-type name="QDomComment"/>
- <template name="qdomdocument_setcontent">
- QString _errorMsg_;
- int _errorLine_ = 0;
- int _errorColumn_ = 0;
- %BEGIN_ALLOW_THREADS
- bool _ret_ = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;_errorMsg_, &amp;_errorLine_, &amp;_errorColumn_);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(4);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](_ret_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](_errorMsg_));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](_errorLine_));
- PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](_errorColumn_));
- </template>
<value-type name="QDomDocument">
<!-- will be replaced in inject code -->
@@ -85,9 +73,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(const QString&amp;,bool,QString*,int*,int*)">
<modify-argument index="3">
@@ -105,9 +91,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(QIODevice*,bool,QString*,int*,int*)">
<modify-argument index="3">
@@ -125,9 +109,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(const QByteArray&amp;,QString*,int*,int*)">
<modify-argument index="2">
@@ -145,9 +127,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(QIODevice*,QString*,int*,int*)">
<modify-argument index="2">
@@ -165,9 +145,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(QXmlInputSource*,bool,QString*,int*,int*)">
<modify-argument index="3">
@@ -185,9 +163,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(QXmlInputSource*,QXmlReader*,QString*,int*,int*)">
<modify-argument index="3">
@@ -205,9 +181,7 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
<modify-function signature="setContent(const QString&amp;,QString*,int*,int*)">
<modify-argument index="2">
@@ -225,21 +199,19 @@
<modify-argument index="return">
<replace-type modified-type="(retval, errorMsg, errorLine, errorColumn)"/>
</modify-argument>
- <inject-code class="target" position="beginning">
- <insert-template name="qdomdocument_setcontent" />
- </inject-code>
+ <inject-code class="target" position="beginning" file="../glue/qtxml.cpp" snippet="qdomdocument-setcontent" />
</modify-function>
</value-type>
- <value-type name="QDomDocumentFragment" />
- <value-type name="QDomDocumentType" />
- <value-type name="QDomEntity" />
- <value-type name="QDomEntityReference" />
+ <value-type name="QDomDocumentFragment"/>
+ <value-type name="QDomDocumentType"/>
+ <value-type name="QDomEntity"/>
+ <value-type name="QDomEntityReference"/>
<value-type name="QDomImplementation">
<enum-type name="InvalidDataPolicy"/>
</value-type>
- <value-type name="QDomNamedNodeMap" />
+ <value-type name="QDomNamedNodeMap"/>
<value-type name="QDomNode">
<enum-type name="EncodingPolicy"/>
@@ -247,11 +219,11 @@
<modify-function signature="save(QTextStream&amp;,int,QDomNode::EncodingPolicy)const" allow-thread="yes"/>
</value-type>
- <value-type name="QDomNodeList" />
- <value-type name="QDomNotation" />
- <value-type name="QDomProcessingInstruction" />
+ <value-type name="QDomNodeList"/>
+ <value-type name="QDomNotation"/>
+ <value-type name="QDomProcessingInstruction"/>
- <value-type name="QDomText" />
+ <value-type name="QDomText"/>
<object-type name="QXmlParseException"/>
@@ -273,12 +245,6 @@
<object-type name="QXmlErrorHandler"/>
<object-type name="QXmlLexicalHandler"/>
- <template name="QXmlEntityResolver_resolveEntity_return_conversion_native">
- Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
- Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
- %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ok_);
- %3 = %CONVERTTOCPP[QXmlInputSource*](_py_ret_);
- </template>
<object-type name="QXmlEntityResolver">
<modify-function signature="resolveEntity(const QString&amp;,const QString&amp;,QXmlInputSource*&amp;)">
@@ -291,15 +257,7 @@
<insert-template name="QXmlEntityResolver_resolveEntity_return_conversion_native"/>
</conversion-rule>
</modify-argument>
- <inject-code class="target" position="end">
- QXmlInputSource* _qxmlinputsource_arg_ = 0;
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, _qxmlinputsource_arg_);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QXmlInputSource*](_qxmlinputsource_arg_));
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtxml.cpp" snippet="qxmlentityresolver-resolveentity"/>
</modify-function>
</object-type>
<object-type name="QXmlDefaultHandler">
@@ -318,15 +276,7 @@
<insert-template name="QXmlEntityResolver_resolveEntity_return_conversion_native"/>
</conversion-rule>
</modify-argument>
- <inject-code class="target" position="end">
- QXmlInputSource* _qxmlinputsource_arg_ = 0;
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE %0 = %CPPSELF.%TYPE::%FUNCTION_NAME(%1, %2, _qxmlinputsource_arg_);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QXmlInputSource*](_qxmlinputsource_arg_));
- </inject-code>
+ <inject-code class="target" position="end" file="../glue/qtxml.cpp" snippet="qxmlentityresolver-resolveentity"/>
</modify-function>
</object-type>
<object-type name="QXmlInputSource"/>
@@ -342,7 +292,7 @@
<remove-argument/>
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
<conversion-rule class="native">
<insert-template name="fix_virtual_method_return_value_and_bool*"/>
</conversion-rule>
@@ -357,7 +307,7 @@
<remove-argument/>
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
<conversion-rule class="native">
<insert-template name="fix_virtual_method_return_value_and_bool*"/>
</conversion-rule>
@@ -409,7 +359,7 @@
<remove-argument/>
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
<conversion-rule class="native">
<insert-template name="fix_virtual_method_return_value_and_bool*"/>
</conversion-rule>
@@ -424,7 +374,7 @@
<remove-argument/>
</modify-argument>
<modify-argument index="return">
- <replace-type modified-type="PySequence" />
+ <replace-type modified-type="PySequence"/>
<conversion-rule class="native">
<insert-template name="fix_virtual_method_return_value_and_bool*"/>
</conversion-rule>
diff --git a/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt b/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt
index d279f43ae..d9e936517 100644
--- a/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt
+++ b/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt
@@ -35,11 +35,10 @@ set(QtXmlPatterns_libraries pyside2
${Qt5XmlPatterns_LIBRARIES})
set(QtXmlPatterns_deps QtCore)
-create_pyside_module(QtXmlPatterns
- QtXmlPatterns_include_dirs
- QtXmlPatterns_libraries
- QtXmlPatterns_deps
- QtXmlPatterns_SOURCE_DIR
- QtXmlPatterns_SRC
- "")
+create_pyside_module(NAME QtXmlPatterns
+ INCLUDE_DIRS QtXmlPatterns_include_dirs
+ LIBRARIES QtXmlPatterns_libraries
+ DEPS QtXmlPatterns_deps
+ TYPESYSTEM_PATH QtXmlPatterns_SOURCE_DIR
+ SOURCES QtXmlPatterns_SRC)
diff --git a/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml b/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml
index f4e690874..f3f689cf6 100644
--- a/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml
+++ b/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml
@@ -42,83 +42,80 @@
<typesystem package="PySide2.QtXmlPatterns">
<load-typesystem name="QtCore/typesystem_core.xml" generate="no"/>
- <object-type name="QXmlSchema" since="4.6" /> <!-- Qt scoped pointer does not allow declare this as value type -->
+ <object-type name="QXmlSchema" since="4.6"/> <!-- Qt scoped pointer does not allow declare this as value type -->
<object-type name="QXmlSchemaValidator" since="4.6">
<modify-function signature="schema()const">
<modify-argument index="return">
<replace-type modified-type="QXmlSchema*"/>
<define-ownership owner="target"/>
</modify-argument>
- <inject-code>
- QXmlSchema* %0 = new QXmlSchema(%CPPSELF.schema());
- %PYARG_0 = %CONVERTTOPYTHON[QXmlSchema*](%0);
- </inject-code>
+ <inject-code file="../glue/qtxmlpatterns.cpp" snippet="qxmlschemavalidator-schema"/>
</modify-function>
</object-type>
- <object-type name="QAbstractMessageHandler" />
- <object-type name="QAbstractUriResolver" />
+ <object-type name="QAbstractMessageHandler"/>
+ <object-type name="QAbstractUriResolver"/>
<object-type name="QAbstractXmlNodeModel">
- <enum-type name="NodeCopySetting" />
- <enum-type name="SimpleAxis" />
+ <enum-type name="NodeCopySetting"/>
+ <enum-type name="SimpleAxis"/>
</object-type>
- <object-type name="QAbstractXmlReceiver" />
- <value-type name="QSourceLocation" />
- <object-type name="QXmlFormatter" />
- <value-type name="QXmlItem" />
+ <object-type name="QAbstractXmlReceiver"/>
+ <value-type name="QSourceLocation"/>
+ <object-type name="QXmlFormatter"/>
+ <value-type name="QXmlItem"/>
<value-type name="QXmlName">
<primitive-type name="NamespaceCode"/>
<primitive-type name="PrefixCode"/>
<primitive-type name="LocalNameCode"/>
<!-- ### These methods aren't part of Qt public API -->
<modify-function signature="QXmlName(QXmlName::NamespaceCode,QXmlName::LocalNameCode,QXmlName::PrefixCode)" remove="all"/>
- <modify-function signature="setNamespaceURI(QXmlName::NamespaceCode)" remove="all" />
- <modify-function signature="localName()const" remove="all" />
- <modify-function signature="prefix()const" remove="all" />
- <modify-function signature="hasPrefix()const" remove="all" />
- <modify-function signature="hasNamespace()const" remove="all" />
- <modify-function signature="namespaceURI()const" remove="all" />
- <modify-function signature="isLexicallyEqual(const QXmlName&amp;)const" remove="all" />
- <modify-function signature="setPrefix(QXmlName::PrefixCode)" remove="all" />
- <modify-function signature="setLocalName(QXmlName::LocalNameCode)" remove="all" />
- <modify-function signature="code()const" remove="all" />
+ <modify-function signature="setNamespaceURI(QXmlName::NamespaceCode)" remove="all"/>
+ <modify-function signature="localName()const" remove="all"/>
+ <modify-function signature="prefix()const" remove="all"/>
+ <modify-function signature="hasPrefix()const" remove="all"/>
+ <modify-function signature="hasNamespace()const" remove="all"/>
+ <modify-function signature="namespaceURI()const" remove="all"/>
+ <modify-function signature="isLexicallyEqual(const QXmlName&amp;)const" remove="all"/>
+ <modify-function signature="setPrefix(QXmlName::PrefixCode)" remove="all"/>
+ <modify-function signature="setLocalName(QXmlName::LocalNameCode)" remove="all"/>
+ <modify-function signature="code()const" remove="all"/>
<!-- ### -->
</value-type>
- <value-type name="QXmlNamePool" />
+ <value-type name="QXmlNamePool"/>
- <rejection class="QXmlNodeModelIndex" function-name="type" />
- <rejection class="QXmlNodeModelIndex" function-name="sequencedTypedValue" />
- <rejection class="QXmlNodeModelIndex" function-name="iterate" />
+ <rejection class="QXmlNodeModelIndex" function-name="type"/>
+ <rejection class="QXmlNodeModelIndex" function-name="sequencedTypedValue"/>
+ <rejection class="QXmlNodeModelIndex" function-name="iterate"/>
<!-- ### This enum isn't part of Qt public API -->
<suppress-warning text="enum 'QXmlNodeModelIndex::Axis' does not have a type entry or is not an enum"/>
<value-type name="QXmlNodeModelIndex">
- <enum-type name="DocumentOrder" />
- <enum-type name="NodeKind" />
+ <enum-type name="DocumentOrder"/>
+ <enum-type name="NodeKind"/>
<!-- ### Qt internal methods -->
- <modify-function signature="name()const" remove="all" />
- <modify-function signature="root()const" remove="all" />
- <modify-function signature="documentUri()const" remove="all" />
- <modify-function signature="baseUri()const" remove="all" />
- <modify-function signature="kind()const" remove="all" />
- <modify-function signature="isDeepEqual(const QXmlNodeModelIndex&amp;)const" remove="all" />
- <modify-function signature="compareOrder(const QXmlNodeModelIndex &amp;)const" remove="all" />
- <modify-function signature="sendNamespaces(QAbstractXmlReceiver*)const" remove="all" />
- <modify-function signature="namespaceBindings()const" remove="all" />
- <modify-function signature="namespaceForPrefix(QXmlName::PrefixCode)const" remove="all" />
- <modify-function signature="stringValue()const" remove="all" />
- <modify-function signature="is(const QXmlNodeModelIndex &amp;)const" remove="all" />
- <modify-function signature="reset()" remove="all" />
+ <modify-function signature="name()const" remove="all"/>
+ <modify-function signature="root()const" remove="all"/>
+ <modify-function signature="documentUri()const" remove="all"/>
+ <modify-function signature="baseUri()const" remove="all"/>
+ <modify-function signature="kind()const" remove="all"/>
+ <modify-function signature="isDeepEqual(const QXmlNodeModelIndex&amp;)const" remove="all"/>
+ <modify-function signature="compareOrder(const QXmlNodeModelIndex &amp;)const" remove="all"/>
+ <modify-function signature="sendNamespaces(QAbstractXmlReceiver*const)const" remove="all"/>
+ <modify-function signature="namespaceBindings()const" remove="all"/>
+ <modify-function signature="namespaceForPrefix(QXmlName::PrefixCode)const" remove="all"/>
+ <modify-function signature="stringValue()const" remove="all"/>
+ <modify-function signature="is(const QXmlNodeModelIndex &amp;)const" remove="all"/>
+ <modify-function signature="reset()" remove="all"/>
<!-- ### -->
</value-type>
<value-type name="QXmlQuery">
<!-- ### TODO: must evaluate if anything other than removal is needed. -->
- <enum-type name="QueryLanguage" />
- <modify-function signature="evaluateTo(QStringList*)const" remove="all" />
- <modify-function signature="evaluateTo(QString*)const" remove="all" />
+ <enum-type name="QueryLanguage"/>
+ <modify-function signature="evaluateTo(QStringList*)const" remove="all"/>
+ <modify-function signature="evaluateTo(QString*)const" remove="all"/>
<!-- ### -->
</value-type>
- <object-type name="QXmlResultItems" />
- <object-type name="QXmlSerializer" />
+ <object-type name="QXmlResultItems"/>
+ <object-type name="QXmlSerializer"/>
<suppress-warning text="class 'QAbstractXmlNodeModel' inherits from unknown base class 'QSharedData'"/>
<suppress-warning text="class not found for setup inheritance 'QSharedData'"/>
diff --git a/sources/pyside2/PySide2/__init__.py.in b/sources/pyside2/PySide2/__init__.py.in
index ab50ef776..ac75f52b6 100644
--- a/sources/pyside2/PySide2/__init__.py.in
+++ b/sources/pyside2/PySide2/__init__.py.in
@@ -4,21 +4,23 @@ __all__ = list("Qt" + body for body in
__version__ = "@FINAL_PACKAGE_VERSION@"
__version_info__ = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@")
-@PYSIDE_BUILD_DATE@
-@PYSIDE_BUILD_COMMIT_DATE@
-@PYSIDE_BUILD_COMMIT_HASH@
-@PYSIDE_BUILD_COMMIT_HASH_DESCRIBED@
-
-# Timestamp used for snapshot build, which is part of snapshot package version.
-@PYSIDE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
-
def _setupQtDirectories():
import sys
import os
+ # On Windows we need to explicitly import the shiboken2 module so
+ # that the libshiboken.dll dependency is loaded by the time a
+ # Qt module is imported. Otherwise due to PATH not containing
+ # the shiboken2 module path, the Qt module import would fail
+ # due to the missing libshiboken dll.
+ # We need to do the same on Linux and macOS, because we do not
+ # embed rpaths into the PySide2 libraries that would point to
+ # the libshiboken library location. Importing the module
+ # loads the libraries into the process memory beforehand, and
+ # thus takes care of it for us.
+ import shiboken2
+
pyside_package_dir = os.path.abspath(os.path.dirname(__file__))
- # Used by signature module.
- os.environ["PYSIDE_PACKAGE_DIR"] = pyside_package_dir
if sys.platform == 'win32':
# PATH has to contain the package directory, otherwise plugins
diff --git a/sources/pyside2/PySide2/_config.py.in b/sources/pyside2/PySide2/_config.py.in
index 31a2f7a50..740e9a001 100644
--- a/sources/pyside2/PySide2/_config.py.in
+++ b/sources/pyside2/PySide2/_config.py.in
@@ -8,10 +8,9 @@ pyside_library_soversion = str(@PYSIDE_SO_VERSION@)
version = "@FINAL_PACKAGE_VERSION@"
version_info = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@")
-@PYSIDE_BUILD_DATE@
-@PYSIDE_BUILD_COMMIT_DATE@
-@PYSIDE_BUILD_COMMIT_HASH@
-@PYSIDE_BUILD_COMMIT_HASH_DESCRIBED@
-
-# Timestamp used for snapshot build, which is part of snapshot package version.
-@PYSIDE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
+@PACKAGE_BUILD_DATE@
+@PACKAGE_BUILD_COMMIT_DATE@
+@PACKAGE_BUILD_COMMIT_HASH@
+@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@
+@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
+@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@
diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp b/sources/pyside2/PySide2/glue/qtcharts.cpp
index aef11f2c7..1828fecc0 100644
--- a/sources/pyside2/PySide2/QtWidgets/glue/qapplication_init.cpp
+++ b/sources/pyside2/PySide2/glue/qtcharts.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,14 +37,6 @@
**
****************************************************************************/
-static void QApplicationConstructor(PyObject *self, PyObject *pyargv, QApplicationWrapper **cptr)
-{
- static int argc;
- static char **argv;
- PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
- if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
- *cptr = new QApplicationWrapper(argc, argv, 0);
- Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self));
- PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
- }
-}
+// @snippet qchart-releaseownership
+Shiboken::Object::releaseOwnership(%PYARG_1);
+// @snippet qchart-releaseownership
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
new file mode 100644
index 000000000..4c77e9e87
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -0,0 +1,1816 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet include-pyside
+#include <pyside.h>
+// @snippet include-pyside
+
+// @snippet pystring-check
+bool py2kStrCheck(PyObject *obj)
+{
+#ifdef IS_PY3K
+ return false;
+#else
+ return PyString_Check(obj);
+#endif
+}
+// @snippet pystring-check
+
+// @snippet qvariant-conversion
+static const char *QVariant_resolveMetaType(PyTypeObject *type, int *typeId)
+{
+ if (PyObject_TypeCheck(type, SbkObjectType_TypeF())) {
+ SbkObjectType* sbkType = (SbkObjectType*)type;
+ const char* typeName = Shiboken::ObjectType::getOriginalName(sbkType);
+ if (!typeName)
+ return nullptr;
+ const bool valueType = '*' != typeName[qstrlen(typeName) - 1];
+ // Do not convert user type of value
+ if (valueType && Shiboken::ObjectType::isUserType(type))
+ return nullptr;
+ int obTypeId = QMetaType::type(typeName);
+ if (obTypeId) {
+ *typeId = obTypeId;
+ return typeName;
+ }
+ // Do not resolve types to value type
+ if (valueType)
+ return nullptr;
+ // Find in base types. First check tp_bases, and only after check tp_base, because
+ // tp_base does not always point to the first base class, but rather to the first
+ // that has added any python fields or slots to its object layout.
+ // See https://mail.python.org/pipermail/python-list/2009-January/520733.html
+ if (type->tp_bases) {
+ for (int i = 0, size = PyTuple_GET_SIZE(type->tp_bases); i < size; ++i) {
+ const char *derivedName = QVariant_resolveMetaType(reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(
+ type->tp_bases, i)), typeId);
+ if (derivedName)
+ return derivedName;
+ }
+ }
+ else if (type->tp_base) {
+ return QVariant_resolveMetaType(type->tp_base, typeId);
+ }
+ }
+ *typeId = 0;
+ return nullptr;
+}
+static QVariant QVariant_convertToValueList(PyObject *list)
+{
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return QVariant();
+ }
+
+ Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
+ int typeId;
+ const char *typeName = QVariant_resolveMetaType(element.cast<PyTypeObject*>(), &typeId);
+ if (typeName) {
+ QByteArray listTypeName("QList<");
+ listTypeName += typeName;
+ listTypeName += '>';
+ typeId = QMetaType::type(listTypeName);
+ if (typeId > 0) {
+ Shiboken::Conversions::SpecificConverter converter(listTypeName);
+ if (converter) {
+ QVariant var(typeId, nullptr);
+ converter.toCpp(list, &var);
+ return var;
+ }
+ qWarning() << "Type converter for :" << listTypeName << "not registered.";
+ }
+ }
+ return QVariant();
+}
+static bool QVariant_isStringList(PyObject *list)
+{
+ if (!PySequence_Check(list)) {
+ // If it is not a list or a derived list class
+ // we assume that will not be a String list neither.
+ return false;
+ }
+
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return false;
+ }
+
+ Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
+ const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
+ if (!%CHECKTYPE[QString](item))
+ return false;
+ }
+ return true;
+}
+static QVariant QVariant_convertToVariantMap(PyObject *map)
+{
+ Py_ssize_t pos = 0;
+ Shiboken::AutoDecRef keys(PyDict_Keys(map));
+ if (!QVariant_isStringList(keys))
+ return QVariant();
+ PyObject *key;
+ PyObject *value;
+ QMap<QString,QVariant> ret;
+ while (PyDict_Next(map, &pos, &key, &value)) {
+ QString cppKey = %CONVERTTOCPP[QString](key);
+ QVariant cppValue = %CONVERTTOCPP[QVariant](value);
+ ret.insert(cppKey, cppValue);
+ }
+ return QVariant(ret);
+}
+static QVariant QVariant_convertToVariantList(PyObject *list)
+{
+ if (QVariant_isStringList(list)) {
+ QList<QString > lst = %CONVERTTOCPP[QList<QString>](list);
+ return QVariant(QStringList(lst));
+ }
+ QVariant valueList = QVariant_convertToValueList(list);
+ if (valueList.isValid())
+ return valueList;
+
+ if (PySequence_Size(list) < 0) {
+ // clear the error if < 0 which means no length at all
+ PyErr_Clear();
+ return QVariant();
+ }
+
+ QList<QVariant> lst;
+ Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
+ const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ PyObject *pyItem = PySequence_Fast_GET_ITEM(fast.object(), i);
+ QVariant item = %CONVERTTOCPP[QVariant](pyItem);
+ lst.append(item);
+ }
+ return QVariant(lst);
+}
+// @snippet qvariant-conversion
+
+// @snippet qvariantmap-register
+Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QMAP_QSTRING_QVARIANT_IDX], "QVariantMap");
+// @snippet qvariantmap-register
+
+// @snippet qvariantmap-check
+static bool QVariantType_isStringList(PyObject *list)
+{
+ Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
+ const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
+ for (Py_ssize_t i=0; i < size; i++) {
+ PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
+ if (!%CHECKTYPE[QString](item))
+ return false;
+ }
+ return true;
+}
+static bool QVariantType_checkAllStringKeys(PyObject *dict)
+{
+ Shiboken::AutoDecRef keys(PyDict_Keys(dict));
+ return QVariantType_isStringList(keys);
+}
+// @snippet qvariantmap-check
+
+// @snippet qt-qabs
+double _abs = qAbs(%1);
+%PYARG_0 = %CONVERTTOPYTHON[double](_abs);
+// @snippet qt-qabs
+
+// @snippet qt-postroutine
+namespace PySide {
+static QStack<PyObject*> globalPostRoutineFunctions;
+void globalPostRoutineCallback()
+{
+ Shiboken::GilState state;
+ for (auto *callback : globalPostRoutineFunctions) {
+ Shiboken::AutoDecRef result(PyObject_CallObject(callback, nullptr));
+ Py_DECREF(callback);
+ }
+ globalPostRoutineFunctions.clear();
+}
+void addPostRoutine(PyObject *callback)
+{
+ if (PyCallable_Check(callback)) {
+ globalPostRoutineFunctions << callback;
+ Py_INCREF(callback);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "qAddPostRoutine: The argument must be a callable object.");
+ }
+}
+} // namespace
+// @snippet qt-postroutine
+
+// @snippet qt-addpostroutine
+PySide::addPostRoutine(%1);
+// @snippet qt-addpostroutine
+
+// @snippet qt-qaddpostroutine
+qAddPostRoutine(PySide::globalPostRoutineCallback);
+// @snippet qt-qaddpostroutine
+
+// @snippet qt-version
+QList<QByteArray> version = QByteArray(qVersion()).split('.');
+PyObject *pyQtVersion = PyTuple_New(3);
+for (int i = 0; i < 3; ++i)
+ PyTuple_SET_ITEM(pyQtVersion, i, PyInt_FromLong(version[i].toInt()));
+PyModule_AddObject(module, "__version_info__", pyQtVersion);
+PyModule_AddStringConstant(module, "__version__", qVersion());
+// @snippet qt-version
+
+// @snippet qobject-connect
+static bool isDecorator(PyObject* method, PyObject* self)
+{
+ Shiboken::AutoDecRef methodName(PyObject_GetAttrString(method, "__name__"));
+ if (!PyObject_HasAttr(self, methodName))
+ return true;
+ Shiboken::AutoDecRef otherMethod(PyObject_GetAttr(self, methodName));
+ return PyMethod_GET_FUNCTION(otherMethod.object()) != PyMethod_GET_FUNCTION(method);
+}
+
+static bool getReceiver(QObject *source, const char* signal, PyObject* callback, QObject** receiver, PyObject** self, QByteArray* callbackSig)
+{
+ bool forceGlobalReceiver = false;
+ if (PyMethod_Check(callback)) {
+ *self = PyMethod_GET_SELF(callback);
+ if (%CHECKTYPE[QObject*](*self))
+ *receiver = %CONVERTTOCPP[QObject*](*self);
+ forceGlobalReceiver = isDecorator(callback, *self);
+ } else if (PyCFunction_Check(callback)) {
+ *self = PyCFunction_GET_SELF(callback);
+ if (*self && %CHECKTYPE[QObject*](*self))
+ *receiver = %CONVERTTOCPP[QObject*](*self);
+ } else if (PyCallable_Check(callback)) {
+ // Ok, just a callable object
+ *receiver = nullptr;
+ *self = nullptr;
+ }
+
+ bool usingGlobalReceiver = !*receiver || forceGlobalReceiver;
+
+ // Check if this callback is a overwrite of a non-virtual Qt slot.
+ if (!usingGlobalReceiver && receiver && self) {
+ *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1();
+ const QMetaObject* metaObject = (*receiver)->metaObject();
+ int slotIndex = metaObject->indexOfSlot(callbackSig->constData());
+ if (slotIndex != -1 && slotIndex < metaObject->methodOffset() && PyMethod_Check(callback))
+ usingGlobalReceiver = true;
+ }
+
+ if (usingGlobalReceiver) {
+ PySide::SignalManager& signalManager = PySide::SignalManager::instance();
+ *receiver = signalManager.globalReceiver(source, callback);
+ *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1();
+ }
+
+ return usingGlobalReceiver;
+}
+
+static bool qobjectConnect(QObject* source, const char* signal, QObject* receiver, const char* slot, Qt::ConnectionType type)
+{
+ if (!signal || !slot)
+ return false;
+
+ if (!PySide::Signal::checkQtSignal(signal))
+ return false;
+ signal++;
+
+ if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal))
+ return false;
+
+ bool isSignal = PySide::Signal::isQtSignal(slot);
+ slot++;
+ PySide::SignalManager::registerMetaMethod(receiver, slot, isSignal ? QMetaMethod::Signal : QMetaMethod::Slot);
+ bool connection;
+ Py_BEGIN_ALLOW_THREADS
+ connection = QObject::connect(source, signal - 1, receiver, slot - 1, type);
+ Py_END_ALLOW_THREADS
+ return connection;
+}
+
+static bool qobjectConnect(QObject* source, QMetaMethod signal, QObject* receiver, QMetaMethod slot, Qt::ConnectionType type)
+{
+ return qobjectConnect(source, signal.methodSignature(), receiver, slot.methodSignature(), type);
+}
+
+static bool qobjectConnectCallback(QObject* source, const char* signal, PyObject* callback, Qt::ConnectionType type)
+{
+ if (!signal || !PySide::Signal::checkQtSignal(signal))
+ return false;
+ signal++;
+
+ int signalIndex = PySide::SignalManager::registerMetaMethodGetIndex(source, signal, QMetaMethod::Signal);
+ if (signalIndex == -1)
+ return false;
+
+ PySide::SignalManager& signalManager = PySide::SignalManager::instance();
+
+ // Extract receiver from callback
+ QObject* receiver = nullptr;
+ PyObject* self = nullptr;
+ QByteArray callbackSig;
+ bool usingGlobalReceiver = getReceiver(source, signal, callback, &receiver, &self, &callbackSig);
+ if (receiver == nullptr && self == nullptr)
+ return false;
+
+ const QMetaObject* metaObject = receiver->metaObject();
+ const char* slot = callbackSig.constData();
+ int slotIndex = metaObject->indexOfSlot(slot);
+ QMetaMethod signalMethod = metaObject->method(signalIndex);
+
+ if (slotIndex == -1) {
+ if (!usingGlobalReceiver && self && !Shiboken::Object::hasCppWrapper((SbkObject*)self)) {
+ qWarning("You can't add dynamic slots on an object originated from C++.");
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
+ return false;
+ }
+
+ if (usingGlobalReceiver)
+ slotIndex = signalManager.globalReceiverSlotIndex(receiver, slot);
+ else
+ slotIndex = PySide::SignalManager::registerMetaMethodGetIndex(receiver, slot, QMetaMethod::Slot);
+
+ if (slotIndex == -1) {
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
+ return false;
+ }
+ }
+ bool connection;
+ Py_BEGIN_ALLOW_THREADS
+ connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type);
+ Py_END_ALLOW_THREADS
+ if (connection) {
+ if (usingGlobalReceiver)
+ signalManager.notifyGlobalReceiver(receiver);
+ #ifndef AVOID_PROTECTED_HACK
+ source->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char*
+ #else
+ // Need to cast to QObjectWrapper* and call the public version of
+ // connectNotify when avoiding the protected hack.
+ reinterpret_cast<QObjectWrapper*>(source)->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char*
+ #endif
+
+ return connection;
+ }
+
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
+ return false;
+}
+
+
+static bool qobjectDisconnectCallback(QObject* source, const char* signal, PyObject* callback)
+{
+ if (!PySide::Signal::checkQtSignal(signal))
+ return false;
+
+ PySide::SignalManager& signalManager = PySide::SignalManager::instance();
+
+ // Extract receiver from callback
+ QObject* receiver = nullptr;
+ PyObject* self = nullptr;
+ QByteArray callbackSig;
+ QMetaMethod slotMethod;
+ bool usingGlobalReceiver = getReceiver(nullptr, signal, callback, &receiver, &self, &callbackSig);
+ if (receiver == nullptr && self == nullptr)
+ return false;
+
+ const QMetaObject* metaObject = receiver->metaObject();
+ int signalIndex = source->metaObject()->indexOfSignal(++signal);
+ int slotIndex = -1;
+
+ slotIndex = metaObject->indexOfSlot(callbackSig);
+ slotMethod = metaObject->method(slotIndex);
+
+ bool disconnected;
+ Py_BEGIN_ALLOW_THREADS
+ disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex);
+ Py_END_ALLOW_THREADS
+
+ if (disconnected) {
+ if (usingGlobalReceiver)
+ signalManager.releaseGlobalReceiver(source, receiver);
+
+ #ifndef AVOID_PROTECTED_HACK
+ source->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char*
+ #else
+ // Need to cast to QObjectWrapper* and call the public version of
+ // connectNotify when avoiding the protected hack.
+ reinterpret_cast<QObjectWrapper*>(source)->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char*
+ #endif
+ return true;
+ }
+ return false;
+}
+// @snippet qobject-connect
+
+// @snippet qobject-connect-1
+// %FUNCTION_NAME() - disable generation of function call.
+bool %0 = qobjectConnect(%1, %2, %CPPSELF, %3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[bool](%0);
+// @snippet qobject-connect-1
+
+// @snippet qobject-connect-2
+// %FUNCTION_NAME() - disable generation of function call.
+bool %0 = qobjectConnect(%1, %2, %3, %4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[bool](%0);
+// @snippet qobject-connect-2
+
+// @snippet qobject-connect-3
+// %FUNCTION_NAME() - disable generation of function call.
+bool %0 = qobjectConnect(%1, %2, %3, %4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[bool](%0);
+// @snippet qobject-connect-3
+
+// @snippet qobject-connect-4
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = qobjectConnectCallback(%1, %2, %PYARG_3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-4
+
+// @snippet qobject-connect-5
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = qobjectConnectCallback(%CPPSELF, %1, %PYARG_2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-5
+
+// @snippet qobject-connect-6
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = qobjectConnect(%CPPSELF, %1, %2, %3, %4);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-connect-6
+
+// @snippet qobject-emit
+%RETURN_TYPE %0 = PySide::SignalManager::instance().emitSignal(%CPPSELF, %1, %PYARG_2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-emit
+
+// @snippet qobject-disconnect-1
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = qobjectDisconnectCallback(%CPPSELF, %1, %2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-disconnect-1
+
+// @snippet qobject-disconnect-2
+// %FUNCTION_NAME() - disable generation of function call.
+%RETURN_TYPE %0 = qobjectDisconnectCallback(%1, %2, %3);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-disconnect-2
+
+// @snippet qfatal
+// qFatal doesn't have a stream version, so we do a
+// qWarning call followed by a qFatal() call using a
+// literal.
+qWarning() << %1;
+qFatal("[A qFatal() call was made from Python code]");
+// @snippet qfatal
+
+// @snippet moduleshutdown
+PySide::runCleanupFunctions();
+// @snippet moduleshutdown
+
+// @snippet qt-pysideinit
+Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode");
+Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "str");
+Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList");
+
+PySide::registerInternalQtConf();
+PySide::init(module);
+Py_AtExit(QtCoreModuleExit);
+// @snippet qt-pysideinit
+
+// @snippet qt-messagehandler
+// Define a global variable to handle qInstallMessageHandler callback
+static PyObject *qtmsghandler = nullptr;
+
+static void msgHandlerCallback(QtMsgType type, const QMessageLogContext &ctx, const QString &msg)
+{
+ Shiboken::GilState state;
+ Shiboken::AutoDecRef arglist(PyTuple_New(3));
+ PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QtMsgType](type));
+ PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMessageLogContext &](ctx));
+ QByteArray array = msg.toLocal8Bit();
+ char *data = array.data();
+ PyTuple_SET_ITEM(arglist, 2, %CONVERTTOPYTHON[char *](data));
+ Shiboken::AutoDecRef ret(PyObject_CallObject(qtmsghandler, arglist));
+}
+static void QtCoreModuleExit()
+{
+ PySide::SignalManager::instance().clear();
+}
+// @snippet qt-messagehandler
+
+// @snippet qt-installmessagehandler
+if (%PYARG_1 == Py_None) {
+ qInstallMessageHandler(0);
+ %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None;
+ qtmsghandler = 0;
+} else if (!PyCallable_Check(%PYARG_1)) {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+} else {
+ %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None;
+ Py_INCREF(%PYARG_1);
+ qtmsghandler = %PYARG_1;
+ qInstallMessageHandler(msgHandlerCallback);
+}
+
+if (%PYARG_0 == Py_None)
+ Py_INCREF(%PYARG_0);
+// @snippet qt-installmessagehandler
+
+// @snippet qline-hash
+namespace PySide {
+ template<> inline uint hash(const QLine &v) {
+ return qHash(qMakePair(qMakePair(v.x1(), v.y1()), qMakePair(v.x2(), v.y2())));
+ }
+};
+// @snippet qline-hash
+
+// @snippet qlinef-intersect
+QPointF p;
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &p);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QPointF](p));
+// @snippet qlinef-intersect
+
+// @snippet qresource-data
+const void *d = %CPPSELF.%FUNCTION_NAME();
+if (d) {
+ %PYARG_0 = Shiboken::Buffer::newObject(d, %CPPSELF.size());
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qresource-data
+
+// @snippet qdate-topython
+if (!PyDateTimeAPI)
+ PySideDateTime_IMPORT;
+%PYARG_0 = PyDate_FromDate(%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day());
+// @snippet qdate-topython
+
+// @snippet qdate-getdate
+int year, month, day;
+%BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(&year, &month, &day);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](year));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](month));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](day));
+// @snippet qdate-getdate
+
+// @snippet qdate-weeknumber
+int yearNumber;
+%BEGIN_ALLOW_THREADS
+int week = %CPPSELF.%FUNCTION_NAME(&yearNumber);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](week));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](yearNumber));
+// @snippet qdate-weeknumber
+
+// @snippet qdatetime-1
+QDate date(%1, %2, %3);
+QTime time(%4, %5, %6, %7);
+%0 = new %TYPE(date, time, Qt::TimeSpec(%8));
+// @snippet qdatetime-1
+
+// @snippet qdatetime-2
+QDate date(%1, %2, %3);
+QTime time(%4, %5, %6);
+%0 = new %TYPE(date, time);
+// @snippet qdatetime-2
+
+// @snippet qdatetime-topython
+QDate date = %CPPSELF.date();
+QTime time = %CPPSELF.time();
+if (!PyDateTimeAPI) PySideDateTime_IMPORT;
+%PYARG_0 = PyDateTime_FromDateAndTime(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.msec()*1000);
+// @snippet qdatetime-topython
+
+// @snippet qpoint
+namespace PySide {
+ template<> inline uint hash(const QPoint &v) {
+ return qHash(qMakePair(v.x(), v.y()));
+ }
+};
+// @snippet qpoint
+
+// @snippet qrect
+namespace PySide {
+ template<> inline uint hash(const QRect &v) {
+ return qHash(qMakePair(qMakePair(v.x(), v.y()), qMakePair(v.width(), v.height())));
+ }
+};
+// @snippet qrect
+
+// @snippet qsize
+namespace PySide {
+ template<> inline uint hash(const QSize &v) {
+ return qHash(qMakePair(v.width(), v.height()));
+ }
+};
+// @snippet qsize
+
+// @snippet qtime-topython
+if (!PyDateTimeAPI)
+ PySideDateTime_IMPORT;
+%PYARG_0 = PyTime_FromTime(%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()*1000);
+// @snippet qtime-topython
+
+// @snippet qbitarray-len
+return %CPPSELF.size();
+// @snippet qbitarray-len
+
+// @snippet qbitarray-getitem
+if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+}
+bool ret = %CPPSELF.at(_i);
+return %CONVERTTOPYTHON[bool](ret);
+// @snippet qbitarray-getitem
+
+// @snippet qbitarray-setitem
+PyObject *args = Py_BuildValue("(iiO)", _i, 1, _value);
+PyObject *result = Sbk_QBitArrayFunc_setBit(self, args);
+Py_DECREF(args);
+Py_XDECREF(result);
+return !result ? -1 : 0;
+// @snippet qbitarray-setitem
+
+// @snippet unlock
+%CPPSELF.unlock();
+// @snippet unlock
+
+// @snippet qabstractitemmodel-createindex
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, %PYARG_3);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qabstractitemmodel-createindex
+
+// @snippet qabstractitemmodel
+qRegisterMetaType<QVector<int> >("QVector<int>");
+// @snippet qabstractitemmodel
+
+// @snippet qobject-metaobject
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME();
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qobject-metaobject
+
+// @snippet qobject-findchild-1
+static QObject* _findChildHelper(const QObject* parent, const QString& name, PyTypeObject* desiredType)
+{
+ for (auto *child : parent->children()) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child));
+ if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType)
+ && (name.isNull() || name == child->objectName())) {
+ return child;
+ }
+ }
+
+ for (auto *child : parent->children()) {
+ QObject *obj = _findChildHelper(child, name, desiredType);
+ if (obj)
+ return obj;
+ }
+ return nullptr;
+}
+
+static inline bool _findChildrenComparator(const QObject*& child, const QRegExp& name)
+{
+ return name.indexIn(child->objectName()) != -1;
+}
+
+static inline bool _findChildrenComparator(const QObject*& child, const QString& name)
+{
+ return name.isNull() || name == child->objectName();
+}
+
+template<typename T>
+static void _findChildrenHelper(const QObject* parent, const T& name, PyTypeObject* desiredType, PyObject* result)
+{
+ for (const auto *child : parent->children()) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child));
+ if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) && _findChildrenComparator(child, name))
+ PyList_Append(result, pyChild);
+ _findChildrenHelper(child, name, desiredType, result);
+ }
+}
+// @snippet qobject-findchild-1
+
+// @snippet qobject-findchild-2
+QObject *child = _findChildHelper(%CPPSELF, %2, (PyTypeObject*)%PYARG_1);
+%PYARG_0 = %CONVERTTOPYTHON[QObject*](child);
+// @snippet qobject-findchild-2
+
+// @snippet qobject-findchildren-1
+%PYARG_0 = PyList_New(0);
+_findChildrenHelper(%CPPSELF, %2, (PyTypeObject*)%PYARG_1, %PYARG_0);
+// @snippet qobject-findchildren-1
+
+// @snippet qobject-findchildren-2
+%PYARG_0 = PyList_New(0);
+_findChildrenHelper(%CPPSELF, %2, (PyTypeObject*)%PYARG_1, %PYARG_0);
+// @snippet qobject-findchildren-2
+
+// @snippet qobject-tr
+QString result;
+if (QCoreApplication::instance()) {
+ PyObject *klass = PyObject_GetAttrString(%PYSELF, "__class__");
+ PyObject *cname = PyObject_GetAttrString(klass, "__name__");
+ result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname),
+ /* %1, %2, QCoreApplication::CodecForTr, %3)); */
+ %1, %2, %3));
+
+ Py_DECREF(klass);
+ Py_DECREF(cname);
+} else {
+ result = QString(QString::fromLatin1(%1));
+}
+%PYARG_0 = %CONVERTTOPYTHON[QString](result);
+// @snippet qobject-tr
+
+// @snippet qobject-receivers
+// Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife
+int ret = %CPPSELF.%FUNCTION_NAME(%1);
+if (ret > 0 && ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0)))
+ ret -= PySide::SignalManager::instance().countConnectionsWith(%CPPSELF);
+
+%PYARG_0 = %CONVERTTOPYTHON[int](ret);
+// @snippet qobject-receivers
+
+// @snippet qregexp-replace
+%1.replace(*%CPPSELF, %2);
+%PYARG_0 = %CONVERTTOPYTHON[QString](%1);
+// @snippet qregexp-replace
+
+// @snippet qbytearray-mgetitem
+if (PyIndex_Check(_key)) {
+ Py_ssize_t _i;
+ _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
+ if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+ } else {
+ char res[2];
+ res[0] = %CPPSELF.at(_i);
+ res[1] = 0;
+ return PyBytes_FromStringAndSize(res, 1);
+ }
+} else if (PySlice_Check(_key)) {
+ Py_ssize_t start, stop, step, slicelength, cur;
+
+#ifdef IS_PY3K
+ PyObject *key = _key;
+#else
+ PySliceObject *key = reinterpret_cast<PySliceObject *>(_key);
+#endif
+ if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) {
+ return nullptr;
+ }
+
+ QByteArray ba;
+ if (slicelength <= 0) {
+ return %CONVERTTOPYTHON[QByteArray](ba);
+ } else if (step == 1) {
+ Py_ssize_t max = %CPPSELF.count();
+ start = qBound(Py_ssize_t(0), start, max);
+ stop = qBound(Py_ssize_t(0), stop, max);
+ QByteArray ba;
+ if (start < stop)
+ ba = %CPPSELF.mid(start, stop - start);
+ return %CONVERTTOPYTHON[QByteArray](ba);
+ } else {
+ QByteArray ba;
+ for (cur = start; slicelength > 0; cur += static_cast<size_t>(step), slicelength--) {
+ ba.append(%CPPSELF.at(cur));
+ }
+ return %CONVERTTOPYTHON[QByteArray](ba);
+ }
+} else {
+ PyErr_Format(PyExc_TypeError,
+ "list indices must be integers or slices, not %.200s",
+ Py_TYPE(_key)->tp_name);
+ return nullptr;
+}
+// @snippet qbytearray-mgetitem
+
+// @snippet qbytearray-msetitem
+if (PyIndex_Check(_key)) {
+ Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
+ if (_i == -1 && PyErr_Occurred())
+ return -1;
+
+ if (_i < 0)
+ _i += %CPPSELF.count();
+
+ if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "QByteArray index out of range");
+ return -1;
+ }
+
+ // Provide more specific error message for bytes/str, bytearray, QByteArray respectively
+#ifdef IS_PY3K
+ if (PyBytes_Check(_value)) {
+ if (Py_SIZE(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "bytes must be of size 1");
+#else
+ if (PyString_CheckExact(_value)) {
+ if (Py_SIZE(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "str must be of size 1");
+#endif
+ return -1;
+ }
+ } else if (PyByteArray_Check(_value)) {
+ if (Py_SIZE(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "bytearray must be of size 1");
+ return -1;
+ }
+ } else if (reinterpret_cast<PyTypeObject *>(Py_TYPE(_value)) == reinterpret_cast<PyTypeObject *>(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX])) {
+ if (PyObject_Length(_value) != 1) {
+ PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1");
+ return -1;
+ }
+ } else {
+#ifdef IS_PY3K
+ PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required");
+#else
+ PyErr_SetString(PyExc_ValueError, "a str, bytearray, QByteArray of size 1 is required");
+#endif
+ return -1;
+ }
+
+ // Not support int or long.
+ %CPPSELF.remove(_i, 1);
+ PyObject *args = Py_BuildValue("(nO)", _i, _value);
+ PyObject *result = Sbk_QByteArrayFunc_insert(self, args);
+ Py_DECREF(args);
+ Py_XDECREF(result);
+ return !result ? -1 : 0;
+} else if (PySlice_Check(_key)) {
+ Py_ssize_t start, stop, step, slicelength, value_length;
+
+#ifdef IS_PY3K
+ PyObject *key = _key;
+#else
+ PySliceObject *key = reinterpret_cast<PySliceObject *>(_key);
+#endif
+ if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) {
+ return -1;
+ }
+ // The parameter candidates are: bytes/str, bytearray, QByteArray itself.
+ // Not support iterable which contains ints between 0~255
+
+ // case 1: value is nullpre, means delete the items within the range
+ // case 2: step is 1, means shrink or expanse
+ // case 3: step is not 1, then the number of slots have to equal the number of items in _value
+ QByteArray ba;
+ if (_value == nullptr || _value == Py_None) {
+ ba = QByteArray();
+ value_length = 0;
+ } else if (!(PyBytes_Check(_value) || PyByteArray_Check(_value) || reinterpret_cast<PyTypeObject *>(Py_TYPE(_value)) == reinterpret_cast<PyTypeObject *>(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX]))) {
+ PyErr_Format(PyExc_TypeError, "bytes, bytearray or QByteArray is required, not %.200s", Py_TYPE(_value)->tp_name);
+ return -1;
+ } else {
+ value_length = PyObject_Length(_value);
+ }
+
+ if (step != 1 && value_length != slicelength) {
+ PyErr_Format(PyExc_ValueError, "attempt to assign %s of size %d to extended slice of size %d",Py_TYPE(_value)->tp_name, value_length, slicelength);
+ return -1;
+ }
+
+ if (step != 1) {
+ int i = start;
+ for (int j = 0; j < slicelength; j++) {
+ PyObject *item = PyObject_GetItem(_value, PyLong_FromLong(j));
+ QByteArray temp;
+#ifdef IS_PY3K
+ if (PyLong_Check(item)) {
+#else
+ if (PyLong_Check(item) || PyInt_Check(item)) {
+#endif
+ int overflow;
+ long ival = PyLong_AsLongAndOverflow(item, &overflow);
+ // Not suppose to bigger than 255 because only bytes, bytearray, QByteArray were accept
+ const char *el = reinterpret_cast<const char*>(&ival);
+ temp = QByteArray(el);
+ } else {
+ temp = %CONVERTTOCPP[QByteArray](item);
+ }
+
+ %CPPSELF.replace(i, 1, temp);
+ i += step;
+ }
+ return 0;
+ } else {
+ ba = %CONVERTTOCPP[QByteArray](_value);
+ %CPPSELF.replace(start, slicelength, ba);
+ return 0;
+ }
+} else {
+ PyErr_Format(PyExc_TypeError, "QBytearray indices must be integers or slices, not %.200s",
+ Py_TYPE(_key)->tp_name);
+ return -1;
+}
+// @snippet qbytearray-msetitem
+
+// @snippet qbytearray-bufferprotocol
+#if PY_VERSION_HEX < 0x03000000
+
+// QByteArray buffer protocol functions
+// see: http://www.python.org/dev/peps/pep-3118/
+
+extern "C" {
+
+static Py_ssize_t SbkQByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp)
+{
+ if (lenp)
+ *lenp = Py_TYPE(self)->tp_as_sequence->sq_length(self);
+ return 1;
+}
+
+static Py_ssize_t SbkQByteArray_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr)
+{
+ if (segment || !Shiboken::Object::isValid(self))
+ return -1;
+
+ QByteArray* cppSelf = %CONVERTTOCPP[QByteArray*](self);
+ *ptrptr = reinterpret_cast<void*>(cppSelf->data());
+ return cppSelf->size();
+}
+
+PyBufferProcs SbkQByteArrayBufferProc = {
+ /*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc,
+ /*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc,
+ /*bf_getsegcount*/ &SbkQByteArray_segcountproc,
+ /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc
+};
+
+}
+
+#endif
+// @snippet qbytearray-bufferprotocol
+
+// @snippet qbytearray-operatorplus-1
+QByteArray ba = QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)) + *%CPPSELF;
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-operatorplus-1
+
+// @snippet qbytearray-operatorplus-2
+QByteArray ba = QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)) + *%CPPSELF;
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-operatorplus-2
+
+// @snippet qbytearray-operatorplus-3
+QByteArray ba = *%CPPSELF + QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
+%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+// @snippet qbytearray-operatorplus-3
+
+// @snippet qbytearray-operatorplusequal
+*%CPPSELF += QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
+// @snippet qbytearray-operatorplusequal
+
+// @snippet qbytearray-operatorequalequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF == ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorequalequal
+
+// @snippet qbytearray-operatornotequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF != ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatornotequal
+
+// @snippet qbytearray-operatorgreater
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF > ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorgreater
+
+// @snippet qbytearray-operatorgreaterequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF >= ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorgreaterequal
+
+// @snippet qbytearray-operatorlower
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF < ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorlower
+
+// @snippet qbytearray-operatorlowerequal
+if (PyUnicode_CheckExact(%PYARG_1)) {
+ Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1));
+ QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object()));
+ bool cppResult = %CPPSELF <= ba;
+ %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult);
+}
+// @snippet qbytearray-operatorlowerequal
+
+// @snippet qbytearray-repr
+PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size());
+if (aux == nullptr) {
+ return nullptr;
+}
+QByteArray b(Py_TYPE(%PYSELF)->tp_name);
+#ifdef IS_PY3K
+ %PYARG_0 = PyUnicode_FromFormat("%s(%R)", b.constData(), aux);
+#else
+ aux = PyObject_Repr(aux);
+ b += '(';
+ b += QByteArray(PyBytes_AS_STRING(aux), PyBytes_GET_SIZE(aux));
+ b += ')';
+ %PYARG_0 = Shiboken::String::fromStringAndSize(b.constData(), b.size());
+#endif
+Py_DECREF(aux);
+// @snippet qbytearray-repr
+
+// @snippet qbytearray-1
+if (PyBytes_Check(%PYARG_1)) {
+ %0 = new QByteArray(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
+} else if (Shiboken::String::check(%PYARG_1)) {
+ %0 = new QByteArray(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1));
+}
+// @snippet qbytearray-1
+
+// @snippet qbytearray-2
+%0 = new QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1));
+// @snippet qbytearray-2
+
+// @snippet qbytearray-3
+%0 = new QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
+// @snippet qbytearray-3
+
+// @snippet qbytearray-py3
+#if PY_VERSION_HEX < 0x03000000
+ Shiboken::SbkType<QByteArray>()->tp_as_buffer = &SbkQByteArrayBufferProc;
+ Shiboken::SbkType<QByteArray>()->tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER;
+#endif
+// @snippet qbytearray-py3
+
+// @snippet qbytearray-data
+%PYARG_0 = PyBytes_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size());
+// @snippet qbytearray-data
+
+// @snippet qbytearray-fromrawdata
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qbytearray-fromrawdata
+
+// @snippet qbytearray-str
+PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size());
+if (aux == nullptr) {
+ return nullptr;
+}
+#ifdef IS_PY3K
+ %PYARG_0 = PyObject_Repr(aux);
+ Py_DECREF(aux);
+#else
+ %PYARG_0 = aux;
+#endif
+// @snippet qbytearray-str
+
+// @snippet qbytearray-len
+return %CPPSELF.count();
+// @snippet qbytearray-len
+
+// @snippet qbytearray-getitem
+if (_i < 0 || _i >= %CPPSELF.size()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+} else {
+ char res[2];
+ res[0] = %CPPSELF.at(_i);
+ res[1] = 0;
+ return PyBytes_FromStringAndSize(res, 1);
+}
+// @snippet qbytearray-getitem
+
+// @snippet qbytearray-setitem
+%CPPSELF.remove(_i, 1);
+PyObject *args = Py_BuildValue("(nO)", _i, _value);
+PyObject *result = Sbk_QByteArrayFunc_insert(self, args);
+Py_DECREF(args);
+Py_XDECREF(result);
+return !result ? -1 : 0;
+// @snippet qbytearray-setitem
+
+// @snippet qfiledevice-unmap
+uchar *ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ptr);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qfiledevice-unmap
+
+// @snippet qfiledevice-map
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1, %2, %3), %2, Shiboken::Buffer::ReadWrite);
+// @snippet qfiledevice-map
+
+// @snippet qiodevice-readdata
+QByteArray ba(1 + int(%2), char(0));
+%CPPSELF.%FUNCTION_NAME(ba.data(), int(%2));
+%PYARG_0 = Shiboken::String::fromCString(ba.constData());
+// @snippet qiodevice-readdata
+
+// @snippet qcryptographichash-adddata
+%CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1));
+// @snippet qcryptographichash-adddata
+
+// @snippet qsocketnotifier
+Shiboken::AutoDecRef socket(%PYARG_1);
+if (!socket.isNull()) {
+ // We use qintptr as PyLong, but we check for int
+ // since it is currently an alias to be Python2 compatible.
+ // Internally, ints are qlonglongs.
+ if (%CHECKTYPE[int](socket)) {
+ int cppSocket = %CONVERTTOCPP[int](socket);
+ qintptr socket = (qintptr)cppSocket;
+ %0 = new %TYPE(socket, %2, %3);
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "QSocketNotifier: first argument (socket) must be an int.");
+ }
+}
+// @snippet qsocketnotifier
+
+// @snippet qtranslator-load
+Py_ssize_t size;
+uchar *ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1, &size));
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast<const uchar*>(ptr), size);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qtranslator-load
+
+// @snippet qtimer-singleshot-1
+// %FUNCTION_NAME() - disable generation of c++ function call
+(void) %2; // remove warning about unused variable
+Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+PyObject *pyTimer = reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, 0);
+reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_init(pyTimer, emptyTuple, 0);
+
+QTimer* timer = %CONVERTTOCPP[QTimer*](pyTimer);
+Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer,
+ const_cast<char*>("connect"),
+ const_cast<char*>("OsOs"),
+ pyTimer,
+ SIGNAL(timeout()),
+ %PYARG_2,
+ %3)
+);
+Shiboken::Object::releaseOwnership((SbkObject*)pyTimer);
+Py_XDECREF(pyTimer);
+timer->setSingleShot(true);
+timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()));
+timer->start(%1);
+// @snippet qtimer-singleshot-1
+
+// @snippet qtimer-singleshot-2
+// %FUNCTION_NAME() - disable generation of c++ function call
+Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
+PyObject *pyTimer = reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, 0);
+reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_init(pyTimer, emptyTuple, 0);
+QTimer* timer = %CONVERTTOCPP[QTimer*](pyTimer);
+timer->setSingleShot(true);
+
+if (PyObject_TypeCheck(%2, PySideSignalInstanceTypeF())) {
+ PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance*>(%2);
+ Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance)));
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer,
+ const_cast<char*>("connect"),
+ const_cast<char*>("OsOO"),
+ pyTimer,
+ SIGNAL(timeout()),
+ PySide::Signal::getObject(signalInstance),
+ signalSignature.object())
+ );
+} else {
+ Shiboken::AutoDecRef result(
+ PyObject_CallMethod(pyTimer,
+ const_cast<char*>("connect"),
+ const_cast<char*>("OsO"),
+ pyTimer,
+ SIGNAL(timeout()),
+ %PYARG_2)
+ );
+}
+
+timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()), Qt::DirectConnection);
+Shiboken::Object::releaseOwnership((SbkObject*)pyTimer);
+Py_XDECREF(pyTimer);
+timer->start(%1);
+// @snippet qtimer-singleshot-2
+
+// @snippet qprocess-startdetached
+qint64 pid;
+%RETURN_TYPE retval = %TYPE::%FUNCTION_NAME(%1, %2, %3, &pid);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[qint64](pid));
+// @snippet qprocess-startdetached
+
+// @snippet qprocess-pid
+long result;
+#ifdef WIN32
+ _PROCESS_INFORMATION *procInfo = %CPPSELF.%FUNCTION_NAME();
+ result = procInfo ? procInfo->dwProcessId : 0;
+#else
+ result = %CPPSELF.%FUNCTION_NAME();
+#endif
+%PYARG_0 = %CONVERTTOPYTHON[long](result);
+// @snippet qprocess-pid
+
+// @snippet qcoreapplication-init
+static void QCoreApplicationConstructor(PyObject *self, PyObject *pyargv, QCoreApplicationWrapper **cptr)
+{
+ static int argc;
+ static char **argv;
+ PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
+ if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
+ *cptr = new QCoreApplicationWrapper(argc, argv);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self));
+ PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
+ }
+}
+// @snippet qcoreapplication-init
+
+// @snippet qcoreapplication-1
+QCoreApplicationConstructor(%PYSELF, args, &%0);
+// @snippet qcoreapplication-1
+
+// @snippet qcoreapplication-2
+PyObject *empty = PyTuple_New(2);
+if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
+ QCoreApplicationConstructor(%PYSELF, empty, &%0);
+}
+// @snippet qcoreapplication-2
+
+// @snippet qcoreapplication-instance
+QCoreApplication *app = QCoreApplication::instance();
+PyObject *pyApp = Py_None;
+if (app) {
+ pyApp = reinterpret_cast<PyObject*>(
+ Shiboken::BindingManager::instance().retrieveWrapper(app));
+ if (!pyApp)
+ pyApp = %CONVERTTOPYTHON[QCoreApplication*](app);
+ // this will keep app live after python exit (extra ref)
+}
+// PYSIDE-571: make sure that we return the singleton "None"
+if (pyApp == Py_None)
+ Py_DECREF(MakeSingletonQAppWrapper(0)); // here qApp and instance() diverge
+%PYARG_0 = pyApp;
+Py_XINCREF(%PYARG_0);
+// @snippet qcoreapplication-instance
+
+// @snippet qdatastream-readrawdata
+QByteArray data;
+data.resize(%2);
+int result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size());
+if (result == -1) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else {
+ %PYARG_0 = PyBytes_FromStringAndSize(data.data(), result);
+}
+// @snippet qdatastream-readrawdata
+
+// @snippet qdatastream-writerawdata
+int r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1));
+%PYARG_0 = %CONVERTTOPYTHON[int](r);
+// @snippet qdatastream-writerawdata
+
+// @snippet releaseownership
+Shiboken::Object::releaseOwnership(%PYARG_0);
+// @snippet releaseownership
+
+// @snippet qanimationgroup-clear
+for (int counter = 0, count = %CPPSELF.animationCount(); counter < count; ++counter ) {
+ QAbstractAnimation *animation = %CPPSELF.animationAt(counter);
+ PyObject *obj = %CONVERTTOPYTHON[QAbstractAnimation*](animation);
+ Shiboken::Object::setParent(nullptr, obj);
+ Py_DECREF(obj);
+}
+%CPPSELF.clear();
+// @snippet qanimationgroup-clear
+
+// @snippet qeasingcurve
+PySideEasingCurveFunctor::init();
+// @snippet qeasingcurve
+
+// @snippet qeasingcurve-setcustomtype
+QEasingCurve::EasingFunction func = PySideEasingCurveFunctor::createCustomFuntion(%PYSELF, %PYARG_1);
+if (func)
+ %CPPSELF.%FUNCTION_NAME(func);
+// @snippet qeasingcurve-setcustomtype
+
+// @snippet qeasingcurve-customtype
+//%FUNCTION_NAME()
+%PYARG_0 = PySideEasingCurveFunctor::callable(%PYSELF);
+// @snippet qeasingcurve-customtype
+
+// @snippet qsignaltransition
+if (PyObject_TypeCheck(%1, PySideSignalInstanceTypeF())) {
+ PyObject *dataSource = PySide::Signal::getObject((PySideSignalInstance*)%PYARG_1);
+ Shiboken::AutoDecRef obType(PyObject_Type(dataSource));
+ QObject* sender = %CONVERTTOCPP[QObject*](dataSource);
+ if (sender) {
+ const char*dataSignature = PySide::Signal::getSignature((PySideSignalInstance*)%PYARG_1);
+ QByteArray signature(dataSignature); // Append SIGNAL flag (2)
+ signature.prepend('2');
+ %0 = new QSignalTransitionWrapper(sender, signature, %2);
+ }
+}
+// @snippet qsignaltransition
+
+// @snippet qstate-addtransition-1
+QString signalName(%2);
+if (PySide::SignalManager::registerMetaMethod(%1, signalName.mid(1).toLatin1().data(), QMetaMethod::Signal)) {
+ QSignalTransition *%0 = %CPPSELF->addTransition(%1, %2, %3);
+ %PYARG_0 = %CONVERTTOPYTHON[QSignalTransition*](%0);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qstate-addtransition-1
+
+// @snippet qstate-addtransition-2
+// Obviously the label used by the following goto is a very awkward solution,
+// since it refers to a name very tied to the generator implementation.
+// Check bug #362 for more information on this
+// http://bugs.openbossa.org/show_bug.cgi?id=362
+if (!PyObject_TypeCheck(%1, PySideSignalInstanceTypeF()))
+ goto Sbk_%TYPEFunc_%FUNCTION_NAME_TypeError;
+PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance*>(%1);
+QObject* sender = %CONVERTTOCPP[QObject*](PySide::Signal::getObject(signalInstance));
+QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2);
+%PYARG_0 = %CONVERTTOPYTHON[QSignalTransition*](%0);
+// @snippet qstate-addtransition-2
+
+// @snippet qstatemachine-configuration
+%PYARG_0 = PySet_New(0);
+for (auto *abs_state : %CPPSELF.configuration()) {
+ Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractState*](abs_state));
+ Shiboken::Object::setParent(self, obj);
+ PySet_Add(%PYARG_0, obj);
+}
+// @snippet qstatemachine-configuration
+
+// @snippet qstatemachine-defaultanimations
+%PYARG_0 = PyList_New(0);
+for (auto *abs_anim : %CPPSELF.defaultAnimations()) {
+ Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractAnimation*](abs_anim));
+ Shiboken::Object::setParent(self, obj);
+ PyList_Append(%PYARG_0, obj);
+}
+// @snippet qstatemachine-defaultanimations
+
+// @snippet qt-signal
+%PYARG_0 = Shiboken::String::fromFormat("2%s",QMetaObject::normalizedSignature(%1).constData());
+// @snippet qt-signal
+
+// @snippet qt-slot
+%PYARG_0 = Shiboken::String::fromFormat("1%s",QMetaObject::normalizedSignature(%1).constData());
+// @snippet qt-slot
+
+// @snippet qt-registerresourcedata
+QT_BEGIN_NAMESPACE
+extern bool
+qRegisterResourceData(int,
+ const unsigned char *,
+ const unsigned char *,
+ const unsigned char *);
+
+extern bool
+qUnregisterResourceData(int,
+ const unsigned char *,
+ const unsigned char *,
+ const unsigned char *);
+QT_END_NAMESPACE
+// @snippet qt-registerresourcedata
+
+// @snippet qt-qregisterresourcedata
+%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast<uchar*>(PyBytes_AS_STRING(%PYARG_2)),
+ reinterpret_cast<uchar*>(PyBytes_AS_STRING(%PYARG_3)),
+ reinterpret_cast<uchar*>(PyBytes_AS_STRING(%PYARG_4)));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qt-qregisterresourcedata
+
+// @snippet qt-qunregisterresourcedata
+%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast<uchar*>(PyBytes_AS_STRING(%PYARG_2)),
+ reinterpret_cast<uchar*>(PyBytes_AS_STRING(%PYARG_3)),
+ reinterpret_cast<uchar*>(PyBytes_AS_STRING(%PYARG_4)));
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qt-qunregisterresourcedata
+
+// @snippet use-stream-for-format-security
+// Uses the stream version for security reasons
+// see gcc man page at -Wformat-security
+%FUNCTION_NAME() << %1;
+// @snippet use-stream-for-format-security
+
+// @snippet qresource-registerResource
+ auto ptr = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_1));
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast<const uchar*>(ptr), %2);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet qresource-registerResource
+
+// @snippet qstring-return
+%PYARG_0 = %CONVERTTOPYTHON[QString](%1);
+// @snippet qstring-return
+
+// @snippet stream-write-method
+(*%CPPSELF) << %1;
+// @snippet stream-write-method
+
+// @snippet stream-read-method
+%RETURN_TYPE _cpp_result;
+(*%CPPSELF) >> _cpp_result;
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](_cpp_result);
+// @snippet stream-read-method
+
+// @snippet return-qstring-ref
+QString &res = *%0;
+%PYARG_0 = %CONVERTTOPYTHON[QString](res);
+// @snippet return-qstring-ref
+
+// @snippet return-readData
+%RETURN_TYPE %0 = 0;
+if (PyBytes_Check(%PYARG_0)) {
+ %0 = PyBytes_GET_SIZE((PyObject*)%PYARG_0);
+ memcpy(%1, PyBytes_AS_STRING((PyObject*)%PYARG_0), %0);
+} else if (Shiboken::String::check(%PYARG_0)) {
+ %0 = Shiboken::String::len((PyObject*)%PYARG_0);
+ memcpy(%1, Shiboken::String::toCString((PyObject*)%PYARG_0), %0);
+}
+// @snippet return-readData
+
+// @snippet qiodevice-readData
+QByteArray ba(1 + int(%2), char(0));
+%CPPSELF.%FUNCTION_NAME(ba.data(), int(%2));
+%PYARG_0 = Shiboken::String::fromCString(ba.constData());
+// @snippet qiodevice-readData
+
+// @snippet qt-module-shutdown
+{ // Avoid name clash
+ Shiboken::AutoDecRef regFunc((PyObject*)NULL);
+ Shiboken::AutoDecRef atexit(Shiboken::Module::import("atexit"));
+ if (atexit.isNull()) {
+ qWarning("Module atexit not found for registering __moduleShutdown");
+ PyErr_Clear();
+ }else{
+ regFunc.reset(PyObject_GetAttrString(atexit, "register"));
+ if (regFunc.isNull()) {
+ qWarning("Function atexit.register not found for registering __moduleShutdown");
+ PyErr_Clear();
+ }
+ }
+ if (!atexit.isNull() && !regFunc.isNull()){
+ PyObject *shutDownFunc = PyObject_GetAttrString(module, "__moduleShutdown");
+ Shiboken::AutoDecRef args(PyTuple_New(1));
+ PyTuple_SET_ITEM(args, 0, shutDownFunc);
+ Shiboken::AutoDecRef retval(PyObject_Call(regFunc, args, 0));
+ Q_ASSERT(!retval.isNull());
+ }
+}
+// @snippet qt-module-shutdown
+
+
+/*********************************************************************
+ * CONVERSIONS
+ ********************************************************************/
+
+// @snippet conversion-pybool
+%out = %OUTTYPE(%in == Py_True);
+// @snippet conversion-pybool
+
+// @snippet conversion-pylong
+%out = %OUTTYPE(PyLong_AsLong(%in));
+// @snippet conversion-pylong
+
+// @snippet conversion-pylong-unsigned
+%out = %OUTTYPE(PyLong_AsUnsignedLong(%in));
+// @snippet conversion-pylong-unsigned
+
+// @snippet conversion-pyunicode
+#ifndef Py_LIMITED_API
+Py_UNICODE* unicode = PyUnicode_AS_UNICODE(%in);
+# if defined(Py_UNICODE_WIDE)
+// cast as Py_UNICODE can be a different type
+%out = QString::fromUcs4((const uint*)unicode);
+# else
+%out = QString::fromUtf16((const ushort*)unicode, PyUnicode_GET_SIZE(%in));
+# endif
+#else
+wchar_t *temp = PyUnicode_AsWideCharString(%in, NULL);
+%out = QString::fromWCharArray(temp);
+PyMem_Free(temp);
+#endif
+// @snippet conversion-pyunicode
+
+// @snippet conversion-pystring
+#ifndef IS_PY3K
+const char* str = %CONVERTTOCPP[const char*](%in);
+%out = %OUTTYPE(str);
+#endif
+// @snippet conversion-pystring
+
+// @snippet conversion-pynone
+%out = %OUTTYPE();
+// @snippet conversion-pynone
+
+// @snippet conversion-pystring-char
+char c = %CONVERTTOCPP[char](%in);
+%out = %OUTTYPE(c);
+// @snippet conversion-pystring-char
+
+// @snippet conversion-pyint
+int i = %CONVERTTOCPP[int](%in);
+%out = %OUTTYPE(i);
+// @snippet conversion-pyint
+
+// @snippet conversion-qlonglong
+qlonglong in = %CONVERTTOCPP[qlonglong](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-qlonglong
+
+// @snippet conversion-qstring
+QString in = %CONVERTTOCPP[QString](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-qstring
+
+// @snippet conversion-qbytearray
+QByteArray in = %CONVERTTOCPP[QByteArray](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-qbytearray
+
+// @snippet conversion-pyfloat
+double in = %CONVERTTOCPP[double](%in);
+%out = %OUTTYPE(in);
+// @snippet conversion-pyfloat
+
+// @snippet conversion-sbkobject
+// a class supported by QVariant?
+int typeCode;
+const char *typeName = QVariant_resolveMetaType(Py_TYPE(%in), &typeCode);
+if (!typeCode || !typeName)
+ return;
+QVariant var(typeCode, (void*)0);
+Shiboken::Conversions::SpecificConverter converter(typeName);
+converter.toCpp(pyIn, var.data());
+%out = var;
+// @snippet conversion-sbkobject
+
+// @snippet conversion-pydict
+QVariant ret = QVariant_convertToVariantMap(%in);
+%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-pydict
+
+// @snippet conversion-pylist
+QVariant ret = QVariant_convertToVariantList(%in);
+%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-pylist
+
+// @snippet conversion-pyobject
+// Is a shiboken type not known by Qt
+%out = QVariant::fromValue(PySide::PyObjectWrapper(%in));
+// @snippet conversion-pyobject
+
+// @snippet conversion-qvariant-invalid
+%out = QVariant::Invalid;
+// @snippet conversion-qvariant-invalid
+
+// @snippet conversion-qvariant-pytypeobject
+const char *typeName;
+if (Shiboken::String::checkType(reinterpret_cast<PyTypeObject *>(%in)))
+ typeName = "QString";
+else if (%in == reinterpret_cast<PyObject*>(&PyFloat_Type))
+ typeName = "double"; // float is a UserType in QVariant.
+else if (%in == reinterpret_cast<PyObject*>(&PyLong_Type))
+ typeName = "int"; // long is a UserType in QVariant.
+else if (Py_TYPE(%in) == SbkObjectType_TypeF())
+ typeName = Shiboken::ObjectType::getOriginalName((SbkObjectType*)%in);
+else
+ typeName = reinterpret_cast<PyTypeObject *>(%in)->tp_name;
+%out = QVariant::nameToType(typeName);
+// @snippet conversion-qvariant-pytypeobject
+
+// @snippet conversion-qvariant-pystring
+%out = QVariant::nameToType(Shiboken::String::toCString(%in));
+// @snippet conversion-qvariant-pystring
+
+// @snippet conversion-qvariant-pydict
+%out = QVariant::nameToType("QVariantMap");
+// @snippet conversion-qvariant-pydict
+
+// @snippet conversion-qvariant-pysequence
+%out = QVariantType_isStringList(%in) ? QVariant::StringList : QVariant::List;
+// @snippet conversion-qvariant-pysequence
+
+// @snippet conversion-qjsonobject-pydict
+QVariant dict = QVariant_convertToVariantMap(%in);
+QJsonValue val = QJsonValue::fromVariant(dict);
+%out = val.toObject();
+// @snippet conversion-qjsonobject-pydict
+
+// @snippet conversion-qpair-pysequence
+%out.first = %CONVERTTOCPP[%OUTTYPE_0](PySequence_Fast_GET_ITEM(%in, 0));
+%out.second = %CONVERTTOCPP[%OUTTYPE_1](PySequence_Fast_GET_ITEM(%in, 1));
+// @snippet conversion-qpair-pysequence
+
+// @snippet conversion-qdate-pydate
+int day = PyDateTime_GET_DAY(%in);
+int month = PyDateTime_GET_MONTH(%in);
+int year = PyDateTime_GET_YEAR(%in);
+%out = %OUTTYPE(year, month, day);
+// @snippet conversion-qdate-pydate
+
+// @snippet conversion-qdatetime-pydatetime
+int day = PyDateTime_GET_DAY(%in);
+int month = PyDateTime_GET_MONTH(%in);
+int year = PyDateTime_GET_YEAR(%in);
+int hour = PyDateTime_DATE_GET_HOUR(%in);
+int min = PyDateTime_DATE_GET_MINUTE(%in);
+int sec = PyDateTime_DATE_GET_SECOND(%in);
+int usec = PyDateTime_DATE_GET_MICROSECOND(%in);
+%out = %OUTTYPE(QDate(year, month, day), QTime(hour, min, sec, usec/1000));
+// @snippet conversion-qdatetime-pydatetime
+
+// @snippet conversion-qtime-pytime
+int hour = PyDateTime_TIME_GET_HOUR(%in);
+int min = PyDateTime_TIME_GET_MINUTE(%in);
+int sec = PyDateTime_TIME_GET_SECOND(%in);
+int usec = PyDateTime_TIME_GET_MICROSECOND(%in);
+%out = %OUTTYPE(hour, min, sec, usec/1000);
+// @snippet conversion-qtime-pytime
+
+// @snippet conversion-qbytearray-pybytes
+#ifdef IS_PY3K
+%out = %OUTTYPE(PyBytes_AS_STRING(%in), PyBytes_GET_SIZE(%in));
+#else
+%out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in));
+#endif
+// @snippet conversion-qbytearray-pybytes
+
+// @snippet conversion-qbytearray-pybytearray
+%out = %OUTTYPE(PyByteArray_AsString(%in), PyByteArray_Size(%in));
+// @snippet conversion-qbytearray-pybytearray
+
+// @snippet conversion-qbytearray-pystring
+%out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in));
+// @snippet conversion-qbytearray-pystring
+
+/*********************************************************************
+ * NATIVE TO TARGET CONVERSIONS
+ ********************************************************************/
+
+// @snippet return-pybool
+return PyBool_FromLong((bool)%in);
+// @snippet return-pybool
+
+// @snippet return-pylong
+return PyLong_FromLong(%in);
+// @snippet return-pylong
+
+// @snippet return-pylong-unsigned
+return PyLong_FromUnsignedLong(%in);
+// @snippet return-pylong-unsigned
+
+// @snippet return-pyunicode
+QByteArray ba = %in.toUtf8();
+return PyUnicode_FromStringAndSize(ba.constData(), ba.size());
+// @snippet return-pyunicode
+
+// @snippet return-pyunicode-qstringref
+ const int N = %in.length();
+ wchar_t *str = new wchar_t[N];
+ %in.toString().toWCharArray(str);
+ PyObject *%out = PyUnicode_FromWideChar(str, N);
+ delete[] str;
+ return %out;
+// @snippet return-pyunicode-qstringref
+
+// @snippet return-pyunicode-qchar
+wchar_t c = (wchar_t)%in.unicode();
+return PyUnicode_FromWideChar(&c, 1);
+// @snippet return-pyunicode-qchar
+
+// @snippet return-qvariant
+if (!%in.isValid())
+ Py_RETURN_NONE;
+
+if (qstrcmp(%in.typeName(), "QVariantList") == 0) {
+ QList<QVariant> var = %in.value<QVariantList>();
+ return %CONVERTTOPYTHON[QList<QVariant>](var);
+}
+
+if (qstrcmp(%in.typeName(), "QStringList") == 0) {
+ QStringList var = %in.value<QStringList>();
+ return %CONVERTTOPYTHON[QList<QString>](var);
+}
+
+if (qstrcmp(%in.typeName(), "QVariantMap") == 0) {
+ QMap<QString, QVariant> var = %in.value<QVariantMap>();
+ return %CONVERTTOPYTHON[QMap<QString, QVariant>](var);
+}
+
+Shiboken::Conversions::SpecificConverter converter(cppInRef.typeName());
+if (converter) {
+ void *ptr = cppInRef.data();
+ return converter.toPython(ptr);
+}
+PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName());
+return 0;
+// @snippet return-qvariant
+
+// @snippet return-qvariant-type
+const char *typeName = QVariant::typeToName(%in);
+PyObject *%out;
+PyTypeObject *pyType = nullptr;
+if (typeName)
+ pyType = Shiboken::Conversions::getPythonTypeObject(typeName);
+%out = pyType ? (reinterpret_cast<PyObject*>(pyType)) : Py_None;
+Py_INCREF(%out);
+return %out;
+// @snippet return-qvariant-type
+
+// @snippet return-qjsonobject
+// The QVariantMap returned by QJsonObject seems to cause a segfault, so
+// using QJsonObject.toVariantMap() won't work.
+// Wrapping it in a QJsonValue first allows it to work
+QJsonValue val(%in);
+QVariant ret = val.toVariant();
+
+return %CONVERTTOPYTHON[QVariant](ret);
+// @snippet return-qjsonobject
+
+// @snippet return-qpair
+PyObject *%out = PyTuple_New(2);
+PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first));
+PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second));
+return %out;
+// @snippet return-qpair
diff --git a/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp b/sources/pyside2/PySide2/glue/qtdatavisualization.cpp
index 9bdaa011e..119d79a40 100644
--- a/sources/pyside2/PySide2/QtCore/glue/qcoreapplication_init.cpp
+++ b/sources/pyside2/PySide2/glue/qtdatavisualization.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,14 +37,6 @@
**
****************************************************************************/
-static void QCoreApplicationConstructor(PyObject *self, PyObject *pyargv, QCoreApplicationWrapper **cptr)
-{
- static int argc;
- static char **argv;
- PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
- if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
- *cptr = new QCoreApplicationWrapper(argc, argv);
- Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self));
- PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
- }
-}
+// @snippet releaseownership
+Shiboken::Object::releaseOwnership(%PYARG_1);
+// @snippet releaseownership
diff --git a/sources/pyside2/PySide2/glue/qtgui.cpp b/sources/pyside2/PySide2/glue/qtgui.cpp
new file mode 100644
index 000000000..4ae3eef75
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtgui.cpp
@@ -0,0 +1,539 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qtransform-quadtoquad
+QTransform _result;
+if (QTransform::quadToQuad(%1, %2, _result)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qtransform-quadtoquad
+
+// @snippet qtransform-quadtosquare
+QTransform _result;
+if (QTransform::quadToSquare(%1, _result)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qtransform-quadtosquare
+
+// @snippet qtransform-squaretoquad
+QTransform _result;
+if (QTransform::squareToQuad(%1, _result)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result);
+} else {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+}
+// @snippet qtransform-squaretoquad
+
+// @snippet qbitmap-fromdata
+uchar *buffer = reinterpret_cast<uchar*>(Shiboken::Buffer::getPointer(%PYARG_2));
+QBitmap %0 = QBitmap::fromData(%1, buffer, %3);
+%PYARG_0 = %CONVERTTOPYTHON[QBitmap](%0);
+// @snippet qbitmap-fromdata
+
+// @snippet qtextline-cursortox
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE %0 = %CPPSELF->::%TYPE::%FUNCTION_NAME(&%1, %2);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+// @snippet qtextline-cursortox
+
+// @snippet qkeysequence-getitem
+if (_i < 0 || _i >= %CPPSELF.count()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+}
+int item = (*%CPPSELF)[_i];
+return %CONVERTTOPYTHON[int](item);
+// @snippet qkeysequence-getitem
+
+// @snippet qpicture-data
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.data(), %CPPSELF.size());
+// @snippet qpicture-data
+
+// @snippet qtextblock-setuserdata
+const QTextDocument *doc = %CPPSELF.document();
+if (doc) {
+ Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument*](doc));
+ Shiboken::Object::setParent(pyDocument, %PYARG_1);
+}
+// @snippet qtextblock-setuserdata
+
+// @snippet qtextblock-userdata
+const QTextDocument *doc = %CPPSELF.document();
+if (doc) {
+ Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument*](doc));
+ Shiboken::Object::setParent(pyDocument, %PYARG_0);
+}
+// @snippet qtextblock-userdata
+
+// @snippet qpolygon-reduce
+PyObject *points = PyList_New(%CPPSELF.count());
+for (int i = 0, i_max = %CPPSELF.count(); i < i_max; ++i){
+ int x, y;
+ %CPPSELF.point(i, &x, &y);
+ QPoint pt = QPoint(x, y);
+ PyList_SET_ITEM(points, i, %CONVERTTOPYTHON[QPoint](pt));
+}
+// @snippet qpolygon-reduce
+
+// @snippet qpolygon-operatorlowerlower
+// %FUNCTION_NAME()
+*%CPPSELF << %1;
+%PYARG_0 = %CONVERTTOPYTHON[QPolygon*](%CPPSELF);
+// @snippet qpolygon-operatorlowerlower
+
+// @snippet qpixmap
+%0 = new %TYPE(QPixmap::fromImage(%1));
+// @snippet qpixmap
+
+// @snippet qimage-constbits
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.byteCount());
+// @snippet qimage-constbits
+
+// @snippet qimage-bits
+// byteCount() is only available on Qt4.7, so we use bytesPerLine * height
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.bytesPerLine() * %CPPSELF.height(), Shiboken::Buffer::ReadWrite);
+// @snippet qimage-bits
+
+// @snippet qimage-constscanline
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine());
+// @snippet qimage-constscanline
+
+// @snippet qimage-scanline
+%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine(), Shiboken::Buffer::ReadWrite);
+// @snippet qimage-scanline
+
+// @snippet qcolor-setstate
+Shiboken::AutoDecRef func(PyObject_GetAttr(%PYSELF, PyTuple_GET_ITEM(%1, 0)));
+PyObject *args = PyTuple_GET_ITEM(%1, 1);
+%PYARG_0 = PyObject_Call(func, args, NULL);
+// @snippet qcolor-setstate
+
+// @snippet qcolor-reduce
+switch (%CPPSELF.spec()) {
+ case QColor::Rgb:
+ {
+ qreal r, g, b, a;
+ %CPPSELF.getRgbF(&r, &g, &b, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setRgbF", float(r), float(g), float(b), float(a));
+ break;
+ }
+ case QColor::Hsv:
+ {
+ qreal h, s, v, a;
+ %CPPSELF.getHsvF(&h, &s, &v, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setHsvF", float(h), float(s), float(v), float(a));
+ break;
+ }
+ case QColor::Cmyk:
+ {
+ qreal c, m, y, k, a;
+ %CPPSELF.getCmykF(&c, &m, &y, &k, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(fffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setCmykF", float(c), float(m), float(y), float(k), float(a));
+ break;
+ }
+ case QColor::Hsl:
+ {
+ qreal h, s, l, a;
+ %CPPSELF.getHslF(&h, &s, &l, &a);
+ %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0),
+ "setHslF", float(h), float(s), float(l), float(a));
+ break;
+ }
+ default:
+ {
+ %PYARG_0 = Py_BuildValue("(N(O))", PyObject_Type(%PYSELF), Py_None);
+ }
+}
+// @snippet qcolor-reduce
+
+// @snippet qcolor-totuple
+switch (%CPPSELF.spec()) {
+ case QColor::Rgb:
+ {
+ int r, g, b, a;
+ %CPPSELF.getRgb(&r, &g, &b, &a);
+ %PYARG_0 = Py_BuildValue("iiii", r, g, b, a);
+ break;
+ }
+ case QColor::Hsv:
+ {
+ int h, s, v, a;
+ %CPPSELF.getHsv(&h, &s, &v, &a);
+ %PYARG_0 = Py_BuildValue("iiii", h, s, v, a);
+ break;
+ }
+ case QColor::Cmyk:
+ {
+ int c, m, y, k, a;
+ %CPPSELF.getCmyk(&c, &m, &y, &k, &a);
+ %PYARG_0 = Py_BuildValue("iiiii", c, m, y, k, a);
+ break;
+ }
+ case QColor::Hsl:
+ {
+ int h, s, l, a;
+ %CPPSELF.getHsl(&h, &s, &l, &a);
+ %PYARG_0 = Py_BuildValue("iiii", h, s, l, a);
+ break;
+ }
+ default:
+ {
+ %PYARG_0 = 0;
+ }
+}
+// @snippet qcolor-totuple
+
+// @snippet qcolor
+if (%1.type() == QVariant::Color)
+ %0 = new %TYPE(%1.value<QColor>());
+else
+ PyErr_SetString(PyExc_TypeError, "QVariant must be holding a QColor");
+// @snippet qcolor
+
+// @snippet qfontmetricsf-boundingrect
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 5) {
+ array = Shiboken::sequenceToIntArray(%PYARG_5, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetricsf-boundingrect
+
+// @snippet qfontmetricsf-size
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 4) {
+ array = Shiboken::sequenceToIntArray(%PYARG_4, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetricsf-size
+
+// @snippet qfontmetrics-boundingrect-1
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 8) {
+ array = Shiboken::sequenceToIntArray(%PYARG_8, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetrics-boundingrect-1
+
+// @snippet qfontmetrics-boundingrect-2
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 5) {
+ array = Shiboken::sequenceToIntArray(%PYARG_5, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetrics-boundingrect-2
+
+// @snippet qfontmetrics-size
+int *array = nullptr;
+bool errorOccurred = false;
+
+if (numArgs == 4) {
+ array = Shiboken::sequenceToIntArray(%PYARG_4, true);
+ if (PyErr_Occurred()) {
+ delete [] array;
+ errorOccurred = true;
+ }
+}
+
+if (!errorOccurred) {
+ %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array);
+
+ delete [] array;
+
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+}
+// @snippet qfontmetrics-size
+
+// @snippet qpixmapcache-find
+QPixmap p;
+if (%CPPSELF.%FUNCTION_NAME(%1, &p)) {
+ %PYARG_0 = %CONVERTTOPYTHON[QPixmap](p);
+} else {
+ %PYARG_0 = Py_None;
+ Py_INCREF(%PYARG_0);
+}
+// @snippet qpixmapcache-find
+
+// @snippet qstandarditem-setchild-1
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->child(%1, %2);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditem-setchild-1
+
+// @snippet qstandarditem-setchild-2
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->child(%1);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditem-setchild-2
+
+// @snippet qkeyevent-operatornotequal
+bool ret = !(&%CPPSELF == %1);
+%PYARG_0 = %CONVERTTOPYTHON[bool](ret);
+// @snippet qkeyevent-operatornotequal
+
+// @snippet qstandarditemmodel-setitem-1
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->item(%1, %2);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditemmodel-setitem-1
+
+// @snippet qstandarditemmodel-setitem-2
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->item(%1);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditemmodel-setitem-2
+
+// @snippet qstandarditemmodel-setverticalheaderitem
+// Clear parent from the old child
+QStandardItem *_i = %CPPSELF->verticalHeaderItem(%1);
+if (_i) {
+ PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem*](_i);
+ Shiboken::Object::setParent(nullptr, _pyI);
+}
+// @snippet qstandarditemmodel-setverticalheaderitem
+
+// @snippet qstandarditemmodel-clear
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+SbkObject *pyRoot = bm.retrieveWrapper(%CPPSELF.invisibleRootItem());
+if (pyRoot) {
+ Shiboken::Object::destroy(pyRoot, %CPPSELF.invisibleRootItem());
+}
+
+for (int r=0, r_max = %CPPSELF.rowCount(); r < r_max; r++) {
+ QList<QStandardItem *> ri = %CPPSELF.takeRow(0);
+
+ PyObject *pyResult = %CONVERTTOPYTHON[QList<QStandardItem * >](ri);
+ Shiboken::Object::setParent(Py_None, pyResult);
+ Py_XDECREF(pyResult);
+}
+// @snippet qstandarditemmodel-clear
+
+// @snippet qclipboard-text
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+// @snippet qclipboard-text
+
+// @snippet qpainter-drawpolygon
+%BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(%1.data(), %1.size(), %2);
+%END_ALLOW_THREADS
+// @snippet qpainter-drawpolygon
+
+// @snippet qmatrix-map-point
+QPoint p(%CPPSELF.%FUNCTION_NAME(%1));
+%PYARG_0 = %CONVERTTOPYTHON[QPoint](p);
+// @snippet qmatrix-map-point
+
+// @snippet qmatrix4x4
+if (PySequence_Size(%PYARG_1) == 16) {
+ float values[16];
+ for (int i=0; i < 16; ++i) {
+ PyObject *pv = PySequence_Fast_GET_ITEM(%PYARG_1, i);
+ values[i] = PyFloat_AsDouble(pv);
+ }
+
+ %0 = new %TYPE(values[0], values[1], values[2], values[3],
+ values[4], values[5], values[6], values[7],
+ values[8], values[9], values[10], values[11],
+ values[12], values[13], values[14], values[15]);
+}
+// @snippet qmatrix4x4
+
+// @snippet qmatrix4x4-copydatato
+float values[16];
+%CPPSELF.%FUNCTION_NAME(values);
+%PYARG_0 = PyTuple_New(16);
+for (int i = 0; i < 16; ++i) {
+ PyObject *v = PyFloat_FromDouble(values[i]);
+ PyTuple_SET_ITEM(%PYARG_0, i, v);
+}
+// @snippet qmatrix4x4-copydatato
+
+// @snippet qmatrix4x4-mgetitem
+if (PySequence_Check(_key)) {
+ Shiboken::AutoDecRef key(PySequence_Fast(_key, "Invalid matrix index."));
+ if (PySequence_Fast_GET_SIZE(key.object()) == 2) {
+ PyObject *posx = PySequence_Fast_GET_ITEM(key.object(), 0);
+ PyObject *posy = PySequence_Fast_GET_ITEM(key.object(), 1);
+ Py_ssize_t x = PyInt_AsSsize_t(posx);
+ Py_ssize_t y = PyInt_AsSsize_t(posy);
+ float ret = (*%CPPSELF)(x,y);
+ return %CONVERTTOPYTHON[float](ret);
+ }
+}
+PyErr_SetString(PyExc_IndexError, "Invalid matrix index.");
+return 0;
+// @snippet qmatrix4x4-mgetitem
+
+// @snippet qguiapplication-init
+static void QGuiApplicationConstructor(PyObject *self, PyObject *pyargv, QGuiApplicationWrapper **cptr)
+{
+ static int argc;
+ static char **argv;
+ PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
+ if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
+ *cptr = new QGuiApplicationWrapper(argc, argv, 0);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self));
+ PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
+ }
+}
+// @snippet qguiapplication-init
+
+// @snippet qguiapplication-1
+QGuiApplicationConstructor(%PYSELF, args, &%0);
+// @snippet qguiapplication-1
+
+// @snippet qguiapplication-2
+PyObject *empty = PyTuple_New(2);
+if (!PyTuple_SetItem(empty, 0, PyList_New(0))) {
+ QGuiApplicationConstructor(%PYSELF, empty, &%0);
+}
+// @snippet qguiapplication-2
+
+// @snippet qscreen-grabWindow
+WId id = %1;
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id, %2, %3, %4, %5);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+// @snippet qscreen-grabWindow
+
+// @snippet qwindow-fromWinId
+WId id = %1;
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+// @snippet qwindow-fromWinId
+
+/*********************************************************************
+ * CONVERSIONS
+ ********************************************************************/
+
+// @snippet conversion-pylong
+%out = reinterpret_cast<%OUTTYPE>(PyLong_AsVoidPtr(%in));
+// @snippet conversion-pylong
+
+/*********************************************************************
+ * NATIVE TO TARGET CONVERSIONS
+ ********************************************************************/
+
+// @snippet return-pylong-voidptr
+return PyLong_FromVoidPtr(reinterpret_cast<void *>(%in));
+// @snippet return-pylong-voidptr
diff --git a/sources/pyside2/PySide2/QtGui/glue/qguiapplication_init.cpp b/sources/pyside2/PySide2/glue/qtmultimedia.cpp
index ae5dd22d2..520b5c4fa 100644
--- a/sources/pyside2/PySide2/QtGui/glue/qguiapplication_init.cpp
+++ b/sources/pyside2/PySide2/glue/qtmultimedia.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,14 +37,9 @@
**
****************************************************************************/
-static void QGuiApplicationConstructor(PyObject *self, PyObject *pyargv, QGuiApplicationWrapper **cptr)
-{
- static int argc;
- static char **argv;
- PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
- if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
- *cptr = new QGuiApplicationWrapper(argc, argv, 0);
- Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self));
- PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
- }
-}
+// @snippet upcast
+%BEGIN_ALLOW_THREADS
+QObject* upcastedArg = %CONVERTTOCPP[QObject*](%PYARG_1);
+%CPPSELF.%FUNCTION_NAME(reinterpret_cast< %ARG1_TYPE >(upcastedArg));
+%END_ALLOW_THREADS
+// @snippet upcast
diff --git a/sources/pyside2/PySide2/QtCore/glue/qbytearray_bufferprotocol.cpp b/sources/pyside2/PySide2/glue/qtnetwork.cpp
index ed5fef3ae..cdb330c40 100644
--- a/sources/pyside2/PySide2/QtCore/glue/qbytearray_bufferprotocol.cpp
+++ b/sources/pyside2/PySide2/glue/qtnetwork.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,37 +37,44 @@
**
****************************************************************************/
-#if PY_VERSION_HEX < 0x03000000
+// @snippet qudpsocket-readdatagram
+Shiboken::AutoArrayPointer<char> data(%ARGUMENT_NAMES);
+QHostAddress ha;
+quint16 port;
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(data, %ARGUMENT_NAMES, &ha, &port);
+%END_ALLOW_THREADS
+QByteArray ba(data, retval);
+%PYARG_0 = PyTuple_New(3);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QByteArray](ba));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QHostAddress](ha));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[quint16](port));
+// @snippet qudpsocket-readdatagram
-// QByteArray buffer protocol functions
-// see: http://www.python.org/dev/peps/pep-3118/
+// @snippet qipv6address-len
+return 16;
+// @snippet qipv6address-len
-extern "C" {
-
-static Py_ssize_t SbkQByteArray_segcountproc(PyObject* self, Py_ssize_t* lenp)
-{
- if (lenp)
- *lenp = Py_TYPE(self)->tp_as_sequence->sq_length(self);
- return 1;
+// @snippet qipv6address-getitem
+if (_i >= 16) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
}
+if (_i < 0)
+ _i = 16 - qAbs(_i);
-static Py_ssize_t SbkQByteArray_readbufferproc(PyObject* self, Py_ssize_t segment, void** ptrptr)
-{
- if (segment || !Shiboken::Object::isValid(self))
- return -1;
+uint item = %CPPSELF.c[_i];
+return %CONVERTTOPYTHON[uint](item);
+// @snippet qipv6address-getitem
- QByteArray* cppSelf = %CONVERTTOCPP[QByteArray*](self);
- *ptrptr = reinterpret_cast<void*>(cppSelf->data());
- return cppSelf->size();
+// @snippet qipv6address-setitem
+if (_i >= 16) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return -1;
}
-
-PyBufferProcs SbkQByteArrayBufferProc = {
- /*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc,
- /*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc,
- /*bf_getsegcount*/ &SbkQByteArray_segcountproc,
- /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc
-};
-
-}
-
-#endif
+if (_i < 0)
+ _i = 16 - qAbs(_i);
+quint8 item = %CONVERTTOCPP[quint8](_value);
+%CPPSELF.c[_i] = item;
+return 0;
+// @snippet qipv6address-setitem
diff --git a/sources/pyside2/libpyside/globalreceiver.h b/sources/pyside2/PySide2/glue/qtopengl.cpp
index 426d40bfe..6c106522c 100644
--- a/sources/pyside2/libpyside/globalreceiver.h
+++ b/sources/pyside2/PySide2/glue/qtopengl.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,44 +37,38 @@
**
****************************************************************************/
-#ifndef GLOBALRECEIVER_H
-#define GLOBALRECEIVER_H
+// @snippet qglbuffer-allocate
+int size = (%2 < 0) ? %1.size() : %2;
+%CPPSELF.allocate((const void*) %1.data(), size);
+// @snippet qglbuffer-allocate
-#include <sbkpython.h>
-#include <QObject>
-#include <QHash>
-#include <QSet>
-#include "dynamicqmetaobject.h"
+// @snippet qglbuffer-read
+char *data = new char[%3];
+bool result = %CPPSELF.read(%1, data, %3);
+QByteArray ret;
+if (result)
+ ret.append((const char*)data, %3);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](result));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QByteArray](ret));
+delete[] data;
+// @snippet qglbuffer-read
-namespace PySide
-{
+// @snippet qglbuffer-write
+int size = (%3 < 0) ? %2.size() : %3;
+%CPPSELF.write(%1, (const void*) %2.data(), size);
+// @snippet qglbuffer-write
-class DynamicSlotData;
-
-class GlobalReceiver : public QObject
-{
-public:
- GlobalReceiver();
- ~GlobalReceiver();
- int qt_metacall(QMetaObject::Call call, int id, void** args);
- const QMetaObject* metaObject() const;
- int addSlot(const char* slot, PyObject* callback);
- void removeSlot(int slotId);
- void connectNotify(QObject* sender, int slotId);
- void disconnectNotify(QObject* sender, int slotId);
- bool hasConnectionWith(const QObject* object);
-
-protected:
- using QObject::connectNotify;
- using QObject::disconnectNotify;
-
-private:
- DynamicQMetaObject m_metaObject;
- QSet<int> m_shortCircuitSlots;
- QHash<int, DynamicSlotData* > m_slotReceivers;
-};
+// @snippet qglbuffer-map
+Py_ssize_t dataSize = %CPPSELF.size();
+void* data = %CPPSELF.map(%1);
+if (!data) {
+ Py_INCREF(Py_None);
+ %PYARG_0 = Py_None;
+} else if (%1 == QGLBuffer::ReadOnly) {
+ %PYARG_0 = Shiboken::Buffer::newObject(data, dataSize, Shiboken::Buffer::ReadOnly);
+} else {
+ %PYARG_0 = Shiboken::Buffer::newObject(data, dataSize, Shiboken::Buffer::ReadWrite);
}
-
-#endif
-
+// @snippet qglbuffer-map
diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp b/sources/pyside2/PySide2/glue/qtqml.cpp
index 8cdbc2e01..1913204c3 100644
--- a/sources/pyside2/PySide2/QtWidgets/glue/qmenubar_glue.cpp
+++ b/sources/pyside2/PySide2/glue/qtqml.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,26 +37,16 @@
**
****************************************************************************/
-inline PyObject*
-addActionWithPyObject(QMenuBar* self, const QString& text, PyObject* callback)
-{
- QAction* act = new QAction(text, self);
+// @snippet qmlregistertype
+int %0 = PySide::qmlRegisterType(%ARGUMENT_NAMES);
+%PYARG_0 = %CONVERTTOPYTHON[int](%0);
+// @snippet qmlregistertype
- self->addAction(act);
+// @snippet init
+PySide::initQmlSupport(module);
+// @snippet init
- PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act);
- PyObject* result = PyObject_CallMethod(pyAct,
- const_cast<char *>("connect"),
- const_cast<char *>("OsO"),
- pyAct,
- SIGNAL(triggered(bool)), callback);
-
- if (result == 0 || result == Py_False) {
- if (result)
- Py_DECREF(result);
- Py_DECREF(pyAct);
- return 0;
- }
-
- return pyAct;
-}
+// @snippet qjsengine-toscriptvalue
+%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1);
+return %CONVERTTOPYTHON[%RETURN_TYPE](retval);
+// @snippet qjsengine-toscriptvalue
diff --git a/sources/pyside2/PySide2/glue/qtquick.cpp b/sources/pyside2/PySide2/glue/qtquick.cpp
new file mode 100644
index 000000000..b7c31aff3
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtquick.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+// @snippet qtquick
+PySide::initQuickSupport(module);
+// @snippet qtquick
diff --git a/sources/pyside2/PySide2/glue/qtscript.cpp b/sources/pyside2/PySide2/glue/qtscript.cpp
new file mode 100644
index 000000000..7efc26f3e
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtscript.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+// @snippet qscriptvalue-repr
+if (%CPPSELF.isVariant() || %CPPSELF.isString()) {
+ QString format = QString::asprintf("%s(\"%s\")",
+ Py_TYPE(%PYSELF)->tp_name,
+ qPrintable(%CPPSELF.toString()));
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(format));
+ } else {
+ %PYARG_0 = Shiboken::String::fromCString(Py_TYPE(%PYSELF)->tp_name);
+}
+// @snippet qscriptvalue-repr
+
+// @snippet qscriptvalue-mgetitem
+Shiboken::AutoDecRef key(PyObject_Str(_key));
+QVariant res = %CPPSELF.property(Shiboken::String::toCString(key.object())).toVariant();
+if (res.isValid()) {
+ return %CONVERTTOPYTHON[QVariant](res);
+} else {
+ PyObject* errorType = PyInt_Check(_key) ? PyExc_IndexError : PyExc_KeyError;
+ PyErr_SetString(errorType, "Key not found.");
+ return 0;
+}
+// @snippet qscriptvalue-mgetitem
+
+// @snippet qscriptvalueiterator-next
+if (%CPPSELF.hasNext()) {
+ %CPPSELF.next();
+ QString name = %CPPSELF.name();
+ QVariant value = %CPPSELF.value().toVariant();
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QString](name));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QVariant](value));
+} else {
+ PyErr_SetNone(PyExc_StopIteration);
+}
+// @snippet qscriptvalueiterator-next
diff --git a/sources/pyside2/PySide2/QtUiTools/glue/uitools_loadui.cpp b/sources/pyside2/PySide2/glue/qtuitools.cpp
index c078eacee..d0469e97d 100644
--- a/sources/pyside2/PySide2/QtUiTools/glue/uitools_loadui.cpp
+++ b/sources/pyside2/PySide2/glue/qtuitools.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -36,7 +36,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
+// @snippet uitools-loadui
/*
* Based on code provided by:
* Antonio Valentino <antonio.valentino at tiscali.it>
@@ -50,12 +50,11 @@
static void createChildrenNameAttributes(PyObject* root, QObject* object)
{
- foreach (QObject* child, object->children()) {
+ for (auto *child : object->children()) {
const QByteArray name = child->objectName().toLocal8Bit();
if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) {
- bool hasAttr = PyObject_HasAttrString(root, name.constData());
- if (!hasAttr) {
+ if (!PyObject_HasAttrString(root, name.constData())) {
Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child));
PyObject_SetAttrString(root, name.constData(), pyChild);
}
@@ -81,7 +80,7 @@ static PyObject* QUiLoadedLoadUiFromDevice(QUiLoader* self, QIODevice* dev, QWid
if (!PyErr_Occurred())
PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device");
- return 0;
+ return nullptr;
}
static PyObject* QUiLoaderLoadUiFromFileName(QUiLoader* self, const QString& uiFile, QWidget* parent)
@@ -89,3 +88,23 @@ static PyObject* QUiLoaderLoadUiFromFileName(QUiLoader* self, const QString& uiF
QFile fd(uiFile);
return QUiLoadedLoadUiFromDevice(self, &fd, parent);
}
+// @snippet uitools-loadui
+
+// @snippet quiloader
+Q_IMPORT_PLUGIN(PyCustomWidgets);
+// @snippet quiloader
+
+// @snippet quiloader-registercustomwidget
+registerCustomWidget(%PYARG_1);
+%CPPSELF.addPluginPath(""); // force reload widgets
+// @snippet quiloader-registercustomwidget
+
+// @snippet quiloader-load-1
+// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
+%PYARG_0 = QUiLoadedLoadUiFromDevice(%CPPSELF, %1, %2);
+// @snippet quiloader-load-1
+
+// @snippet quiloader-load-2
+// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME()
+%PYARG_0 = QUiLoaderLoadUiFromFileName(%CPPSELF, %1, %2);
+// @snippet quiloader-load-2
diff --git a/sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp b/sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp
new file mode 100644
index 000000000..086ee3b85
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+// @snippet qwebview-page
+SbkObject* _pyReturn = reinterpret_cast<SbkObject*>(%PYARG_0);
+if (!Shiboken::Object::hasParentInfo(_pyReturn))
+ Shiboken::Object::setParent(%PYSELF, %PYARG_0);
+// @snippet qwebview-page
+
+// @snippet qwebelementcollection-len
+return %CPPSELF.count();
+// @snippet qwebelementcollection-len
+
+// @snippet qwebelementcollection-getitem
+if (_i < 0 || _i >= %CPPSELF.count()) {
+ PyErr_SetString(PyExc_IndexError, "index out of bounds");
+ return 0;
+}
+QWebElement element = %CPPSELF.at(_i);
+return %CONVERTTOPYTHON[QWebElement](element);
+// @snippet qwebelementcollection-getitem
+
+// @snippet qwebpage-qt-metacall
+static int _signalIndex = -1;
+static QMetaMethod _m;
+
+if (_signalIndex == -1) {
+ _signalIndex = QWebPage::staticMetaObject.indexOfSlot("shouldInterruptJavaScript()")
+ _m = QWebPage::staticMetaObject.method(_signalIndex);
+}
+
+if (_signalIndex == id) {
+ Shiboken::GilState gil;
+ PyObject* self = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(this);
+
+ if (self) {
+ Shiboken::AutoDecRef _pyMethod(PyObject_GetAttrString(self, "shouldInterruptJavaScript"));
+ return PySide::SignalManager::callPythonMetaMethod(_m, args, _pyMethod, false);
+ }
+}
+// @snippet qwebpage-qt-metacall
+
+// @snippet qwebframe-metadata
+%PYARG_0 = PyDict_New();
+const auto &keys = %0.keys();
+for (const auto &_key : keys) {
+ Shiboken::AutoDecRef _pyValueList(PyList_New(0));
+ for (auto it = %0.lowerBound(key), end = %0.upperBound(key); it ! = end; ++it) {
+ Shiboken::AutoDecRef _pyValue(%CONVERTTOPYTHON[QString](it.value));
+ PyList_Append(_pyValueList, _pyValue);
+ }
+
+ Shiboken::AutoDecRef _pyKey(%CONVERTTOPYTHON[QString](_key));
+ PyDict_SetItem(%PYARG_0, _pyKey, _pyValueList);
+}
+// @snippet qwebframe-metadata
diff --git a/sources/pyside2/PySide2/glue/qtwidgets.cpp b/sources/pyside2/PySide2/glue/qtwidgets.cpp
new file mode 100644
index 000000000..b44be183d
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtwidgets.cpp
@@ -0,0 +1,664 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+/*********************************************************************
+ * INJECT CODE
+ ********************************************************************/
+
+// @snippet qtreewidgetitemiterator-next
+if (**%CPPSELF) {
+ QTreeWidgetItemIterator *%0 = new QTreeWidgetItemIterator((*%CPPSELF)++);
+ %PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItemIterator*](%0);
+}
+// @snippet qtreewidgetitemiterator-next
+
+// @snippet qtreewidgetitemiterator-value
+QTreeWidgetItem *%0 = %CPPSELF.operator*();
+%PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItem*](%0);
+Shiboken::Object::releaseOwnership(%PYARG_0);
+// @snippet qtreewidgetitemiterator-value
+
+// @snippet qgraphicsitem
+PyObject *userTypeConstant = PyInt_FromLong(QGraphicsItem::UserType);
+PyDict_SetItemString(reinterpret_cast<PyTypeObject *>(Sbk_QGraphicsItem_TypeF())->tp_dict, "UserType", userTypeConstant);
+// @snippet qgraphicsitem
+
+// @snippet qgraphicsitem-scene-return-parenting
+if (%0) {
+ QObject *parent = %0->parent();
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QObject*](parent));
+ Shiboken::Object::setParent(pyParent, %PYARG_0);
+}
+// @snippet qgraphicsitem-scene-return-parenting
+
+// @snippet qgraphicsitem-isblockedbymodalpanel
+QGraphicsItem *item_ = NULL;
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&item_);
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QGraphicsItem*](item_));
+// @snippet qgraphicsitem-isblockedbymodalpanel
+
+// @snippet qitemeditorfactory-registereditor
+Shiboken::Object::releaseOwnership(%PYARG_2);
+// @snippet qitemeditorfactory-registereditor
+
+// @snippet qitemeditorfactory-setdefaultfactory
+//this function is static we need keep ref to default value, to be able to call python virtual functions
+static PyObject* _defaultValue = 0;
+%CPPSELF.%FUNCTION_NAME(%1);
+Py_INCREF(%PYARG_1);
+if (_defaultValue)
+ Py_DECREF(_defaultValue);
+
+_defaultValue = %PYARG_1;
+// @snippet qitemeditorfactory-setdefaultfactory
+
+// @snippet qformlayout-fix-args
+int _row;
+QFormLayout::ItemRole _role;
+%BEGIN_ALLOW_THREADS
+%CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &_row, &_role);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role));
+// @snippet qformlayout-fix-args
+
+// @snippet qfiledialog-return
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &%5, %6);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG5_TYPE](%5));
+// @snippet qfiledialog-return
+
+// @snippet qmenu-glue
+inline PyObject* addActionWithPyObject(QMenu* self, const QIcon& icon, const QString& text, PyObject* callback, const QKeySequence& shortcut)
+{
+ QAction* act = self->addAction(text);
+
+ if (!icon.isNull())
+ act->setIcon(icon);
+
+ if (!shortcut.isEmpty())
+ act->setShortcut(shortcut);
+
+ self->addAction(act);
+
+ PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act);
+ Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct,
+ const_cast<char *>("connect"),
+ const_cast<char *>("OsO"),
+ pyAct,
+ SIGNAL(triggered()), callback));
+ if (result.isNull()) {
+ Py_DECREF(pyAct);
+ return nullptr;
+ }
+
+ return pyAct;
+}
+// @snippet qmenu-glue
+
+// @snippet qmenu-addaction-1
+%PYARG_0 = addActionWithPyObject(%CPPSELF, QIcon(), %1, %2, %3);
+// @snippet qmenu-addaction-1
+
+// @snippet qmenu-addaction-2
+%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2, %3, %4);
+// @snippet qmenu-addaction-2
+
+// @snippet qmenu-addaction-3
+%CPPSELF.addAction(%1);
+// @snippet qmenu-addaction-3
+
+// @snippet qmenu-clear
+Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
+const auto &actions = %CPPSELF.actions();
+for (auto *act : actions) {
+ if (auto wrapper = bm.retrieveWrapper(act)) {
+ auto pyObj = reinterpret_cast<PyObject *>(wrapper);
+ Py_INCREF(pyObj);
+ Shiboken::Object::setParent(NULL, pyObj);
+ Shiboken::Object::invalidate(pyObj);
+ Py_DECREF(pyObj);
+ }
+}
+// @snippet qmenu-clear
+
+// @snippet qmenubar-glue
+inline PyObject*
+addActionWithPyObject(QMenuBar* self, const QString& text, PyObject* callback)
+{
+ QAction* act = self->addAction(text);
+
+ self->addAction(act);
+
+ PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act);
+ PyObject* result = PyObject_CallMethod(pyAct,
+ const_cast<char *>("connect"),
+ const_cast<char *>("OsO"),
+ pyAct,
+ SIGNAL(triggered(bool)), callback);
+
+ if (result == nullptr || result == Py_False) {
+ if (result)
+ Py_DECREF(result);
+ Py_DECREF(pyAct);
+ return nullptr;
+ }
+
+ return pyAct;
+}
+// @snippet qmenubar-glue
+
+// @snippet qmenubar-clear
+const auto &actions = %CPPSELF.actions();
+for (auto *act : actions) {
+ Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act));
+ Shiboken::Object::setParent(NULL, pyAct);
+ Shiboken::Object::invalidate(pyAct);
+}
+// @snippet qmenubar-clear
+
+// @snippet qmenubar-addaction-1
+%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2);
+// @snippet qmenubar-addaction-1
+
+// @snippet qmenubar-addaction-2
+%CPPSELF.addAction(%1);
+// @snippet qmenubar-addaction-2
+
+// @snippet qshortcut-1
+%0 = new %TYPE(%1, %2);
+// @snippet qshortcut-1
+
+// @snippet qshortcut-2
+Shiboken::AutoDecRef result(PyObject_CallMethod(%PYSELF,
+ const_cast<char *>("connect"),
+ const_cast<char *>("OsO"),
+ %PYSELF, SIGNAL(activated()), %PYARG_3)
+);
+if (!result.isNull())
+ Shiboken::Object::setParent(%PYARG_2, %PYSELF);
+// @snippet qshortcut-2
+
+// @snippet qtoolbox-removeitem
+QWidget *_widget = %CPPSELF.widget(%1);
+if (_widget) {
+ Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget*](_widget));
+ Shiboken::Object::setParent(0, pyWidget);
+}
+// @snippet qtoolbox-removeitem
+
+// @snippet qlayout-help-functions
+void addLayoutOwnership(QLayout* layout, QLayoutItem* item);
+void removeLayoutOwnership(QLayout* layout, QWidget* widget);
+
+inline QByteArray retrieveObjectName(PyObject* obj)
+{
+ Shiboken::AutoDecRef objName(PyObject_Str(obj));
+ return Shiboken::String::toCString(objName);
+}
+
+inline void addLayoutOwnership(QLayout* layout, QWidget* widget)
+{
+ //transfer ownership to parent widget
+ QWidget *lw = layout->parentWidget();
+ QWidget *pw = widget->parentWidget();
+
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget));
+
+ //Transfer parent to layout widget
+ if (pw && lw && pw != lw)
+ Shiboken::Object::setParent(0, pyChild);
+
+ if (!lw && !pw) {
+ //keep the reference while the layout is orphan
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout));
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true);
+ } else {
+ if (!lw)
+ lw = pw;
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](lw));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ }
+}
+
+inline void addLayoutOwnership(QLayout* layout, QLayout* other)
+{
+ //transfer all children widgets from other to layout parent widget
+ QWidget* parent = layout->parentWidget();
+ if (!parent) {
+ //keep the reference while the layout is orphan
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other));
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true);
+ return;
+ }
+
+ for (int i=0, i_max=other->count(); i < i_max; i++) {
+ QLayoutItem* item = other->itemAt(i);
+ if (PyErr_Occurred() || !item)
+ return;
+ addLayoutOwnership(layout, item);
+ }
+
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](other));
+ Shiboken::Object::setParent(pyParent, pyChild);
+}
+
+inline void addLayoutOwnership(QLayout* layout, QLayoutItem* item)
+{
+ if (!item)
+ return;
+
+ QWidget* w = item->widget();
+ if (w)
+ addLayoutOwnership(layout, w);
+ else {
+ QLayout* l = item->layout();
+ if (l)
+ addLayoutOwnership(layout, l);
+ }
+
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout*](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item));
+ Shiboken::Object::setParent(pyParent, pyChild);
+}
+
+static void removeWidgetFromLayout(QLayout* layout, QWidget* widget)
+{
+ QWidget* parent = widget->parentWidget();
+
+ if (!parent) {
+ //remove reference on layout
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](layout));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget));
+ Shiboken::Object::removeReference(reinterpret_cast<SbkObject*>(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild);
+ } else {
+ //give the ownership to parent
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent));
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](widget));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ }
+}
+
+inline void removeLayoutOwnership(QLayout* layout, QLayoutItem* item)
+{
+ QWidget* w = item->widget();
+ if (w)
+ removeWidgetFromLayout(layout, w);
+ else {
+ QLayout* l = item->layout();
+ if (l && item != l)
+ removeLayoutOwnership(layout, l);
+ }
+
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem*](item));
+ Shiboken::Object::invalidate(pyChild);
+ Shiboken::Object::setParent(0, pyChild);
+}
+
+inline void removeLayoutOwnership(QLayout* layout, QWidget* widget)
+{
+ if (!widget)
+ return;
+
+ for (int i=0, i_max=layout->count(); i < i_max; i++) {
+ QLayoutItem* item = layout->itemAt(i);
+ if (PyErr_Occurred() || !item)
+ return;
+ if (item->widget() == widget)
+ removeLayoutOwnership(layout, item);
+ }
+}
+// @snippet qlayout-help-functions
+
+// @snippet qlayout-setalignment
+%CPPSELF.setAlignment(%1);
+// @snippet qlayout-setalignment
+
+// @snippet addownership-0
+addLayoutOwnership(%CPPSELF, %0);
+// @snippet addownership-0
+
+// @snippet addownership-1
+addLayoutOwnership(%CPPSELF, %1);
+// @snippet addownership-1
+
+// @snippet addownership-2
+addLayoutOwnership(%CPPSELF, %2);
+// @snippet addownership-2
+
+// @snippet removeownership-1
+removeLayoutOwnership(%CPPSELF, %1);
+// @snippet removeownership-1
+
+// @snippet qgridlayout-getitemposition
+int a, b, c, d;
+%CPPSELF.%FUNCTION_NAME(%1, &a, &b, &c, &d);
+%PYARG_0 = PyTuple_New(4);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](a));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](b));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](c));
+PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](d));
+// @snippet qgridlayout-getitemposition
+
+// @snippet qgraphicsscene-destroyitemgroup
+QGraphicsItem* parentItem = %1->parentItem();
+Shiboken::AutoDecRef parent(%CONVERTTOPYTHON[QGraphicsItem*](parentItem));
+const auto &childItems = %1->childItems();
+for (auto *item : childItems)
+ Shiboken::Object::setParent(parent, %CONVERTTOPYTHON[QGraphicsItem*](item));
+%BEGIN_ALLOW_THREADS
+%CPPSELF.%FUNCTION_NAME(%1);
+%END_ALLOW_THREADS
+// the arg was destroyed by Qt.
+Shiboken::Object::invalidate(%PYARG_1);
+// @snippet qgraphicsscene-destroyitemgroup
+
+// @snippet qgraphicsscene-addwidget
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+Shiboken::Object::keepReference((SbkObject*)%PYARG_0, "setWidget(QWidget*)1", %PYARG_1);
+// @snippet qgraphicsscene-addwidget
+
+// @snippet qgraphicsscene-clear
+const QList<QGraphicsItem*> items = %CPPSELF.items();
+Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
+for (auto *item : items) {
+ SbkObject* obj = bm.retrieveWrapper(item);
+ if (obj) {
+ if (reinterpret_cast<PyObject*>(obj)->ob_refcnt > 1) // If the refcnt is 1 the object will vannish anyway.
+ Shiboken::Object::invalidate(obj);
+ Shiboken::Object::removeParent(obj);
+ }
+}
+%CPPSELF.%FUNCTION_NAME();
+// @snippet qgraphicsscene-clear
+
+// @snippet qtreewidget-clear
+QTreeWidgetItem *rootItem = %CPPSELF.invisibleRootItem();
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+for (int i = 0, i_count = rootItem->childCount(); i < i_count; ++i) {
+ QTreeWidgetItem *item = rootItem->child(i);
+ SbkObject* wrapper = bm.retrieveWrapper(item);
+ if (wrapper)
+ Shiboken::Object::setParent(0, reinterpret_cast<PyObject*>(wrapper));
+}
+// @snippet qtreewidget-clear
+
+// @snippet qtreewidgetitem
+// Only call the parent function if this return some value
+// the parent can be the TreeWidget
+if (%0)
+ Shiboken::Object::setParent(%PYARG_0, %PYSELF);
+// @snippet qtreewidgetitem
+
+// @snippet qlistwidget-clear
+Shiboken::BindingManager &bm = Shiboken::BindingManager::instance();
+for (int i = 0, count = %CPPSELF.count(); i < count; ++i) {
+ QListWidgetItem *item = %CPPSELF.item(i);
+ if (auto wrapper = bm.retrieveWrapper(item)) {
+ auto pyObj = reinterpret_cast<PyObject*>(wrapper);
+ Py_INCREF(pyObj);
+ Shiboken::Object::setParent(NULL, pyObj);
+ Shiboken::Object::invalidate(pyObj);
+ Py_DECREF(pyObj);
+ }
+}
+%CPPSELF.%FUNCTION_NAME();
+// @snippet qlistwidget-clear
+
+// @snippet qwidget-glue
+static QString retrieveObjectName(PyObject *obj)
+{
+ Shiboken::AutoDecRef objName(PyObject_Str(obj));
+ return QString(Shiboken::String::toCString(objName));
+}
+
+
+// Transfer objects ownership from layout to widget
+static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout)
+{
+ Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget*](parent));
+
+ for (int i=0, i_count = layout->count(); i < i_count; i++) {
+ QLayoutItem* item = layout->itemAt(i);
+ if (PyErr_Occurred() || !item)
+ return;
+
+ QWidget* w = item->widget();
+ if (w) {
+ QWidget* pw = w->parentWidget();
+ if (pw != parent) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget*](w));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ }
+ } else {
+ QLayout* l = item->layout();
+ if (l)
+ qwidgetReparentLayout(parent, l);
+ }
+ }
+
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout*](layout));
+ Shiboken::Object::setParent(pyParent, pyChild);
+ //remove previous references
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(pyChild.object()), qPrintable(retrieveObjectName(pyChild)), Py_None);
+}
+
+static inline void qwidgetSetLayout(QWidget *self, QLayout *layout)
+{
+ if (!layout || self->layout())
+ return;
+
+ QObject* oldParent = layout->parent();
+ if (oldParent && oldParent != self) {
+ if (oldParent->isWidgetType()) {
+ // remove old parent policy
+ Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout*](layout));
+ Shiboken::Object::setParent(Py_None, pyLayout);
+ } else {
+ PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent",
+ qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName()));
+ return;
+ }
+ }
+
+ if (oldParent != self) {
+ qwidgetReparentLayout(self, layout);
+ if (PyErr_Occurred())
+ return;
+
+ self->setLayout(layout);
+ }
+}
+// @snippet qwidget-glue
+
+// @snippet qwidget-setstyle
+Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(%PYSELF), "__style__", %PYARG_1);
+// @snippet qwidget-setstyle
+
+// @snippet qwidget-style
+QStyle* myStyle = %CPPSELF->style();
+if (myStyle && qApp) {
+%PYARG_0 = %CONVERTTOPYTHON[QStyle*](myStyle);
+ QStyle *appStyle = qApp->style();
+ if (appStyle == myStyle) {
+ Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication*](qApp));
+ Shiboken::Object::setParent(pyApp, %PYARG_0);
+ Shiboken::Object::releaseOwnership(%PYARG_0);
+ } else {
+ Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(%PYSELF), "__style__", %PYARG_0);
+ }
+}
+// @snippet qwidget-style
+
+// @snippet qapplication-init
+static void QApplicationConstructor(PyObject *self, PyObject *pyargv, QApplicationWrapper **cptr)
+{
+ static int argc;
+ static char **argv;
+ PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0);
+ if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) {
+ *cptr = new QApplicationWrapper(argc, argv, 0);
+ Shiboken::Object::releaseOwnership(reinterpret_cast<SbkObject*>(self));
+ PySide::registerCleanupFunction(&PySide::destroyQCoreApplication);
+ }
+}
+// @snippet qapplication-init
+
+// @snippet qapplication-setStyle
+if (qApp) {
+ Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication*](qApp));
+ Shiboken::Object::setParent(pyApp, %PYARG_1);
+ Shiboken::Object::releaseOwnership(%PYARG_1);
+}
+// @snippet qapplication-setStyle
+
+// @snippet qwidget-setlayout
+qwidgetSetLayout(%CPPSELF, %1);
+// %FUNCTION_NAME() - disable generation of function call.
+// @snippet qwidget-setlayout
+
+// @snippet qtabwidget-removetab
+QWidget* tab = %CPPSELF.widget(%1);
+if (tab) {
+ Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget*](tab));
+ %CPPSELF.%FUNCTION_NAME(%1);
+}
+// @snippet qtabwidget-removetab
+
+// @snippet qtabwidget-clear
+Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
+for (int i = 0, count = %CPPSELF.count(); i < count; ++i) {
+ QWidget* widget = %CPPSELF.widget(i);
+ if (bm.hasWrapper(widget)) {
+ Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget*](widget));
+ Shiboken::Object::releaseOwnership(pyWidget);
+ }
+}
+%CPPSELF.%FUNCTION_NAME();
+// @snippet qtabwidget-clear
+
+// @snippet qlineedit-addaction
+%CPPSELF.addAction(%1);
+// @snippet qlineedit-addaction
+
+// @snippet qtoolbar-addaction-1
+QAction *action = %CPPSELF.addAction(%1, %2);
+%PYARG_0 = %CONVERTTOPYTHON[QAction*](action);
+Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0,
+ const_cast<char *>("connect"),
+ const_cast<char *>("OsO"),
+ %PYARG_0, SIGNAL(triggered()), %PYARG_3)
+);
+// @snippet qtoolbar-addaction-1
+
+// @snippet qtoolbar-addaction-2
+QAction *action = %CPPSELF.addAction(%1);
+%PYARG_0 = %CONVERTTOPYTHON[QAction*](action);
+Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0,
+ const_cast<char *>("connect"),
+ const_cast<char *>("OsO"),
+ %PYARG_0, SIGNAL(triggered()), %PYARG_2)
+);
+// @snippet qtoolbar-addaction-2
+
+// @snippet qtoolbar-addaction-3
+%CPPSELF.addAction(%1);
+// @snippet qtoolbar-addaction-3
+
+// @snippet qtoolbar-clear
+QList<PyObject* > lst;
+Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
+const auto &toolButtonChildren = %CPPSELF.findChildren<QToolButton*>();
+for (auto *child : toolButtonChildren) {
+ if (bm.hasWrapper(child)) {
+ PyObject* pyChild = %CONVERTTOPYTHON[QToolButton*](child);
+ Shiboken::Object::setParent(0, pyChild);
+ lst << pyChild;
+ }
+}
+
+//Remove actions
+const auto &actions = %CPPSELF.actions();
+for (auto *act : actions) {
+ Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction*](act));
+ Shiboken::Object::setParent(NULL, pyAct);
+ Shiboken::Object::invalidate(pyAct);
+}
+
+%CPPSELF.clear();
+for (auto *obj : lst) {
+ Shiboken::Object::invalidate(reinterpret_cast<SbkObject* >(obj));
+ Py_XDECREF(obj);
+}
+// @snippet qtoolbar-clear
+
+// @snippet qapplication-1
+QApplicationConstructor(%PYSELF, args, &%0);
+// @snippet qapplication-1
+
+// @snippet qapplication-2
+PyObject *empty = PyTuple_New(2);
+if (!PyTuple_SetItem(empty, 0, PyList_New(0)))
+ QApplicationConstructor(%PYSELF, empty, &%0);
+// @snippet qapplication-2
+
+// @snippet qgraphicsproxywidget-setwidget
+QWidget* _old = %CPPSELF.widget();
+if (_old)
+ Shiboken::Object::setParent(nullptr, %CONVERTTOPYTHON[QWidget*](_old));
+%CPPSELF.%FUNCTION_NAME(%1);
+Shiboken::Object::setParent(%PYSELF, %PYARG_1);
+// @snippet qgraphicsproxywidget-setwidget
+
+/*********************************************************************
+ * CONVERSIONS
+ ********************************************************************/
+
+/*********************************************************************
+ * NATIVE TO TARGET CONVERSIONS
+ ********************************************************************/
diff --git a/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp b/sources/pyside2/PySide2/glue/qtxml.cpp
index 4e9c8c3b7..ff8be58e2 100644
--- a/sources/pyside2/PySide2/QtWidgets/glue/qmenu_glue.cpp
+++ b/sources/pyside2/PySide2/glue/qtxml.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -37,28 +37,27 @@
**
****************************************************************************/
-inline PyObject* addActionWithPyObject(QMenu* self, const QIcon& icon, const QString& text, PyObject* callback, const QKeySequence& shortcut)
-{
- QAction* act = new QAction(text, self);
+// @snippet qxmlentityresolver-resolveentity
+QXmlInputSource* _qxmlinputsource_arg_ = nullptr;
+%BEGIN_ALLOW_THREADS
+%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, _qxmlinputsource_arg_);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(2);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QXmlInputSource*](_qxmlinputsource_arg_));
+// @snippet qxmlentityresolver-resolveentity
- if (!icon.isNull())
- act->setIcon(icon);
-
- if (!shortcut.isEmpty())
- act->setShortcut(shortcut);
-
- self->addAction(act);
-
- PyObject* pyAct = %CONVERTTOPYTHON[QAction*](act);
- Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct,
- const_cast<char *>("connect"),
- const_cast<char *>("OsO"),
- pyAct,
- SIGNAL(triggered()), callback));
- if (result.isNull()) {
- Py_DECREF(pyAct);
- return 0;
- }
-
- return pyAct;
-}
+// @snippet qdomdocument-setcontent
+QString _errorMsg_;
+int _errorLine_ = 0;
+int _errorColumn_ = 0;
+%BEGIN_ALLOW_THREADS
+bool _ret_ = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &_errorMsg_, &_errorLine_,
+ &_errorColumn_);
+%END_ALLOW_THREADS
+%PYARG_0 = PyTuple_New(4);
+PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](_ret_));
+PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](_errorMsg_));
+PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](_errorLine_));
+PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](_errorColumn_));
+// @snippet qdomdocument-setcontent
diff --git a/sources/pyside2/PySide2/glue/qtxmlpatterns.cpp b/sources/pyside2/PySide2/glue/qtxmlpatterns.cpp
new file mode 100644
index 000000000..b559ad1d4
--- /dev/null
+++ b/sources/pyside2/PySide2/glue/qtxmlpatterns.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+// @snippet qxmlschemavalidator-schema
+QXmlSchema* %0 = new QXmlSchema(%CPPSELF.schema());
+%PYARG_0 = %CONVERTTOPYTHON[QXmlSchema*](%0);
+// @snippet qxmlschemavalidator-schema
diff --git a/sources/pyside2/PySide2/support/__init__.py b/sources/pyside2/PySide2/support/__init__.py
index 18abd9d0e..dda01474d 100644
--- a/sources/pyside2/PySide2/support/__init__.py
+++ b/sources/pyside2/PySide2/support/__init__.py
@@ -37,12 +37,4 @@
##
#############################################################################
-# Import VoidPtr type to expose it under PySide2.support.VoidPtr
-try:
- # The normal import statement when PySide2 is installed.
- from PySide2.shiboken2 import VoidPtr
-except ImportError:
- # When running make test in shiboken build dir, or when running testrunner.py,
- # shiboken2 is not part of the PySide2 module, so it needs to be imported as a standalone
- # module.
- from shiboken2 import VoidPtr
+from shiboken2 import VoidPtr
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
new file mode 100644
index 000000000..bd3e7500a
--- /dev/null
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -0,0 +1,351 @@
+# This Python file uses the following encoding: utf-8
+#############################################################################
+##
+## Copyright (C) 2018 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, unicode_literals
+
+"""
+generate_pyi.py
+
+This script generates the .pyi files for all PySide modules.
+"""
+
+import sys
+import os
+import io
+import re
+import subprocess
+import argparse
+from contextlib import contextmanager
+from textwrap import dedent
+
+
+import logging
+logging.basicConfig(level=logging.INFO)
+logger = logging.getLogger("generate_pyi")
+
+
+# Make sure not to get .pyc in Python2.
+sourcepath = os.path.splitext(__file__)[0] + ".py"
+
+# Can we use forward references?
+USE_PEP563 = sys.version_info[:2] >= (3, 7)
+
+indent = " " * 4
+
+class Writer(object):
+ def __init__(self, outfile):
+ self.outfile = outfile
+ self.history = [True, True]
+
+ def print(self, *args, **kw):
+ # controlling too much blank lines
+ if self.outfile:
+ if args == () or args == ("",):
+ # Python 2.7 glitch: Empty tuples have wrong encoding.
+ # But we use that to skip too many blank lines:
+ if self.history[-2:] == [True, True]:
+ return
+ print("", file=self.outfile, **kw)
+ self.history.append(True)
+ else:
+ print(*args, file=self.outfile, **kw)
+ self.history.append(False)
+
+
+class Formatter(Writer):
+ """
+ Formatter is formatting the signature listing of an enumerator.
+
+ It is written as context managers in order to avoid many callbacks.
+ The separation in formatter and enumerator is done to keep the
+ unrelated tasks of enumeration and formatting apart.
+ """
+ @contextmanager
+ def module(self, mod_name):
+ self.mod_name = mod_name
+ self.print("# Module", mod_name)
+ self.print("import shiboken2 as Shiboken")
+ from PySide2.support.signature import typing
+ self.print("from PySide2.support.signature import typing")
+ self.print("from PySide2.support.signature.mapping import (")
+ self.print(" Virtual, Missing, Invalid, Default, Instance)")
+ self.print()
+ self.print("class Object(object): pass")
+ self.print()
+ self.print("Shiboken.Object = Object")
+ self.print()
+ # This line will be replaced by the missing imports.
+ self.print("IMPORTS")
+ yield
+
+ @contextmanager
+ def klass(self, class_name, class_str):
+ self.class_name = class_name
+ spaces = ""
+ while "." in class_name:
+ spaces += indent
+ class_name = class_name.split(".", 1)[-1]
+ class_str = class_str.split(".", 1)[-1]
+ self.print()
+ if not spaces:
+ self.print()
+ here = self.outfile.tell()
+ self.print("{spaces}class {class_str}:".format(**locals()))
+ self.print()
+ pos = self.outfile.tell()
+ self.spaces = spaces
+ yield
+ if pos == self.outfile.tell():
+ # we have not written any function
+ self.outfile.seek(here)
+ self.outfile.truncate()
+ # Note: we cannot use class_str when we have no body.
+ self.print("{spaces}class {class_name}: ...".format(**locals()))
+ if "<" in class_name:
+ # This is happening in QtQuick for some reason:
+ ## class QSharedPointer<QQuickItemGrabResult >:
+ # We simply skip over this class.
+ self.outfile.seek(here)
+ self.outfile.truncate()
+
+ @contextmanager
+ def function(self, func_name, signature):
+ key = func_name
+ spaces = indent + self.spaces if self.class_name else ""
+ if type(signature) == type([]):
+ for sig in signature:
+ self.print('{spaces}@typing.overload'.format(**locals()))
+ self._function(func_name, sig, spaces)
+ else:
+ self._function(func_name, signature, spaces)
+ yield key
+
+ def _function(self, func_name, signature, spaces):
+ # this would be nicer to get somehow together with the signature
+ is_meth = re.match(r"\((\w*)", str(signature)).group(1) == "self"
+ if self.class_name and not is_meth:
+ self.print('{spaces}@staticmethod'.format(**locals()))
+ self.print('{spaces}def {func_name}{signature}: ...'.format(**locals()))
+
+
+def get_license_text():
+ with io.open(sourcepath) as f:
+ lines = f.readlines()
+ license_line = next((lno for lno, line in enumerate(lines)
+ if "$QT_END_LICENSE$" in line))
+ return "".join(lines[:license_line + 3])
+
+
+def find_imports(text):
+ return [imp for imp in PySide2.__all__ if imp + "." in text]
+
+
+def safe_create(filename):
+ pid = os.getpid()
+ locname = "{filename}.{pid}".format(**locals())
+ f = io.open(locname, "w") # do not close for atomic rename on Linux
+ if sys.platform == "win32":
+ f.close()
+ try:
+ os.rename(locname, filename)
+ logger.debug("{pid}:File {filename} created".format(**locals()))
+ if sys.platform == "win32":
+ f = io.open(filename, "w")
+ return f
+ except OSError:
+ logger.debug("{pid}:Could not rename {locname} to {filename}"
+ .format(**locals()))
+ try:
+ os.remove(locname)
+ except OSError as e:
+ logger.warning("{pid}: unexpected os.remove error in safe_create: {e}"
+ .format(**locals()))
+ return None
+
+
+def generate_pyi(import_name, outpath, options):
+ """
+ Generates a .pyi file.
+
+ Returns 1 If the result is valid, else 0.
+ """
+ pid = os.getpid()
+ plainname = import_name.split(".")[-1]
+ if not outpath:
+ outpath = os.path.dirname(PySide2.__file__)
+ outfilepath = os.path.join(outpath, plainname + ".pyi")
+ if options.skip and os.path.exists(outfilepath):
+ logger.debug("{pid}:Skipped existing: {outfilepath}".format(**locals()))
+ return 1
+ workpath = outfilepath + ".working"
+ if os.path.exists(workpath):
+ return 0
+ realfile = safe_create(workpath)
+ if not realfile:
+ return 0
+
+ try:
+ top = __import__(import_name)
+ obj = getattr(top, plainname)
+ if not getattr(obj, "__file__", None) or os.path.isdir(obj.__file__):
+ raise ImportError("We do not accept a namespace as module {plainname}"
+ .format(**locals()))
+ module = sys.modules[import_name]
+
+ outfile = io.StringIO()
+ fmt = Formatter(outfile)
+ enu = HintingEnumerator(fmt)
+ fmt.print(get_license_text()) # which has encoding, already
+ need_imports = not USE_PEP563
+ if USE_PEP563:
+ fmt.print("from __future__ import annotations")
+ fmt.print()
+ fmt.print(dedent('''\
+ """
+ This file contains the exact signatures for all functions in module
+ {import_name}, except for defaults which are replaced by "...".
+ """
+ '''.format(**locals())))
+ enu.module(import_name)
+ fmt.print()
+ fmt.print("# eof")
+
+ except ImportError as e:
+ logger.debug("{pid}:Import problem with module {plainname}: {e}".format(**locals()))
+ try:
+ os.remove(workpath)
+ except OSError as e:
+ logger.warning("{pid}: unexpected os.remove error in generate_pyi: {e}"
+ .format(**locals()))
+ return 0
+
+ wr = Writer(realfile)
+ outfile.seek(0)
+ while True:
+ line = outfile.readline()
+ if not line:
+ break
+ line = line.rstrip()
+ # we remove the IMPORTS marker and insert imports if needed
+ if line == "IMPORTS":
+ if need_imports:
+ for mod_name in find_imports(outfile.getvalue()):
+ imp = "PySide2." + mod_name
+ if imp != import_name:
+ wr.print("import " + imp)
+ wr.print("import " + import_name)
+ wr.print()
+ wr.print()
+ else:
+ wr.print(line)
+ realfile.close()
+
+ if os.path.exists(outfilepath):
+ os.remove(outfilepath)
+ try:
+ os.rename(workpath, outfilepath)
+ except OSError:
+ logger.warning("{pid}: probable duplicate generated: {outfilepath}"#
+ .format(**locals()))
+ return 0
+ logger.info("Generated: {outfilepath}".format(**locals()))
+ if sys.version_info[0] == 3:
+ # Python 3: We can check the file directly if the syntax is ok.
+ subprocess.check_output([sys.executable, outfilepath])
+ return 1
+
+
+def generate_all_pyi(outpath, options):
+ ps = os.pathsep
+ if options.sys_path:
+ # make sure to propagate the paths from sys_path to subprocesses
+ sys_path = [os.path.normpath(_) for _ in options.sys_path]
+ sys.path[0:0] = sys_path
+ pypath = ps.join(sys_path)
+ os.environ["PYTHONPATH"] = pypath
+ if options.lib_path:
+ # the path changes are automatically propagated to subprocesses
+ ospath_var = "PATH" if sys.platform == "win32" else "LD_LIBRARY_PATH"
+ old_val = os.environ.get(ospath_var, "")
+ lib_path = [os.path.normpath(_) for _ in options.lib_path]
+ ospath = ps.join(lib_path + old_val.split(ps))
+ os.environ[ospath_var] = ospath
+
+ # now we can import
+ global PySide2, inspect, HintingEnumerator
+ import PySide2
+ from PySide2.support.signature import inspect
+ from PySide2.support.signature.lib.enum_sig import HintingEnumerator
+
+ valid = 0
+ for mod_name in PySide2.__all__:
+ import_name = "PySide2." + mod_name
+ valid += generate_pyi(import_name, outpath, options)
+
+ npyi = len(PySide2.__all__)
+ if valid == npyi:
+ logger.info("+++ All {npyi} .pyi files have been created.".format(**locals()))
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(dest="command")
+ # create the parser for the "run" command
+ parser_run = subparsers.add_parser("run",
+ help="run the generation",
+ description="This script generates the .pyi file for all PySide modules.")
+ parser_run.add_argument("--skip", action="store_true",
+ help="skip existing files")
+ parser_run.add_argument("--outpath",
+ help="the output directory (default = binary location)")
+ parser_run.add_argument("--sys-path", nargs="+",
+ help="a list of strings prepended to sys.path")
+ parser_run.add_argument("--lib-path", nargs="+",
+ help="a list of strings prepended to LD_LIBRARY_PATH (unix) or PATH (windows)")
+ options = parser.parse_args()
+ if options.command == "run":
+ outpath = options.outpath
+ if outpath and not os.path.exists(outpath):
+ os.makedirs(outpath)
+ logger.info("+++ Created path {outpath}".format(**locals()))
+ generate_all_pyi(outpath, options=options)
+ else:
+ parser_run.print_help()
+ sys.exit(1)
diff --git a/sources/pyside2/PySide2/support/signature/__init__.py b/sources/pyside2/PySide2/support/signature/__init__.py
index 0ff9ec7e9..5a87a814a 100644
--- a/sources/pyside2/PySide2/support/signature/__init__.py
+++ b/sources/pyside2/PySide2/support/signature/__init__.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -39,4 +39,8 @@
from __future__ import print_function, absolute_import
-from .loader import inspect
+# Trigger initialization phase 2.
+_ = type.__signature__
+from signature_loader import get_signature, inspect, typing
+
+__all__ = "get_signature inspect typing layout mapping lib".split()
diff --git a/sources/pyside2/PySide2/support/signature/layout.py b/sources/pyside2/PySide2/support/signature/layout.py
new file mode 100644
index 000000000..c8a4062cb
--- /dev/null
+++ b/sources/pyside2/PySide2/support/signature/layout.py
@@ -0,0 +1,42 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+from signature_loader.layout import *
diff --git a/sources/pyside2/PySide2/support/signature/lib/__init__.py b/sources/pyside2/PySide2/support/signature/lib/__init__.py
new file mode 100644
index 000000000..2d640cb89
--- /dev/null
+++ b/sources/pyside2/PySide2/support/signature/lib/__init__.py
@@ -0,0 +1,40 @@
+#############################################################################
+##
+## Copyright (C) 2018 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$
+##
+#############################################################################
+
+# this file intentionally left blank
diff --git a/sources/pyside2/PySide2/support/signature/lib/enum_sig.py b/sources/pyside2/PySide2/support/signature/lib/enum_sig.py
new file mode 100644
index 000000000..1d19ad5e4
--- /dev/null
+++ b/sources/pyside2/PySide2/support/signature/lib/enum_sig.py
@@ -0,0 +1,42 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+from signature_loader.enum_sig import *
diff --git a/sources/pyside2/PySide2/support/signature/loader.py b/sources/pyside2/PySide2/support/signature/loader.py
deleted file mode 100644
index f51bafe79..000000000
--- a/sources/pyside2/PySide2/support/signature/loader.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#############################################################################
-##
-## Copyright (C) 2017 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
-
-"""
-loader.py
-
-The loader has to lazy-load the signature module and also provides a few
-Python modules to support Python 2.7 .
-
-This file was originally directly embedded into the C source.
-After it grew more and more, I now prefer to have it as Python file.
-The remaining stub loader in the C source is now only a short string.
-
-This version does no longer use an embedded .zip file but is a package.
-The old code without a package but with zip compression can still be found
-at https://codereview.qt-project.org/#/c/203533/ for reference.
-"""
-
-import sys
-import os
-
-# Make sure that we always have the PySide containing package first.
-# This is crucial for the mapping during reload in the tests.
-package_dir = __file__
-for _ in "four":
- package_dir = os.path.dirname(package_dir)
-sys.path.insert(0, package_dir)
-if sys.version_info >= (3,):
- import inspect
-else:
- import inspect
- namespace = inspect.__dict__
- from PySide2.support.signature import backport_inspect as inspect
- _doc = inspect.__doc__
- inspect.__dict__.update(namespace)
- inspect.__doc__ += _doc
- # force inspect to find all attributes. See "heuristic" in pydoc.py!
- inspect.__all__ = list(x for x in dir(inspect) if not x.startswith("_"))
-
-# name used in signature.cpp
-from PySide2.support.signature.parser import pyside_type_init
-sys.path.pop(0)
-# Note also that during the tests we have a different encoding that would
-# break the Python license decorated files without an encoding line.
-
-# name used in signature.cpp
-def create_signature(props, sig_kind):
- if not props:
- # empty signatures string
- return
- if isinstance(props["multi"], list):
- return list(create_signature(elem, sig_kind)
- for elem in props["multi"])
- varnames = props["varnames"]
- if sig_kind == "method":
- varnames = ("self",) + varnames
- elif sig_kind == "staticmethod":
- pass
- elif sig_kind == "classmethod":
- varnames = ("klass",) + varnames
- else:
- raise SystemError("Methods must be normal, staticmethod or "
- "classmethod")
- argstr = ", ".join(varnames)
- fakefunc = eval("lambda {}: None".format(argstr))
- fakefunc.__name__ = props["name"]
- fakefunc.__defaults__ = props["defaults"]
- fakefunc.__kwdefaults__ = props["kwdefaults"]
- fakefunc.__annotations__ = props["annotations"]
- return inspect._signature_from_function(inspect.Signature, fakefunc)
-
-# end of file
diff --git a/sources/pyside2/PySide2/support/signature/mapping.py b/sources/pyside2/PySide2/support/signature/mapping.py
index dd3df0988..1a769484d 100644
--- a/sources/pyside2/PySide2/support/signature/mapping.py
+++ b/sources/pyside2/PySide2/support/signature/mapping.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -46,114 +46,28 @@ This module has the mapping from the pyside C-modules view of signatures
to the Python representation.
The PySide modules are not loaded in advance, but only after they appear
-in sys.modules. This minimises the loading overhead.
-In principle, we need to re-load the module, when the imports change.
-But it is much easier to do it on demand, when we get an exception.
-See _resolve_value() in singature.py
+in sys.modules. This minimizes the loading overhead.
"""
-import sys
-import struct
import PySide2
-try:
- from . import typing
-except ImportError:
- import typing
-
-ellipsis = "..."
-Char = typing.Union[str, int] # how do I model the limitation to 1 char?
-StringList = typing.List[str]
-IntList = typing.List[int]
-Variant = typing.Any
-ModelIndexList = typing.List[int]
-QImageCleanupFunction = typing.Callable
-FloatMatrix = typing.List[typing.List[float]]
-# Pair could be more specific, but we loose the info in the generator.
-Pair = typing.Tuple[typing.Any, typing.Any]
-MultiMap = typing.DefaultDict[str, typing.List[str]]
-Text = typing.Text
-
-# ulong_max is only 32 bit on windows.
-ulong_max = 2*sys.maxsize+1 if len(struct.pack("L", 1)) != 4 else 0xffffffff
-ushort_max = 0xffff
-
-GL_COLOR_BUFFER_BIT = 0x00004000
-GL_NEAREST = 0x2600
-
-WId = int
-# from 5.9
-GL_TEXTURE_2D = 0x0DE1
-GL_RGBA = 0x1908
-
-class _NotCalled(str):
- """
- Wrap some text with semantics
-
- This class is wrapped around text in order to avoid calling it.
- There are three reasons for this:
-
- - some instances cannot be created since they are abstract,
- - some can only be created after qApp was created,
- - some have an ugly __repr__ with angle brackets in it.
-
- By using derived classes, good looking instances can be created
- which can be used to generate source code or .pyi files. When the
- real object is needed, the wrapper can simply be called.
- """
- def __repr__(self):
- suppress = "PySide2.support.signature.typing."
- text = self[len(suppress):] if self.startswith(suppress) else self
- return "{}({})".format(type(self).__name__, text)
-
- def __call__(self):
- from .mapping import __dict__ as namespace
- text = self if self.endswith(")") else self + "()"
- return eval(text, namespace)
-
-# Some types are abstract. They just show their name.
-class Virtual(_NotCalled):
- pass
-
-# Other types I simply could not find.
-class Missing(_NotCalled):
- pass
+from signature_loader.sbk_mapping import *
-class Invalid(_NotCalled):
- pass
+Sbk_Reloader = Reloader
-# Helper types
-class Default(_NotCalled):
- pass
-
-class Instance(_NotCalled):
- pass
-
-
-class Reloader(object):
- def __init__(self):
- self.sys_module_count = 0
- self.uninitialized = PySide2.__all__[:]
+class Reloader(Sbk_Reloader):
+ _uninitialized = Sbk_Reloader._uninitialized + PySide2.__all__
+ _prefixes = Sbk_Reloader._prefixes + ["PySide2."]
def update(self):
- if self.sys_module_count == len(sys.modules):
- return
- self.sys_module_count = len(sys.modules)
- g = globals()
- for mod_name in self.uninitialized[:]:
- if "PySide2." + mod_name in sys.modules:
- self.uninitialized.remove(mod_name)
- proc_name = "init_" + mod_name
- if proc_name in g:
- g.update(g[proc_name]())
-
+ Sbk_Reloader.update(self, globals())
update_mapping = Reloader().update
-type_map = {}
+
def init_QtCore():
import PySide2.QtCore
- from PySide2.QtCore import Qt, QUrl, QDir, QGenericArgument
+ from PySide2.QtCore import Qt, QUrl, QDir
from PySide2.QtCore import QRect, QSize, QPoint, QLocale, QByteArray
from PySide2.QtCore import QMarginsF # 5.9
try:
@@ -201,9 +115,8 @@ def init_QtCore():
"ULONG_MAX": ulong_max,
"quintptr": int,
"PyCallable": typing.Callable,
- "...": ellipsis, # no idea how this should be translated... maybe so?
"PyTypeObject": type,
- "PySequence": typing.Sequence,
+ "PySequence": typing.Iterable, # important for numpy
"qptrdiff": int,
"true": True,
"Qt.HANDLE": int, # be more explicit with some consts?
@@ -242,7 +155,7 @@ def init_QtCore():
"QDir.SortFlags(QDir.Name | QDir.IgnoreCase)"),
"PyBytes": bytes,
"PyByteArray": bytearray,
- "PyUnicode": Text,
+ "PyUnicode": typing.Text,
"signed long": int,
"PySide2.QtCore.int": int,
"PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
@@ -259,13 +172,13 @@ def init_QtCore():
"float[][]": FloatMatrix, # 5.9
"PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
"PySide2.QtCore.long long": int, # 5.9, MSVC 15
- "QGenericArgument(nullptr)": QGenericArgument(None), # 5.10
+ "QGenericArgument(nullptr)": ellipsis, # 5.10
"QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
- "QGenericArgument((0))": None, # 5.6, RHEL 6.6. Is that ok?
- "QGenericArgument()": None,
- "QGenericArgument(0)": None,
- "QGenericArgument(NULL)": None, # 5.6, MSVC
- "QGenericArgument(Q_NULLPTR)": None,
+ "QGenericArgument((0))": ellipsis, # 5.6, RHEL 6.6. Is that ok?
+ "QGenericArgument()": ellipsis,
+ "QGenericArgument(0)": ellipsis,
+ "QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
+ "QGenericArgument(Q_NULLPTR)": ellipsis,
"zero(PySide2.QtCore.QObject)": None,
"zero(PySide2.QtCore.QThread)": None,
"zero(quintptr)": 0,
@@ -289,6 +202,9 @@ def init_QtCore():
"zero(PySide2.QtCore.QEvent.Type)": None,
"CheckIndexOption.NoOption": Instance(
"PySide2.QtCore.QAbstractItemModel.CheckIndexOptions.NoOption"), # 5.11
+ "QVariantMap": dict,
+ "PySide2.QtCore.QCborStreamReader.StringResult": typing.AnyStr,
+ "PySide2.QtCore.double": float,
})
try:
type_map.update({
@@ -299,9 +215,10 @@ def init_QtCore():
pass
return locals()
+
def init_QtGui():
import PySide2.QtGui
- from PySide2.QtGui import QPageLayout, QPageSize # 5.9
+ from PySide2.QtGui import QPageLayout, QPageSize # 5.12 macOS
type_map.update({
"QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
"USHRT_MAX": ushort_max,
@@ -313,7 +230,7 @@ def init_QtGui():
"GL_COLOR_BUFFER_BIT": GL_COLOR_BUFFER_BIT,
"GL_NEAREST": GL_NEAREST,
"WId": WId,
- "PySide2.QtGui.QPlatformSurface": Virtual("PySide2.QtGui.QPlatformSurface"), # hmm...
+ "PySide2.QtGui.QPlatformSurface": int, # a handle
"QList< QTouchEvent.TouchPoint >()": [], # XXX improve?
"QPixmap()": Default("PySide2.QtGui.QPixmap"), # can't create without qApp
"PySide2.QtCore.uint8_t": int, # macOS 5.9
@@ -325,9 +242,11 @@ def init_QtGui():
"zero(PySide2.QtGui.QTextLayout.FormatRange)": None,
"zero(PySide2.QtGui.QTouchDevice)": None,
"zero(PySide2.QtGui.QScreen)": None,
+ "PySide2.QtGui.QGenericMatrix": Missing("PySide2.QtGui.QGenericMatrix"),
})
return locals()
+
def init_QtWidgets():
import PySide2.QtWidgets
from PySide2.QtWidgets import QWidget, QMessageBox, QStyleOption, QStyleHintReturn, QStyleOptionComplex
@@ -364,6 +283,7 @@ def init_QtWidgets():
})
return locals()
+
def init_QtSql():
import PySide2.QtSql
from PySide2.QtSql import QSqlDatabase
@@ -373,6 +293,7 @@ def init_QtSql():
})
return locals()
+
def init_QtNetwork():
import PySide2.QtNetwork
type_map.update({
@@ -383,6 +304,7 @@ def init_QtNetwork():
})
return locals()
+
def init_QtXmlPatterns():
import PySide2.QtXmlPatterns
from PySide2.QtXmlPatterns import QXmlName
@@ -392,16 +314,16 @@ def init_QtXmlPatterns():
})
return locals()
-def init_QtMultimedia():
- import PySide2.QtMultimedia
+
+def init_QtMultimediaWidgets():
import PySide2.QtMultimediaWidgets
type_map.update({
- "QVariantMap": dict,
"QGraphicsVideoItem": PySide2.QtMultimediaWidgets.QGraphicsVideoItem,
"QVideoWidget": PySide2.QtMultimediaWidgets.QVideoWidget,
})
return locals()
+
def init_QtOpenGL():
import PySide2.QtOpenGL
type_map.update({
@@ -418,6 +340,7 @@ def init_QtOpenGL():
})
return locals()
+
def init_QtQml():
import PySide2.QtQml
type_map.update({
@@ -430,6 +353,7 @@ def init_QtQml():
})
return locals()
+
def init_QtQuick():
import PySide2.QtQuick
type_map.update({
@@ -441,6 +365,7 @@ def init_QtQuick():
})
return locals()
+
def init_QtScript():
import PySide2.QtScript
type_map.update({
@@ -448,6 +373,7 @@ def init_QtScript():
})
return locals()
+
def init_QtTest():
import PySide2.QtTest
type_map.update({
@@ -459,7 +385,6 @@ def init_QtTest():
def init_QtWebEngineWidgets():
import PySide2.QtWebEngineWidgets
type_map.update({
- "PySide2.QtTest.QTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
"zero(PySide2.QtWebEngineWidgets.QWebEnginePage.FindFlags)": 0,
})
return locals()
@@ -472,6 +397,16 @@ def init_QtWinExtras():
})
return locals()
-# Here was testbinding, actually the source of all evil.
+# from 5.12, macOS
+def init_QtDataVisualization():
+ from PySide2.QtDataVisualization import QtDataVisualization
+ QtDataVisualization.QBarDataRow = typing.List[QtDataVisualization.QBarDataItem]
+ QtDataVisualization.QBarDataArray = typing.List[QtDataVisualization.QBarDataRow]
+ QtDataVisualization.QSurfaceDataRow = typing.List[QtDataVisualization.QSurfaceDataItem]
+ QtDataVisualization.QSurfaceDataArray = typing.List[QtDataVisualization.QSurfaceDataRow]
+ type_map.update({
+ "100.0f": 100.0,
+ })
+ return locals()
# end of file
diff --git a/sources/pyside2/PySide2/support/signature/typing.py b/sources/pyside2/PySide2/support/signature/typing.py
new file mode 100644
index 000000000..dd52a2c45
--- /dev/null
+++ b/sources/pyside2/PySide2/support/signature/typing.py
@@ -0,0 +1,42 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+from signature_loader.typing import *
diff --git a/sources/pyside2/PySide2/typesystem_templates.xml b/sources/pyside2/PySide2/templates/core_common.xml
index 187dc5c42..0fe19273b 100644
--- a/sources/pyside2/PySide2/typesystem_templates.xml
+++ b/sources/pyside2/PySide2/templates/core_common.xml
@@ -2,7 +2,7 @@
<!--
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -40,21 +40,13 @@
****************************************************************************/
-->
<typesystem>
- <template name="replace_child">
- $CHILD_TYPE* oldChild = %CPPSELF.$FUNCTION_GET_OLD();
- if (oldChild &amp;&amp; (oldChild != $CPPARG)) {
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[$CHILD_TYPE*](oldChild));
- Shiboken::Object::setParent(0, pyChild);
- Shiboken::Object::releaseOwnership(pyChild);
- }
- Shiboken::Object::setParent(%PYSELF, $PYARG);
- </template>
<template name="tuple_ok_retval">
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](ok_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](ok_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
</template>
+
<template name="bool*_fix,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -62,6 +54,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_ok_retval"/>
</template>
+
<template name="bool*_fix,arg,arg,arg,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -69,12 +62,14 @@
%END_ALLOW_THREADS
<insert-template name="tuple_ok_retval"/>
</template>
+
<!-- Templates to fix bool* parameters -->
<template name="tuple_retval_ok">
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[bool](ok_));
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[bool](ok_));
</template>
+
<template name="fix_bool*">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -82,6 +77,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_args,bool*">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -89,6 +85,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_arg,bool*,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -96,6 +93,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_bool*,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -103,6 +101,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_bool*,arg,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -110,6 +109,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_bool*,arg,arg,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -117,6 +117,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_bool*,arg,arg,arg,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -124,6 +125,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_arg,arg,arg,arg,arg,arg,arg,bool*,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -131,6 +133,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_arg,arg,arg,arg,arg,arg,bool*,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -138,6 +141,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_arg,arg,arg,arg,arg,bool*,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -145,6 +149,7 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
+
<template name="fix_arg,arg,arg,arg,bool*,arg,arg">
bool ok_;
%BEGIN_ALLOW_THREADS
@@ -152,86 +157,39 @@
%END_ALLOW_THREADS
<insert-template name="tuple_retval_ok"/>
</template>
- <template name="get_slice">
- %TYPE* sequence;
- Py_ssize_t start, end;
- Py_ssize_t len = %CPPSELF->count();
-
- if (_i1 &gt; len)
- start = len;
- else if (_i1 &lt; 0)
- start = 0;
- else
- start = _i1;
-
- if (_i2 &gt; len)
- end = len;
- else if (_i2 &lt; 0)
- end = 0;
- else
- end = _i2;
-
- sequence = new %TYPE();
- for (Py_ssize_t i = start; i &lt; end; i++)
- sequence->append(%CPPSELF->at(i));
-
- return %CONVERTTOPYTHON[%TYPE](*sequence);
- </template>
- <template name="fix_args,QRectF*">
- QRectF rect_;
+ <template name="fix_char*">
+ char val_{};
%BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;rect_);
+ %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;val_);
%END_ALLOW_THREADS
- %PYARG_0 = %CONVERTTOPYTHON[QRectF](rect_);
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[char](val_));
</template>
- <template name="glGetString_return_QString">
- %BEGIN_ALLOW_THREADS
- const GLubyte *us = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES);
- const QString s = QString::fromLocal8Bit(reinterpret_cast&lt;const char *&gt;(us));
- %END_ALLOW_THREADS
- %PYARG_0 = %CONVERTTOPYTHON[QString](s);
+ <template name="tuple_abcd_same_type">
+ %PYARG_0 = PyTuple_New(4);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[$TYPE](c));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[$TYPE](d));
</template>
- <template name="fix_args,QRect*">
- QRect rect_;
+ <template name="fix_number*,number*,number*,number*">
+ $TYPE a, b, c, d;
%BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;rect_);
+ %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d);
%END_ALLOW_THREADS
- %PYARG_0 = %CONVERTTOPYTHON[QRect](rect_);
- </template>
-
- <template name="fix_char*">
- char val_{};
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&amp;val_);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[char](val_));
+ <insert-template name="tuple_abcd_same_type"/>
</template>
- <template name="tuple_abcd_same_type">
- %PYARG_0 = PyTuple_New(4);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[$TYPE](c));
- PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[$TYPE](d));
- </template>
- <template name="fix_number*,number*,number*,number*">
- $TYPE a, b, c, d;
- %BEGIN_ALLOW_THREADS
- %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d);
- %END_ALLOW_THREADS
- <insert-template name="tuple_abcd_same_type"/>
- </template>
<template name="fix_number*,number*,number*,number*,args">
- $TYPE a, b, c, d;
- %BEGIN_ALLOW_THREADS
- %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d, %ARGUMENT_NAMES);
- %END_ALLOW_THREADS
- <insert-template name="tuple_abcd_same_type"/>
+ $TYPE a, b, c, d;
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF->::%TYPE::%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d, %ARGUMENT_NAMES);
+ %END_ALLOW_THREADS
+ <insert-template name="tuple_abcd_same_type"/>
</template>
<template name="fix_native_return_number*,number*,number*,number*">
@@ -252,42 +210,26 @@
</template>
<template name="fix_number*,number*,number*,number*,number*">
- $TYPE a, b, c, d, e;
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d, &amp;e);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(5);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[$TYPE](c));
- PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[$TYPE](d));
- PyTuple_SET_ITEM(%PYARG_0, 4, %CONVERTTOPYTHON[$TYPE](e));
- </template>
-
- <template name="read_wrapper">
- Shiboken::AutoArrayPointer&lt;char&gt; _data(%2);
- qint64 _size = %CPPSELF.%FUNCTION_NAME(_data, %2);
- QByteArray ba;
- if (_size > 0)
- ba = QByteArray(_data, _size);
- %PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba);
+ $TYPE a, b, c, d, e;
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF.%FUNCTION_NAME(&amp;a, &amp;b, &amp;c, &amp;d, &amp;e);
+ %END_ALLOW_THREADS
+ %PYARG_0 = PyTuple_New(5);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[$TYPE](c));
+ PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[$TYPE](d));
+ PyTuple_SET_ITEM(%PYARG_0, 4, %CONVERTTOPYTHON[$TYPE](e));
</template>
<template name="fix_args,number*,number*">
- $TYPE a, b;
- %BEGIN_ALLOW_THREADS
- %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;a, &amp;b);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
- </template>
-
- <template name="fix_virtual_method_return_value_and_bool*">
- Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 0));
- Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 1));
- %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
- *%2 = %CONVERTTOCPP[bool](_py_ok_);
+ $TYPE a, b;
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;a, &amp;b);
+ %END_ALLOW_THREADS
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[$TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[$TYPE](b));
</template>
<template name="fix_arg,int*,int*">
@@ -302,114 +244,48 @@
PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](b));
</template>
- <template name="return_QString">
- %PYARG_0 = %CONVERTTOPYTHON[QString](%1);
- </template>
- <template name="return_QString_native">
- if (%ISCONVERTIBLE[QString](%PYARG_0))
- %1 = %CONVERTTOCPP[QString](%PYARG_0);
- else
- qWarning("%TYPE::%FUNCTION_NAME: Argument is not convertible to unicode.");
- </template>
-
<template name="return_tuple_QValidator_QString_int">
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE retval_ = %RETURN_TYPE(%CPPSELF.%FUNCTION_NAME(%1, %2));
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(3);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
- PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[%ARG2_TYPE](%2));
- </template>
-
- <template name="return_for_QFileDialog">
- %BEGIN_ALLOW_THREADS
- %RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &amp;%5, %6);
- %END_ALLOW_THREADS
- %PYARG_0 = PyTuple_New(2);
- PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
- PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG5_TYPE](%5));
+ %BEGIN_ALLOW_THREADS
+ %RETURN_TYPE retval_ = %RETURN_TYPE(%CPPSELF.%FUNCTION_NAME(%1, %2));
+ %END_ALLOW_THREADS
+ %PYARG_0 = PyTuple_New(3);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1));
+ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[%ARG2_TYPE](%2));
</template>
- <!-- templates for __repr__ -->
<template name="repr_code">
- QString format = QString().sprintf("%s(%REPR_FORMAT)",
+ QString format = QString::asprintf("%s(%REPR_FORMAT)",
Py_TYPE(%PYSELF)->tp_name, %REPR_ARGS);
%PYARG_0 = Shiboken::String::fromCString(qPrintable(format));
</template>
- <template name="repr_code_matrix">
- QString format= QString("%1((").arg(Py_TYPE(%PYSELF)->tp_name);
-
- QList&lt; %MATRIX_TYPE &gt; cppArgs;
- %MATRIX_TYPE data[%MATRIX_SIZE];
- %CPPSELF.copyDataTo(data);
- int matrixSize = %MATRIX_SIZE;
- for(int size=0; size &lt; matrixSize; size++) {
- if (size > 0)
- format += ", ";
- format += QString::number(data[size]);
- }
- format += "))";
- %PYARG_0 = Shiboken::String::fromCString(qPrintable(format));
+ <!-- Helpers for modifying "bool nativeEventFilter(QByteArray, void*, long *result)"
+ to return a tuple of bool,long -->
+ <template name="return_native_eventfilter_conversion_variables">
+ long resultVar{0};
+ long *%out = &amp;resultVar;
+ </template>
+ <template name="return_native_eventfilter_conversion">
+ %RETURN_TYPE %out = false;
+ if (PySequence_Check(%PYARG_0) &amp;&amp; (PySequence_Size(%PYARG_0) == 2)) {
+ Shiboken::AutoDecRef pyItem(PySequence_GetItem(%PYARG_0, 0));
+ %out = %CONVERTTOCPP[bool](pyItem);
+ Shiboken::AutoDecRef pyResultItem(PySequence_GetItem(pyResult, 1));
+ *result = %CONVERTTOCPP[long](pyResultItem);
+ }
</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 name="return_native_eventfilter">
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[long](*result_out));
</template>
<!-- templates for __reduce__ -->
<template name="reduce_code">
%PYARG_0 = Py_BuildValue("(N(%REDUCE_FORMAT))", PyObject_Type(%PYSELF), %REDUCE_ARGS);
</template>
- <template name="reduce_code_matrix">
- QList&lt; %MATRIX_TYPE &gt; cppArgs;
- %MATRIX_TYPE data[%MATRIX_SIZE];
- %CPPSELF.copyDataTo(data);
- int matrixSize = %MATRIX_SIZE;
- for(int size=0; size &lt; matrixSize; size++)
- cppArgs.append(data[size]);
-
- PyObject *type = PyObject_Type(%PYSELF);
- PyObject *args = Py_BuildValue("(N)", %CONVERTTOPYTHON[QList&lt;%MATRIX_TYPE&gt; ](cppArgs));
- %PYARG_0 = Py_BuildValue("(NN)", type, args);
- </template>
-
- <!-- Matrix Aux functions -->
- <template name="matrix_constructor">
- if (PySequence_Size(%PYARG_1) == %SIZE) {
- Shiboken::AutoDecRef fast(PySequence_Fast(%PYARG_1, "Failed to parse sequence on %TYPE constructor."));
- float values[%SIZE];
- for(int i=0; i &lt; %SIZE; i++) {
- PyObject *pv = PySequence_Fast_GET_ITEM(fast.object(), i);
- values[i] = %CONVERTTOCPP[float](pv);
- }
- %0 = new %TYPE(values);
- }
- </template>
-
- <template name="matrix_data_function">
- const float* data = %CPPSELF.constData();
- PyObject *pyData = PyTuple_New(%MATRIX_SIZE);
- if (data) {
- for(int i=0; i &lt; %MATRIX_SIZE; i++)
- PyTuple_SET_ITEM(pyData, i, %CONVERTTOPYTHON[float](data[i]));
- }
- return pyData;
- </template>
-
- <template name="matrix_fill_function">
- float value = %CONVERTTOCPP[float](%PYARG_1);
- %CPPSELF.fill(value);
- </template>
-
- <template name="matrix_transposed_function">
- %TRANSPOSED_TYPE transp = %CPPSELF.transposed();
- return %CONVERTTOPYTHON[%TRANSPOSED_TYPE](transp);
- </template>
<!-- Replace '#' for the argument number you want. -->
<template name="return_argument">
@@ -423,32 +299,6 @@
%PYARG_0 = %PYSELF;
</template>
- <template name="__iter_parent__">
- %CPPSELF_TYPE _tmp = %CPPSELF.begin();
- %PYARG_0 = %CONVERTTOPYTHON[%CPPSELF_TYPE](_tmp);
- </template>
-
- <template name="__next__">
- if (!%CPPSELF.atEnd()) {
- %PYARG_0 = %CONVERTTOPYTHON[%CPPSELF_TYPE](*%CPPSELF);
- ++(*%CPPSELF);
- }
- </template>
-
- <template name="convertFromMultiMap">
- %RETURN_NAME = PyDict_New();
- foreach(%KEY_TYPE _key, %MAP_NAME.keys()) {
- Shiboken::AutoDecRef _pyValueList(PyList_New(0));
- foreach(%VALUE_TYPE _value, %MAP_NAME.values(_key)) {
- Shiboken::AutoDecRef _pyValue(%CONVERTTOPYTHON[%VALUE_TYPE](_value));
- PyList_Append(_pyValueList, _pyValue);
- }
-
- Shiboken::AutoDecRef _pyKey(%CONVERTTOPYTHON[%KEY_TYPE](_key));
- PyDict_SetItem(%RETURN_NAME, _pyKey, _pyValueList);
- }
- </template>
-
<template name="to_tuple">
%PYARG_0 = Py_BuildValue("%TT_FORMAT", %TT_ARGS);
</template>
@@ -462,13 +312,16 @@
}
return %out;
</template>
+
<template name="pyseq_to_cpplist_conversion">
- for (int i = 0; i &lt; PySequence_Size(%in); i++) {
+ for (int i = 0, size = PySequence_Size(%in); i &lt; size; i++) {
+
Shiboken::AutoDecRef pyItem(PySequence_GetItem(%in, i));
%OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
%out &lt;&lt; cppItem;
}
</template>
+
<template name="cppvector_to_pylist_conversion">
%INTYPE::size_type vectorSize = %in.size();
PyObject* %out = PyList_New((int) vectorSize);
@@ -478,6 +331,7 @@
}
return %out;
</template>
+
<template name="pyseq_to_cppvector_conversion">
int vectorSize = PySequence_Size(%in);
%out.reserve(vectorSize);
@@ -499,4 +353,43 @@
}
</template>
+ <template name="cppmap_to_pymap_conversion">
+ PyObject *%out = PyDict_New();
+ for (%INTYPE::const_iterator it = %in.begin(), end = %in.end(); it != end; ++it) {
+ %INTYPE_0 key = it.key();
+ %INTYPE_1 value = it.value();
+ PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
+ PyObject *pyValue = %CONVERTTOPYTHON[%INTYPE_1](value);
+ PyDict_SetItem(%out, pyKey, pyValue);
+ Py_DECREF(pyKey);
+ Py_DECREF(pyValue);
+ }
+ return %out;
+ </template>
+
+ <template name="pydict_to_cppmap_conversion">
+ PyObject *key;
+ PyObject *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(%in, &amp;pos, &amp;key, &amp;value)) {
+ %OUTTYPE_0 cppKey = %CONVERTTOCPP[%OUTTYPE_0](key);
+ %OUTTYPE_1 cppValue = %CONVERTTOCPP[%OUTTYPE_1](value);
+ %out.insert(cppKey, cppValue);
+ }
+ </template>
+
+ <template name="pydatetime_importandcheck_function">
+ #ifdef IS_PY3K
+ #define PySideDateTime_IMPORT PyDateTime_IMPORT
+ #else
+ #define PySideDateTime_IMPORT \
+ (PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import((char*)"datetime", \
+ (char*)"datetime_CAPI"))
+ #endif
+ static bool PyDateTime_ImportAndCheck(PyObject *pyIn) {
+ if (!PyDateTimeAPI) PySideDateTime_IMPORT;
+ return $DATETIMETYPE_Check(pyIn);
+ }
+ </template>
+
</typesystem>
diff --git a/sources/pyside2/PySide2/QtCore/glue/qbytearray_mgetitem.cpp b/sources/pyside2/PySide2/templates/datavisualization_common.xml
index 9612f41b0..ee040c977 100644
--- a/sources/pyside2/PySide2/QtCore/glue/qbytearray_mgetitem.cpp
+++ b/sources/pyside2/PySide2/templates/datavisualization_common.xml
@@ -1,3 +1,5 @@
+<?xml version="1.0"?>
+<!--
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
@@ -36,52 +38,39 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+-->
+<typesystem>
+ <template name="cppqlistofptrtoqvectors_to_py_conversion">
+ const int rowCount = %in.size();
+ PyObject* %out = PyList_New(rowCount);
+ for (int r = 0; r &lt; rowCount; ++r) {
+ const QVector&lt;%INTYPE_0&gt; *row = %in.at(r);
+ const int columnCount = row->size();
+ PyObject *pyRow = PyList_New(columnCount);
+ for (int c = 0; c &lt; columnCount; ++c) {
+ const %INTYPE_0 &amp;cppItem = row->at(c);
+ PyList_SET_ITEM(pyRow, c, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+ }
+ PyList_SET_ITEM(%out, r, pyRow);
+ }
+ return %out;
+ </template>
-if (PyIndex_Check(_key)) {
- Py_ssize_t _i;
- _i = PyNumber_AsSsize_t(_key, PyExc_IndexError);
- if (_i < 0 || _i >= %CPPSELF.size()) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return 0;
- } else {
- char res[2];
- res[0] = %CPPSELF.at(_i);
- res[1] = 0;
- return PyBytes_FromStringAndSize(res, 1);
- }
-} else if (PySlice_Check(_key)) {
- Py_ssize_t start, stop, step, slicelength, cur;
-
-#ifdef IS_PY3K
- PyObject *key = _key;
-#else
- PySliceObject *key = reinterpret_cast<PySliceObject *>(_key);
-#endif
- if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
-
- QByteArray ba;
- if (slicelength <= 0) {
- return %CONVERTTOPYTHON[QByteArray](ba);
- } else if (step == 1) {
- Py_ssize_t max = %CPPSELF.count();
- start = qBound(Py_ssize_t(0), start, max);
- stop = qBound(Py_ssize_t(0), stop, max);
- QByteArray ba;
- if (start < stop)
- ba = %CPPSELF.mid(start, stop - start);
- return %CONVERTTOPYTHON[QByteArray](ba);
- } else {
- QByteArray ba;
- for (cur = start; slicelength > 0; cur += static_cast<size_t>(step), slicelength--) {
- ba.append(%CPPSELF.at(cur));
+ <template name="py_to_cppqlistofptrtoqvectors_conversion">
+ const int rowCount = int(PySequence_Size(%in));
+ %OUTTYPE &amp;result = %out;
+ result.reserve(rowCount);
+ for (int r = 0; r &lt; rowCount; ++r) {
+ Shiboken::AutoDecRef rowItem(PySequence_GetItem(%in, r));
+ const int columnCount = int(PySequence_Size(rowItem));
+ QVector&lt;%OUTTYPE_0&gt; *row = new QVector&lt;%OUTTYPE_0&gt;;
+ row->reserve(columnCount);
+ for (int c = 0; c &lt; columnCount; ++c) {
+ Shiboken::AutoDecRef pyItem(PySequence_GetItem(rowItem, c));
+ %OUTTYPE_0 v = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
+ row->append(v);
+ }
+ result.append(row);
}
- return %CONVERTTOPYTHON[QByteArray](ba);
- }
-} else {
- PyErr_Format(PyExc_TypeError,
- "list indices must be integers or slices, not %.200s",
- Py_TYPE(_key)->tp_name);
- return NULL;
-}
+ </template>
+</typesystem>
diff --git a/sources/pyside2/PySide2/templates/gui_common.xml b/sources/pyside2/PySide2/templates/gui_common.xml
new file mode 100644
index 000000000..d25d50014
--- /dev/null
+++ b/sources/pyside2/PySide2/templates/gui_common.xml
@@ -0,0 +1,312 @@
+<?xml version="1.0"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+-->
+<typesystem>
+ <template name="QFontCharFix">
+ int size = Shiboken::String::len(%PYARG_1);
+ if (size == 1) {
+ const char *str = Shiboken::String::toCString(%PYARG_1);
+ QChar ch(str[0]);
+ %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ch);
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "String must have only one character");
+ }
+ </template>
+
+ <template name="load_xpm">
+ Shiboken::AutoDecRef strList(PySequence_Fast(%PYARG_1, "Invalid sequence."));
+ int lineCount = PySequence_Fast_GET_SIZE(strList.object());
+ for (int line = 0; line &lt; lineCount; ++line) {
+ if (!Shiboken::String::check(PySequence_Fast_GET_ITEM(strList.object(), line))) {
+ PyErr_SetString(PyExc_TypeError, "The argument must be a sequence of strings.");
+ break;
+ }
+ }
+
+ const char **xpm = reinterpret_cast&lt;const char**&gt;(malloc(lineCount * sizeof(const char**)));
+ for (int line = 0; line &lt; lineCount; ++line)
+ xpm[line] = Shiboken::String::toCString(PySequence_Fast_GET_ITEM(strList.object(), line));
+
+ %BEGIN_ALLOW_THREADS
+ %0 = new %TYPE(xpm);
+ %END_ALLOW_THREADS
+
+ free(xpm);
+ </template>
+
+ <template name="qmatrix_map">
+ %ARG1_TYPE a, b;
+ %CPPSELF.%FUNCTION_NAME(%1, %2, &amp;a, &amp;b);
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%ARG1_TYPE](a));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](b));
+ </template>
+
+ <template name="qimage_buffer_constructor">
+ auto ptr = reinterpret_cast&lt;uchar*&gt;(Shiboken::Buffer::getPointer(%PYARG_1));
+ %0 = new %TYPE(ptr, %ARGS);
+ </template>
+
+ <template name="qcolor_repr">
+ switch(%CPPSELF.spec()) {
+ case QColor::Rgb:
+ {
+ qreal r, g, b, a;
+ %CPPSELF.getRgbF(&amp;r, &amp;g, &amp;b, &amp;a);
+ QString repr = QString::asprintf("PySide2.QtGui.QColor.fromRgbF(%.6f, %.6f, %.6f, %.6f)", r, g, b, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ case QColor::Hsv:
+ {
+ qreal h, s, v, a;
+ %CPPSELF.getHsvF(&amp;h, &amp;s, &amp;v, &amp;a);
+ QString repr = QString::asprintf("PySide2.QtGui.QColor.fromHsvF(%.6f, %.6f, %.6f, %.6f)", h, s, v, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ case QColor::Cmyk:
+ {
+ qreal c, m, y, k, a;
+ %CPPSELF.getCmykF(&amp;c, &amp;m, &amp;y, &amp;k, &amp;a);
+ QString repr = QString::asprintf("PySide2.QtGui.QColor.fromCmykF(%.6f, %.6f, %.6f, %.6f, %.6f)", c, m, y, k, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ case QColor::Hsl:
+ {
+ qreal h, s, l, a;
+ %CPPSELF.getHslF(&amp;h, &amp;s, &amp;l, &amp;a);
+ QString repr = QString::asprintf("PySide2.QtGui.QColor.fromHslF(%.6f, %.6f, %.6f, %.6f)", h, s, l, a);
+ %PYARG_0 = Shiboken::String::fromCString(qPrintable(repr));
+ break;
+ }
+ default:
+ {
+ %PYARG_0 = Shiboken::String::fromCString("PySide2.QtGui.QColor()");
+ }
+ }
+ </template>
+
+ <template name="validator_conversionrule">
+ QValidator::State %out;
+
+ if (PySequence_Check(%PYARG_0)) {
+ Shiboken::AutoDecRef seq(PySequence_Fast(%PYARG_0, 0));
+ int size = PySequence_Fast_GET_SIZE(seq.object());
+
+ if (size > 1) {
+ if (%ISCONVERTIBLE[QString](PySequence_Fast_GET_ITEM(seq.object(), 1)))
+ %1 = %CONVERTTOCPP[QString](PySequence_Fast_GET_ITEM(seq.object(), 1));
+ else
+ qWarning("%TYPE::%FUNCTION_NAME: Second tuple element is not convertible to unicode.");
+ }
+
+ if (size > 2) {
+ if (%ISCONVERTIBLE[int](PySequence_Fast_GET_ITEM(seq.object(), 2)))
+ %2 = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(seq.object(), 2));
+ else
+ qWarning("%TYPE::%FUNCTION_NAME: Second tuple element is not convertible to int.");
+ }
+ %PYARG_0.reset(PySequence_Fast_GET_ITEM(seq.object(), 0));
+ Py_INCREF(%PYARG_0); // we need to incref, because "%PYARG_0 = ..." will decref the tuple and the tuple will be decrefed again at the end of this scope.
+ }
+
+ // check retrun value
+ if (%ISCONVERTIBLE[QValidator::State](%PYARG_0)) {
+ %out = %CONVERTTOCPP[QValidator::State](%PYARG_0);
+ } else {
+ PyErr_Format(PyExc_TypeError, "Invalid return value in function %s, expected %s, got %s.",
+ "QValidator.validate",
+ "PySide2.QtGui.QValidator.State, (PySide2.QtGui.QValidator.State,), (PySide2.QtGui.QValidator.State, unicode) or (PySide2.QtGui.QValidator.State, unicode, int)",
+ Py_TYPE(pyResult)->tp_name);
+ return QValidator::State();
+ }
+ </template>
+
+ <template name="qpainter_drawlist">
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF.%FUNCTION_NAME(%1.data(), %1.size());
+ %END_ALLOW_THREADS
+ </template>
+
+ <template name="inplace_add">
+ *%CPPSELF += %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="inplace_sub">
+ *%CPPSELF -= %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="inplace_mult">
+ *%CPPSELF *= %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="inplace_div">
+ *%CPPSELF /= %1;
+ return %CONVERTTOPYTHON[%RETURN_TYPE](*%CPPSELF);
+ </template>
+
+ <template name="return_QString_native">
+ if (%ISCONVERTIBLE[QString](%PYARG_0))
+ %1 = %CONVERTTOCPP[QString](%PYARG_0);
+ else
+ qWarning("%TYPE::%FUNCTION_NAME: Argument is not convertible to unicode.");
+ </template>
+
+ <template name="repr_code_matrix">
+ QByteArray format(Py_TYPE(%PYSELF)->tp_name);
+ format += QByteArray("((");
+
+ QList&lt; %MATRIX_TYPE &gt; cppArgs;
+ %MATRIX_TYPE data[%MATRIX_SIZE];
+ %CPPSELF.copyDataTo(data);
+ int matrixSize = %MATRIX_SIZE;
+ for(int size=0; size &lt; matrixSize; size++) {
+ if (size > 0)
+ format += ", ";
+ format += QByteArray::number(data[size]);
+ }
+ format += "))";
+
+ %PYARG_0 = Shiboken::String::fromStringAndSize(format, format.size());
+ </template>
+
+ <template name="reduce_code_matrix">
+ QList&lt; %MATRIX_TYPE &gt; cppArgs;
+ %MATRIX_TYPE data[%MATRIX_SIZE];
+ %CPPSELF.copyDataTo(data);
+ int matrixSize = %MATRIX_SIZE;
+ for(int size=0; size &lt; matrixSize; size++)
+ cppArgs.append(data[size]);
+
+ PyObject *type = PyObject_Type(%PYSELF);
+ PyObject *args = Py_BuildValue("(N)",
+ %CONVERTTOPYTHON[QList&lt;%MATRIX_TYPE&gt; ](cppArgs));
+ %PYARG_0 = Py_BuildValue("(NN)", type, args);
+ </template>
+
+ <template name="matrix_data_function">
+ const float* data = %CPPSELF.constData();
+ PyObject *pyData = PyTuple_New(%MATRIX_SIZE);
+ if (data) {
+ for(int i=0; i &lt; %MATRIX_SIZE; i++)
+ PyTuple_SET_ITEM(pyData, i, %CONVERTTOPYTHON[float](data[i]));
+ }
+ return pyData;
+ </template>
+
+ <template name="matrix_constructor">
+ if (PySequence_Size(%PYARG_1) == %SIZE) {
+ Shiboken::AutoDecRef fast(PySequence_Fast(%PYARG_1,
+ "Failed to parse sequence on %TYPE constructor."));
+ float values[%SIZE];
+ for(int i=0; i &lt; %SIZE; i++) {
+ PyObject *pv = PySequence_Fast_GET_ITEM(fast.object(), i);
+ values[i] = %CONVERTTOCPP[float](pv);
+ }
+ %0 = new %TYPE(values);
+ }
+ </template>
+
+ <template name="glGetString_return_QString">
+ %BEGIN_ALLOW_THREADS
+ const GLubyte *us = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES);
+ const QString s = QString::fromLocal8Bit(reinterpret_cast&lt;const char *&gt;(us));
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[QString](s);
+ </template>
+
+ <template name="fix_args,QRectF*">
+ QRectF rect_;
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;rect_);
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[QRectF](rect_);
+ </template>
+
+ <template name="fix_args,QRect*">
+ QRect rect_;
+ %BEGIN_ALLOW_THREADS
+ %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &amp;rect_);
+ %END_ALLOW_THREADS
+ %PYARG_0 = %CONVERTTOPYTHON[QRect](rect_);
+ </template>
+
+ <template name="__next__">
+ if (!%CPPSELF.atEnd()) {
+ %PYARG_0 = %CONVERTTOPYTHON[%CPPSELF_TYPE](*%CPPSELF);
+ ++(*%CPPSELF);
+ }
+ </template>
+
+ <template name="__iter_parent__">
+ %CPPSELF_TYPE _tmp = %CPPSELF.begin();
+ %PYARG_0 = %CONVERTTOPYTHON[%CPPSELF_TYPE](_tmp);
+ </template>
+
+ <template name="const_char_pybuffer">
+ PyObject *%out = Shiboken::Buffer::newObject(%in, size);
+ </template>
+
+ <template name="pybuffer_const_char">
+ Py_ssize_t bufferLen;
+ char *%out = reinterpret_cast&lt;char*&gt;(Shiboken::Buffer::getPointer(%PYARG_1, &amp;bufferLen));
+ </template>
+
+ <template name="uint_remove">
+ uint %out = bufferLen;
+ </template>
+
+ <template name="pybytes_const_uchar">
+ const uchar *%out = reinterpret_cast&lt;const uchar*>(PyBytes_AS_STRING(%PYARG_1));
+ </template>
+
+ <template name="pybytes_uint">
+ uint %out = static_cast&lt;uint>(PyBytes_Size(%PYARG_1));
+ </template>
+
+
+</typesystem>
diff --git a/sources/pyside2/PySide2/templates/opengl_common.xml b/sources/pyside2/PySide2/templates/opengl_common.xml
new file mode 100644
index 000000000..46299d8d7
--- /dev/null
+++ b/sources/pyside2/PySide2/templates/opengl_common.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+-->
+<typesystem>
+ <template name="callArrayFunction">
+ Py_ssize_t _size = PySequence_Size(%PYARG_2);
+ if (_size) {
+ $ATTR_TYPE *_list = new $ATTR_TYPE[_size];
+ if (_size) {
+ Shiboken::AutoDecRef fast(PySequence_Fast(%PYARG_2,
+ "Failed to parse sequence with type %VECTOR_TYPE."));
+ for(Py_ssize_t i=0; i &lt; _size; i++) {
+ PyObject* pv = PySequence_Fast_GET_ITEM(fast.object(), i);
+ _list[i] = %CONVERTTOCPP[$ATTR_TYPE](pv);
+ }
+ }
+ %CPPSELF.%FUNCTION_NAME(%1, _list, $ARG0);
+ delete[] _list;
+ } else {
+ %CPPSELF.%FUNCTION_NAME(%1, ($ATTR_TYPE*)nullptr, $ARG1);
+ }
+ </template>
+</typesystem>
diff --git a/sources/pyside2/PySide2/QtCore/glue/qobject_findchild.cpp b/sources/pyside2/PySide2/templates/webkitwidgets_common.xml
index b32d104fd..43e560c5f 100644
--- a/sources/pyside2/PySide2/QtCore/glue/qobject_findchild.cpp
+++ b/sources/pyside2/PySide2/templates/webkitwidgets_common.xml
@@ -1,6 +1,8 @@
+<?xml version="1.0"?>
+<!--
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -36,43 +38,36 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-static QObject* _findChildHelper(const QObject* parent, const QString& name, PyTypeObject* desiredType)
-{
- foreach(QObject* child, parent->children()) {
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child));
- if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType)
- && (name.isNull() || name == child->objectName())) {
- return child;
+-->
+<typesystem>
+ <template name="qwebpage_extension_argument_conversion">
+ PyObject* %out = 0;
+ // Cast the parameters according to the extension type
+ if (extension == QWebPage::ChooseMultipleFilesExtension) {
+ const ChooseMultipleFilesExtension$TYPE_SUFFIX* _in = reinterpret_cast&lt;const ChooseMultipleFilesExtension$TYPE_SUFFIX*>(%in);
+ %out = %CONVERTTOPYTHON[const QWebPage::ChooseMultipleFilesExtension$TYPE_SUFFIX*](_in);
+ } else if (extension == QWebPage::ErrorPageExtension) {
+ const auto _in = reinterpret_cast&lt;const ErrorPageExtension$TYPE_SUFFIX*>(%in);
+ %out = %CONVERTTOPYTHON[const QWebPage::ErrorPageExtension$TYPE_SUFFIX*](_in);
}
- }
+ </template>
- QObject* obj;
- foreach(QObject* child, parent->children()) {
- obj = _findChildHelper(child, name, desiredType);
- if (obj)
- return obj;
- }
- return 0;
-}
+ <template name="qstring_remove">
+ QString _local;
+ QString* %4 = &amp;_local;
+ </template>
-static inline bool _findChildrenComparator(const QObject*& child, const QRegExp& name)
-{
- return name.indexIn(child->objectName()) != -1;
-}
+ <template name="pysequence_qstring">
+ Shiboken::AutoDecRef pyRes(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef pyStr(PySequence_GetItem(%PYARG_0, 1));
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](pyRes);
+ *%4 = %CONVERTTOCPP[QString](pyStr);
+ </template>
-static inline bool _findChildrenComparator(const QObject*& child, const QString& name)
-{
- return name.isNull() || name == child->objectName();
-}
+ <template name="qstring_pytuple">
+ %PYARG_0 = PyTuple_New(2);
+ PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0));
+ PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](*%4));
+ </template>
-template<typename T>
-static void _findChildrenHelper(const QObject* parent, const T& name, PyTypeObject* desiredType, PyObject* result)
-{
- foreach(const QObject* child, parent->children()) {
- Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject*](child));
- if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) && _findChildrenComparator(child, name))
- PyList_Append(result, pyChild);
- _findChildrenHelper(child, name, desiredType, result);
- }
-}
+</typesystem>
diff --git a/sources/pyside2/PySide2/templates/widgets_common.xml b/sources/pyside2/PySide2/templates/widgets_common.xml
new file mode 100644
index 000000000..e63785bb2
--- /dev/null
+++ b/sources/pyside2/PySide2/templates/widgets_common.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+-->
+<typesystem>
+
+ <template name="replace_child">
+ $CHILD_TYPE* oldChild = %CPPSELF.$FUNCTION_GET_OLD();
+ if (oldChild &amp;&amp; (oldChild != $CPPARG)) {
+ Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[$CHILD_TYPE*](oldChild));
+ Shiboken::Object::setParent(0, pyChild);
+ Shiboken::Object::releaseOwnership(pyChild);
+ }
+ Shiboken::Object::setParent(%PYSELF, $PYARG);
+ </template>
+
+ <template name="qgraphicsitem_pysequence">
+ int numItems = PySequence_Size(%PYARG_1);
+ Shiboken::AutoArrayPointer&lt;QGraphicsItem*&gt; %out(numItems);
+ for (int i=0; i &lt; numItems; i++) {
+ %out[i] = %CONVERTTOCPP[QGraphicsItem*](PySequence_Fast_GET_ITEM(%PYARG_1, i));
+ }
+ </template>
+
+ <template name="qgraphicsitem_pyobject">
+ Shiboken::AutoDecRef object(PyList_New(0));
+ for (int i=0, max=numItems; i &lt; max; i++) {
+ PyList_Append(object, %CONVERTTOPYTHON[QGraphicsItem*](%in[i]));
+ }
+ PyObject *%out = object.object();
+ </template>
+
+ <template name="qstyleoptiongraphicsitem_pyobject">
+ Shiboken::AutoDecRef option_object(PyList_New(0));
+ for (int i=0, max=numItems; i &lt; max; i++) {
+ const QStyleOptionGraphicsItem* item = &amp;%in[i];
+ PyList_Append(option_object, %CONVERTTOPYTHON[QStyleOptionGraphicsItem](item));
+ }
+ PyObject* %out = option_object.object();
+ </template>
+
+ <template name="pysequence_qstyleoptiongraphicsitem">
+ int numOptions = PySequence_Size(%PYARG_2);
+ Shiboken::AutoArrayPointer&lt;QStyleOptionGraphicsItem&gt; %out(numOptions);
+ for (int i=0; i &lt; numOptions; i++) {
+ %out[i] = %CONVERTTOCPP[QStyleOptionGraphicsItem](PySequence_Fast_GET_ITEM(%PYARG_1, i));
+ }
+ </template>
+
+ <template name="pysequencesize_int">
+ int %out = PySequence_Size(%PYARG_1);
+ </template>
+
+</typesystem>
diff --git a/sources/pyside2/PySide2/templates/xml_common.xml b/sources/pyside2/PySide2/templates/xml_common.xml
new file mode 100644
index 000000000..b13a10c25
--- /dev/null
+++ b/sources/pyside2/PySide2/templates/xml_common.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+-->
+<typesystem>
+
+ <template name="QXmlEntityResolver_resolveEntity_return_conversion_native">
+ Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ok_);
+ %3 = %CONVERTTOCPP[QXmlInputSource*](_py_ret_);
+ </template>
+
+ <template name="fix_virtual_method_return_value_and_bool*">
+ Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 1));
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
+ *%2 = %CONVERTTOCPP[bool](_py_ok_);
+ </template>
+
+</typesystem>
diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake
index 36488912d..42ba8e8a0 100644
--- a/sources/pyside2/cmake/Macros/PySideModules.cmake
+++ b/sources/pyside2/cmake/Macros/PySideModules.cmake
@@ -1,3 +1,14 @@
+include(CMakeParseArguments)
+
+# A version of cmake_parse_arguments that makes sure all arguments are processed and errors out
+# with a message about ${type} having received unknown arguments.
+macro(pyside_parse_all_arguments prefix type flags options multiopts)
+ cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN})
+ if(DEFINED ${prefix}_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).")
+ endif()
+endmacro()
+
macro(make_path varname)
# accepts any number of path variables
string(REPLACE ";" "${PATH_SEP}" ${varname} "${ARGN}")
@@ -7,46 +18,59 @@ macro(unmake_path varname)
string(REPLACE "${PATH_SEP}" ";" ${varname} "${ARGN}")
endmacro()
-macro(create_pyside_module
- module_name
- module_include_dir
- module_libraries
- module_deps
- module_typesystem_path
- module_sources
- module_static_sources)
- string(TOLOWER ${module_name} _module)
- string(REGEX REPLACE ^qt "" _module ${_module})
- if(${ARGC} GREATER 7)
- set (typesystem_name ${ARGV7})
- else()
- set (typesystem_name "")
+# Sample usage
+# create_pyside_module(NAME QtGui
+# INCLUDE_DIRS QtGui_include_dirs
+# LIBRARIES QtGui_libraries
+# DEPS QtGui_deps
+# TYPESYSTEM_PATH QtGui_SOURCE_DIR
+# SOURCES QtGui_SRC
+# STATIC_SOURCES QtGui_static_sources
+# TYPESYSTEM_NAME ${QtGui_BINARY_DIR}/typesystem_gui.xml
+# DROPPED_ENTRIES QtGui_DROPPED_ENTRIES
+# GLUE_SOURCES QtGui_glue_sources)
+macro(create_pyside_module)
+ pyside_parse_all_arguments(
+ "module" # Prefix
+ "create_pyside_module" # Macro name
+ "" # Flags
+ "NAME;TYPESYSTEM_PATH;TYPESYSTEM_NAME" # Single value
+ "INCLUDE_DIRS;LIBRARIES;DEPS;SOURCES;STATIC_SOURCES;DROPPED_ENTRIES;GLUE_SOURCES" # Multival
+ ${ARGN} # Number of arguments given when the macros is called
+ )
+
+ if ("${module_NAME}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs a NAME value.")
+ endif()
+ if ("${module_INCLUDE_DIRS}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs at least one INCLUDE_DIRS value.")
endif()
- if(${ARGC} GREATER 8)
- string(REPLACE ";" "\\;" dropped_entries "${${ARGV8}}")
+ if ("${module_TYPESYSTEM_PATH}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs a TYPESYSTEM_PATH value.")
+ endif()
+ if ("${module_SOURCES}" STREQUAL "")
+ message(FATAL_ERROR "create_pyside_module needs at least one SOURCES value.")
+ endif()
+
+ string(TOLOWER ${module_NAME} _module)
+ string(REGEX REPLACE ^qt "" _module ${_module})
+
+ if(${module_DROPPED_ENTRIES})
+ string(REPLACE ";" "\\;" dropped_entries "${${module_DROPPED_ENTRIES}}")
else()
set (dropped_entries "")
endif()
- if (NOT EXISTS ${typesystem_name})
- set(typesystem_path ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_${_module}.xml)
+ if(${module_GLUE_SOURCES})
+ set (module_GLUE_SOURCES "${${module_GLUE_SOURCES}}")
else()
- set(typesystem_path ${typesystem_name})
+ set (module_GLUE_SOURCES "")
endif()
- # check for class files that were commented away.
- if(DEFINED ${module_sources}_skipped_files)
- if(DEFINED PYTHON3_EXECUTABLE)
- set(_python_interpreter "${PYTHON3_EXECUTABLE}")
- else()
- set(_python_interpreter "${PYTHON_EXECUTABLE}")
- endif()
- if(NOT _python_interpreter)
- message(FATAL_ERROR "*** we need a python interpreter for postprocessing!")
- endif()
- set(_python_postprocessor "${_python_interpreter}" "${CMAKE_CURRENT_BINARY_DIR}/filter_init.py")
+ if (NOT EXISTS ${module_TYPESYSTEM_NAME})
+ set(typesystem_path ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_${_module}.xml)
else()
- set(_python_postprocessor "")
+ set(typesystem_path ${module_TYPESYSTEM_NAME})
endif()
# Create typesystem XML dependencies list, so that whenever they change, shiboken is invoked
@@ -56,7 +80,7 @@ macro(create_pyside_module
get_filename_component(typesystem_root "${CMAKE_CURRENT_SOURCE_DIR}" DIRECTORY)
- set(deps ${module_name} ${${module_deps}})
+ set(deps ${module_NAME} ${${module_DEPS}})
foreach(dep ${deps})
set(glob_expression "${typesystem_root}/${dep}/*.xml")
file(GLOB type_system_files ${glob_expression})
@@ -80,44 +104,74 @@ macro(create_pyside_module
get_filename_component(pyside_binary_dir ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
- add_custom_command(OUTPUT ${${module_sources}}
+ # Install module glue files.
+ string(TOLOWER ${module_NAME} lower_module_name)
+ set(${module_NAME}_glue "${CMAKE_CURRENT_SOURCE_DIR}/../glue/${lower_module_name}.cpp")
+ set(${module_name}_glue_dependency "")
+ if(EXISTS ${${module_NAME}_glue})
+ install(FILES ${${module_NAME}_glue} DESTINATION share/PySide2${pyside2_SUFFIX}/glue)
+ set(${module_NAME}_glue_dependency ${${module_NAME}_glue})
+ endif()
+
+ # Install standalone glue files into typesystems subfolder, so that the resolved relative
+ # paths remain correct.
+ if (module_GLUE_SOURCES)
+ install(FILES ${module_GLUE_SOURCES} DESTINATION share/PySide2${pyside2_SUFFIX}/typesystems/glue)
+ endif()
+
+ add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${${module_SOURCES}}
COMMAND "${SHIBOKEN_BINARY}" ${GENERATOR_EXTRA_FLAGS}
- "${pyside2_BINARY_DIR}/${module_name}_global.h"
+ "${pyside2_BINARY_DIR}/${module_NAME}_global.h"
--include-paths=${shiboken_include_dirs}
${shiboken_framework_include_dirs_option}
- --typesystem-paths=${pyside_binary_dir}${PATH_SEP}${pyside2_SOURCE_DIR}${PATH_SEP}${${module_typesystem_path}}
+ --typesystem-paths=${pyside_binary_dir}${PATH_SEP}${pyside2_SOURCE_DIR}${PATH_SEP}${${module_TYPESYSTEM_PATH}}
--output-directory=${CMAKE_CURRENT_BINARY_DIR}
--license-file=${CMAKE_CURRENT_SOURCE_DIR}/../licensecomment.txt
${typesystem_path}
--api-version=${SUPPORTED_QT_VERSION}
--drop-type-entries="${dropped_entries}"
- COMMAND ${_python_postprocessor}
DEPENDS ${total_type_system_files}
+ ${module_GLUE_SOURCES}
+ ${${module_NAME}_glue_dependency}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
- COMMENT "Running generator for ${module_name}...")
+ COMMENT "Running generator for ${module_NAME}...")
- include_directories(${module_name} ${${module_include_dir}} ${pyside2_SOURCE_DIR})
- add_library(${module_name} MODULE ${${module_sources}} ${${module_static_sources}})
- set_target_properties(${module_name} PROPERTIES
+ include_directories(${module_NAME} ${${module_INCLUDE_DIRS}} ${pyside2_SOURCE_DIR})
+ add_library(${module_NAME} MODULE ${${module_SOURCES}}
+ ${${module_STATIC_SOURCES}})
+ set_target_properties(${module_NAME} PROPERTIES
PREFIX ""
- OUTPUT_NAME "${module_name}${PYTHON_EXTENSION_SUFFIX}"
+ OUTPUT_NAME "${module_NAME}${PYTHON_EXTENSION_SUFFIX}"
LIBRARY_OUTPUT_DIRECTORY ${pyside2_BINARY_DIR})
if(WIN32)
- set_target_properties(${module_name} PROPERTIES SUFFIX ".pyd")
+ set_target_properties(${module_NAME} PROPERTIES SUFFIX ".pyd")
# Sanitize windows.h as pulled by gl.h to prevent clashes with QAbstract3dAxis::min(), etc.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX")
endif()
- target_link_libraries(${module_name} ${${module_libraries}})
- if(${module_deps})
- add_dependencies(${module_name} ${${module_deps}})
+ target_link_libraries(${module_NAME} ${${module_LIBRARIES}})
+ if(${module_DEPS})
+ add_dependencies(${module_NAME} ${${module_DEPS}})
endif()
-
+ create_generator_target(${module_NAME})
+
+ # build type hinting stubs
+ add_custom_command( TARGET ${module_NAME} POST_BUILD
+ COMMAND "${SHIBOKEN_PYTHON_INTERPRETER}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/../support/generate_pyi.py" run --skip
+ --sys-path "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}/../shiboken2/shibokenmodule"
+ --lib-path "${CMAKE_BINARY_DIR}/libpyside" "${CMAKE_BINARY_DIR}/../shiboken2/libshiboken"
+ )
# install
- install(TARGETS ${module_name} LIBRARY DESTINATION ${PYTHON_SITE_PACKAGES}/PySide2)
- string(TOLOWER ${module_name} lower_module_name)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PySide2/${module_name}/pyside2_${lower_module_name}_python.h
- DESTINATION include/PySide2${pyside2_SUFFIX}/${module_name}/)
+ install(TARGETS ${module_NAME} LIBRARY DESTINATION "${PYTHON_SITE_PACKAGES}/PySide2")
+
+ install(DIRECTORY "${CMAKE_BINARY_DIR}/" DESTINATION "${PYTHON_SITE_PACKAGES}"
+ OPTIONAL
+ FILES_MATCHING PATTERN "*.pyi")
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PySide2/${module_NAME}/pyside2_${lower_module_name}_python.h
+ DESTINATION include/PySide2${pyside2_SUFFIX}/${module_NAME}/)
file(GLOB typesystem_files ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_*.xml ${typesystem_path})
# Copy typesystem files and remove module names from the <load-typesystem> element
@@ -134,77 +188,6 @@ macro(create_pyside_module
endforeach()
endmacro()
-#macro(check_qt_class_with_namespace module namespace class optional_source_files dropped_entries [namespace] [module])
-macro(check_qt_class module class optional_source_files dropped_entries)
- if (${ARGC} GREATER 4)
- set (namespace ${ARGV4})
- string(TOLOWER ${namespace} _namespace)
- else ()
- set (namespace "")
- endif ()
- if (${ARGC} GREATER 5)
- set (include_file ${ARGV5})
- else ()
- set (include_file ${class})
- endif ()
- string(TOLOWER ${class} _class)
- # Remove the "Qt" prefix.
- string(SUBSTRING ${module} 2 -1 _module_no_qt_prefix)
- if (_namespace)
- set(_cppfile ${CMAKE_CURRENT_BINARY_DIR}/PySide2/${module}/${_namespace}_${_class}_wrapper.cpp)
- else ()
- set(_cppfile ${CMAKE_CURRENT_BINARY_DIR}/PySide2/${module}/${_class}_wrapper.cpp)
- endif ()
- if (DEFINED PYSIDE_${class})
- if (PYSIDE_${class})
- list(APPEND ${optional_source_files} ${_cppfile})
- else()
- list(APPEND ${dropped_entries} PySide2.${module}.${class})
- endif()
- else()
- if (NOT ${namespace} STREQUAL "" )
- set (NAMESPACE_USE "using namespace ${namespace};")
- else ()
- set (NAMESPACE_USE "")
- endif ()
- set(SRC_FILE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test${class}.cxx)
- file(WRITE ${SRC_FILE}
- "#include <${include_file}>\n"
- "${NAMESPACE_USE}\n"
- "int main() { sizeof(${class}); }\n"
- )
-
- # Because Qt is built with -fPIC (by default), the compile tests also have to have that.
- get_property(ADDITIONAL_FLAGS TARGET Qt5::Core PROPERTY INTERFACE_COMPILE_OPTIONS)
-
- # Don't add version tagging, because for some reason linker fails with:
- # (.qtversion[qt_version_tag]+0x0): undefined reference to `qt_version_tag'
- # Force usage of the C++11 standard. CMAKE_CXX_STANDARD does not work with try_compile
- # but the issue has a fix in CMake 3.9. Thus we use a terrible workaround, we pass the C++
- # standard flag the way CheckCXXSourceCompiles.cmake does it.
-
- set(ADDITIONAL_FLAGS "${ADDITIONAL_FLAGS} -DQT_NO_VERSION_TAGGING ${CMAKE_CXX11_EXTENSION_COMPILE_OPTION}")
-
- try_compile(Q_WORKS ${CMAKE_BINARY_DIR}
- ${SRC_FILE}
- CMAKE_FLAGS
- "-DINCLUDE_DIRECTORIES=${QT_INCLUDE_DIR};${Qt5${_module_no_qt_prefix}_INCLUDE_DIRS}"
- "-DCOMPILE_DEFINITIONS:STRING=${ADDITIONAL_FLAGS}"
- OUTPUT_VARIABLE OUTPUT)
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCheckQtClassTest.log ${OUTPUT})
-
- set("PYSIDE_${class}" ${Q_WORKS} CACHE STRING "Has ${class} class been found?")
- if(Q_WORKS)
- message(STATUS "Checking for ${class} in ${module} -- found")
- list(APPEND ${optional_source_files} ${_cppfile})
- else()
- message(STATUS "Checking for ${class} in ${module} -- not found")
- list(APPEND ${dropped_entries} PySide2.${module}.${class})
- endif()
- endif()
-endmacro()
-
-
# Only add subdirectory if the associated Qt module is found.
# As a side effect, this macro now also defines the variable ${name}_GEN_DIR
# and must be called for every subproject.
diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt
index 5a78db453..428b83350 100644
--- a/sources/pyside2/doc/CMakeLists.txt
+++ b/sources/pyside2/doc/CMakeLists.txt
@@ -87,6 +87,16 @@ add_custom_target(qdoc
add_custom_target(apidoc
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst
COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b html ${CMAKE_CURRENT_BINARY_DIR}/rst html
+ #copying shiboken2 and ApiExtractor doc htmls
+ COMMENT "Copying over the Shiboken2 and ApiExtractor doc HTMLs..."
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2/ApiExtractor
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/doc/html
+ ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/ApiExtractor/doc/html
+ ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2/ApiExtractor
)
# create conf.py based on conf.py.in
@@ -128,7 +138,6 @@ add_dependencies(docrsts qdoc)
# COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_INSTALL_PREFIX}/share/devhelp/books"
# COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_INSTALL_PREFIX}/share/doc/${BINDING_NAME}/html" "${CMAKE_INSTALL_PREFIX}/share/devhelp/books/${BINDING_NAME}"
# )
-
#install files
add_custom_target(apidocinstall
COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/share/doc/PySide2-${BINDING_API_VERSION} && cp -rv ${CMAKE_CURRENT_BINARY_DIR}/html/* ${CMAKE_INSTALL_PREFIX}/share/doc/PySide-${BINDING_API_VERSION}
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py
index 4696bd38b..4696bd38b 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py
index 84e7e9189..84e7e9189 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py
index 63c5665cd..63c5665cd 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py
index fb5541603..fb5541603 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py
index 3eeb024db..3eeb024db 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py
index bf55f0c7e..bf55f0c7e 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py
index 31849e785..31849e785 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py
index 34dd7bb5a..34dd7bb5a 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py
index a0deee957..a0deee957 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py
index 077be436d..077be436d 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py
index bfc35e1ee..bfc35e1ee 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py
index 11c3cf5e9..11c3cf5e9 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py
index 494145357..494145357 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py
index c3363e97e..c3363e97e 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py
index 141189ad8..141189ad8 100644
--- a/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.cpp
+++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py
diff --git a/sources/pyside2/doc/conf.py.in b/sources/pyside2/doc/conf.py.in
index 2eb4e6bf3..99b74deef 100644
--- a/sources/pyside2/doc/conf.py.in
+++ b/sources/pyside2/doc/conf.py.in
@@ -114,7 +114,7 @@ html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-html_title = u'Qt for Python (Technology Preview)'
+html_title = u'Qt for Python'
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
@@ -169,4 +169,4 @@ html_show_sourcelink = False
# Link to the shiboken2 sphinx project to enable linking
# between the two projects.
-intersphinx_mapping = {'shiboken2': ('../../../shiboken2/doc/html','../../../shiboken2/doc/html/objects.inv')}
+intersphinx_mapping = {'shiboken2': ('shiboken2','@CMAKE_BINARY_DIR@/../shiboken2/doc/html/objects.inv')}
diff --git a/sources/pyside2/doc/gettingstarted.rst b/sources/pyside2/doc/gettingstarted.rst
index f24051c18..0a58226a7 100644
--- a/sources/pyside2/doc/gettingstarted.rst
+++ b/sources/pyside2/doc/gettingstarted.rst
@@ -4,15 +4,19 @@ Getting Started
To get started with |project|, install the following prerequisites:
-* Python v3.5 or later
-* libclang v3.9 or later
-* Optional: a virtual environment, such as `venv <https://docs.python.org/3/library/venv.html>`_ or `virtualenv <https://virtualenv.pypa.io/en/stable/installation>`_
+* Python 3.5+ or 2.7
+* libclang 5.0+ (for Qt 5.11) or 6.0+ (for Qt 5.12)
+* Recommended: a virtual environment, such as `venv <https://docs.python.org/3/library/venv.html>`_ or `virtualenv <https://virtualenv.pypa.io/en/stable/installation>`_
With these installed, you are ready to install the |project|
packages using the pip wheel. Run the following command from your command
prompt to install::
- python -m pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.11/latest pyside2 --trusted-host download.qt.io
+ pip install PySide2 # For the latest version on PyPi
+
+or::
+
+ pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.12/latest pyside2 --trusted-host download.qt.io
Now that you have |project| installed, you can test your setup by running the following Python
constructs to print version information:
@@ -44,16 +48,12 @@ guide you through the development process:
def __init__(self):
super().__init__()
- self.hello = ["Hallo Welt", "你好,世界", "Hei maailma",\
- "Hola Mundo", "Привет мир"]
+ self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"]
self.button = QtWidgets.QPushButton("Click me!")
self.text = QtWidgets.QLabel("Hello World")
self.text.setAlignment(QtCore.Qt.AlignCenter)
- self.text.setFont(QtGui.QFont("Titillium", 30))
- self.button.setFont(QtGui.QFont("Titillium", 20))
-
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.text)
self.layout.addWidget(self.button)
diff --git a/sources/pyside2/doc/index.rst b/sources/pyside2/doc/index.rst
index fa1daec00..27fefeb16 100644
--- a/sources/pyside2/doc/index.rst
+++ b/sources/pyside2/doc/index.rst
@@ -102,8 +102,7 @@ Qt Modules
Provides classes to create and use state machines from SCXML files.
|project| also comes with the
-:doc:`Shiboken2 <shiboken2:contents>` generator that outputs C++ code
-for CPython extensions.
+:doc:`Shiboken2 <shiboken2:index>` CPython binding code generator.
.. toctree::
:maxdepth: 2
diff --git a/sources/pyside2/doc/pysideapi2.rst b/sources/pyside2/doc/pysideapi2.rst
index f1cc13391..e552bf21d 100644
--- a/sources/pyside2/doc/pysideapi2.rst
+++ b/sources/pyside2/doc/pysideapi2.rst
@@ -1,12 +1,15 @@
.. _pysideapi2:
-|pymodname| API
-***************
+Qt for Python API
+*******************
One of the goals of |pymodname| is to be API compatible with PyQt5,
with certain exceptions. For example, |pymodname| will not export C++ components
that are marked as deprecated by Qt.
+The latest considerations and known issues will be also reported
+in the `wiki <https://wiki.qt.io/Qt_for_Python/Considerations>`_.
+
__hash__() function return value
================================
diff --git a/sources/pyside2/doc/pysideversion.rst b/sources/pyside2/doc/pysideversion.rst
index 24afba12d..bde48b39e 100644
--- a/sources/pyside2/doc/pysideversion.rst
+++ b/sources/pyside2/doc/pysideversion.rst
@@ -8,20 +8,20 @@ numbers using the following python constructs:
import PySide2.QtCore
- # Prints PySide version
- # e.g. 1.0.2
+ # Prints PySide2 version
+ # e.g. 5.11.1a1
print(PySide2.__version__)
# Gets a tuple with each version component
- # e.g. (1, 0, 2, 'final', 1)
+ # e.g. (5, 11, 1, 'a', 1)
print(PySide2.__version_info__)
- # Prints the Qt version used to compile PySide
- # e.g. "5.11.0"
+ # Prints the Qt version used to compile PySide2
+ # e.g. "5.11.2"
print(PySide2.QtCore.__version__)
- # Gets a tuple with each version components of Qt used to compile PySide
- # e.g. (5, 11, 0)
+ # Gets a tuple with each version components of Qt used to compile PySide2
+ # e.g. (5, 11, 2)
print(PySide2.QtCore.__version_info__)
diff --git a/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst
new file mode 100644
index 000000000..afec6d84f
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst
@@ -0,0 +1,84 @@
+A Simple Button Tutorial
+************************
+
+In this tutorial, we'll show you how to handle **signals and slots**
+using Qt for Python. **Signals and slots** is a Qt feature that lets
+your graphical widgets communicate with other graphical widgets or
+your python code. Our application creates a button that logs the
+`Button clicked, Hello!` message to the python console each time you
+click it.
+
+Let's start by importing the necessary PySide2 classes and python
+`sys` module:
+::
+ import sys
+ from PySide2.QtWidgets import QApplication, QPushButton
+ from PySide2.QtCore import Slot
+
+Let's also create a python function that logs the message to the
+console:
+::
+
+ # Greetings
+ @Slot()
+ def say_hello():
+ print("Button clicked, Hello!")
+
+.. note:: The `@Slot()` is a decorator that identifies a function as
+ a slot. It is not important to understand why for now,
+ but use it always to avoid unexpected behavior.
+
+Now, as mentioned in previous examples you must create the
+`QApplication` to run your PySide2 code:
+::
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+
+Let's create the clickable button, which is a `QPushButton` instance.
+To label the button, we pass a python string to the constructor:
+::
+ # Create a button
+ button = QPushButton("Click me")
+
+Before we show the button, we must connect it to the `say_hello()`
+function that we defined earlier. There are two ways of doing this;
+using the old style or the new style, which is more pythonic. Let's
+use the new style in this case. You can find more information about
+both these styles in the
+`Signals and Slots in PySide2 <https://wiki.qt.io/Qt_for_Python_Signals_and_Slots>`_
+wiki page.
+
+The `QPushButton` has a predefined signal called **clicked**, which
+is triggered every time the button is clicked. We'll connect this
+signal to the `say_hello()` function:
+::
+ # Connect the button to the function
+ button.clicked.connect(say_hello)
+
+Finally, we show the button and start the Qt main loop:
+::
+ # Show the button
+ button.show()
+ # Run the main Qt loop
+ app.exec_()
+
+Here is the complete code for this example:
+::
+ #!/usr/bin/python
+
+ import sys
+ from PySide2.QtWidgets import QApplication, QPushButton
+ from PySide2.QtCore import Slot
+
+ @Slot()
+ def say_hello():
+ print("Button clicked, Hello!")
+
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+ # Create a button, connect it and show it
+ button = QPushButton("Click me")
+ button.clicked.connect(say_hello)
+ button.show()
+ # Run the main Qt loop
+ app.exec_()
diff --git a/sources/pyside2/doc/tutorials/basictutorial/dialog.rst b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst
new file mode 100644
index 000000000..1daa6b89d
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst
@@ -0,0 +1,139 @@
+Creating a Simple PySide2 Dialog Application
+*********************************************
+
+This tutorial shows how to build a simple dialog with some
+basic widgets. The idea is to let users provide their name
+in a `QLineEdit`, and the dialog greets them on click of a
+`QPushButton`.
+
+Let us just start with a simple stub that creates and shows
+a dialog. This stub is updated during the course of this
+tutorial, but you can use this stub as is if you need to:
+::
+ import sys
+ from PySide2.QtWidgets import QApplication, QDialog, QLineEdit, QPushButton
+
+ class Form(QDialog):
+
+ def __init__(self, parent=None):
+ super(Form, self).__init__(parent)
+ self.setWindowTitle("My Form")
+
+
+ if __name__ == '__main__':
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+ # Create and show the form
+ form = Form()
+ form.show()
+ # Run the main Qt loop
+ sys.exit(app.exec_())
+
+The imports aren't new to you, the same for the creation of the
+`QApplication` and the execution of the Qt main loop.
+The only novelty here is the **class definition**.
+
+You can create any class that subclasses PySide2 widgets.
+In this case, we are subclassing `QDialog` to define a custom
+dialog, which we name as **Form**. We have also implemented the
+`init()` method that calls the `QDialog`'s init method with the
+parent widget, if any. Also, the new `setWindowTitle()` method
+just sets the title of the dialog window. In `main()`, you can see
+that we are creating a *Form object* and showing it to the world.
+
+Create the Widgets
+===================
+
+We are going to create two widgets: a `QLineEdit` where users can
+enter their name, and a `QPushButton` that prints the contents of
+the `QLineEdit`.
+So, let's add the following code to the `init()` method of our Form:
+::
+ # Create widgets
+ self.edit = QLineEdit("Write my name here..")
+ self.button = QPushButton("Show Greetings")
+
+It's obvious from the code that both widgets will show the corresponding
+texts.
+
+Create a layout to organize the Widgets
+========================================
+
+Qt comes with layout-support that helps you organize the widgets
+in your application. In this case, let's use `QVBoxLayout` to lay out
+the widgets vertically. Add the following code to the `init()` method,
+after creating the widgets:
+::
+ # Create layout and add widgets
+ layout = QVBoxLayout()
+ layout.addWidget(self.edit)
+ layout.addWidget(self.button)
+ # Set dialog layout
+ self.setLayout(layout)
+
+So, we create the layout, add the widgets with `addWidget()`,
+and finally we say that our **Form** will have our `QVBoxLayout`
+as its layout.
+
+Create the function to greet and connect the Button
+====================================================
+
+Finally, we just have to add a function to our custom **Form**
+and *connect* our button to it. Our function will be a part of
+the Form, so you have to add it after the `init()` function:
+::
+ # Greets the user
+ def greetings(self):
+ print ("Hello {}".format(self.edit.text()))
+
+Our function just prints the contents of the `QLineEdit` to the
+python console. We have access to the text by means of the
+`QLineEdit.text()` method.
+
+Now that we have everything, we just need to *connect* the
+`QPushButton` to the `Form.greetings()` method. To do so, add the
+following line to the `init()` method:
+::
+ # Add button signal to greetings slot
+ self.button.clicked.connect(self.greetings)
+
+Once executed, you can enter your name in the `QLineEdit` and watch
+the console for greetings.
+
+Complete code
+=============
+
+Here is the complete code for this tutorial:
+::
+ import sys
+ from PySide2.QtWidgets import (QLineEdit, QPushButton, QApplication,
+ QVBoxLayout, QDialog)
+
+ class Form(QDialog):
+
+ def __init__(self, parent=None):
+ super(Form, self).__init__(parent)
+ # Create widgets
+ self.edit = QLineEdit("Write my name here")
+ self.button = QPushButton("Show Greetings")
+ # Create layout and add widgets
+ layout = QVBoxLayout()
+ layout.addWidget(self.edit)
+ layout.addWidget(self.button)
+ # Set dialog layout
+ self.setLayout(layout)
+ # Add button signal to greetings slot
+ self.button.clicked.connect(self.greetings)
+
+ # Greets the user
+ def greetings(self):
+ print ("Hello %s" % self.edit.text())
+
+ if __name__ == '__main__':
+ # Create the Qt Application
+ app = QApplication(sys.argv)
+ # Create and show the form
+ form = Form()
+ form.show()
+ # Run the main Qt loop
+ sys.exit(app.exec_())
diff --git a/sources/pyside2/doc/tutorials/basictutorial/qml.rst b/sources/pyside2/doc/tutorials/basictutorial/qml.rst
new file mode 100644
index 000000000..0b26b3b83
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/qml.rst
@@ -0,0 +1,63 @@
+Your First Application Using PySide2 and QtQuick/QML
+*****************************************************
+
+QML is a declarative language that lets you develop applications
+faster than with traditional languages. It is ideal for designing the
+UI of your applicataion because of its declarative nature. In QML, a
+user interface is specified as a tree of objects with properties. In
+this tutorial, we will show how to make a simple "Hello World"
+application with PySide2 and QML.
+
+A PySide2/QML application consists, at least, of two different files -
+a file with the QML description of the user interface, and a python file
+that loads the QML file. To make things easier, let's save both files in
+the same directory.
+
+Here is a simple QML file called `view.qml`:
+::
+ import QtQuick 2.0
+
+ Rectangle {
+ width: 200
+ height: 200
+ color: "green"
+
+ Text {
+ text: "Hello World"
+ anchors.centerIn: parent
+ }
+ }
+
+We start by importing `QtQuick 2.0`, which is a QML module.
+
+The rest of the QML code is pretty straightforward for those who
+have previously used HTML or XML files. Basically, we are creating
+a green rectangle with the size `200*200`, and adding a Text element
+that reads "Hello World". The code `anchors.centerIn: parent` makes
+the text appear centered in relation to its immediate parent, which
+is the Rectangle in this case.
+
+Now, let's see how the code looks on the PySide2.
+Let's call it `main.py`:
+::
+ from PySide2.QtWidgets import QApplication
+ from PySide2.QtQuick import QQuickView
+ from PySide2.QtCore import QUrl
+
+ app = QApplication([])
+ view = QQuickView()
+ url = QUrl("view.qml")
+
+ view.setSource(url)
+ view.show()
+ app.exec_()
+
+If you are already familiar with PySide2 and have followed our
+tutorials, you have already seen much of this code.
+The only novelties are that you must `import QtQuick` and set the
+source of the `QQuickView` object to the URL of your QML file.
+Then, as any Qt widget, you call `QQuickView.show()`.
+
+.. note:: If you are programming for desktop, you should consider
+ adding `view.setResizeMode(QQuickView.SizeRootObjectToView)`
+ before showing the view.
diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
new file mode 100644
index 000000000..00731abc3
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst
@@ -0,0 +1,166 @@
+Using UI Files
+***************
+
+This page describes the use of Qt Creator to create graphical
+interfaces for your Qt for Python project.
+You will need **Qt Creator** to design and modify your interface (UI file).
+
+If you don't know how to use Qt Creator, refer to the
+`Using Qt Designer <http://doc.qt.io/qtcreator/creator-using-qt-designer.html>`_
+documentation page.
+
+At Qt Creator, create a new Qt Design Form, choose "Main Window" for template.
+And save as `mainwindow.ui`.
+Add a `QPushButton` to the center of the centralwidget.
+
+Your file (mainwindow.ui) should look something like this:
+::
+ <?xml version="1.0" encoding="UTF-8"?>
+ <ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <widget class="QPushButton" name="pushButton">
+ <property name="geometry">
+ <rect>
+ <x>110</x>
+ <y>80</y>
+ <width>201</width>
+ <height>81</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>PushButton</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QToolBar" name="mainToolBar">
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ <widget class="QStatusBar" name="statusBar"/>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+ </ui>
+
+Now we are ready to decide how to use the **UI file** from Python.
+
+Generating a Python class
+=========================
+
+Another option to interact with a **UI file** is to generate a Python
+class from it. This is possible thanks to the `pyside2-uic` tool.
+To use this tool, you need to run the following command on a console:
+::
+ pyside2-uic mainwindow.ui > ui_mainwindow.py
+
+We redirect all the output of the command to a file called `ui_mainwindow.py`,
+which will be imported directly:
+::
+ from ui_mainwindow import Ui_MainWindow
+
+Now to use it, we should create a personalized class for our widget
+to **setup** this generated design.
+
+To understand the idea, let's take a look at the whole code:
+::
+ import sys
+ from PySide2.QtWidgets import QApplication, QMainWindow
+ from PySide2.QtCore import QFile
+ from ui_mainwindow import Ui_MainWindow
+
+ class MainWindow(QMainWindow):
+ def __init__(self):
+ super(MainWindow, self).__init__()
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ window = MainWindow()
+ window.show()
+
+ sys.exit(app.exec_())
+
+What is inside the *if* statement is already known from the previous
+examples, and our new basic class contains only two new lines
+that are in charge of loading the generated python class from the UI
+file:
+::
+ self.ui = Ui_MainWindow()
+ self.ui.setupUi(self)
+
+.. note:: You must run `pyside2-uic` again every time you make changes
+to the **UI file**.
+
+Loading it directly
+====================
+
+To load the UI file directly, we will need a class from the **QtUiTools**
+module:
+::
+ from PySide2.QtUiTools import QUiLoader
+
+The `QUiLoader` lets us load the **ui file** dynamically
+and use it right away:
+::
+ ui_file = QFile("mainwindow.ui")
+ ui_file.open(QFile.ReadOnly)
+
+ loader = QUiLoader()
+ window = loader.load(ui_file)
+ window.show()
+
+The complete code of this example looks like this:
+::
+ # File: main.py
+ import sys
+ from PySide2.QtUiTools import QUiLoader
+ from PySide2.QtWidgets import QApplication
+ from PySide2.QtCore import QFile
+
+ if __name__ == "__main__":
+ app = QApplication(sys.argv)
+
+ ui_file = QFile("mainwindow.ui")
+ ui_file.open(QFile.ReadOnly)
+
+ loader = QUiLoader()
+ window = loader.load(ui_file)
+ ui_file.close()
+ window.show()
+
+ sys.exit(app.exec_())
+
+Then to execute it we just need to run the following on a
+command prompt:
+::
+ python main.py
diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgets.rst b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst
new file mode 100644
index 000000000..80c137cac
--- /dev/null
+++ b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst
@@ -0,0 +1,40 @@
+Your First QtWidgets Application
+*********************************
+
+As with any other programming framework,
+you start with the traditional "Hello World" program.
+
+Here is a simple example of a Hello World application in PySide2:
+::
+ import sys
+ from PySide2.QtWidgets import QApplication, QLabel
+
+ app = QApplication(sys.argv)
+ label = QLabel("Hello World!")
+ label.show()
+ app.exec_()
+
+
+For a widget application using PySide2, you must always start by
+importing the appropriate class from the `PySide2.QtWidgets` module.
+
+After the imports, you create a `QApplication` instance. As Qt can
+receive arguments from command line, you may pass any argument to
+the QApplication object. Usually, you don't need to pass any
+arguments so you can leave it as is, or use the following approach:
+::
+ app = QApplication([])
+
+After the creation of the application object, we have created a
+`QLabel` object. A `QLabel` is a widget that can present text
+(simple or rich, like html), and images:
+::
+ # This HTML approach will be valid too!
+ label = QLabel("<font color=red size=40>Hello World!</font>")
+
+.. note:: After the creation of the label, we are calling the
+method `show()` to show the label.
+
+Finally, we call `app.exec_()` to enter the Qt main loop and start
+to execute the Qt code. In reality, it is only here where the label
+is shown, but this can be ignored for now.
diff --git a/sources/pyside2/doc/tutorials/index.rst b/sources/pyside2/doc/tutorials/index.rst
index 18bac57fd..5b1eb9fe3 100644
--- a/sources/pyside2/doc/tutorials/index.rst
+++ b/sources/pyside2/doc/tutorials/index.rst
@@ -1,5 +1,5 @@
-PySide examples and tutorials
-*****************************
+Qt for Python examples and tutorials
+*************************************
A collection of examples and tutorials with "walkthrough" guides are
provided with |project| to help new users get started. These
@@ -21,5 +21,10 @@ Tutorials
.. toctree::
:maxdepth: 2
+ basictutorial/widgets.rst
+ basictutorial/qml.rst
+ basictutorial/clickablebutton.rst
+ basictutorial/dialog.rst
+ basictutorial/uifiles.rst
qmltutorial/index.rst
qmladvancedtutorial/index.rst
diff --git a/sources/pyside2/libpyside/CMakeLists.txt b/sources/pyside2/libpyside/CMakeLists.txt
index 3069b1ca2..ec6713b62 100644
--- a/sources/pyside2/libpyside/CMakeLists.txt
+++ b/sources/pyside2/libpyside/CMakeLists.txt
@@ -17,6 +17,7 @@ if(${Qt5Quick_FOUND})
endif()
endif()
+set(QML_PRIVATE_API_SUPPORT 0)
if(Qt5Qml_FOUND)
# Used for registering custom QQuickItem classes defined in Python code.
set(QML_SUPPORT 1)
@@ -28,7 +29,6 @@ if(Qt5Qml_FOUND)
set(QML_PRIVATE_API_SUPPORT 1)
set(QML_INCLUDES ${QML_INCLUDES} ${Qt5Qml_PRIVATE_INCLUDE_DIRS})
else()
- set(QML_PRIVATE_API_SUPPORT 0)
message(WARNING "QML private API include files could not be found, support for catching QML exceptions inside Python code will not work.")
endif()
else()
@@ -40,14 +40,10 @@ endif()
qt5_wrap_cpp(DESTROYLISTENER_MOC "destroylistener.h")
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/signalmanager.cpp.in"
- "${CMAKE_CURRENT_BINARY_DIR}/signalmanager.cpp" @ONLY)
-
set(libpyside_SRC
dynamicqmetaobject.cpp
destroylistener.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/signalmanager.cpp
- globalreceiver.cpp
+ signalmanager.cpp
globalreceiverv2.cpp
pysideclassinfo.cpp
pysidemetafunction.cpp
@@ -86,7 +82,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${SHIBOKEN_INCLUDE_DIR}
${SHIBOKEN_PYTHON_INCLUDE_DIR}
${QML_INCLUDES}
- ${Qt5Core_INCLUDE_DIRS})
+ ${Qt5Core_INCLUDE_DIRS}
+ ${Qt5Core_PRIVATE_INCLUDE_DIRS})
add_library(pyside2 SHARED ${libpyside_SRC} ${other_files})
target_link_libraries(pyside2
${SHIBOKEN_PYTHON_LIBRARIES}
@@ -107,6 +104,7 @@ endif()
if(QML_SUPPORT)
target_compile_definitions(pyside2 PUBLIC PYSIDE_QML_SUPPORT=1)
endif()
+target_compile_definitions(pyside2 PRIVATE PYSIDE_QML_PRIVATE_API_SUPPORT=${QML_PRIVATE_API_SUPPORT})
if(PYSIDE_QT_CONF_PREFIX)
set_property(SOURCE pyside.cpp
@@ -122,7 +120,6 @@ endif()
set(libpyside_HEADERS
destroylistener.h
dynamicqmetaobject.h
- globalreceiver.h
pysideclassinfo.h
pysidemacros.h
signalmanager.h
diff --git a/sources/pyside2/libpyside/PySide2Config-spec.cmake.in b/sources/pyside2/libpyside/PySide2Config-spec.cmake.in
index 4281ade5b..afb81f5a6 100644
--- a/sources/pyside2/libpyside/PySide2Config-spec.cmake.in
+++ b/sources/pyside2/libpyside/PySide2Config-spec.cmake.in
@@ -16,3 +16,4 @@ else()
endif()
SET(PYSIDE_PYTHONPATH "@PYTHON_SITE_PACKAGES@")
SET(PYSIDE_TYPESYSTEMS "@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/typesystems")
+SET(PYSIDE_GLUE "@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/glue")
diff --git a/sources/pyside2/libpyside/destroylistener.cpp b/sources/pyside2/libpyside/destroylistener.cpp
index 95e53f709..c6dc54713 100644
--- a/sources/pyside2/libpyside/destroylistener.cpp
+++ b/sources/pyside2/libpyside/destroylistener.cpp
@@ -40,10 +40,7 @@
#include <sbkpython.h>
#include "destroylistener.h"
-#include <QObject>
#include <shiboken.h>
-#include <QDebug>
-#include <QMutex>
PySide::DestroyListener* PySide::DestroyListener::m_instance = 0;
diff --git a/sources/pyside2/libpyside/destroylistener.h b/sources/pyside2/libpyside/destroylistener.h
index 0a800451a..b1a0597c5 100644
--- a/sources/pyside2/libpyside/destroylistener.h
+++ b/sources/pyside2/libpyside/destroylistener.h
@@ -40,10 +40,10 @@
#ifndef PYSIDE_DESTROY_LISTENER
#define PYSIDE_DESTROY_LISTENER
-
-#include <QObject>
#include "pysidemacros.h"
+#include <QtCore/QObject>
+
namespace PySide
{
struct DestroyListenerPrivate;
@@ -63,7 +63,7 @@ class PYSIDE_API DestroyListener : public QObject
static DestroyListener* m_instance;
DestroyListenerPrivate* m_d;
DestroyListener(QObject *parent);
- ~DestroyListener();
+ ~DestroyListener() override;
};
}//namespace
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.cpp b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
index af2f416c6..b664e149b 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.cpp
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.cpp
@@ -45,546 +45,376 @@
#include "pysideproperty_p.h"
#include "pysideslot_p.h"
-#include <QByteArray>
-#include <QString>
-#include <QStringList>
-#include <QList>
-#include <QLinkedList>
-#include <QObject>
-#include <cstring>
-#include <QDebug>
-#include <QMetaMethod>
#include <shiboken.h>
+#include <QtCore/QByteArray>
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QVector>
+#include <private/qmetaobjectbuilder_p.h>
-#define EMPTY_META_METHOD "0()"
+#include <cstring>
+#include <vector>
using namespace PySide;
-enum PropertyFlags {
- Invalid = 0x00000000,
- Readable = 0x00000001,
- Writable = 0x00000002,
- Resettable = 0x00000004,
- EnumOrFlag = 0x00000008,
- StdCppSet = 0x00000100,
-// Override = 0x00000200,
- Constant = 0x00000400,
- Final = 0x00000800,
- Designable = 0x00001000,
- ResolveDesignable = 0x00002000,
- Scriptable = 0x00004000,
- ResolveScriptable = 0x00008000,
- Stored = 0x00010000,
- ResolveStored = 0x00020000,
- Editable = 0x00040000,
- ResolveEditable = 0x00080000,
- User = 0x00100000,
- ResolveUser = 0x00200000,
- Notify = 0x00400000
-};
-
-// these values are from moc source code, generator.cpp:66
-enum MethodFlags {
- AccessPrivate = 0x00,
- AccessProtected = 0x01,
- AccessPublic = 0x02,
- MethodMethod = 0x00,
- MethodSignal = 0x04,
- MethodSlot = 0x08,
- MethodConstructor = 0x0c,
- MethodCompatibility = 0x10,
- MethodCloned = 0x20,
- MethodScriptable = 0x40
-};
-
-enum MetaDataFlags {
- IsUnresolvedType = 0x80000000,
- TypeNameIndexMask = 0x7FFFFFFF
-};
-
-class DynamicQMetaObject::DynamicQMetaObjectPrivate
+// MetaObjectBuilder: Provides the QMetaObject's returned by
+// QObject::metaObject() for PySide2 objects. There are several
+// scenarios to consider:
+// 1) A plain Qt class (say QTimer) is instantiated. In that case,
+// return the base meta object until a modification is made by
+// adding methods, properties or class info (cf qmetaobject_test.py).
+// In that case, instantiate a QMetaObjectBuilder inheriting the
+// base meta meta object, add the method and return the result
+// of QMetaObjectBuilder::toMetaObject() (with dirty handling should
+// further modifications be made).
+// 2) A Python class inheriting a Qt class is instantiated. For this,
+// instantiate a QMetaObjectBuilder and add the methods/properties
+// found by inspecting the Python class.
+
+class MetaObjectBuilderPrivate
{
public:
- QList<MethodData> m_methods;
- QList<PropertyData> m_properties;
-
- QMap<QByteArray, QByteArray> m_info;
- QByteArray m_className;
- bool m_updated; // when the meta data is not update
- int m_methodOffset;
- int m_propertyOffset;
- int m_dataSize;
- int m_emptyMethod;
- int m_nullIndex;
-
- DynamicQMetaObjectPrivate()
- : m_updated(false), m_methodOffset(0), m_propertyOffset(0),
- m_dataSize(0), m_emptyMethod(-1), m_nullIndex(0) {}
-
- int createMetaData(QMetaObject* metaObj, QLinkedList<QByteArray> &strings);
- void updateMetaObject(QMetaObject* metaObj);
- void writeMethodsData(const QList<MethodData>& methods, unsigned int** data, QLinkedList<QByteArray>& strings, int* prtIndex, int nullIndex, int flags);
- void writeStringData(char *, QLinkedList<QByteArray> &strings);
+ using MetaObjects = std::vector<const QMetaObject *>;
+
+ QMetaObjectBuilder *ensureBuilder();
+ void parsePythonType(PyTypeObject *type);
+ int indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const;
+ int indexOfProperty(const QByteArray &name) const;
+ int addSlot(const QByteArray &signature);
+ int addSlot(const QByteArray &signature, const QByteArray &type);
+ int addSignal(const QByteArray &signature);
+ void removeMethod(QMetaMethod::MethodType mtype, int index);
int getPropertyNotifyId(PySideProperty *property) const;
-};
+ int addProperty(const QByteArray &property, PyObject *data);
+ void addInfo(const QByteArray &key, const QByteArray &value);
+ void addInfo(const QMap<QByteArray, QByteArray> &info);
+ void removeProperty(int index);
+ const QMetaObject *update();
-bool sortMethodSignalSlot(const MethodData &m1, const MethodData &m2)
-{
- if (m1.methodType() == QMetaMethod::Signal)
- return m2.methodType() == QMetaMethod::Slot;
- return false;
-}
+ QMetaObjectBuilder *m_builder = nullptr;
+
+ const QMetaObject *m_baseObject = nullptr;
+ MetaObjects m_cachedMetaObjects;
+ bool m_dirty = true;
+};
-static int registerString(const QByteArray& s, QLinkedList<QByteArray>& strings)
+QMetaObjectBuilder *MetaObjectBuilderPrivate::ensureBuilder()
{
- int idx = 0;
- QLinkedList<QByteArray>::const_iterator it = strings.begin();
- QLinkedList<QByteArray>::const_iterator itEnd = strings.end();
- while (it != itEnd) {
- if (strcmp(*it, s) == 0)
- return idx;
- ++idx;
- ++it;
+ if (!m_builder) {
+ m_builder = new QMetaObjectBuilder();
+ m_builder->setClassName(m_baseObject->className());
+ m_builder->setSuperClass(m_baseObject);
}
- strings.append(s);
- return idx;
+ return m_builder;
}
-static int blobSize(QLinkedList<QByteArray> &strings)
+MetaObjectBuilder::MetaObjectBuilder(const char *className, const QMetaObject *metaObject) :
+ m_d(new MetaObjectBuilderPrivate)
{
- int size = strings.size() * sizeof(QByteArrayData);
-
- QByteArray str;
- QByteArray debug_str;
- foreach (const QByteArray &field, strings) {
- str.append(field);
- str.append(char(0));
-
- debug_str.append(field);
- debug_str.append('|');
- }
- //qDebug()<<debug_str;
- size += str.size();
- return size;
+ m_d->m_baseObject = metaObject;
+ m_d->m_builder = new QMetaObjectBuilder();
+ m_d->m_builder->setClassName(className);
+ m_d->m_builder->setSuperClass(metaObject);
+ m_d->m_builder->setClassName(className);
}
-static int aggregateParameterCount(const QList<MethodData> &methods)
+MetaObjectBuilder::MetaObjectBuilder(PyTypeObject *type, const QMetaObject *metaObject)
+ : m_d(new MetaObjectBuilderPrivate)
{
- int sum = 0;
- for (int i = 0; i < methods.size(); ++i)
- sum += methods.at(i).parameterCount() * 2 + 1; // nb_param*2 (type and names) +1 for return type
- return sum;
+ m_d->m_baseObject = metaObject;
+ const char *className = type->tp_name;
+ if (const char *lastDot = strrchr(type->tp_name, '.'))
+ className = lastDot + 1;
+ // Different names indicate a Python class inheriting a Qt class.
+ // Parse the type.
+ if (strcmp(className, metaObject->className()) != 0) {
+ m_d->m_builder = new QMetaObjectBuilder();
+ m_d->m_builder->setClassName(className);
+ m_d->m_builder->setSuperClass(metaObject);
+ m_d->parsePythonType(type);
+ }
}
-static void writeString(char *out, int i, const QByteArray &str,
- const int offsetOfStringdataMember, int &stringdataOffset)
+MetaObjectBuilder::~MetaObjectBuilder()
{
- int size = str.size();
- qptrdiff offset = offsetOfStringdataMember + stringdataOffset
- - i * sizeof(QByteArrayData);
- const QByteArrayData data =
- Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset);
-
- memcpy(out + i * sizeof(QByteArrayData), &data, sizeof(QByteArrayData));
-
- memcpy(out + offsetOfStringdataMember + stringdataOffset, str.constData(), size);
- out[offsetOfStringdataMember + stringdataOffset + size] = '\0';
-
- stringdataOffset += size + 1;
+ qDeleteAll(m_d->m_cachedMetaObjects);
+ delete m_d->m_builder;
+ delete m_d;
}
-static int qvariant_nameToType(const char* name)
+int MetaObjectBuilderPrivate::indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const
{
- if (!name)
- return 0;
-
- if (strcmp(name, "QVariant") == 0)
- return 0xffffffff;
- if (strcmp(name, "QCString") == 0)
- return QMetaType::QByteArray;
- if (strcmp(name, "Q_LLONG") == 0)
- return QMetaType::LongLong;
- if (strcmp(name, "Q_ULLONG") == 0)
- return QMetaType::ULongLong;
- if (strcmp(name, "QIconSet") == 0)
- return QMetaType::QIcon;
-
- uint tp = QMetaType::type(name);
- return tp < QMetaType::User ? tp : 0;
+ int result = -1;
+ if (m_builder) {
+ switch (mtype) {
+ case QMetaMethod::Signal:
+ result = m_builder->indexOfSignal(signature);
+ break;
+ case QMetaMethod::Slot:
+ result = m_builder->indexOfSlot(signature);
+ break;
+ case QMetaMethod::Constructor:
+ result = m_builder->indexOfConstructor(signature);
+ break;
+ case QMetaMethod::Method:
+ result = m_builder->indexOfMethod(signature);
+ break;
+ }
+ if (result >= 0)
+ return result + m_baseObject->methodCount();
+ }
+ switch (mtype) {
+ case QMetaMethod::Signal:
+ result = m_baseObject->indexOfSignal(signature);
+ break;
+ case QMetaMethod::Slot:
+ result = m_baseObject->indexOfSlot(signature);
+ break;
+ case QMetaMethod::Constructor:
+ result = m_baseObject->indexOfConstructor(signature);
+ break;
+ case QMetaMethod::Method:
+ result = m_baseObject->indexOfMethod(signature);
+ break;
+ }
+ return result;
}
-/*
- Returns true if the type is a QVariant types.
-*/
-static bool isVariantType(const char* type)
+int MetaObjectBuilder::indexOfMethod(QMetaMethod::MethodType mtype,
+ const QByteArray &signature) const
{
- return qvariant_nameToType(type) != 0;
+ return m_d->indexOfMethod(mtype, signature);
}
-/*!
- Returns true if the type is qreal.
-*/
-static bool isQRealType(const char *type)
+int MetaObjectBuilderPrivate::indexOfProperty(const QByteArray &name) const
{
- return strcmp(type, "qreal") == 0;
+ if (m_builder) {
+ const int result = m_builder->indexOfProperty(name);
+ if (result >= 0)
+ return m_baseObject->propertyCount() + result;
+ }
+ return m_baseObject->indexOfProperty(name);
}
-uint PropertyData::flags() const
+int MetaObjectBuilder::indexOfProperty(const QByteArray &name) const
{
- const QByteArray btype(type());
- const char* typeName = btype.data();
- uint flags = Invalid;
- if (!isVariantType(typeName))
- flags |= EnumOrFlag;
- else if (!isQRealType(typeName))
- flags |= qvariant_nameToType(typeName) << 24;
-
- if (PySide::Property::isReadable(m_data))
- flags |= Readable;
-
- if (PySide::Property::isWritable(m_data))
- flags |= Writable;
-
- if (PySide::Property::hasReset(m_data))
- flags |= Resettable;
-
- if (PySide::Property::isDesignable(m_data))
- flags |= Designable;
- else
- flags |= ResolveDesignable;
-
- if (PySide::Property::isScriptable(m_data))
- flags |= Scriptable;
- else
- flags |= ResolveScriptable;
-
- if (PySide::Property::isStored(m_data))
- flags |= Stored;
- else
- flags |= ResolveStored;
-
- //EDITABLE
- flags |= ResolveEditable;
-
- if (PySide::Property::isUser(m_data))
- flags |= User;
- else
- flags |= ResolveUser;
-
- if (m_cachedNotifyId != -1)
- flags |= Notify;
-
- if (PySide::Property::isConstant(m_data))
- flags |= Constant;
-
- if (PySide::Property::isFinal(m_data))
- flags |= Final;
-
- return flags;
+ return m_d->indexOfProperty(name);
}
-// const QByteArray with EMPTY_META_METHOD, used to save some memory
-const QByteArray MethodData::m_emptySig(EMPTY_META_METHOD);
-
-MethodData::MethodData()
- : m_signature(m_emptySig)
+static bool checkMethodSignature(const QByteArray &signature)
{
+ // Common mistake not to add parentheses to the signature.
+ const int openParen = signature.indexOf('(');
+ const int closingParen = signature.lastIndexOf(')');
+ const bool ok = openParen != -1 && closingParen != -1 && openParen < closingParen;
+ if (!ok) {
+ const QByteArray message =
+ "MetaObjectBuilder::addMethod: Invalid method signature provided for \""
+ + signature + '"';
+ PyErr_WarnEx(PyExc_RuntimeWarning, message.constData(), 0);
+ }
+ return ok;
}
-MethodData::MethodData(QMetaMethod::MethodType mtype, const QByteArray& signature, const QByteArray& rtype)
- : m_signature(QMetaObject::normalizedSignature(signature.constData()))
- , m_rtype(QMetaObject::normalizedSignature(rtype.constData()))
- , m_mtype(mtype)
+int MetaObjectBuilderPrivate::addSlot(const QByteArray &signature)
{
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ return m_baseObject->methodCount()
+ + ensureBuilder()->addSlot(signature).index();
}
-void MethodData::clear()
+int MetaObjectBuilder::addSlot(const char *signature)
{
- m_signature = m_emptySig;
- m_rtype.clear();
+ return m_d->addSlot(signature);
}
-bool MethodData::isValid() const
+int MetaObjectBuilderPrivate::addSlot(const QByteArray &signature,
+ const QByteArray &type)
{
- return m_signature != m_emptySig;
-}
-
-QList<QByteArray> MethodData::parameterTypes() const
-{
- const char *signature = m_signature.constData();
- QList<QByteArray> list;
- while (*signature && *signature != '(')
- ++signature;
- while (*signature && *signature != ')' && *++signature != ')') {
- const char *begin = signature;
- int level = 0;
- while (*signature && (level > 0 || *signature != ',') && *signature != ')') {
- if (*signature == '<')
- ++level;
- else if (*signature == '>')
- --level;
- ++signature;
- }
- list += QByteArray(begin, signature - begin);
- }
- return list;
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ QMetaMethodBuilder methodBuilder = ensureBuilder()->addSlot(signature);
+ methodBuilder.setReturnType(type);
+ return m_baseObject->methodCount() + methodBuilder.index();
}
-int MethodData::parameterCount() const
+int MetaObjectBuilder::addSlot(const char *signature, const char *type)
{
- return parameterTypes().size();
+ return m_d->addSlot(signature, type);
}
-QByteArray MethodData::name() const
+int MetaObjectBuilderPrivate::addSignal(const QByteArray &signature)
{
- return m_signature.left(qMax(m_signature.indexOf('('), 0));
+ if (!checkMethodSignature(signature))
+ return -1;
+ m_dirty = true;
+ return m_baseObject->methodCount()
+ + ensureBuilder()->addSignal(signature).index();
}
-PropertyData::PropertyData()
- : m_cachedNotifyId(0), m_data(0)
+int MetaObjectBuilder::addSignal(const char *signature)
{
+ return m_d->addSignal(signature);
}
-PropertyData::PropertyData(const char* name, int notifyId, PySideProperty* data)
- : m_name(name), m_cachedNotifyId(notifyId), m_data(data)
+void MetaObjectBuilderPrivate::removeMethod(QMetaMethod::MethodType mtype,
+ int index)
{
+ index -= m_baseObject->methodCount();
+ auto builder = ensureBuilder();
+ Q_ASSERT(index >= 0 && index < builder->methodCount());
+ switch (mtype) {
+ case QMetaMethod::Constructor:
+ builder->removeConstructor(index);
+ break;
+ default:
+ builder->removeMethod(index);
+ break;
+ }
+ m_dirty = true;
}
-QByteArray PropertyData::type() const
+void MetaObjectBuilder::removeMethod(QMetaMethod::MethodType mtype, int index)
{
- return QByteArray(PySide::Property::getTypeName(m_data));
+ m_d->removeMethod(mtype, index);
}
-
-bool PropertyData::isValid() const
+int MetaObjectBuilderPrivate::getPropertyNotifyId(PySideProperty *property) const
{
- return !m_name.isEmpty();
+ int notifyId = -1;
+ if (property->d->notify) {
+ if (const char *signalNotify = PySide::Property::getNotifyName(property))
+ notifyId = indexOfMethod(QMetaMethod::Signal, signalNotify);
+ }
+ return notifyId;
}
-int PropertyData::cachedNotifyId() const
+int MetaObjectBuilderPrivate::addProperty(const QByteArray &propertyName,
+ PyObject *data)
{
- return m_cachedNotifyId;
-}
+ int index = indexOfProperty(propertyName);
+ if (index != -1)
+ return index;
-bool PropertyData::operator==(const PropertyData& other) const
-{
- return m_data == other.m_data;
+ PySideProperty *property = reinterpret_cast<PySideProperty *>(data);
+ int propertyNotifyId = getPropertyNotifyId(property);
+ if (propertyNotifyId >= 0)
+ propertyNotifyId -= m_baseObject->methodCount();
+ auto newProperty =
+ ensureBuilder()->addProperty(propertyName, property->d->typeName,
+ propertyNotifyId);
+ index = newProperty.index() + m_baseObject->propertyCount();
+ m_dirty = true;
+ return index;
}
-bool PropertyData::operator==(const char* name) const
+int MetaObjectBuilder::addProperty(const char *property, PyObject *data)
{
- return m_name == name;
+ return m_d->addProperty(property, data);
}
-
-DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* base)
- : m_d(new DynamicQMetaObjectPrivate)
+void MetaObjectBuilderPrivate::addInfo(const QByteArray &key,
+ const QByteArray &value)
{
- d.superdata = base;
- d.stringdata = NULL;
- d.data = NULL;
- d.extradata = NULL;
- d.relatedMetaObjects = NULL;
- d.static_metacall = NULL;
-
- m_d->m_className = QByteArray(type->tp_name).split('.').last();
- m_d->m_methodOffset = base->methodCount() - 1;
- m_d->m_propertyOffset = base->propertyCount() - 1;
- parsePythonType(type);
+ ensureBuilder()->addClassInfo(key, value);
+ m_dirty = true;
}
-DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject)
- : m_d(new DynamicQMetaObjectPrivate)
+void MetaObjectBuilder::addInfo(const char *key, const char *value)
{
- d.superdata = metaObject;
- d.stringdata = 0;
- d.data = 0;
- d.extradata = 0;
- d.relatedMetaObjects = NULL;
- d.static_metacall = NULL;
-
- m_d->m_className = className;
- m_d->m_methodOffset = metaObject->methodCount() - 1;
- m_d->m_propertyOffset = metaObject->propertyCount() - 1;
+ m_d->addInfo(key, value);
}
-DynamicQMetaObject::~DynamicQMetaObject()
+void MetaObjectBuilderPrivate::addInfo(const QMap<QByteArray, QByteArray> &info)
{
- free(reinterpret_cast<char *>(const_cast<QByteArrayData *>(d.stringdata)));
- free(const_cast<uint*>(d.data));
- delete m_d;
+ auto builder = ensureBuilder();
+ for (auto i = info.constBegin(), end = info.constEnd(); i != end; ++i)
+ builder->addClassInfo(i.key(), i.value());
+ m_dirty = true;
}
-int DynamicQMetaObject::addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type)
+void MetaObjectBuilder::addInfo(const QMap<QByteArray, QByteArray> &info)
{
- int index = -1;
- int counter = 0;
-
- QList<MethodData>::iterator it = m_d->m_methods.begin();
- for (; it != m_d->m_methods.end(); ++it) {
- if ((it->signature() == signature) && (it->methodType() == mtype))
- return m_d->m_methodOffset + counter;
- else if (!it->isValid()) {
- index = counter;
- }
- counter++;
- }
-
- // Common mistake not to add parentheses to the signature.
- if ((strchr(signature, ')') == 0) || ((strchr(signature, '(') == 0))) {
- const QString message =
- QLatin1String("DynamicQMetaObject::addMethod: Invalid method signature "
- "provided for ") + QLatin1String(signature);
- const QByteArray messageLatin = message.toLatin1();
- PyErr_WarnEx(PyExc_RuntimeWarning, messageLatin.constData(), 0);
- return -1;
- }
-
- //has blank method
- if (index != -1) {
- m_d->m_methods[index] = MethodData(mtype, signature, type);
- index++;
- } else {
- m_d->m_methods << MethodData(mtype, signature, type);
- index = m_d->m_methods.size();
- }
-
- m_d->m_updated = false;
- return m_d->m_methodOffset + index;
+ m_d->addInfo(info);
}
-void DynamicQMetaObject::removeMethod(QMetaMethod::MethodType mtype, uint index)
+void MetaObjectBuilderPrivate::removeProperty(int index)
{
- const char* methodSig = method(index).methodSignature();
- QList<MethodData>::iterator it = m_d->m_methods.begin();
- for (; it != m_d->m_methods.end(); ++it) {
- if ((it->signature() == methodSig) && (it->methodType() == mtype)){
- it->clear();
- m_d->m_updated = false;
- break;
- }
- }
+ index -= m_baseObject->propertyCount();
+ auto builder = ensureBuilder();
+ Q_ASSERT(index >= 0 && index < builder->propertyCount());
+ builder->removeProperty(index);
+ m_dirty = true;
}
-int DynamicQMetaObject::addSignal(const char* signal, const char* type)
+void MetaObjectBuilder::removeProperty(int index)
{
- return addMethod(QMetaMethod::Signal, signal, type);
+ m_d->removeProperty(index);
}
-int DynamicQMetaObject::addSlot(const char* slot, const char* type)
-{
- return addMethod(QMetaMethod::Slot, slot, type);
-}
-
-void DynamicQMetaObject::removeSlot(uint index)
-{
- removeMethod(QMetaMethod::Slot, index);
-}
-
-void DynamicQMetaObject::removeSignal(uint index)
-{
- removeMethod(QMetaMethod::Signal, index);
-}
+// PYSIDE-315: Instead of sorting the items and maybe breaking indices, we
+// ensure that the signals and slots are sorted by the improved
+// parsePythonType() (signals must go before slots). The order can only
+// become distorted if the class is modified after creation. In that
+// case, we give a warning.
-int DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data)
+static QString msgMethodSortOrder(const QMetaObject *mo, int offendingIndex)
{
- int index = m_d->m_properties.indexOf(propertyName);
- if (index != -1)
- return m_d->m_propertyOffset + index;
-
- // retrieve notifyId
- PySideProperty *property = reinterpret_cast<PySideProperty *>(data);
- const int notifyId = m_d->getPropertyNotifyId(property);
-
- //search for a empty space
- PropertyData blank;
- index = m_d->m_properties.indexOf(blank);
- if (index != -1) {
- m_d->m_properties[index] = PropertyData(propertyName, notifyId, property);
- } else {
- m_d->m_properties << PropertyData(propertyName, notifyId, property);
- index = m_d->m_properties.size();
+ QString result;
+ QTextStream str(&result);
+ str << "\n\n*** Sort Warning ***\nSignals and slots in QMetaObject '"
+ << mo->className()
+ << "' are not ordered correctly, this may lead to issues.\n";
+ const int methodOffset = mo->methodOffset();
+ for (int m = methodOffset, methodCount = mo->methodCount(); m < methodCount; ++m) {
+ const auto method = mo->method(m);
+ str << (m - methodOffset + 1) << (m > offendingIndex ? '!' : ' ')
+ << (method.methodType() == QMetaMethod::Signal ? " Signal " : " Slot ")
+ << method.methodSignature() << '\n';
}
- m_d->m_updated = false;
- return m_d->m_propertyOffset + index;
+ return result;
}
-int DynamicQMetaObject::DynamicQMetaObjectPrivate::getPropertyNotifyId(PySideProperty *property) const
+static void checkMethodOrder(const QMetaObject *metaObject)
{
- int notifyId = -1;
- if (property->d->notify) {
- const char *signalNotify = PySide::Property::getNotifyName(property);
- if (signalNotify) {
- const MethodData signalObject(QMetaMethod::Signal, signalNotify, "");
- notifyId = m_methods.indexOf(signalObject);
+ const int lastMethod = metaObject->methodCount() - 1;
+ for (int m = metaObject->methodOffset(); m < lastMethod; ++m) {
+ if (metaObject->method(m).methodType() == QMetaMethod::Slot
+ && metaObject->method(m + 1).methodType() == QMetaMethod::Signal) {
+ const auto message = msgMethodSortOrder(metaObject, m);
+ PyErr_WarnEx(PyExc_RuntimeWarning, qPrintable(message), 0);
+ // Prevent a warning from being turned into an error. We cannot easily unwind.
+ PyErr_Clear();
+ break;
}
}
- return notifyId;
-}
-
-void DynamicQMetaObject::addInfo(const char* key, const char* value)
-{
- m_d->m_info[key] = value;
}
-void DynamicQMetaObject::addInfo(QMap<QByteArray, QByteArray> info)
+const QMetaObject *MetaObjectBuilderPrivate::update()
{
- QMap<QByteArray, QByteArray>::const_iterator i = info.constBegin();
- while (i != info.constEnd()) {
- m_d->m_info[i.key()] = i.value();
- ++i;
+ if (!m_builder)
+ return m_baseObject;
+ if (m_cachedMetaObjects.empty() || m_dirty) {
+ m_cachedMetaObjects.push_back(m_builder->toMetaObject());
+ checkMethodOrder(m_cachedMetaObjects.back());
+ m_dirty = false;
}
- m_d->m_updated = false;
+ return m_cachedMetaObjects.back();
}
-const QMetaObject* DynamicQMetaObject::update() const
+const QMetaObject *MetaObjectBuilder::update()
{
- if (!m_d->m_updated) {
- m_d->updateMetaObject(const_cast<DynamicQMetaObject*>(this));
- m_d->m_updated = true;
- }
- return this;
+ return m_d->update();
}
-void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList<MethodData>& methods,
- unsigned int** data,
- QLinkedList<QByteArray>& strings,
- int* prtIndex,
- int nullIndex,
- int flags)
-{
- int index = *prtIndex;
- int paramsIndex = index + methods.count() * 5;
-
- QList<MethodData>::const_iterator it = methods.begin();
-
- if (m_emptyMethod == -1)
- m_emptyMethod = registerString(EMPTY_META_METHOD, strings);
-
- for (; it != methods.end(); ++it) {
- int name_idx = 0;
- int argc = it->parameterCount();
- if (it->signature() != EMPTY_META_METHOD)
- name_idx = registerString(it->name(), strings);
- else
- name_idx = m_emptyMethod; // func name
-
- (*data)[index++] = name_idx;
- (*data)[index++] = argc; // argc (previously: arg name)
- (*data)[index++] = paramsIndex; //parameter index
- (*data)[index++] = nullIndex; // tags
- (*data)[index++] = flags | (it->methodType() == QMetaMethod::Signal ? MethodSignal : MethodSlot);
-
- if (it->methodType() == QMetaMethod::Signal)
- (*data)[13] += 1; //signal count
-
- paramsIndex += 1 + argc * 2;
- }
- *prtIndex = index;
-}
-
-void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
+void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
{
// Get all non-QObject-derived base types in method resolution order, filtering out the types
// that can't have signals, slots or properties.
@@ -594,32 +424,35 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
const PyObject *mro = type->tp_mro;
const Py_ssize_t basesCount = PyTuple_GET_SIZE(mro);
PyTypeObject *qObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
- QVector<PyTypeObject *> basesToCheck;
+
+ std::vector<PyTypeObject *> basesToCheck;
+ // Prepend the actual type that we are parsing.
+ basesToCheck.reserve(1u + basesCount);
+ basesToCheck.push_back(type);
+
+ auto sbkObjTypeF = reinterpret_cast<PyTypeObject *>(SbkObject_TypeF());
+ auto baseObjType = reinterpret_cast<PyTypeObject *>(&PyBaseObject_Type);
for (Py_ssize_t i = 0; i < basesCount; ++i) {
- PyTypeObject *baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
- if (PyType_IsSubtype(baseType, qObjectType)
- || baseType == reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())
- || baseType == reinterpret_cast<PyTypeObject *>(&PyBaseObject_Type)) {
- continue;
- } else {
- basesToCheck.append(baseType);
+ auto baseType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, i));
+ if (baseType != sbkObjTypeF && baseType != baseObjType
+ && PyType_IsSubtype(baseType, qObjectType) == 0) {
+ basesToCheck.push_back(baseType);
}
}
- // Prepend the actual type that we are parsing.
- basesToCheck.prepend(type);
// PYSIDE-315: Handle all signals first, in all involved types.
- for (int baseIndex = 0, baseEnd = basesToCheck.size(); baseIndex < baseEnd; ++baseIndex) {
- PyTypeObject *baseType = basesToCheck[baseIndex];
+ // Leave the properties to be registered after signals because they may depend on
+ // notify signals.
+ for (PyTypeObject *baseType : basesToCheck) {
PyObject *attrs = baseType->tp_dict;
- PyObject *key = 0;
- PyObject *value = 0;
+ PyObject *key = nullptr;
+ PyObject *value = nullptr;
Py_ssize_t pos = 0;
while (PyDict_Next(attrs, &pos, &key, &value)) {
if (Signal::checkType(value)) {
// Register signals.
- PySideSignal *data = reinterpret_cast<PySideSignal *>(value);
+ auto data = reinterpret_cast<PySideSignal *>(value);
const char *signalName = Shiboken::String::toCString(key);
data->signalName = strdup(signalName);
QByteArray sig;
@@ -630,8 +463,8 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
if (data->signatures[i])
sig += data->signatures[i];
sig += ')';
- if (d.superdata->indexOfSignal(sig) == -1)
- addSignal(sig, "void");
+ if (m_baseObject->indexOfSignal(sig) == -1)
+ m_builder->addSignal(sig);
}
}
}
@@ -641,261 +474,41 @@ void DynamicQMetaObject::parsePythonType(PyTypeObject *type)
// PYSIDE-315: Now take care of the rest.
// Signals and slots should be separated, unless the types are modified, later.
// We check for this using "is_sorted()". Sorting no longer happens at all.
- for (int baseIndex = 0, baseEnd = basesToCheck.size(); baseIndex < baseEnd; ++baseIndex) {
- PyTypeObject *baseType = basesToCheck[baseIndex];
+ for (PyTypeObject *baseType : basesToCheck) {
PyObject *attrs = baseType->tp_dict;
- PyObject *key = 0;
- PyObject *value = 0;
+ PyObject *key = nullptr;
+ PyObject *value = nullptr;
Py_ssize_t pos = 0;
- typedef std::pair<const char *, PyObject *> PropPair;
- QVector<PropPair> properties;
-
while (PyDict_Next(attrs, &pos, &key, &value)) {
if (Property::checkType(value)) {
- // Leave the properties to be registered after signals because they may depend on
- // notify signals.
- int index = d.superdata->indexOfProperty(Shiboken::String::toCString(key));
+ const int index = m_baseObject->indexOfProperty(Shiboken::String::toCString(key));
if (index == -1)
- properties << PropPair(Shiboken::String::toCString(key), value);
+ addProperty(Shiboken::String::toCString(key), value);
} else if (PyFunction_Check(value)) {
// Register slots.
if (PyObject_HasAttr(value, slotAttrName)) {
PyObject *signatureList = PyObject_GetAttr(value, slotAttrName);
for (Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) {
- PyObject *signature = PyList_GET_ITEM(signatureList, i);
- QByteArray sig(Shiboken::String::toCString(signature));
+ PyObject *pySignature = PyList_GET_ITEM(signatureList, i);
+ QByteArray signature(Shiboken::String::toCString(pySignature));
// Split the slot type and its signature.
- QList<QByteArray> slotInfo = sig.split(' ');
- int index = d.superdata->indexOfSlot(slotInfo[1]);
- if (index == -1)
- addSlot(slotInfo[1], slotInfo[0]);
+ QByteArray type;
+ const int spacePos = signature.indexOf(' ');
+ if (spacePos != -1) {
+ type = signature.left(spacePos);
+ signature.remove(0, spacePos + 1);
+ }
+ const int index = m_baseObject->indexOfSlot(signature);
+ if (index == -1) {
+ if (type.isEmpty() || type == "void")
+ addSlot(signature);
+ else
+ addSlot(signature, type);
+ }
}
}
}
}
-
- // Register properties
- foreach (const PropPair &propPair, properties)
- addProperty(propPair.first, propPair.second);
}
}
-
-/*!
- Allocate the meta data table.
- Returns the index in the table corresponding to the header fields count.
-*/
-int DynamicQMetaObject::DynamicQMetaObjectPrivate::createMetaData(QMetaObject* metaObj, QLinkedList<QByteArray> &strings)
-{
- const int n_methods = m_methods.size();
- const int n_properties = m_properties.size();
- const int n_info = m_info.size();
-
- int header[] = {7, // revision (Used by moc, qmetaobjectbuilder and qdbus)
- 0, // class name index in m_metadata
- n_info, 0, // classinfo and classinfo index
- n_methods, 0, // method count and method list index
- n_properties, 0, // prop count and prop indexes
- 0, 0, // enum count and enum index
- 0, 0, // constructors (since revision 2)
- 0, // flags (since revision 3)
- 0}; // signal count (since revision 4)
-
- const int HEADER_LENGHT = sizeof(header)/sizeof(int);
-
- m_dataSize = HEADER_LENGHT;
- m_dataSize += n_info*2; //class info: name, value
- m_dataSize += n_methods*5; //method: name, argc, parameters, tag, flags
- m_dataSize += n_properties*4; //property: name, type, flags
- m_dataSize += 1; //eod
-
- m_dataSize += aggregateParameterCount(m_methods); // types and parameter names
-
- uint* data = reinterpret_cast<uint*>(realloc(const_cast<uint*>(metaObj->d.data), m_dataSize * sizeof(uint)));
-
- Q_ASSERT(data);
- std::memcpy(data, header, sizeof(header));
-
- metaObj->d.data = data;
-
- return HEADER_LENGHT;
-}
-
-// Writes strings to string data struct.
-// The struct consists of an array of QByteArrayData, followed by a char array
-// containing the actual strings. This format must match the one produced by
-// moc (see generator.cpp).
-void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeStringData(char *out, QLinkedList<QByteArray> &strings)
-{
- Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (Q_ALIGNOF(QByteArrayData)-1)));
-
- int offsetOfStringdataMember = strings.size() * sizeof(QByteArrayData);
- int stringdataOffset = 0;
- int i = 0;
- foreach(const QByteArray& str, strings) {
- writeString(out, i, str, offsetOfStringdataMember, stringdataOffset);
- i++;
- }
-}
-
-QList<MethodData>::iterator is_sorted_until(QList<MethodData>::iterator first,
- QList<MethodData>::iterator last,
- bool comp(const MethodData &m1, const MethodData &m2))
-{
- if (first != last) {
- QList<MethodData>::iterator next = first;
- while (++next != last) {
- if (comp(*next, *first))
- return next;
- ++first;
- }
- }
- return last;
-}
-
-bool is_sorted(QList<MethodData>::iterator first, QList<MethodData>::iterator last,
- bool comp(const MethodData &m1, const MethodData &m2))
-{
- return is_sorted_until(first, last, comp) == last;
-}
-
-void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject* metaObj)
-{
- Q_ASSERT(!m_updated);
- uint *data = const_cast<uint*>(metaObj->d.data);
- int index = 0;
- QLinkedList<QByteArray> strings;
- m_dataSize = 0;
-
- // Recompute the size and reallocate memory
- // index is set after the last header field.
- index = createMetaData(metaObj, strings);
- data = const_cast<uint*>(metaObj->d.data);
-
- registerString(m_className, strings); // register class string
- m_nullIndex = registerString("", strings); // register a null string
-
- // Write class info.
- if (m_info.size()) {
- if (data[3] == 0)
- data[3] = index;
-
- QMap<QByteArray, QByteArray>::const_iterator i = m_info.constBegin(); //TODO: info is a hash this can fail
- while (i != m_info.constEnd()) {
- int valueIndex = registerString(i.value(), strings);
- int keyIndex = registerString(i.key(), strings);
- data[index++] = keyIndex;
- data[index++] = valueIndex;
- i++;
- }
- }
-
- // Write methods first, then properties, to be consistent with moc.
- // Write signals/slots (signals must be written first, see indexOfMethodRelative in
- // qmetaobject.cpp).
-
- QList<MethodData>::iterator it;
- // PYSIDE-315: Instead of sorting the items and maybe breaking indices,
- // we ensure that the signals and slots are sorted by the improved parsePythonType().
- // The order can only become distorted if the class is modified after creation.
- // In that case, we give a warning.
- if (!is_sorted(m_methods.begin(), m_methods.end(), sortMethodSignalSlot)) {
- const char *metaObjectName = this->m_className.data();
- PyObject *txt = PyBytes_FromFormat("\n\n*** Sort Warning ***\n"
- "Signals and slots in QMetaObject '%s' are not ordered correctly, "
- "this may lead to issues.\n", metaObjectName);
- it = m_methods.begin();
- QList<MethodData>::iterator end = m_methods.end();
- QList<MethodData>::iterator until = is_sorted_until(m_methods.begin(), m_methods.end(),
- sortMethodSignalSlot);
- for (; it != end; ++it) {
- PyObject *atxt = PyBytes_FromFormat("%d%s %s %s\n", it - m_methods.begin() + 1,
- until >= it + 1 ? " " : "!",
- it->methodType() == QMetaMethod::Signal ? "Signal" : "Slot ",
- it->signature().data() );
- PyBytes_ConcatAndDel(&txt, atxt);
- }
- PyErr_WarnEx(PyExc_RuntimeWarning, PyBytes_AsString(txt), 0);
- Py_DECREF(txt);
- // Prevent a warning from being turned into an error. We cannot easily unwind.
- PyErr_Clear();
- }
-
- if (m_methods.size()) {
- if (data[5] == 0)
- data[5] = index;
-
- writeMethodsData(m_methods, &data, strings, &index, m_nullIndex, AccessPublic);
- }
-
- // Write signal/slots parameters.
- if (m_methods.size()) {
- for (it = m_methods.begin(); it != m_methods.end(); ++it) {
- QList<QByteArray> paramTypeNames = it->parameterTypes();
- int paramCount = paramTypeNames.size();
- for (int i = -1; i < paramCount; ++i) {
- const QByteArray &typeName = (i < 0) ? it->returnType() : paramTypeNames.at(i);
- int typeInfo;
- if (QtPrivate::isBuiltinType(typeName))
- typeInfo = QMetaType::type(typeName);
- else
- typeInfo = IsUnresolvedType | registerString(typeName, strings);
- data[index++] = typeInfo;
- }
-
- // Parameter names (use a null string)
- for (int i = 0; i < paramCount; ++i) {
- data[index++] = m_nullIndex;
- }
- }
- }
-
- // Write properties.
- if (m_properties.size()) {
- if (data[7] == 0)
- data[7] = index;
-
- QList<PropertyData>::const_iterator i = m_properties.constBegin();
- while (i != m_properties.constEnd()) {
- if (i->isValid()) {
- data[index++] = registerString(i->name(), strings); // name
- } else
- data[index++] = m_nullIndex;
-
- // Find out the property type index.
- int typeInfo = m_nullIndex;
- if (i->isValid()) {
- const QByteArray &typeName = i->type();
- if (QtPrivate::isBuiltinType(typeName))
- typeInfo = QMetaType::type(typeName);
- else
- typeInfo = IsUnresolvedType | registerString(typeName, strings);
- }
- data[index++] = typeInfo; // normalized type
-
- data[index++] = i->flags();
- i++;
- }
-
- // Write properties notify.
- i = m_properties.constBegin();
- while (i != m_properties.constEnd()) {
- // Recompute notifyId, because sorting the methods might have changed the relative
- // index.
- const int notifyId = getPropertyNotifyId(i->data());
- data[index++] = notifyId >= 0 ? static_cast<uint>(notifyId) : 0; //signal notify index
- i++;
- }
- }
-
- data[index++] = 0; // the end
-
- // Create the m_metadata string.
- int size = blobSize(strings);
- char *blob =
- reinterpret_cast<char *>(realloc(reinterpret_cast<char *>(const_cast<QByteArrayData *>(metaObj->d.stringdata)), size));
- writeStringData(blob, strings);
-
- metaObj->d.stringdata = reinterpret_cast<const QByteArrayData *>(blob);
- metaObj->d.data = data;
-}
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject.h b/sources/pyside2/libpyside/dynamicqmetaobject.h
index 5ecce50c9..1fbe73ea4 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject.h
+++ b/sources/pyside2/libpyside/dynamicqmetaobject.h
@@ -40,43 +40,42 @@
#ifndef DYNAMICQMETAOBJECT_H
#define DYNAMICQMETAOBJECT_H
-#include "pysidemacros.h"
#include <sbkpython.h>
-#include <QMetaObject>
-#include <QMetaMethod>
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QMetaMethod>
+
+class MetaObjectBuilderPrivate;
namespace PySide
{
-class DynamicQMetaObject : public QMetaObject
+class MetaObjectBuilder
{
+ Q_DISABLE_COPY(MetaObjectBuilder)
public:
- DynamicQMetaObject(const char* className, const QMetaObject* metaObject);
- DynamicQMetaObject(PyTypeObject* type, const QMetaObject* metaobject);
- ~DynamicQMetaObject();
+ MetaObjectBuilder(const char *className, const QMetaObject *metaObject);
+ MetaObjectBuilder(PyTypeObject *type, const QMetaObject *metaObject);
+ ~MetaObjectBuilder();
- int addMethod(QMetaMethod::MethodType mtype, const char* signature, const char* type);
- void removeMethod(QMetaMethod::MethodType mtype, uint index);
- int addSignal(const char* signal, const char* type = 0);
- int addSlot(const char* slot, const char* type = 0);
- int addProperty(const char* property, PyObject* data);
- void addInfo(const char* key, const char* value);
- void addInfo(QMap<QByteArray, QByteArray> info);
+ int indexOfMethod(QMetaMethod::MethodType mtype, const QByteArray &signature) const;
+ int indexOfProperty(const QByteArray &name) const;
+ int addSlot(const char *signature);
+ int addSlot(const char *signature, const char *type);
+ int addSignal(const char *signature);
+ void removeMethod(QMetaMethod::MethodType mtype, int index);
+ int addProperty(const char *property, PyObject *data);
+ void addInfo(const char *key, const char *value);
+ void addInfo(const QMap<QByteArray, QByteArray> &info);
- void removeSignal(uint idex);
- void removeSlot(uint index);
- void removeProperty(uint index);
+ void removeProperty(int index);
- const QMetaObject* update() const;
+ const QMetaObject *update();
private:
- class DynamicQMetaObjectPrivate;
- DynamicQMetaObjectPrivate* m_d;
-
- void parsePythonType(PyTypeObject *type);
+ MetaObjectBuilderPrivate *m_d;
};
-
}
#endif
diff --git a/sources/pyside2/libpyside/dynamicqmetaobject_p.h b/sources/pyside2/libpyside/dynamicqmetaobject_p.h
index 219ffc4e3..738b950ba 100644
--- a/sources/pyside2/libpyside/dynamicqmetaobject_p.h
+++ b/sources/pyside2/libpyside/dynamicqmetaobject_p.h
@@ -41,8 +41,9 @@
#define DYNAMICMETAPROPERTY_P_H
#include <sbkpython.h>
-#include <QByteArray>
-#include <QMetaMethod>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QMetaMethod>
#define GLOBAL_RECEIVER_CLASS_NAME "__GlobalReceiver__"
diff --git a/sources/pyside2/libpyside/globalreceiver.cpp b/sources/pyside2/libpyside/globalreceiver.cpp
deleted file mode 100644
index ee1f6354a..000000000
--- a/sources/pyside2/libpyside/globalreceiver.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
-
-#include "globalreceiver.h"
-#include "dynamicqmetaobject_p.h"
-#include "pysideweakref.h"
-
-#include <QMetaMethod>
-#include <QDebug>
-#include <QEvent>
-#include <QLinkedList>
-#include <autodecref.h>
-#include <sbkconverter.h>
-#include <gilstate.h>
-
-#include "signalmanager.h"
-
-#define RECEIVER_DESTROYED_SLOT_NAME "__receiverDestroyed__(QObject*)"
-
-namespace PySide
-{
-class DynamicSlotData
-{
- public:
- DynamicSlotData(int id, PyObject* callback, GlobalReceiver* parent);
- void addRef(const QObject* o);
- void decRef(const QObject* o);
- void clear();
- int hasRefTo(const QObject* o) const;
- int refCount() const;
- int id() const;
- PyObject* call(PyObject* args);
- ~DynamicSlotData();
- static void onCallbackDestroyed(void* data);
-
- private:
- int m_id;
- bool m_isMethod;
- PyObject* m_callback;
- PyObject* m_pythonSelf;
- PyObject* m_pyClass;
- PyObject* m_weakRef;
- GlobalReceiver* m_parent;
- QLinkedList<const QObject*> m_refs;
-};
-
-}
-
-using namespace PySide;
-
-DynamicSlotData::DynamicSlotData(int id, PyObject* callback, GlobalReceiver* parent)
- : m_id(id), m_pythonSelf(0), m_pyClass(0), m_weakRef(0), m_parent(parent)
-{
- Shiboken::GilState gil;
-
- m_isMethod = PyMethod_Check(callback);
- if (m_isMethod) {
- //Can not store calback pointe because this will be destroyed at the end of the scope
- //To avoid increment intance reference keep the callback information
- m_callback = PyMethod_GET_FUNCTION(callback);
-#ifdef IS_PY3K
- m_pyClass = 0;
-#else
- m_pyClass = PyMethod_GET_CLASS(callback);
-#endif
-
- m_pythonSelf = PyMethod_GET_SELF(callback);
-
- //monitor class from method lifetime
- m_weakRef = WeakRef::create(m_pythonSelf, DynamicSlotData::onCallbackDestroyed, this);
- } else {
- m_callback = callback;
- Py_INCREF(m_callback);
- }
-}
-
-PyObject* DynamicSlotData::call(PyObject* args)
-{
- PyObject* callback = m_callback;
-
- //create a callback based on method data
- Shiboken::GilState gil;
- if (m_isMethod)
-#ifdef IS_PY3K
- callback = PyMethod_New(callback, m_pythonSelf);
-#else
- callback = PyMethod_New(callback, m_pythonSelf, m_pyClass);
-#endif
-
- PyObject* result = PyObject_CallObject(callback, args);
-
- if (m_isMethod)
- Py_DECREF(callback);
-
- return result;
-}
-
-void DynamicSlotData::addRef(const QObject *o)
-{
- m_refs.append(o);
-}
-
-void DynamicSlotData::decRef(const QObject *o)
-{
- m_refs.removeOne(o);
-}
-
-int DynamicSlotData::refCount() const
-{
- return m_refs.size();
-}
-
-int DynamicSlotData::id() const
-{
- return m_id;
-}
-
-int DynamicSlotData::hasRefTo(const QObject *o) const
-{
- return m_refs.count(o);
-}
-
-void DynamicSlotData::clear()
-{
- Shiboken::GilState gil;
- Py_XDECREF(m_weakRef);
- m_weakRef = 0;
- m_refs.clear();
-}
-
-DynamicSlotData::~DynamicSlotData()
-{
- Shiboken::GilState gil;
- clear();
- if (!m_isMethod)
- Py_DECREF(m_callback);
-}
-
-void DynamicSlotData::onCallbackDestroyed(void *data)
-{
- Shiboken::GilState gil;
- DynamicSlotData* self = reinterpret_cast<DynamicSlotData*>(data);
-
- //Disconnect all sources
- QMetaMethod m = self->m_parent->metaObject()->method(self->m_id);
- QByteArray methodName = QByteArray::number(m.methodType()).append(m.methodSignature());
- QLinkedList<const QObject*> sources = self->m_refs;
- foreach(const QObject* src, sources)
- const_cast<QObject*>(src)->disconnect(self->m_parent, methodName);
- self->m_weakRef = 0;
-}
-
-GlobalReceiver::GlobalReceiver()
- : m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject)
-{
- //slot used to be notifyed of object destrouction
- m_metaObject.addSlot(RECEIVER_DESTROYED_SLOT_NAME);
- m_metaObject.update();
- setObjectName(QLatin1String("GLOBAL RECEIVER"));
-}
-
-GlobalReceiver::~GlobalReceiver()
-{
- while(!m_slotReceivers.empty()) {
- DynamicSlotData* data = m_slotReceivers.take(m_slotReceivers.begin().key());
- data->clear();
- delete data;
- }
-}
-
-void GlobalReceiver::connectNotify(QObject* source, int slotId)
-{
- if (m_slotReceivers.contains(slotId)) {
- DynamicSlotData* data = m_slotReceivers[slotId];
- if (!data->hasRefTo(source))
- QObject::connect(source, SIGNAL(destroyed(QObject*)), this, "1" RECEIVER_DESTROYED_SLOT_NAME);
- data->addRef(source);
- }
-}
-
-void GlobalReceiver::disconnectNotify(QObject* source, int slotId)
-{
- if (m_slotReceivers.contains(slotId)) {
- DynamicSlotData *data = m_slotReceivers[slotId];
- data->decRef(source);
- if (data->refCount() == 0)
- removeSlot(slotId);
-
- if (!hasConnectionWith(source))
- QObject::disconnect(source, SIGNAL(destroyed(QObject*)), this, "1" RECEIVER_DESTROYED_SLOT_NAME);
- }
-}
-
-const QMetaObject* GlobalReceiver::metaObject() const
-{
- return m_metaObject.update();
-}
-
-int GlobalReceiver::addSlot(const char* slot, PyObject* callback)
-{
- int slotId = m_metaObject.addSlot(slot);
- if (!m_slotReceivers.contains(slotId))
- m_slotReceivers[slotId] = new DynamicSlotData(slotId, callback, this);
-
- bool isShortCircuit = true;
- for (int i = 0; slot[i]; ++i) {
- if (slot[i] == '(') {
- isShortCircuit = false;
- break;
- }
- }
-
- if (isShortCircuit)
- m_shortCircuitSlots << slotId;
-
- Q_ASSERT(slotId >= QObject::staticMetaObject.methodCount());
- return slotId;
-}
-
-void GlobalReceiver::removeSlot(int slotId)
-{
- if (m_slotReceivers.contains(slotId)) {
- delete m_slotReceivers.take(slotId);
- m_metaObject.removeSlot(slotId);
- m_shortCircuitSlots.remove(slotId);
- }
-}
-
-bool GlobalReceiver::hasConnectionWith(const QObject *object)
-{
- QHash<int, DynamicSlotData*>::iterator i = m_slotReceivers.begin();
- while(i != m_slotReceivers.end()) {
- if (i.value()->hasRefTo(object)) {
- return true;
- }
- i++;
- }
- return false;
-}
-
-int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
-{
- Q_ASSERT(call == QMetaObject::InvokeMetaMethod);
- Q_ASSERT(id >= QObject::staticMetaObject.methodCount());
- QMetaMethod slot = metaObject()->method(id);
- Q_ASSERT(slot.methodType() == QMetaMethod::Slot);
-
- if (strcmp(slot.methodSignature(), RECEIVER_DESTROYED_SLOT_NAME) == 0) {
- QObject *arg = *(QObject**)args[1];
-
- //avoid hash changes during the destruction
- QHash<int, DynamicSlotData*> copy = m_slotReceivers;
- QHash<int, DynamicSlotData*>::iterator i = copy.begin();
- while(i != copy.end()) {
- //Remove all refs
- int refs = i.value()->hasRefTo(arg);
- while(refs) {
- disconnectNotify(arg, i.key());
- refs--;
- }
- i++;
- }
- return -1;
- }
-
- DynamicSlotData* data = m_slotReceivers.value(id);
- if (!data) {
- qWarning() << "Unknown global slot, id:" << id;
- return -1;
- }
-
- Shiboken::GilState gil;
- PyObject* retval = 0;
- if (m_shortCircuitSlots.contains(id)) {
- retval = data->call(reinterpret_cast<PyObject*>(args[1]));
- } else {
- QList<QByteArray> paramTypes = slot.parameterTypes();
- Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count()));
- for (int i = 0, max = paramTypes.count(); i < max; ++i) {
- const QByteArray& paramType = paramTypes[i];
- Shiboken::Conversions::SpecificConverter converter(paramType.constData());
- PyTuple_SET_ITEM(preparedArgs.object(), i, converter.toPython(args[i+1]));
- }
- retval = data->call(preparedArgs);
- }
-
- if (!retval)
- PyErr_Print();
- else
- Py_DECREF(retval);
-
- return -1;
-}
diff --git a/sources/pyside2/libpyside/globalreceiverv2.cpp b/sources/pyside2/libpyside/globalreceiverv2.cpp
index 05565e516..43ce50a75 100644
--- a/sources/pyside2/libpyside/globalreceiverv2.cpp
+++ b/sources/pyside2/libpyside/globalreceiverv2.cpp
@@ -40,15 +40,13 @@
#include "globalreceiverv2.h"
#include "dynamicqmetaobject_p.h"
#include "pysideweakref.h"
+#include "signalmanager.h"
-#include <QMetaMethod>
-#include <QDebug>
-#include <QEvent>
-#include <QLinkedList>
#include <autodecref.h>
#include <gilstate.h>
-#include "signalmanager.h"
+#include <QtCore/QMetaMethod>
+#include <QtCore/QSet>
#define RECEIVER_DESTROYED_SLOT_NAME "__receiverDestroyed__(QObject*)"
@@ -62,6 +60,7 @@ namespace PySide
{
class DynamicSlotDataV2
{
+ Q_DISABLE_COPY(DynamicSlotDataV2)
public:
DynamicSlotDataV2(PyObject* callback, GlobalReceiverV2* parent);
~DynamicSlotDataV2();
@@ -128,11 +127,11 @@ QByteArray DynamicSlotDataV2::hash() const
QByteArray DynamicSlotDataV2::hash(PyObject* callback)
{
Shiboken::GilState gil;
- if (PyMethod_Check(callback))
+ if (PyMethod_Check(callback)) {
return QByteArray::number((qlonglong)PyObject_Hash(PyMethod_GET_FUNCTION(callback)))
+ QByteArray::number((qlonglong)PyObject_Hash(PyMethod_GET_SELF(callback)));
- else
- return QByteArray::number((qlonglong)PyObject_Hash(callback));
+ }
+ return QByteArray::number(qlonglong(PyObject_Hash(callback)));
}
PyObject* DynamicSlotDataV2::callback()
@@ -154,18 +153,15 @@ PyObject* DynamicSlotDataV2::callback()
int DynamicSlotDataV2::id(const char* signature) const
{
- if (m_signatures.contains(signature))
- return m_signatures[signature];
- return -1;
+ const auto it = m_signatures.constFind(signature);
+ return it != m_signatures.cend() ? it.value() : -1;
}
int DynamicSlotDataV2::addSlot(const char* signature)
{
int index = id(signature);
- if (index == -1) {
- DynamicQMetaObject *dmo = const_cast<DynamicQMetaObject*>(reinterpret_cast<const DynamicQMetaObject*>(m_parent->metaObject()));
- index = m_signatures[signature] = dmo->addSlot(signature);
- }
+ if (index == -1)
+ index = m_signatures[signature] = m_parent->metaObjectBuilder().addSlot(signature);
return index;
}
@@ -189,8 +185,10 @@ DynamicSlotDataV2::~DynamicSlotDataV2()
Py_DECREF(m_callback);
}
-GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, SharedMap map)
- : QObject(0), m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject), m_sharedMap(map)
+GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, SharedMap map) :
+ QObject(nullptr),
+ m_metaObject(GLOBAL_RECEIVER_CLASS_NAME, &QObject::staticMetaObject),
+ m_sharedMap(std::move(map))
{
m_data = new DynamicSlotDataV2(callback, this);
m_metaObject.addSlot(RECEIVER_DESTROYED_SLOT_NAME);
@@ -202,7 +200,7 @@ GlobalReceiverV2::GlobalReceiverV2(PyObject *callback, SharedMap map)
DESTROY_SIGNAL_ID = QObject::staticMetaObject.indexOfSignal("destroyed(QObject*)");
if (DESTROY_SLOT_ID == 0)
- DESTROY_SLOT_ID = m_metaObject.indexOfSlot(RECEIVER_DESTROYED_SLOT_NAME);
+ DESTROY_SLOT_ID = m_metaObject.indexOfMethod(QMetaMethod::Slot, RECEIVER_DESTROYED_SLOT_NAME);
}
@@ -251,7 +249,7 @@ void GlobalReceiverV2::incRef(const QObject* link)
void GlobalReceiverV2::decRef(const QObject* link)
{
- if (m_refs.size() <= 0)
+ if (m_refs.empty())
return;
@@ -268,7 +266,7 @@ void GlobalReceiverV2::decRef(const QObject* link)
}
}
- if (m_refs.size() == 0)
+ if (m_refs.empty())
Py_BEGIN_ALLOW_THREADS
delete this;
Py_END_ALLOW_THREADS
@@ -285,9 +283,9 @@ int GlobalReceiverV2::refCount(const QObject* link) const
void GlobalReceiverV2::notify()
{
- QSet<const QObject*> objs = QSet<const QObject*>::fromList(m_refs);
+ const auto objSet = QSet<const QObject*>::fromList(m_refs);
Py_BEGIN_ALLOW_THREADS
- foreach(const QObject* o, objs) {
+ for (const QObject *o : objSet) {
QMetaObject::disconnect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
QMetaObject::connect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID);
}
@@ -306,7 +304,7 @@ QByteArray GlobalReceiverV2::hash(PyObject* callback)
const QMetaObject* GlobalReceiverV2::metaObject() const
{
- return m_metaObject.update();
+ return const_cast<GlobalReceiverV2 *>(this)->m_metaObject.update();
}
int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void** args)
@@ -328,9 +326,9 @@ int GlobalReceiverV2::qt_metacall(QMetaObject::Call call, int id, void** args)
}
if (id == DESTROY_SLOT_ID) {
- if (m_refs.size() == 0)
+ if (m_refs.empty())
return -1;
- QObject *obj = *(QObject**)args[1];
+ QObject *obj = *reinterpret_cast<QObject**>(args[1]);
incRef(); //keep the object live (safe ref)
m_refs.removeAll(obj); // remove all refs to this object
decRef(); //remove the safe ref
diff --git a/sources/pyside2/libpyside/globalreceiverv2.h b/sources/pyside2/libpyside/globalreceiverv2.h
index 880719d6f..b92be93a8 100644
--- a/sources/pyside2/libpyside/globalreceiverv2.h
+++ b/sources/pyside2/libpyside/globalreceiverv2.h
@@ -41,15 +41,14 @@
#define GLOBALRECEIVER_V2_H
#include <sbkpython.h>
-#include <QObject>
-#include <QHash>
-#include <QSet>
-#include <QSharedPointer>
-#include <QLinkedList>
-#include <QByteArray>
#include "dynamicqmetaobject.h"
+#include <QtCore/QByteArray>
+#include <QtCore/QObject>
+#include <QtCore/QMap>
+#include <QtCore/QSharedPointer>
+
namespace PySide
{
@@ -78,13 +77,13 @@ public:
/**
* Destructor
**/
- ~GlobalReceiverV2();
+ ~GlobalReceiverV2() override;
/**
* Reimplemented function from QObject
**/
- int qt_metacall(QMetaObject::Call call, int id, void** args);
- const QMetaObject* metaObject() const;
+ int qt_metacall(QMetaObject::Call call, int id, void** args) override;
+ const QMetaObject* metaObject() const override;
/**
* Add a extra slot to this object
@@ -122,22 +121,25 @@ public:
int refCount(const QObject* link) const;
/**
- * Use to retrive the unique hash of this GlobalReceiver object
+ * Use to retrieve the unique hash of this GlobalReceiver object
*
* @return a string with a unique id based on GlobalReceiver contents
**/
QByteArray hash() const;
/**
- * Use to retrive the unique hash of the PyObject based on GlobalReceiver rules
+ * Use to retrieve the unique hash of the PyObject based on GlobalReceiver rules
*
* @param callback The Python callable object used to calculate the id
* @return a string with a unique id based on GlobalReceiver contents
**/
static QByteArray hash(PyObject* callback);
+ const MetaObjectBuilder &metaObjectBuilder() const { return m_metaObject; }
+ MetaObjectBuilder &metaObjectBuilder() { return m_metaObject; }
+
private:
- DynamicQMetaObject m_metaObject;
+ MetaObjectBuilder m_metaObject;
DynamicSlotDataV2 *m_data;
QList<const QObject*> m_refs;
SharedMap m_sharedMap;
diff --git a/sources/pyside2/libpyside/pyside.cpp b/sources/pyside2/libpyside/pyside.cpp
index b4f7d8771..6e4a3efd4 100644
--- a/sources/pyside2/libpyside/pyside.cpp
+++ b/sources/pyside2/libpyside/pyside.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "pyside.h"
+#include "pyside_p.h"
#include "signalmanager.h"
#include "pysideclassinfo_p.h"
#include "pysideproperty_p.h"
@@ -51,23 +52,24 @@
#include "destroylistener.h"
#include <autodecref.h>
-#include <qapp_macro.h>
#include <basewrapper.h>
+#include <bindingmanager.h>
+#include <gilstate.h>
#include <sbkconverter.h>
#include <sbkstring.h>
-#include <gilstate.h>
-#include <bindingmanager.h>
+#include <qapp_macro.h>
+
+#include <QtCore/QByteArray>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QStack>
+
#include <algorithm>
-#include <typeinfo>
#include <cstring>
#include <cctype>
-#include <QByteArray>
-#include <QCoreApplication>
-#include <QDebug>
-#include <QDir>
-#include <QFileInfo>
-#include <QSharedPointer>
-#include <QStack>
+#include <typeinfo>
static QStack<PySide::CleanupFunction> cleanupFunctionList;
static void* qobjectNextAddr;
@@ -188,29 +190,21 @@ void destroyQCoreApplication()
MakeSingletonQAppWrapper(NULL);
}
-struct TypeUserData {
- TypeUserData(PyTypeObject* type, const QMetaObject* metaobject) : mo(type, metaobject) {}
- DynamicQMetaObject mo;
- std::size_t cppObjSize;
-};
-
std::size_t getSizeOfQObject(SbkObjectType* type)
{
- using namespace Shiboken::ObjectType;
- TypeUserData* userData = reinterpret_cast<TypeUserData*>(getTypeUserData(reinterpret_cast<SbkObjectType*>(type)));
- return userData->cppObjSize;
+ return retrieveTypeUserData(type)->cppObjSize;
}
-void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const std::size_t& cppObjSize)
+void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, std::size_t cppObjSize)
{
//create DynamicMetaObject based on python type
- TypeUserData* userData = new TypeUserData(reinterpret_cast<PyTypeObject*>(type), base);
- userData->cppObjSize = cppObjSize;
+ auto userData =
+ new TypeUserData(reinterpret_cast<PyTypeObject*>(type), base, cppObjSize);
userData->mo.update();
Shiboken::ObjectType::setTypeUserData(type, userData, Shiboken::callCppDestructor<TypeUserData>);
//initialize staticQMetaObject property
- void* metaObjectPtr = &userData->mo;
+ void *metaObjectPtr = const_cast<QMetaObject *>(userData->mo.update());
static SbkConverter* converter = Shiboken::Conversions::getConverter("QMetaObject");
if (!converter)
return;
@@ -218,6 +212,36 @@ void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const s
PyObject_SetAttrString(reinterpret_cast<PyObject*>(type), "staticMetaObject", pyMetaObject);
}
+TypeUserData *retrieveTypeUserData(SbkObjectType *sbkTypeObj)
+{
+ return reinterpret_cast<TypeUserData *>(Shiboken::ObjectType::getTypeUserData(sbkTypeObj));
+}
+
+TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj)
+{
+ return retrieveTypeUserData(reinterpret_cast<SbkObjectType *>(pyTypeObj));
+}
+
+TypeUserData *retrieveTypeUserData(PyObject *pyObj)
+{
+ auto pyTypeObj = PyType_Check(pyObj)
+ ? reinterpret_cast<PyTypeObject *>(pyObj) : Py_TYPE(pyObj);
+ return retrieveTypeUserData(pyTypeObj);
+}
+
+const QMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj)
+{
+ TypeUserData *userData = retrieveTypeUserData(pyTypeObj);
+ return userData ? userData->mo.update() : nullptr;
+}
+
+const QMetaObject *retrieveMetaObject(PyObject *pyObj)
+{
+ auto pyTypeObj = PyType_Check(pyObj)
+ ? reinterpret_cast<PyTypeObject *>(pyObj) : Py_TYPE(pyObj);
+ return retrieveMetaObject(pyTypeObj);
+}
+
void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base)
{
initDynamicMetaObject(type, base, 0);
@@ -230,25 +254,21 @@ void initQObjectSubType(SbkObjectType *type, PyObject *args, PyObject * /* kwds
PyObject* bases = PyTuple_GET_ITEM(args, 1);
int numBases = PyTuple_GET_SIZE(bases);
- QMetaObject* baseMo = 0;
- SbkObjectType* qobjBase = 0;
+
+ TypeUserData *userData = nullptr;
for (int i = 0; i < numBases; ++i) {
PyTypeObject* base = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i));
if (PyType_IsSubtype(base, qObjType)) {
- baseMo = reinterpret_cast<QMetaObject*>(Shiboken::ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType*>(base)));
- qobjBase = reinterpret_cast<SbkObjectType*>(base);
- reinterpret_cast<DynamicQMetaObject*>(baseMo)->update();
+ userData = retrieveTypeUserData(base);
break;
}
}
- if (!baseMo) {
+ if (!userData) {
qWarning("Sub class of QObject not inheriting QObject!? Crash will happen when using %s.", className.constData());
return;
}
-
- TypeUserData* userData = reinterpret_cast<TypeUserData*>(Shiboken::ObjectType::getTypeUserData(qobjBase));
- initDynamicMetaObject(type, baseMo, userData->cppObjSize);
+ initDynamicMetaObject(type, userData->mo.update(), userData->cppObjSize);
}
PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* name)
@@ -299,7 +319,7 @@ PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* nam
}
}
}
- if (signalList.size() > 0) {
+ if (!signalList.empty()) {
PyObject* pySignal = reinterpret_cast<PyObject*>(Signal::newObjectFromMethod(self, signalList));
PyObject_SetAttr(self, name, pySignal);
return pySignal;
@@ -366,7 +386,7 @@ PyObject* getWrapperForQObject(QObject* cppSelf, SbkObjectType* sbk_type)
// set and check if it's created after the set call
QVariant existing = cppSelf->property(invalidatePropertyName);
if (!existing.isValid()) {
- QSharedPointer<any_t> shared_with_del((any_t*)cppSelf, invalidatePtr);
+ QSharedPointer<any_t> shared_with_del(reinterpret_cast<any_t*>(cppSelf), invalidatePtr);
cppSelf->setProperty(invalidatePropertyName, QVariant::fromValue(shared_with_del));
pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppSelf));
if (pyOut) {
diff --git a/sources/pyside2/libpyside/pyside.h b/sources/pyside2/libpyside/pyside.h
index e2e108ed8..b53048eba 100644
--- a/sources/pyside2/libpyside/pyside.h
+++ b/sources/pyside2/libpyside/pyside.h
@@ -41,16 +41,15 @@
#define PYSIDE_H
#include <sbkpython.h>
+
#include <pysidemacros.h>
#ifdef PYSIDE_QML_SUPPORT
-# include <qqml.h>
+# include <QtQml/qqml.h>
#endif
-#include <QMetaType>
-#include <QHash>
-#include <QList>
-#include <QLoggingCategory>
+#include <QtCore/QMetaType>
+#include <QtCore/QHash>
struct SbkObjectType;
@@ -101,7 +100,8 @@ struct initQtMetaType<T, false> {
};
PYSIDE_DEPRECATED(PYSIDE_API void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base));
-PYSIDE_API void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const std::size_t& cppObjSize);
+PYSIDE_API void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base,
+ std::size_t cppObjSize);
PYSIDE_API void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds);
/// Return the size in bytes of a type that inherits QObject.
diff --git a/sources/pyside2/libpyside/pyside2.pc.in b/sources/pyside2/libpyside/pyside2.pc.in
index 37a115989..ecbe0bbc8 100644
--- a/sources/pyside2/libpyside/pyside2.pc.in
+++ b/sources/pyside2/libpyside/pyside2.pc.in
@@ -3,6 +3,7 @@ exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@LIB_INSTALL_DIR@
includedir=@CMAKE_INSTALL_PREFIX@/include/PySide2@pyside2_SUFFIX@
typesystemdir=@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/typesystems
+gluedir=@CMAKE_INSTALL_PREFIX@/share/PySide2@pyside2_SUFFIX@/glue
pythonpath=@PYTHON_SITE_PACKAGES@
Name: PySide2@pyside2_SUFFIX@
diff --git a/sources/pyside2/libpyside/pyside_p.h b/sources/pyside2/libpyside/pyside_p.h
new file mode 100644
index 000000000..1084a40a1
--- /dev/null
+++ b/sources/pyside2/libpyside/pyside_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 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$
+**
+****************************************************************************/
+
+#ifndef PYSIDE_P_H
+#define PYSIDE_P_H
+
+#include <pysidemacros.h>
+
+#include <dynamicqmetaobject.h>
+
+struct SbkObjectType;
+
+namespace PySide
+{
+
+// Struct associated with QObject's via Shiboken::Object::getTypeUserData()
+struct TypeUserData
+{
+ explicit TypeUserData(PyTypeObject* type, const QMetaObject* metaobject, std::size_t size) :
+ mo(type, metaobject), cppObjSize(size) {}
+
+ MetaObjectBuilder mo;
+ std::size_t cppObjSize;
+};
+
+TypeUserData *retrieveTypeUserData(SbkObjectType *sbkTypeObj);
+TypeUserData *retrieveTypeUserData(PyTypeObject *pyTypeObj);
+TypeUserData *retrieveTypeUserData(PyObject *pyObj);
+// For QML
+PYSIDE_API const QMetaObject *retrieveMetaObject(PyTypeObject *pyTypeObj);
+PYSIDE_API const QMetaObject *retrieveMetaObject(PyObject *pyObj);
+
+} //namespace PySide
+
+#endif // PYSIDE_P_H
diff --git a/sources/pyside2/libpyside/pysideclassinfo.cpp b/sources/pyside2/libpyside/pysideclassinfo.cpp
index 5593825c3..4edf0fa91 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.cpp
+++ b/sources/pyside2/libpyside/pysideclassinfo.cpp
@@ -38,12 +38,13 @@
****************************************************************************/
#include <sbkpython.h>
+
#include "pysideclassinfo.h"
+#include "pyside_p.h"
#include "pysideclassinfo_p.h"
#include "dynamicqmetaobject.h"
#include <shiboken.h>
-#include <QDebug>
#define CLASSINFO_CLASS_NAME "ClassInfo"
@@ -74,9 +75,8 @@ static PyType_Spec PySideClassInfoType_spec = {
PyTypeObject *PySideClassInfoTypeF(void)
{
- static PyTypeObject *type = nullptr;
- if (!type)
- type = (PyTypeObject *)PyType_FromSpec(&PySideClassInfoType_spec);
+ static PyTypeObject *type =
+ reinterpret_cast<PyTypeObject *>(PyType_FromSpec(&PySideClassInfoType_spec));
return type;
}
@@ -97,8 +97,7 @@ PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */)
return 0;
}
- PyObject* klass;
- klass = PyTuple_GetItem(args, 0);
+ PyObject *klass = PyTuple_GetItem(args, 0);
bool validClass = false;
// This will sometimes segfault if you mistakenly use it on a function declaration
@@ -107,10 +106,11 @@ PyObject *classCall(PyObject *self, PyObject *args, PyObject * /* kw */)
return 0;
}
- if (Shiboken::ObjectType::checkType(reinterpret_cast<PyTypeObject*>(klass))) {
- PySide::DynamicQMetaObject* mo = reinterpret_cast<PySide::DynamicQMetaObject*>(Shiboken::ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType*>(klass)));
- if (mo) {
- mo->addInfo(PySide::ClassInfo::getMap(data));
+ PyTypeObject *klassType = reinterpret_cast<PyTypeObject*>(klass);
+ if (Shiboken::ObjectType::checkType(klassType)) {
+ if (auto userData = PySide::retrieveTypeUserData(klassType)) {
+ PySide::MetaObjectBuilder &mo = userData->mo;
+ mo.addInfo(PySide::ClassInfo::getMap(data));
pData->m_alreadyWrapped = true;
validClass = true;
}
diff --git a/sources/pyside2/libpyside/pysideclassinfo.h b/sources/pyside2/libpyside/pysideclassinfo.h
index 910dd9f82..ff60b91c3 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.h
+++ b/sources/pyside2/libpyside/pysideclassinfo.h
@@ -41,9 +41,11 @@
#define PYSIDE_CLASSINFO_H
#include <pysidemacros.h>
+
#include <sbkpython.h>
-#include <QMap>
-#include <QByteArray>
+
+#include <QtCore/QMap>
+#include <QtCore/QByteArray>
extern "C"
{
diff --git a/sources/pyside2/libpyside/pysidemetafunction.cpp b/sources/pyside2/libpyside/pysidemetafunction.cpp
index a9fbbc7fc..4cdc7ec16 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.cpp
+++ b/sources/pyside2/libpyside/pysidemetafunction.cpp
@@ -36,14 +36,13 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <sbkpython.h>
+
#include "pysidemetafunction.h"
#include "pysidemetafunction_p.h"
#include <shiboken.h>
-#include <QObject>
-#include <QMetaMethod>
-#include <QDebug>
+
+#include <QtCore/QMetaMethod>
extern "C"
{
diff --git a/sources/pyside2/libpyside/pysidemetafunction.h b/sources/pyside2/libpyside/pysidemetafunction.h
index 020f02d49..1085ecb5e 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.h
+++ b/sources/pyside2/libpyside/pysidemetafunction.h
@@ -40,13 +40,12 @@
#ifndef PYSIDE_METAFUNCTION_H
#define PYSIDE_METAFUNCTION_H
-#include <QObject>
-#include <QString>
-#include <QStringList>
-
#include <pysidemacros.h>
+
#include <sbkpython.h>
+#include <QtCore/QObject>
+
extern "C"
{
extern PYSIDE_API PyTypeObject *PySideMetaFunctionTypeF(void);
diff --git a/sources/pyside2/libpyside/pysidemetafunction_p.h b/sources/pyside2/libpyside/pysidemetafunction_p.h
index c3b8fe0c7..442e05ea7 100644
--- a/sources/pyside2/libpyside/pysidemetafunction_p.h
+++ b/sources/pyside2/libpyside/pysidemetafunction_p.h
@@ -41,8 +41,8 @@
#define PYSIDE_METAFUNCTION_P_H
#include <sbkpython.h>
-#include <QList>
-#include <QByteArray>
+
+#include <QtCore/QtGlobal>
QT_BEGIN_NAMESPACE
class QObject;
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index 279e09ec1..091b0c447 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -45,8 +45,6 @@
#include "pysidesignal_p.h"
#include <shiboken.h>
-#include <QDebug>
-
#define QPROPERTY_CLASS_NAME "Property"
@@ -173,7 +171,8 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
"designable", "scriptable", "stored", "user",
"constant", "final", 0};
if (!PyArg_ParseTupleAndKeywords(args, kwds,
- "O|OOOOsObbbbbb:QtCore.QProperty", (char**) kwlist,
+ "O|OOOOsObbbbbb:QtCore.QProperty",
+ const_cast<char**>(kwlist),
/*OO*/ &type, &(pData->fget),
/*OOO*/ &(pData->fset), &(pData->freset), &(pData->fdel),
/*s*/ &(pData->doc),
@@ -197,14 +196,13 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds)
Py_XINCREF(pData->fdel);
Py_XINCREF(pData->notify);
return 1;
- } else {
- pData->fget = 0;
- pData->fset = 0;
- pData->freset = 0;
- pData->fdel = 0;
- pData->notify = 0;
- return -1;
}
+ pData->fget = nullptr;
+ pData->fset = nullptr;
+ pData->freset = nullptr;
+ pData->fdel = nullptr;
+ pData->notify = nullptr;
+ return -1;
}
void qpropertyDeAlloc(PyObject* self)
@@ -225,10 +223,9 @@ PyObject *qPropertyCall(PyObject *self, PyObject *args, PyObject * /* kw */)
Py_INCREF(self);
return self;
- } else {
- PyErr_SetString(PyExc_TypeError, "Invalid property usage.");
- return 0;
}
+ PyErr_SetString(PyExc_TypeError, "Invalid property usage.");
+ return nullptr;
}
PyObject* qPropertySetter(PyObject* self, PyObject* callback)
@@ -242,10 +239,9 @@ PyObject* qPropertySetter(PyObject* self, PyObject* callback)
Py_INCREF(callback);
return callback;
- } else {
- PyErr_SetString(PyExc_TypeError, "Invalid property setter agument.");
- return 0;
}
+ PyErr_SetString(PyExc_TypeError, "Invalid property setter agument.");
+ return nullptr;
}
PyObject* qPropertyGetter(PyObject* self, PyObject* callback)
@@ -259,10 +255,9 @@ PyObject* qPropertyGetter(PyObject* self, PyObject* callback)
Py_INCREF(callback);
return callback;
- } else {
- PyErr_SetString(PyExc_TypeError, "Invalid property getter agument.");
- return 0;
}
+ PyErr_SetString(PyExc_TypeError, "Invalid property getter agument.");
+ return nullptr;
}
static int qpropertyTraverse(PyObject* self, visitproc visit, void* arg)
diff --git a/sources/pyside2/libpyside/pysideproperty.h b/sources/pyside2/libpyside/pysideproperty.h
index d77416abe..0ea5e84d6 100644
--- a/sources/pyside2/libpyside/pysideproperty.h
+++ b/sources/pyside2/libpyside/pysideproperty.h
@@ -41,8 +41,10 @@
#define PYSIDE_PROPERTY_H
#include <pysidemacros.h>
+
#include <sbkpython.h>
-#include <QObject>
+
+#include <QtCore/QMetaObject>
extern "C"
{
diff --git a/sources/pyside2/libpyside/pysideqflags.cpp b/sources/pyside2/libpyside/pysideqflags.cpp
index 684628e57..cb57031b0 100644
--- a/sources/pyside2/libpyside/pysideqflags.cpp
+++ b/sources/pyside2/libpyside/pysideqflags.cpp
@@ -38,8 +38,9 @@
****************************************************************************/
#include "pysideqflags.h"
-#include <sbkenum.h>
+
#include <autodecref.h>
+#include <sbkenum.h>
extern "C" {
struct SbkConverter;
@@ -174,13 +175,8 @@ namespace QFlags
newspec->itemsize = SbkNewQFlagsType_spec.itemsize;
newspec->flags = SbkNewQFlagsType_spec.flags;
int idx = -1;
-#ifdef IS_PY3K
-# define SLOT slot
-#else
-# define SLOT slot_
-#endif
- while (numberMethods[++idx].SLOT) {
- assert(SbkNewQFlagsType_slots[idx].SLOT == numberMethods[idx].SLOT);
+ while (numberMethods[++idx].slot) {
+ assert(SbkNewQFlagsType_slots[idx].slot == numberMethods[idx].slot);
SbkNewQFlagsType_slots[idx].pfunc = numberMethods[idx].pfunc;
}
newspec->slots = SbkNewQFlagsType_spec.slots;
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index c3dc65968..e7fd389a8 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -43,7 +43,12 @@
#include "signalmanager.h"
#include <shiboken.h>
-#include <QDebug>
+
+#include <QtCore/QObject>
+#include <QtCore/QMetaMethod>
+#include <QtCore/QMetaObject>
+
+#include <utility>
#define SIGNAL_CLASS_NAME "Signal"
#define SIGNAL_INSTANCE_NAME "SignalInstance"
@@ -54,14 +59,15 @@ namespace Signal {
//aux
class SignalSignature {
public:
- SignalSignature() : m_attributes(QMetaMethod::Compatibility) {}
- SignalSignature(QByteArray parameterTypes) : m_parameterTypes(parameterTypes),
- m_attributes(QMetaMethod::Compatibility) {}
- SignalSignature(QByteArray parameterTypes, QMetaMethod::Attributes attributes) :
- m_parameterTypes(parameterTypes),
+ SignalSignature() = default;
+ explicit SignalSignature(QByteArray parameterTypes) :
+ m_parameterTypes(std::move(parameterTypes)) {}
+ explicit SignalSignature(QByteArray parameterTypes, QMetaMethod::Attributes attributes) :
+ m_parameterTypes(std::move(parameterTypes)),
m_attributes(attributes) {}
+
QByteArray m_parameterTypes;
- QMetaMethod::Attributes m_attributes;
+ QMetaMethod::Attributes m_attributes = QMetaMethod::Compatibility;
};
static char* buildSignature(const char*, const char*);
@@ -412,8 +418,7 @@ PyObject* signalInstanceConnect(PyObject* self, PyObject* args, PyObject* kwds)
PyObject* result = PyObject_CallObject(pyMethod, tupleArgs);
if (result == Py_True || result == Py_False)
return result;
- else
- Py_XDECREF(result);
+ Py_XDECREF(result);
}
if (!PyErr_Occurred()) // PYSIDE-79: inverse the logic. A Null return needs an error.
PyErr_Format(PyExc_RuntimeError, "Failed to connect signal %s.", source->d->signature);
@@ -661,9 +666,10 @@ char* getTypeName(PyObject* type)
typeName = strdup("PyObject");
}
return typeName;
- } else if (type == Py_None) { // Must be checked before as Shiboken::String::check accepts Py_None
+ }
+ if (type == Py_None) // Must be checked before as Shiboken::String::check accepts Py_None
return strdup("void");
- } else if (Shiboken::String::check(type)) {
+ if (Shiboken::String::check(type)) {
const char *result = Shiboken::String::toCString(type);
if (!strcmp(result, "qreal"))
result = sizeof(qreal) == sizeof(double) ? "double" : "float";
@@ -778,7 +784,7 @@ PySideSignalInstance* newObjectFromMethod(PyObject* source, const QList<QMetaMet
{
PySideSignalInstance* root = 0;
PySideSignalInstance* previous = 0;
- foreach (const QMetaMethod &m, methodList) {
+ for (const QMetaMethod &m : methodList) {
PySideSignalInstance* item = PyObject_New(PySideSignalInstance, PySideSignalInstanceTypeF());
if (!root)
root = item;
@@ -835,7 +841,7 @@ template<typename T>
static typename T::value_type join(T t, const char* sep)
{
typename T::value_type res;
- if (!t.size())
+ if (t.isEmpty())
return res;
typename T::const_iterator it = t.begin();
@@ -894,7 +900,7 @@ void registerSignals(SbkObjectType* pyObj, const QMetaObject* metaObject)
self->signaturesSize = 0;
self->signatures = 0;
self->signatureAttributes = 0;
- self->initialized = 0;
+ self->initialized = false;
self->homonymousMethod = 0;
// Empty signatures comes first! So they will be the default signal signature
@@ -949,9 +955,9 @@ QStringList getArgsFromSignature(const char* signature, bool* isShortCircuit)
if (isShortCircuit)
*isShortCircuit = !qsignature.contains(QLatin1Char('('));
- if (qsignature.contains(QLatin1String("()")) || qsignature.contains(QLatin1String("(void)"))) {
+ if (qsignature.contains(QLatin1String("()")) || qsignature.contains(QLatin1String("(void)")))
return result;
- } else if (qsignature.contains(QLatin1Char('('))) {
+ if (qsignature.contains(QLatin1Char('('))) {
static QRegExp regex(QLatin1String(".+\\((.*)\\)"));
//get args types
QString types = qsignature;
@@ -1047,9 +1053,8 @@ QString codeCallbackName(PyObject* callback, const QString& funcName)
PyObject* self = PyMethod_GET_SELF(callback);
PyObject* func = PyMethod_GET_FUNCTION(callback);
return funcName + QString::number(quint64(self), 16) + QString::number(quint64(func), 16);
- } else {
- return funcName + QString::number(quint64(callback), 16);
}
+ return funcName + QString::number(quint64(callback), 16);
}
} //namespace Signal
diff --git a/sources/pyside2/libpyside/pysidesignal.h b/sources/pyside2/libpyside/pysidesignal.h
index abbefbb1a..a2d58a27c 100644
--- a/sources/pyside2/libpyside/pysidesignal.h
+++ b/sources/pyside2/libpyside/pysidesignal.h
@@ -40,14 +40,19 @@
#ifndef PYSIDE_SIGNAL_H
#define PYSIDE_SIGNAL_H
-#include <QObject>
-#include <QString>
-#include <QStringList>
-
#include <pysidemacros.h>
+
#include <sbkpython.h>
#include <basewrapper.h>
+#include <QtCore/QList>
+#include <QtCore/QMetaMethod>
+
+QT_BEGIN_NAMESPACE
+struct QMetaObject;
+class QObject;
+QT_END_NAMESPACE
+
extern "C"
{
extern PYSIDE_API PyTypeObject *PySideSignalTypeF(void);
diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp
index 6ae664c42..6f6658cf8 100644
--- a/sources/pyside2/libpyside/pysideslot.cpp
+++ b/sources/pyside2/libpyside/pysideslot.cpp
@@ -42,8 +42,9 @@
#include "pysideslot_p.h"
#include <shiboken.h>
-#include <QString>
-#include <QMetaObject>
+
+#include <QtCore/QMetaObject>
+#include <QtCore/QString>
#define SLOT_DEC_NAME "Slot"
@@ -96,8 +97,10 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
if (emptyTuple == 0)
emptyTuple = PyTuple_New(0);
- if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME, (char**) kwlist, &argName, &argResult))
+ if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME,
+ const_cast<char**>(kwlist), &argName, &argResult)) {
return 0;
+ }
PySideSlot *data = reinterpret_cast<PySideSlot*>(self);
for(Py_ssize_t i = 0, i_max = PyTuple_Size(args); i < i_max; i++) {
diff --git a/sources/pyside2/libpyside/pysideweakref.cpp b/sources/pyside2/libpyside/pysideweakref.cpp
index 6c38d39c4..6b5073db8 100644
--- a/sources/pyside2/libpyside/pysideweakref.cpp
+++ b/sources/pyside2/libpyside/pysideweakref.cpp
@@ -65,7 +65,7 @@ static PyType_Spec PySideCallableObjectType_spec = {
};
-static PyTypeObject *PySideCallableObjectTypeF(void)
+static PyTypeObject *PySideCallableObjectTypeF()
{
static PyTypeObject *type =
(PyTypeObject *)PyType_FromSpec(&PySideCallableObjectType_spec);
diff --git a/sources/pyside2/libpyside/signalmanager.cpp.in b/sources/pyside2/libpyside/signalmanager.cpp
index c67bc6369..8925ffd35 100644
--- a/sources/pyside2/libpyside/signalmanager.cpp.in
+++ b/sources/pyside2/libpyside/signalmanager.cpp
@@ -43,25 +43,25 @@
#include "pysideproperty.h"
#include "pysideproperty_p.h"
#include "pyside.h"
+#include "pyside_p.h"
#include "dynamicqmetaobject.h"
#include "pysidemetafunction_p.h"
-#include <QtCore>
-#include <QHash>
-#include <QStringList>
-#include <QMetaMethod>
#include <autodecref.h>
-#include <gilstate.h>
-#include <QDebug>
-#include <limits>
-#include <algorithm>
#include <basewrapper.h>
#include <bindingmanager.h>
+#include <gilstate.h>
#include <sbkconverter.h>
#include <sbkstring.h>
+#include <QtCore/QDebug>
+#include <QtCore/QHash>
+
+#include <algorithm>
+#include <limits>
+
// These private headers are needed to throw JavaScript exceptions
-#if @QML_PRIVATE_API_SUPPORT@
+#if PYSIDE_QML_PRIVATE_API_SUPPORT
#include <private/qv4engine_p.h>
#include <private/qv4context_p.h>
#include <private/qqmldata_p.h>
@@ -76,7 +76,6 @@
#define PYSIDE_SLOT '1'
#define PYSIDE_SIGNAL '2'
#include "globalreceiverv2.h"
-#include "globalreceiver.h"
#define PYTHON_TYPE "PyObject"
@@ -91,7 +90,7 @@ namespace {
static void destroyMetaObject(PyObject* obj)
{
void* ptr = PyCapsule_GetPointer(obj, 0);
- PySide::DynamicQMetaObject* meta = reinterpret_cast<PySide::DynamicQMetaObject*>(ptr);
+ auto meta = reinterpret_cast<PySide::MetaObjectBuilder*>(ptr);
SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta);
if (wrapper)
Shiboken::BindingManager::instance().releaseWrapper(wrapper);
@@ -101,7 +100,7 @@ namespace {
#else
static void destroyMetaObject(void* obj)
{
- PySide::DynamicQMetaObject* meta = reinterpret_cast<PySide::DynamicQMetaObject*>(obj);
+ auto meta = reinterpret_cast<PySide::MetaObjectBuilder*>(obj);
SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(meta);
if (wrapper)
Shiboken::BindingManager::instance().releaseWrapper(wrapper);
@@ -142,11 +141,16 @@ PyObjectWrapper::~PyObjectWrapper()
Py_XDECREF(m_me);
}
-PyObjectWrapper& PyObjectWrapper::operator=(const PySide::PyObjectWrapper& other)
+void PyObjectWrapper::reset(PyObject *o)
{
- Py_XINCREF(other.m_me);
+ Py_XINCREF(o);
Py_XDECREF(m_me);
- m_me = other.m_me;
+ m_me = o;
+}
+
+PyObjectWrapper& PyObjectWrapper::operator=(const PySide::PyObjectWrapper& other)
+{
+ reset(other.m_me);
return *this;
}
@@ -205,10 +209,9 @@ QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj)
in >> repr;
Shiboken::AutoDecRef pyCode(PyBytes_FromStringAndSize(repr.data(), repr.size()));
Shiboken::AutoDecRef value(PyObject_CallFunctionObjArgs(eval_func, pyCode.object(), 0));
- if (!value.object()) {
- value = Py_None;
- }
- myObj = PyObjectWrapper(value);
+ if (!value.object())
+ value.reset(Py_None);
+ myObj.reset(value);
return in;
}
@@ -220,9 +223,6 @@ struct SignalManager::SignalManagerPrivate
{
SharedMap m_globalReceivers;
- //Deprecated
- GlobalReceiver m_globalReceiver;
-
SignalManagerPrivate()
{
m_globalReceivers = SharedMap( new QMap<QByteArray, GlobalReceiverV2*>() );
@@ -304,44 +304,21 @@ SignalManager& SignalManager::instance()
return me;
}
-QObject* SignalManager::globalReceiver()
-{
- return &m_d->m_globalReceiver;
-}
-
-void SignalManager::globalReceiverConnectNotify(QObject* source, int slotIndex)
-{
- m_d->m_globalReceiver.connectNotify(source, slotIndex);
-}
-
-void SignalManager::globalReceiverDisconnectNotify(QObject* source, int slotIndex)
-{
- m_d->m_globalReceiver.disconnectNotify(source, slotIndex);
-}
-
-void SignalManager::addGlobalSlot(const char* slot, PyObject* callback)
-{
- addGlobalSlotGetIndex(slot, callback);
-}
-
-int SignalManager::addGlobalSlotGetIndex(const char* slot, PyObject* callback)
-{
- return m_d->m_globalReceiver.addSlot(slot, callback);
-}
-
QObject* SignalManager::globalReceiver(QObject *sender, PyObject *callback)
{
SharedMap globalReceivers = m_d->m_globalReceivers;
QByteArray hash = GlobalReceiverV2::hash(callback);
GlobalReceiverV2* gr = 0;
- if (!globalReceivers->contains(hash)) {
- gr = (*globalReceivers)[hash] = new GlobalReceiverV2(callback, globalReceivers);
+ auto it = globalReceivers->find(hash);
+ if (it == globalReceivers->end()) {
+ gr = new GlobalReceiverV2(callback, globalReceivers);
+ globalReceivers->insert(hash, gr);
if (sender) {
gr->incRef(sender); // create a link reference
gr->decRef(); // remove extra reference
}
} else {
- gr = (*globalReceivers)[hash];
+ gr = it.value();
if (sender)
gr->incRef(sender);
}
@@ -465,7 +442,7 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id,
if (PyErr_Occurred()) {
-#if @QML_PRIVATE_API_SUPPORT@
+#if PYSIDE_QML_PRIVATE_API_SUPPORT
// This JS engine grabber based off of Qt 5.5's `qjsEngine` function
QQmlData *data = QQmlData::get(object, false);
@@ -572,9 +549,26 @@ bool SignalManager::registerMetaMethod(QObject* source, const char* signature, Q
return (ret != -1);
}
+static MetaObjectBuilder *metaBuilderFromDict(PyObject* dict)
+{
+ if (!dict || !PyDict_Contains(dict, metaObjectAttr))
+ return nullptr;
+
+ PyObject *pyBuilder = PyDict_GetItem(dict, metaObjectAttr);
+#ifdef IS_PY3K
+ return reinterpret_cast<MetaObjectBuilder *>(PyCapsule_GetPointer(pyBuilder, nullptr));
+#else
+ return reinterpret_cast<MetaObjectBuilder *>(PyCObject_AsVoidPtr(pyBuilder));
+#endif
+}
+
int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type)
{
- Q_ASSERT(source);
+ if (!source) {
+ qWarning("SignalManager::registerMetaMethodGetIndex(\"%s\") called with source=nullptr.",
+ signature);
+ return -1;
+ }
const QMetaObject* metaObject = source->metaObject();
int methodIndex = metaObject->indexOfMethod(signature);
// Create the dynamic signal is needed
@@ -584,13 +578,13 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa
qWarning() << "Invalid Signal signature:" << signature;
return -1;
} else {
- DynamicQMetaObject *dmo = 0;
PyObject *pySelf = reinterpret_cast<PyObject*>(self);
PyObject* dict = self->ob_dict;
+ MetaObjectBuilder *dmo = metaBuilderFromDict(dict);
// Create a instance meta object
- if (!dict || !PyDict_Contains(dict, metaObjectAttr)) {
- dmo = new DynamicQMetaObject(Py_TYPE(pySelf), metaObject);
+ if (!dmo) {
+ dmo = new MetaObjectBuilder(Py_TYPE(pySelf), metaObject);
#ifdef IS_PY3K
PyObject* pyDmo = PyCapsule_New(dmo, 0, destroyMetaObject);
#else
@@ -599,8 +593,6 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa
PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo);
Py_DECREF(pyDmo);
- } else {
- dmo = reinterpret_cast<DynamicQMetaObject*>(const_cast<QMetaObject*>(metaObject));
}
if (type == QMetaMethod::Signal)
@@ -612,32 +604,16 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa
return methodIndex;
}
-bool SignalManager::hasConnectionWith(const QObject *object)
-{
- return m_d->m_globalReceiver.hasConnectionWith(object);
-}
-
-const QMetaObject* SignalManager::retriveMetaObject(PyObject *self)
+const QMetaObject* SignalManager::retrieveMetaObject(PyObject *self)
{
Shiboken::GilState gil;
- DynamicQMetaObject *mo = 0;
Q_ASSERT(self);
- PyObject* dict = reinterpret_cast<SbkObject*>(self)->ob_dict;
- if (dict && PyDict_Contains(dict, metaObjectAttr)) {
- PyObject *pyMo = PyDict_GetItem(dict, metaObjectAttr);
-
-#ifdef IS_PY3K
- mo = reinterpret_cast<DynamicQMetaObject*>(PyCapsule_GetPointer(pyMo, 0));
-#else
- mo = reinterpret_cast<DynamicQMetaObject*>(PyCObject_AsVoidPtr(pyMo));
-#endif
- } else {
- mo = reinterpret_cast<DynamicQMetaObject*>(Shiboken::Object::getTypeUserData(reinterpret_cast<SbkObject*>(self)));
- }
+ MetaObjectBuilder *builder = metaBuilderFromDict(reinterpret_cast<SbkObject*>(self)->ob_dict);
+ if (!builder)
+ builder = &(retrieveTypeUserData(self)->mo);
- mo->update();
- return mo;
+ return builder->update();
}
namespace {
diff --git a/sources/pyside2/libpyside/signalmanager.h b/sources/pyside2/libpyside/signalmanager.h
index 5948a7df1..229ddb91d 100644
--- a/sources/pyside2/libpyside/signalmanager.h
+++ b/sources/pyside2/libpyside/signalmanager.h
@@ -41,10 +41,12 @@
#define SIGNALMANAGER_H
#include "pysidemacros.h"
+
#include <sbkpython.h>
-#include <Qt>
-#include <QStringList>
-#include <QMetaMethod>
+
+#include <QtCore/QMetaMethod>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
namespace PySide
{
@@ -53,12 +55,19 @@ namespace PySide
class PYSIDE_API PyObjectWrapper
{
public:
+ PyObjectWrapper(PyObjectWrapper&&) = delete;
+ PyObjectWrapper& operator=(PyObjectWrapper &&) = delete;
+
PyObjectWrapper();
- PyObjectWrapper(PyObject* me);
+ explicit PyObjectWrapper(PyObject* me);
PyObjectWrapper(const PyObjectWrapper &other);
+ PyObjectWrapper& operator=(const PyObjectWrapper &other);
+
+ void reset(PyObject *o);
+
~PyObjectWrapper();
operator PyObject*() const;
- PyObjectWrapper& operator=(const PyObjectWrapper &other);
+
private:
PyObject* m_me;
};
@@ -68,6 +77,7 @@ PYSIDE_API QDataStream &operator>>(QDataStream& in, PyObjectWrapper& myObj);
class PYSIDE_API SignalManager
{
+ Q_DISABLE_COPY(SignalManager)
public:
static SignalManager& instance();
@@ -84,7 +94,7 @@ public:
static int registerMetaMethodGetIndex(QObject* source, const char* signature, QMetaMethod::MethodType type);
// used to discovery metaobject
- static const QMetaObject* retriveMetaObject(PyObject* self);
+ static const QMetaObject* retrieveMetaObject(PyObject* self);
// Used to discovery if SignalManager was connected with object "destroyed()" signal.
int countConnectionsWith(const QObject *object);
@@ -95,24 +105,12 @@ public:
// Utility function to call a python method usign args received in qt_metacall
static int callPythonMetaMethod(const QMetaMethod& method, void** args, PyObject* obj, bool isShortCuit);
- PYSIDE_DEPRECATED(QObject* globalReceiver());
- PYSIDE_DEPRECATED(void addGlobalSlot(const char* slot, PyObject* callback));
- PYSIDE_DEPRECATED(int addGlobalSlotGetIndex(const char* slot, PyObject* callback));
-
- PYSIDE_DEPRECATED(void globalReceiverConnectNotify(QObject *sender, int slotIndex));
- PYSIDE_DEPRECATED(void globalReceiverDisconnectNotify(QObject *sender, int slotIndex));
- PYSIDE_DEPRECATED(bool hasConnectionWith(const QObject *object));
-
private:
struct SignalManagerPrivate;
SignalManagerPrivate* m_d;
SignalManager();
~SignalManager();
-
- // disable copy
- SignalManager(const SignalManager&);
- SignalManager operator=(const SignalManager&);
};
}
diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py
index 709dd8714..f104f09e6 100644
--- a/sources/pyside2/pyside_version.py
+++ b/sources/pyside2/pyside_version.py
@@ -38,8 +38,8 @@
#############################################################################
major_version = "5"
-minor_version = "11"
-patch_version = "4"
+minor_version = "12"
+patch_version = "0"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/pyside2/tests/CMakeLists.txt b/sources/pyside2/tests/CMakeLists.txt
index 2386950e9..4289012a8 100644
--- a/sources/pyside2/tests/CMakeLists.txt
+++ b/sources/pyside2/tests/CMakeLists.txt
@@ -54,6 +54,7 @@ else()
endif()
add_subdirectory(registry)
add_subdirectory(signals)
+ add_subdirectory(support)
foreach(shortname IN LISTS all_module_shortnames)
message(STATUS "preparing tests for module 'Qt${shortname}'")
diff --git a/sources/pyside2/tests/QtCore/CMakeLists.txt b/sources/pyside2/tests/QtCore/CMakeLists.txt
index 649e796cc..08e63d043 100644
--- a/sources/pyside2/tests/QtCore/CMakeLists.txt
+++ b/sources/pyside2/tests/QtCore/CMakeLists.txt
@@ -52,6 +52,7 @@ PYSIDE_TEST(qbytearray_concatenation_operator_test.py)
PYSIDE_TEST(qbytearray_operator_iadd_test.py)
PYSIDE_TEST(qbytearray_operator_test.py)
PYSIDE_TEST(qbytearray_test.py)
+PYSIDE_TEST(qcbor_test.py)
PYSIDE_TEST(qcollator_test.py)
PYSIDE_TEST(qcommandlineparser_test.py)
PYSIDE_TEST(qcoreapplication_instance_test.py)
@@ -67,6 +68,7 @@ PYSIDE_TEST(qfile_test.py)
PYSIDE_TEST(qfileread_test.py)
PYSIDE_TEST(qflags_test.py)
PYSIDE_TEST(qinstallmsghandler_test.py)
+PYSIDE_TEST(qjsondocument_test.py)
PYSIDE_TEST(qlinef_test.py)
PYSIDE_TEST(qlocale_test.py)
PYSIDE_TEST(qlockfile_test.py)
diff --git a/sources/pyside2/tests/QtCore/bug_826.py b/sources/pyside2/tests/QtCore/bug_826.py
index 5e3a12146..b5701fc5a 100644
--- a/sources/pyside2/tests/QtCore/bug_826.py
+++ b/sources/pyside2/tests/QtCore/bug_826.py
@@ -46,8 +46,8 @@ class TestEvent(QEvent):
class TestEnums(unittest.TestCase):
def testUserTypesValues(self):
- self.assertTrue(QEvent.User <= int(TestEvent.TestEventType) <= QEvent.MaxUser)
- self.assertTrue(QEvent.User <= int(TEST_EVENT_TYPE) <= QEvent.MaxUser)
+ self.assertTrue(QEvent.User <= TestEvent.TestEventType <= QEvent.MaxUser)
+ self.assertTrue(QEvent.User <= TEST_EVENT_TYPE <= QEvent.MaxUser)
def testUserTypesRepr(self):
self.assertEqual(eval(repr(TestEvent.TestEventType)), TestEvent.TestEventType)
diff --git a/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py b/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py
index 70b610c34..fd8d01c99 100644
--- a/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py
+++ b/sources/pyside2/tests/QtCore/qabstractitemmodel_test.py
@@ -34,14 +34,12 @@ from PySide2.QtCore import *
class MyModel (QAbstractListModel):
pass
-class Foo:
- pass
class TestQModelIndexInternalPointer(unittest.TestCase):
def testInternalPointer(self):
m = MyModel()
- foo = Foo()
+ foo = QObject()
idx = m.createIndex(0,0, foo)
check = m.checkIndex(idx, QAbstractItemModel.CheckIndexOption.IndexIsValid
| QAbstractItemModel.CheckIndexOption.DoNotUseParent
diff --git a/sources/pyside2/tests/QtCore/qcbor_test.py b/sources/pyside2/tests/QtCore/qcbor_test.py
new file mode 100644
index 000000000..2ac46673a
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/qcbor_test.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## 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 General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## 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-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for QCbor'''
+
+import unittest
+
+from PySide2.QtCore import (QByteArray, QCborStreamReader, QCborStreamWriter,
+ QCborValue)
+
+class TestCbor(unittest.TestCase):
+ def testReader(self):
+ ba = QByteArray()
+ writer = QCborStreamWriter(ba)
+ writer.append(42)
+ del writer
+ self.assertTrue(not ba.isEmpty())
+ reader = QCborStreamReader(ba)
+ self.assertTrue(reader.hasNext())
+ value = reader.toInteger()
+ self.assertEqual(value, 42)
+
+ def testReader(self):
+ ba = QByteArray()
+ writer = QCborStreamWriter(ba)
+ writer.append("hello")
+ del writer
+ self.assertTrue(not ba.isEmpty())
+ reader = QCborStreamReader(ba)
+ self.assertTrue(reader.hasNext())
+ if (reader.isByteArray()): # Python 2
+ value = reader.readByteArray()
+ self.assertTrue(value)
+ self.assertEqual(value.data, "hello")
+ else:
+ self.assertTrue(reader.isString())
+ value = reader.readString()
+ self.assertTrue(value)
+ self.assertEqual(value.data, "hello")
+
+ def testValue(self):
+ value = QCborValue('hello')
+ self.assertTrue(value.isString())
+ self.assertEqual(value.toString(), 'hello')
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside2/tests/QtCore/qenum_test.py b/sources/pyside2/tests/QtCore/qenum_test.py
index eccbfac23..ada625f24 100644
--- a/sources/pyside2/tests/QtCore/qenum_test.py
+++ b/sources/pyside2/tests/QtCore/qenum_test.py
@@ -49,6 +49,24 @@ class TestEnum(unittest.TestCase):
def testToIntInFunction(self):
self.assertEqual(str(int(QIODevice.WriteOnly)), "2")
+ def testOperations(self):
+ k = Qt.Key.Key_1
+
+ # Integers
+ self.assertEqual(k + 2, 2 + k)
+ self.assertEqual(k - 2, -(2 - k))
+ self.assertEqual(k * 2, 2 * k)
+
+ # Floats
+ with self.assertRaises(TypeError):
+ a = k+2.0
+
+ with self.assertRaises(TypeError):
+ a = k-2.0
+
+ with self.assertRaises(TypeError):
+ a = k*2.0
+
class TestQFlags(unittest.TestCase):
def testToItn(self):
om = QIODevice.NotOpen
diff --git a/sources/pyside2/tests/QtCore/qjsondocument_test.py b/sources/pyside2/tests/QtCore/qjsondocument_test.py
new file mode 100644
index 000000000..0cd4dc5b2
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/qjsondocument_test.py
@@ -0,0 +1,56 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## 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 General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## 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-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for QJsonDocument/nullptr_t'''
+
+import unittest
+from PySide2.QtCore import QJsonDocument
+import py3kcompat as py3k
+
+class QJsonDocumentTest(unittest.TestCase):
+
+ def testToVariant(self):
+ a = QJsonDocument.fromJson(b'{"test": null}')
+ self.assertIsInstance(a, QJsonDocument)
+ if py3k.IS_PY3K:
+ self.assertEqual(str(a.toVariant()), "{'test': None}")
+ else:
+ self.assertEqual(str(a.toVariant()), "{u'test': None}")
+
+ b = QJsonDocument.fromJson(b'{"test": [null]}')
+ self.assertIsInstance(b, QJsonDocument)
+ if py3k.IS_PY3K:
+ self.assertEqual(str(b.toVariant()), "{'test': [None]}")
+ else:
+ self.assertEqual(str(b.toVariant()), "{u'test': [None]}")
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside2/tests/QtCore/qmetaobject_test.py b/sources/pyside2/tests/QtCore/qmetaobject_test.py
index 12b5312a6..73ab81c7c 100644
--- a/sources/pyside2/tests/QtCore/qmetaobject_test.py
+++ b/sources/pyside2/tests/QtCore/qmetaobject_test.py
@@ -78,6 +78,12 @@ class qmetaobject_test(unittest.TestCase):
#self.assertTrue(slot_index != signal_index)
+ # PYSIDE-784, plain Qt objects should not have intermediary
+ # metaObjects.
+ def test_PlainQObject(self):
+ timer = QTimer()
+ self.assertEqual(timer.metaObject().superClass().className(),
+ "QObject")
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py b/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py
index 875d2075c..a67bb380a 100644
--- a/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py
+++ b/sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py
@@ -33,6 +33,7 @@
import sys
import unittest
from PySide2.QtCore import *
+from PySide2.support import VoidPtr
class MyModel (QAbstractListModel):
pass
@@ -50,22 +51,22 @@ class TestQModelIndexInternalPointer(unittest.TestCase):
def testInternalPointer(self):
#Test QAbstractListModel.createIndex and
- #QModelIndex.internalPointer with regular
- #Python objects
- idx = self.model.createIndex(0, 0, "Hello")
- self.assertEqual("Hello", idx.internalPointer())
- a = [1, 2, 3]
- idx = self.model.createIndex(0, 0, a)
- self.assertEqual(a, idx.internalPointer())
+ #QModelIndex.internalPointer
+ obj = QObject()
+ obj_ptr = VoidPtr(obj)
+ idx = self.model.createIndex(0, 0, obj)
+ i = idx.internalPointer()
+ self.assertEqual(int(obj_ptr), int(i))
def testReferenceCounting(self):
#Test reference counting when retrieving data with
#QModelIndex.internalPointer
- a = [1, 2, 3]
- a_refcnt = sys.getrefcount(a)
- idx = self.model.createIndex(0, 0, a)
+ o = QObject()
+ o_refcnt = sys.getrefcount(o)
+ idx = self.model.createIndex(0, 0, o)
ptr = idx.internalPointer()
- self.assertEqual(sys.getrefcount(a), a_refcnt + 1)
+ self.assertEqual(sys.getrefcount(o), o_refcnt)
+
def testIndexForDefaultDataArg(self):
#Test QAbstractListModel.createIndex with a default
diff --git a/sources/pyside2/tests/QtCore/qrandomgenerator_test.py b/sources/pyside2/tests/QtCore/qrandomgenerator_test.py
index 7d80510a7..2b732ad5e 100644
--- a/sources/pyside2/tests/QtCore/qrandomgenerator_test.py
+++ b/sources/pyside2/tests/QtCore/qrandomgenerator_test.py
@@ -3,7 +3,7 @@
## Copyright (C) 2017 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
-## This file is part of the test suite of PySide2.
+## This file is part of the test suite of Qt for Python.
##
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
## Commercial License Usage
diff --git a/sources/pyside2/tests/QtGui/qmatrix_test.py b/sources/pyside2/tests/QtGui/qmatrix_test.py
index cac8a7ab7..7cfe9ea60 100644
--- a/sources/pyside2/tests/QtGui/qmatrix_test.py
+++ b/sources/pyside2/tests/QtGui/qmatrix_test.py
@@ -29,7 +29,7 @@
import unittest
from PySide2.QtCore import QPoint
-from PySide2.QtGui import QMatrix, QMatrix4x4
+from PySide2.QtGui import QMatrix, QMatrix2x2, QMatrix4x4
def qpointTimesQMatrix(point, matrix):
@@ -42,13 +42,26 @@ class QMatrixTest(unittest.TestCase):
def testMatrix(self):
matrix = QMatrix(11, 12, 21, 22, 100, 200)
point = QPoint(3, 3)
- self.assertEqual(point * matrix, qpointTimesQMatrix(point, matrix))
+ self.assertEqual(matrix.map(point), qpointTimesQMatrix(point, matrix))
def testMatrixWithWrongType(self):
matrix = QMatrix(11, 12, 21, 22, 100, 200)
point = QPoint(3, 3)
self.assertRaises(TypeError, matrix.__mul__, point)
+ def testMatrix2x2(self):
+ matrix = QMatrix2x2([1.0, 2.0, 3.0, 4.0])
+
+ expectedTransposed = QMatrix2x2([1.0, 3.0, 2.0, 4.0])
+ self.assertEqual(matrix.transposed(), expectedTransposed)
+
+ expectedMultiplied = QMatrix2x2([2.0, 4.0, 6.0, 8.0])
+ matrix *= 2.0
+ self.assertEqual(matrix, expectedMultiplied)
+
+ matrix.setToIdentity()
+ self.assertTrue(matrix.isIdentity())
+
def testMatrix4x4(self):
self.assertRaises(TypeError, QMatrix4x4, [0.0, 1.0, 2.0, 3.0])
self.assertRaises(TypeError, QMatrix4x4, [0.0, 1.0, 2.0, 'I',
diff --git a/sources/pyside2/tests/QtNetwork/CMakeLists.txt b/sources/pyside2/tests/QtNetwork/CMakeLists.txt
index c14c19fa9..57c5266c8 100644
--- a/sources/pyside2/tests/QtNetwork/CMakeLists.txt
+++ b/sources/pyside2/tests/QtNetwork/CMakeLists.txt
@@ -3,6 +3,7 @@ PYSIDE_TEST(bug_1084.py)
PYSIDE_TEST(accessManager_test.py)
PYSIDE_TEST(dnslookup_test.py)
# Qt5: QHttp is gone PYSIDE_TEST(http_test.py)
+PYSIDE_TEST(qpassworddigestor_test.py)
PYSIDE_TEST(tcpserver_test.py)
PYSIDE_TEST(udpsocket_test.py)
PYSIDE_TEST(qipv6address_test.py)
diff --git a/sources/pyside2/tests/QtNetwork/qpassworddigestor_test.py b/sources/pyside2/tests/QtNetwork/qpassworddigestor_test.py
new file mode 100644
index 000000000..503ffecdc
--- /dev/null
+++ b/sources/pyside2/tests/QtNetwork/qpassworddigestor_test.py
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## 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 General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## 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-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+'''Test cases for QPasswordDigestor'''
+
+import unittest
+
+from PySide2.QtCore import QByteArray, QCryptographicHash
+from PySide2.QtNetwork import QPasswordDigestor
+
+class TestPasswordDigestor(unittest.TestCase):
+ def test(self):
+ b = QPasswordDigestor.deriveKeyPbkdf1(QCryptographicHash.Sha1,
+ b'test', b'saltnpep', 10, 20)
+ self.assertEqual(b.size(), 20)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside2/tests/QtWidgets/bug_493.py b/sources/pyside2/tests/QtWidgets/bug_493.py
index 100959fbb..19cbb0023 100644
--- a/sources/pyside2/tests/QtWidgets/bug_493.py
+++ b/sources/pyside2/tests/QtWidgets/bug_493.py
@@ -32,7 +32,7 @@ from PySide2.QtWidgets import QApplication
import unittest
-class TestBug569(unittest.TestCase):
+class TestBug493(unittest.TestCase):
def testIt(self):
# We need a qapp otherwise Qt will crash when trying to detect the
@@ -42,10 +42,8 @@ class TestBug569(unittest.TestCase):
ev2 = QKeyEvent(QEvent.KeyRelease, Qt.Key_Copy, Qt.NoModifier)
ks = QKeySequence.Delete
- self.assertEqual(ev1, ks)
- self.assertEqual(ks, ev1)
- self.assertNotEqual(ev2, ks)
- self.assertNotEqual(ks, ev2)
+ self.assertTrue(ev1.matches(ks))
+ self.assertFalse(ev2.matches(ks))
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside2/tests/QtWidgets/python_properties_test.py b/sources/pyside2/tests/QtWidgets/python_properties_test.py
index f5bcf5eb8..f4e46f2bd 100644
--- a/sources/pyside2/tests/QtWidgets/python_properties_test.py
+++ b/sources/pyside2/tests/QtWidgets/python_properties_test.py
@@ -39,6 +39,8 @@ class Properties(unittest.TestCase):
p = QtWidgets.QStyleOptionViewItem()
self.assertTrue(isinstance(p.locale, QtCore.QLocale))
+ # PSYIDE-304, can assign to a "const QWidget *" field
+ p.widget = None
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside2/tests/QtWidgets/qlabel_test.py b/sources/pyside2/tests/QtWidgets/qlabel_test.py
index 2c5616001..9d84b5c17 100644
--- a/sources/pyside2/tests/QtWidgets/qlabel_test.py
+++ b/sources/pyside2/tests/QtWidgets/qlabel_test.py
@@ -32,14 +32,7 @@ import unittest
from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QLabel
-try:
- # The normal import statement when PySide2 is installed.
- from PySide2 import shiboken2 as shiboken
-except ImportError:
- # When running make test in shiboken build dir, or when running
- # testrunner.py, shiboken2 is not part of the PySide2 module,
- # so it needs to be imported as a standalone module.
- import shiboken2 as shiboken
+import shiboken2 as shiboken
from helper import UsesQApplication
diff --git a/sources/pyside2/tests/QtWidgets/qstandarditemmodel_test.py b/sources/pyside2/tests/QtWidgets/qstandarditemmodel_test.py
index 7a34cf238..c07bd8705 100644
--- a/sources/pyside2/tests/QtWidgets/qstandarditemmodel_test.py
+++ b/sources/pyside2/tests/QtWidgets/qstandarditemmodel_test.py
@@ -31,14 +31,7 @@ import sys
from PySide2.QtGui import QStandardItemModel, QStandardItem
from PySide2.QtWidgets import QWidget
-try:
- # The normal import statement when PySide2 is installed.
- from PySide2 import shiboken2 as shiboken
-except ImportError:
- # When running make test in shiboken build dir, or when running testrunner.py,
- # shiboken2 is not part of the PySide2 module, so it needs to be imported as a standalone
- # module.
- import shiboken2 as shiboken
+import shiboken2 as shiboken
from helper import UsesQApplication
diff --git a/sources/pyside2/tests/QtWidgets/qstyle_test.py b/sources/pyside2/tests/QtWidgets/qstyle_test.py
index eb2a73d29..1dcce2737 100644
--- a/sources/pyside2/tests/QtWidgets/qstyle_test.py
+++ b/sources/pyside2/tests/QtWidgets/qstyle_test.py
@@ -26,6 +26,7 @@
##
#############################################################################
+import sys
import unittest
from helper import UsesQApplication
@@ -78,6 +79,13 @@ class SetStyleTest(UsesQApplication):
QApplication.instance().processEvents()
self.assertTrue(proxyStyle.polished > 0)
+ def testSetStyleOwnership(self):
+ style = QStyleFactory.create(QStyleFactory.keys()[0])
+ self.assertEqual(sys.getrefcount(style), 2)
+ QApplication.instance().setStyle(style)
+ self.assertEqual(sys.getrefcount(style), 3)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside2/tests/QtWidgets/qwidget_test.py b/sources/pyside2/tests/QtWidgets/qwidget_test.py
index 1e8387d11..028751ba7 100644
--- a/sources/pyside2/tests/QtWidgets/qwidget_test.py
+++ b/sources/pyside2/tests/QtWidgets/qwidget_test.py
@@ -26,6 +26,7 @@
##
#############################################################################
+import sys
import unittest
from PySide2.QtWidgets import QWidget, QMainWindow
@@ -35,6 +36,17 @@ class QWidgetInherit(QMainWindow):
def __init__(self):
QWidget.__init__(self)
+class NativeEventTestWidget(QWidget):
+
+ nativeEventCount = 0
+
+ def __init__(self):
+ QWidget.__init__(self)
+
+ def nativeEvent(self, eventType, message):
+ self.nativeEventCount = self.nativeEventCount + 1
+ return [False, 0]
+
class QWidgetTest(UsesQApplication):
def testInheritance(self):
@@ -44,12 +56,19 @@ class QWidgetVisible(UsesQApplication):
def testBasic(self):
# Also related to bug #244, on existence of setVisible'''
- widget = QWidget()
+ widget = NativeEventTestWidget()
self.assertTrue(not widget.isVisible())
widget.setVisible(True)
self.assertTrue(widget.isVisible())
self.assertTrue(widget.winId() is not 0)
-
+ # skip this test on macOS since no native events are received
+ if sys.platform == 'darwin':
+ return
+ for i in range(10):
+ if widget.nativeEventCount > 0:
+ break
+ self.app.processEvents()
+ self.assertTrue(widget.nativeEventCount > 0)
if __name__ == '__main__':
unittest.main()
diff --git a/sources/pyside2/tests/pysidetest/CMakeLists.txt b/sources/pyside2/tests/pysidetest/CMakeLists.txt
index c6d3bb13b..119553fad 100644
--- a/sources/pyside2/tests/pysidetest/CMakeLists.txt
+++ b/sources/pyside2/tests/pysidetest/CMakeLists.txt
@@ -3,9 +3,6 @@ project(testbinding)
cmake_minimum_required(VERSION 3.1)
-# On Windows, don't link to qtmain.lib for executables automatically.
-cmake_policy(SET CMP0020 OLD)
-
set(QT_USE_QTCORE 1)
# no more supported: include(${QT_USE_FILE})
add_definitions(${Qt5Core_DEFINITIONS})
@@ -69,7 +66,9 @@ make_path(testbinding_include_dirs ${pyside2_BINARY_DIR}
make_path(testbinding_typesystem_path ${pyside2_SOURCE_DIR}
${pyside2_BINARY_DIR})
-add_custom_command(OUTPUT ${testbinding_SRC}
+add_custom_command(
+OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+BYPRODUCTS ${testbinding_SRC}
COMMAND ${SHIBOKEN_BINARY} ${GENERATOR_EXTRA_FLAGS}
${CMAKE_CURRENT_SOURCE_DIR}/pysidetest_global.h
--include-paths=${testbinding_include_dirs}
@@ -119,6 +118,7 @@ target_link_libraries(testbinding
${SBK_PYTHON_LIBRARIES})
add_dependencies(testbinding pyside2 QtCore QtGui QtWidgets pysidetest)
+create_generator_target(testbinding)
PYSIDE_TEST(decoratedslot_test.py)
# Will always crash when built against Qt 5.6, no point in running it.
diff --git a/sources/pyside2/tests/pysidetest/new_inherited_functions_test.py b/sources/pyside2/tests/pysidetest/new_inherited_functions_test.py
index 960f675ea..54b81acae 100644
--- a/sources/pyside2/tests/pysidetest/new_inherited_functions_test.py
+++ b/sources/pyside2/tests/pysidetest/new_inherited_functions_test.py
@@ -32,17 +32,16 @@ import sys
import os
import unittest
-import PySide2.QtCore
+from PySide2 import *
+for modname, mod in sys.modules.items():
+ # Python 2 leaves "None" in the dict.
+ if modname.startswith("PySide2.") and mod is not None:
+ print("importing", modname)
+ exec("import " + modname)
# This test tests the existence and callability of the newly existing functions,
# after the inheritance was made complete in the course of PYSIDE-331.
-def warn_essential(modname):
- print(80 * "*")
- print("*** Warning: '{}' is an essential module! Are you sure to skip it?"
- .format(modname))
- print(80 * "*")
-
new_functions = """
PySide2.QtCore.QAbstractItemModel().parent()
PySide2.QtCore.QAbstractListModel().parent()
@@ -52,85 +51,67 @@ new_functions = """
PySide2.QtCore.QSortFilterProxyModel().parent()
PySide2.QtCore.QTemporaryFile(tfarg).open(openMode)
"""
-try:
- modname = "PySide2.QtGui"
- exec("import " + modname)
- new_functions += """
- PySide2.QtGui.QBitmap().transformed(qMatrix,transformationMode)
- PySide2.QtGui.QStandardItemModel().insertColumn(int,qModelIndex)
- PySide2.QtGui.QStandardItemModel().parent()
- # PySide2.QtGui.QTextList(qTextDocument).setFormat(qTextFormat) # Segmentation fault: 11
- # PySide2.QtGui.QTextTable(qTextDocument).setFormat(qTextFormat) # Segmentation fault: 11
- """
-except ImportError:
- warn_essential(modname)
-try:
- modname = "PySide2.QtWidgets"
- exec("import " + modname)
- new_functions += """
- PySide2.QtWidgets.QAbstractItemView().update()
- PySide2.QtWidgets.QApplication.palette()
- PySide2.QtWidgets.QApplication.setFont(qFont)
- PySide2.QtWidgets.QApplication.setPalette(qPalette)
- PySide2.QtWidgets.QBoxLayout(direction).addWidget(qWidget)
- PySide2.QtWidgets.QColorDialog().open()
- PySide2.QtWidgets.QDirModel().index(int,int,qModelIndex)
- PySide2.QtWidgets.QDirModel().parent()
- PySide2.QtWidgets.QFileDialog().open()
- PySide2.QtWidgets.QFileSystemModel().index(int,int,qModelIndex)
- PySide2.QtWidgets.QFileSystemModel().parent()
- PySide2.QtWidgets.QFontDialog().open()
- PySide2.QtWidgets.QGestureEvent([]).accept()
- PySide2.QtWidgets.QGestureEvent([]).ignore()
- PySide2.QtWidgets.QGestureEvent([]).isAccepted()
- PySide2.QtWidgets.QGestureEvent([]).setAccepted(bool)
- # PySide2.QtWidgets.QGraphicsView().render(qPaintDevice,qPoint,qRegion,renderFlags) # QPaintDevice: NotImplementedError
- PySide2.QtWidgets.QGridLayout().addWidget(qWidget)
- PySide2.QtWidgets.QHeaderView(orientation).initStyleOption(qStyleOptionFrame)
- PySide2.QtWidgets.QInputDialog().open()
- PySide2.QtWidgets.QLineEdit().addAction(qAction)
- PySide2.QtWidgets.QListWidget().closePersistentEditor(qModelIndex)
- PySide2.QtWidgets.QListWidget().openPersistentEditor(qModelIndex)
- PySide2.QtWidgets.QMessageBox().open()
- PySide2.QtWidgets.QPlainTextEdit.find(quintptr)
- PySide2.QtWidgets.QProgressDialog().open()
- PySide2.QtWidgets.QStackedLayout().widget()
- # PySide2.QtWidgets.QStylePainter().begin(qPaintDevice) # QPaintDevice: NotImplementedError
- PySide2.QtWidgets.QTableWidget().closePersistentEditor(qModelIndex)
- PySide2.QtWidgets.QTableWidget().openPersistentEditor(qModelIndex)
- PySide2.QtWidgets.QTextEdit.find(quintptr)
- PySide2.QtWidgets.QTreeWidget().closePersistentEditor(qModelIndex)
- PySide2.QtWidgets.QTreeWidget().openPersistentEditor(qModelIndex)
- """
-except ImportError:
- warn_essential(modname)
-try:
- modname = "PySide2.QtPrintSupport"
- exec("import " + modname)
- new_functions += """
- # PySide2.QtPrintSupport.QPageSetupDialog().open() # Segmentation fault: 11
- # PySide2.QtPrintSupport.QPrintDialog().open() # opens the dialog, but works
- PySide2.QtPrintSupport.QPrintDialog().printer()
- PySide2.QtPrintSupport.QPrintPreviewDialog().open() # note: this prints something, but really shouldn't ;-)
- """
-except ImportError:
- warn_essential(modname)
-try:
- import PySide2.QtHelp
- new_functions += """
- PySide2.QtHelp.QHelpContentModel().parent()
- # PySide2.QtHelp.QHelpIndexModel().createIndex(int,int,quintptr) # returned NULL without setting an error
- # PySide2.QtHelp.QHelpIndexModel().createIndex(int,int,object()) # returned NULL without setting an error
- """
-except ImportError:
- pass
-try:
- import PySide2.QtQuick
- new_functions += """
- PySide2.QtQuick.QQuickPaintedItem().update()
- """
-except ImportError:
- pass
+
+new_functions += """
+ PySide2.QtGui.QBitmap().transformed(qMatrix,transformationMode)
+ PySide2.QtGui.QStandardItemModel().insertColumn(int,qModelIndex)
+ PySide2.QtGui.QStandardItemModel().parent()
+ # PySide2.QtGui.QTextList(qTextDocument).setFormat(qTextFormat) # Segmentation fault: 11
+ # PySide2.QtGui.QTextTable(qTextDocument).setFormat(qTextFormat) # Segmentation fault: 11
+""" if "PySide2.QtGui" in sys.modules else ""
+
+new_functions += """
+ PySide2.QtWidgets.QAbstractItemView().update()
+ PySide2.QtWidgets.QApplication.palette()
+ PySide2.QtWidgets.QApplication.setFont(qFont)
+ PySide2.QtWidgets.QApplication.setPalette(qPalette)
+ PySide2.QtWidgets.QBoxLayout(direction).addWidget(qWidget)
+ PySide2.QtWidgets.QColorDialog().open()
+ PySide2.QtWidgets.QDirModel().index(int,int,qModelIndex)
+ PySide2.QtWidgets.QDirModel().parent()
+ PySide2.QtWidgets.QFileDialog().open()
+ PySide2.QtWidgets.QFileSystemModel().index(int,int,qModelIndex)
+ PySide2.QtWidgets.QFileSystemModel().parent()
+ PySide2.QtWidgets.QFontDialog().open()
+ PySide2.QtWidgets.QGestureEvent([]).accept()
+ PySide2.QtWidgets.QGestureEvent([]).ignore()
+ PySide2.QtWidgets.QGestureEvent([]).isAccepted()
+ PySide2.QtWidgets.QGestureEvent([]).setAccepted(bool)
+ # PySide2.QtWidgets.QGraphicsView().render(qPaintDevice,qPoint,qRegion,renderFlags) # QPaintDevice: NotImplementedError
+ PySide2.QtWidgets.QGridLayout().addWidget(qWidget)
+ PySide2.QtWidgets.QHeaderView(orientation).initStyleOption(qStyleOptionFrame)
+ PySide2.QtWidgets.QInputDialog().open()
+ PySide2.QtWidgets.QLineEdit().addAction(qAction)
+ PySide2.QtWidgets.QListWidget().closePersistentEditor(qModelIndex)
+ PySide2.QtWidgets.QListWidget().openPersistentEditor(qModelIndex)
+ PySide2.QtWidgets.QMessageBox().open()
+ PySide2.QtWidgets.QPlainTextEdit.find(quintptr)
+ PySide2.QtWidgets.QProgressDialog().open()
+ PySide2.QtWidgets.QStackedLayout().widget()
+ # PySide2.QtWidgets.QStylePainter().begin(qPaintDevice) # QPaintDevice: NotImplementedError
+ PySide2.QtWidgets.QTableWidget().closePersistentEditor(qModelIndex)
+ PySide2.QtWidgets.QTableWidget().openPersistentEditor(qModelIndex)
+ PySide2.QtWidgets.QTextEdit.find(quintptr)
+ PySide2.QtWidgets.QTreeWidget().closePersistentEditor(qModelIndex)
+ PySide2.QtWidgets.QTreeWidget().openPersistentEditor(qModelIndex)
+""" if "PySide2.QtWidgets" in sys.modules else ""
+
+new_functions += """
+ # PySide2.QtPrintSupport.QPageSetupDialog().open() # Segmentation fault: 11
+ # PySide2.QtPrintSupport.QPrintDialog().open() # opens the dialog, but works
+ PySide2.QtPrintSupport.QPrintDialog().printer()
+ PySide2.QtPrintSupport.QPrintPreviewDialog().open() # note: this prints something, but really shouldn't ;-)
+""" if "PySide2.QtPrintSupport" in sys.modules else ""
+
+new_functions += """
+ PySide2.QtHelp.QHelpContentModel().parent()
+ # PySide2.QtHelp.QHelpIndexModel().createIndex(int,int,quintptr) # returned NULL without setting an error
+ # PySide2.QtHelp.QHelpIndexModel().createIndex(int,int,object()) # returned NULL without setting an error
+""" if "PySide2.QtHelp" in sys.modules else ""
+
+new_functions += """
+ PySide2.QtQuick.QQuickPaintedItem().update()
+""" if "PySide2.QtQuick" in sys.modules else ""
class MainTest(unittest.TestCase):
diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py
index 6e870385d..0d8014ad8 100644
--- a/sources/pyside2/tests/registry/existence_test.py
+++ b/sources/pyside2/tests/registry/existence_test.py
@@ -130,7 +130,7 @@ class TestSignaturesExists(unittest.TestCase):
warn(msgMultiSignatureCount(key, found_sigs[key], value))
self.assertTrue(check_warnings())
-tested_versions = (5, 6), (5, 9), (5, 11)
+tested_versions = (5, 6), (5, 9), (5, 11) #, (5, 12) # activate this, soon!
if not have_refmodule and is_ci and qtVersion()[:2] in tested_versions:
class TestFor_CI_Init(unittest.TestCase):
diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py
index 03d0ed133..ded8ba81c 100644
--- a/sources/pyside2/tests/registry/init_platform.py
+++ b/sources/pyside2/tests/registry/init_platform.py
@@ -55,8 +55,8 @@ from textwrap import dedent
all_modules = list("PySide2." + x for x in PySide2.__all__)
-from PySide2.support.signature import inspect
from PySide2.QtCore import __version__
+from PySide2.support.signature.lib.enum_sig import SimplifyingEnumerator
is_py3 = sys.version_info[0] == 3
is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci"
@@ -114,7 +114,7 @@ class Formatter(object):
Formatter is formatting the signature listing of an enumerator.
It is written as context managers in order to avoid many callbacks.
- The division in formatter and enumerator is done to keep the
+ The separation in formatter and enumerator is done to keep the
unrelated tasks of enumeration and formatting apart.
"""
def __init__(self, outfile):
@@ -134,7 +134,7 @@ class Formatter(object):
self.print(" })")
@contextmanager
- def klass(self, class_name):
+ def klass(self, class_name, class_str):
self.class_name = class_name
self.print()
self.print(" # class {}.{}:".format(self.mod_name, class_name))
@@ -142,7 +142,10 @@ class Formatter(object):
@contextmanager
def function(self, func_name, signature):
- key = viskey = "{}.{}".format(self.class_name, func_name)
+ if self.class_name is None:
+ key = viskey = "{}".format(func_name)
+ else:
+ key = viskey = "{}.{}".format(self.class_name, func_name)
if key.endswith("lY"):
# Some classes like PySide2.QtGui.QContextMenuEvent have functions
# globalX and the same with Y. The gerrit robot thinks that this
@@ -152,89 +155,6 @@ class Formatter(object):
yield key
-class ExactEnumerator(object):
- """
- ExactEnumerator enumerates all signatures in a module as they are.
-
- This class is used for generating complete listings of all signatures.
- An appropriate formatter should be supplied, if printable output
- is desired.
- """
- def __init__(self, formatter, result_type=dict):
- self.fmt = formatter
- self.result_type = result_type
-
- def module(self, mod_name):
- __import__(mod_name)
- with self.fmt.module(mod_name):
- module = sys.modules[mod_name]
- members = inspect.getmembers(module, inspect.isclass)
- ret = self.result_type()
- for class_name, klass in members:
- ret.update(self.klass(class_name, klass))
- return ret
-
- def klass(self, class_name, klass):
- with self.fmt.klass(class_name):
- ret = self.function("__init__", klass)
- # class_members = inspect.getmembers(klass)
- # gives us also the inherited things.
- class_members = sorted(list(klass.__dict__.items()))
- for func_name, func in class_members:
- ret.update(self.function(func_name, func))
- return ret
-
- def function(self, func_name, func):
- ret = self.result_type()
- signature = getattr(func, '__signature__', None)
- if signature is not None:
- with self.fmt.function(func_name, signature) as key:
- ret[key] = signature
- return ret
-
-
-def simplify(signature):
- if isinstance(signature, list):
- # remove duplicates which still sometimes occour:
- ret = set(simplify(sig) for sig in signature)
- return sorted(ret) if len(ret) > 1 else list(ret)[0]
- ret = []
- for pv in signature.parameters.values():
- txt = str(pv)
- if txt == "self":
- continue
- txt = txt[txt.index(":") + 1:]
- if "=" in txt:
- txt = txt[:txt.index("=")]
- quote = txt[0]
- if quote in ("'", '"') and txt[-1] == quote:
- txt = txt[1:-1]
- ret.append(txt)
- return tuple(ret)
-
-
-class SimplifyingEnumerator(ExactEnumerator):
- """
- SimplifyingEnumerator enumerates all signatures in a module filtered.
-
- There are no default values, no variable
- names and no self parameter. Only types are present after simplification.
- The functions 'next' resp. '__next__' are removed
- to make the output identical for Python 2 and 3.
- An appropriate formatter should be supplied, if printable output
- is desired.
- """
-
- def function(self, func_name, func):
- ret = self.result_type()
- signature = getattr(func, '__signature__', None)
- sig = simplify(signature) if signature is not None else None
- if sig is not None and func_name not in ("next", "__next__"):
- with self.fmt.function(func_name, sig) as key:
- ret[key] = sig
- return ret
-
-
def enum_all():
fmt = Formatter(None)
enu = SimplifyingEnumerator(fmt)
@@ -258,8 +178,9 @@ def generate_all():
This file contains the simplified signatures for all functions in PySide
for module '{}'. There are no default values, no variable
names and no self parameter. Only types are present after simplification.
- The functions 'next' resp. '__next__' are removed
- to make the output identical for Python 2 and 3.
+ The functions 'next' resp. '__next__' are removed to make the output
+ identical for Python 2 and 3. '__div__' is also removed,
+ since it exists in Python 2, only.
"""
'''.format(module)))
fmt.print("import sys")
diff --git a/sources/pyside2/tests/support/voidptr_test.py b/sources/pyside2/tests/support/voidptr_test.py
index 8179407e5..330788c63 100644
--- a/sources/pyside2/tests/support/voidptr_test.py
+++ b/sources/pyside2/tests/support/voidptr_test.py
@@ -27,7 +27,7 @@
#############################################################################
import unittest
-from PySide2 import shiboken2
+import shiboken2 as shiboken
from PySide2.support import VoidPtr
from PySide2.QtCore import QByteArray
@@ -40,7 +40,7 @@ class PySide2Support(unittest.TestCase):
# or another VoidPtr object.
ba = QByteArray(b"Hello world")
voidptr = VoidPtr(ba)
- self.assertIsInstance(voidptr, shiboken2.VoidPtr)
+ self.assertIsInstance(voidptr, shiboken.VoidPtr)
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt
index b67a352f0..b4fd1cb99 100644
--- a/sources/shiboken2/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/CMakeLists.txt
@@ -37,6 +37,7 @@ abstractmetabuilder.cpp
abstractmetalang.cpp
fileout.cpp
graph.cpp
+messages.cpp
reporthandler.cpp
typeparser.cpp
typesystem.cpp
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index 84c116708..f6724e61d 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "abstractmetabuilder_p.h"
+#include "messages.h"
#include "reporthandler.h"
#include "typedatabase.h"
@@ -159,38 +160,18 @@ AbstractMetaEnumList AbstractMetaBuilder::globalEnums() const
return d->m_globalEnums;
}
-static QString msgNoFunctionForModification(const QString &signature,
- const QString &originalSignature,
- const QString &className,
- const QStringList &possibleSignatures,
- const AbstractMetaFunctionList &allFunctions)
-{
- QString result;
- QTextStream str(&result);
- str << "signature '" << signature << '\'';
- if (!originalSignature.isEmpty() && originalSignature != signature)
- str << " (specified as '" << originalSignature << "')";
- str << " for function modification in '"
- << className << "' not found.";
- if (possibleSignatures.isEmpty()) {
- str << " No candidates were found. Member functions: ";
- for (int f = 0, size = allFunctions.size(); f < size; ++f) {
- if (f)
- str << ", ";
- str << allFunctions.at(f)->minimalSignature();
- }
- } else {
- str << " Possible candidates: " << possibleSignatures.join(QLatin1String(", "));
- }
- return result;
+AbstractMetaEnum *AbstractMetaBuilder::findEnum(const TypeEntry *typeEntry) const
+{
+ if (typeEntry && typeEntry->isFlags())
+ typeEntry = static_cast<const FlagsTypeEntry*>(typeEntry)->originator();
+ return d->m_enums.value(typeEntry);
}
void AbstractMetaBuilderPrivate::checkFunctionModifications()
{
- TypeDatabase *types = TypeDatabase::instance();
- const SingleTypeEntryHash entryHash = types->entries();
+ const auto &entries = TypeDatabase::instance()->entries();
- for (SingleTypeEntryHash::const_iterator it = entryHash.cbegin(), end = entryHash.cend(); it != end; ++it) {
+ for (auto it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
const TypeEntry *entry = it.value();
if (!entry)
continue;
@@ -241,7 +222,7 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(ArgumentModelItem argument)
+AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument)
{
AbstractMetaClass* returned = 0;
AbstractMetaType *type = translateType(argument->type());
@@ -256,7 +237,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(ArgumentModelItem
/**
* Checks the argument of a hash function and flags the type if it is a complex type
*/
-void AbstractMetaBuilderPrivate::registerHashFunction(FunctionModelItem function_item)
+void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 1) {
@@ -269,12 +250,12 @@ void AbstractMetaBuilderPrivate::registerHashFunction(FunctionModelItem function
* Check if a class has a debug stream operator that can be used as toString
*/
-void AbstractMetaBuilderPrivate::registerToStringCapability(FunctionModelItem function_item)
+void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 2) {
if (arguments.at(0)->type().toString() == QLatin1String("QDebug")) {
- ArgumentModelItem arg = arguments.at(1);
+ const ArgumentModelItem &arg = arguments.at(1);
if (AbstractMetaClass *cls = argumentToClass(arg)) {
if (arg->type().indirections() < 2)
cls->setToStringCapability(true);
@@ -283,7 +264,7 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(FunctionModelItem fu
}
}
-void AbstractMetaBuilderPrivate::traverseOperatorFunction(FunctionModelItem item)
+void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item)
{
if (item->accessPolicy() != CodeModel::Public)
return;
@@ -348,7 +329,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(FunctionModelItem item
setupFunctionDefaults(metaFunction, baseoperandClass);
baseoperandClass->addFunction(metaFunction);
Q_ASSERT(!metaFunction->wasPrivate());
- } else if (metaFunction) {
+ } else {
delete metaFunction;
}
@@ -356,7 +337,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(FunctionModelItem item
}
}
-void AbstractMetaBuilderPrivate::traverseStreamOperator(FunctionModelItem item)
+void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item)
{
ArgumentList arguments = item->arguments();
if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
@@ -404,7 +385,7 @@ void AbstractMetaBuilderPrivate::traverseStreamOperator(FunctionModelItem item)
funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
m_currentClass = oldCurrentClass;
- } else if (streamFunction) {
+ } else {
delete streamFunction;
}
@@ -422,7 +403,7 @@ void AbstractMetaBuilderPrivate::fixQObjectForScope(const FileModelItem &dom,
TypeEntry* entry = types->findType(qualifiedName);
if (entry) {
if (isQObject(dom, qualifiedName) && entry->isComplex())
- ((ComplexTypeEntry*) entry)->setQObject(true);
+ static_cast<ComplexTypeEntry *>(entry)->setQObject(true);
}
}
@@ -475,19 +456,18 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
const ClassList &typeValues = dom->classes();
ReportHandler::setProgressReference(typeValues);
for (const ClassModelItem &item : typeValues) {
- ReportHandler::progress(QLatin1String("Generating class model..."));
- AbstractMetaClass *cls = traverseClass(dom, item);
- if (!cls)
- continue;
-
- addAbstractMetaClass(cls);
+ ReportHandler::progress(QStringLiteral("Generating class model (%1)...")
+ .arg(typeValues.size()));
+ if (AbstractMetaClass *cls = traverseClass(dom, item))
+ addAbstractMetaClass(cls);
}
// We need to know all global enums
const EnumList &enums = dom->enums();
ReportHandler::setProgressReference(enums);
for (const EnumModelItem &item : enums) {
- ReportHandler::progress(QLatin1String("Generating enum model..."));
+ ReportHandler::progress(QStringLiteral("Generating enum model (%1)...")
+ .arg(enums.size()));
AbstractMetaEnum *metaEnum = traverseEnum(item, 0, QSet<QString>());
if (metaEnum) {
if (metaEnum->typeEntry()->generateCode())
@@ -495,10 +475,11 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
}
- const QSet<NamespaceModelItem> &namespaceTypeValues = dom->uniqueNamespaces();
+ const auto &namespaceTypeValues = dom->namespaces();
ReportHandler::setProgressReference(namespaceTypeValues);
for (const NamespaceModelItem &item : namespaceTypeValues) {
- ReportHandler::progress(QLatin1String("Generating namespace model..."));
+ ReportHandler::progress(QStringLiteral("Generating namespace model (%1)...")
+ .arg(namespaceTypeValues.size()));
AbstractMetaClass *metaClass = traverseNamespace(dom, item);
if (metaClass)
m_metaClasses << metaClass;
@@ -509,11 +490,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
const TypeDefList typeDefs = dom->typeDefs();
ReportHandler::setProgressReference(typeDefs);
for (const TypeDefModelItem &typeDef : typeDefs) {
- ReportHandler::progress(QLatin1String("Resolving typedefs..."));
- AbstractMetaClass* cls = traverseTypeDef(dom, typeDef);
- addAbstractMetaClass(cls);
+ ReportHandler::progress(QStringLiteral("Resolving typedefs (%1)...")
+ .arg(typeDefs.size()));
+ if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef))
+ addAbstractMetaClass(cls);
}
+ traverseTypesystemTypedefs();
+
for (const ClassModelItem &item : typeValues)
traverseClassMembers(item);
@@ -580,13 +564,12 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
if (cls->isAbstract() && !cls->isInterface())
cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + QLatin1String("$ConcreteWrapper"));
}
- const TypeEntryHash allEntries = types->allEntries();
- ReportHandler::progress(QLatin1String("Detecting inconsistencies in typesystem..."));
- for (TypeEntryHash::const_iterator it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
- for (TypeEntry *entry : it.value()) {
- if (entry->isPrimitive())
- continue;
-
+ const auto &allEntries = types->entries();
+ ReportHandler::progress(QStringLiteral("Detecting inconsistencies in typesystem (%1)...")
+ .arg(allEntries.size()));
+ for (auto it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
+ TypeEntry *entry = it.value();
+ if (!entry->isPrimitive()) {
if ((entry->isValue() || entry->isObject())
&& !entry->isString()
&& !entry->isChar()
@@ -616,20 +599,13 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
}
} else if (entry->isEnum() && (entry->generateCode() & TypeEntry::GenerateTargetLang)) {
- const QString name = ((EnumTypeEntry*) entry)->targetLangQualifier();
+ const QString name = static_cast<const EnumTypeEntry *>(entry)->targetLangQualifier();
AbstractMetaClass *cls = AbstractMetaClass::findClass(m_metaClasses, name);
- bool enumFound = false;
- if (cls) {
- enumFound = cls->findEnum(entry->targetLangName());
- } else { // Global enum
- for (AbstractMetaEnum *metaEnum : qAsConst(m_enums)) {
- if (metaEnum->typeEntry() == entry) {
- enumFound = true;
- break;
- }
- }
- }
+ const bool enumFound = cls
+ ? cls->findEnum(entry->targetLangName()) != nullptr
+ : m_enums.contains(entry);
+
if (!enumFound) {
entry->setCodeGeneration(TypeEntry::GenerateNothing);
qCWarning(lcShiboken).noquote().nospace()
@@ -727,6 +703,15 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
std::puts("");
}
+static bool metaEnumLessThan(const AbstractMetaEnum *e1, const AbstractMetaEnum *e2)
+{ return e1->fullName() < e2->fullName(); }
+
+static bool metaClassLessThan(const AbstractMetaClass *c1, const AbstractMetaClass *c2)
+{ return c1->fullName() < c2->fullName(); }
+
+static bool metaFunctionLessThan(const AbstractMetaFunction *f1, const AbstractMetaFunction *f2)
+{ return f1->name() < f2->name(); }
+
bool AbstractMetaBuilder::build(const QByteArrayList &arguments,
LanguageLevel level,
unsigned clangFlags)
@@ -737,6 +722,14 @@ bool AbstractMetaBuilder::build(const QByteArrayList &arguments,
if (ReportHandler::isDebug(ReportHandler::MediumDebug))
qCDebug(lcShiboken) << dom.data();
d->traverseDom(dom);
+
+ // Ensure that indexes are in alphabetical order, roughly
+ std::sort(d->m_globalEnums.begin(), d->m_globalEnums.end(), metaEnumLessThan);
+ std::sort(d->m_metaClasses.begin(), d->m_metaClasses.end(), metaClassLessThan);
+ std::sort(d->m_templates.begin(), d->m_templates.end(), metaClassLessThan);
+ std::sort(d->m_smartPointers.begin(), d->m_smartPointers.end(), metaClassLessThan);
+ std::sort(d->m_globalFunctions.begin(), d->m_globalFunctions.end(), metaFunctionLessThan);
+
return true;
}
@@ -749,9 +742,6 @@ void AbstractMetaBuilder::setLogDirectory(const QString& logDir)
void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls)
{
- if (!cls)
- return;
-
cls->setOriginalAttributes(cls->attributes());
if (cls->typeEntry()->isContainer()) {
m_templates << cls;
@@ -827,8 +817,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
}
// Traverse namespaces recursively
- const QSet<NamespaceModelItem> &innerNamespaces = namespaceItem->uniqueNamespaces();
- for (const NamespaceModelItem &ni : innerNamespaces) {
+ for (const NamespaceModelItem &ni : namespaceItem->namespaces()) {
AbstractMetaClass* mjc = traverseNamespace(dom, ni);
if (mjc) {
metaClass->addInnerClass(mjc);
@@ -848,7 +837,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
return metaClass;
}
-AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumItem,
+AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &enumItem,
AbstractMetaClass *enclosing,
const QSet<QString> &enumsDeclarations)
{
@@ -857,7 +846,7 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
TypeEntry* typeEntry = 0;
if (enumItem->accessPolicy() == CodeModel::Private) {
QStringList names = enumItem->qualifiedName();
- QString enumName = names.constLast();
+ const QString &enumName = names.constLast();
QString nspace;
if (names.size() > 1)
nspace = QStringList(names.mid(0, names.size() - 1)).join(colonColon());
@@ -892,15 +881,23 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
return 0;
}
- if ((!typeEntry || !typeEntry->isEnum())) {
- if (!m_currentClass ||
- (m_currentClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang)) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("enum '%1' does not have a type entry or is not an enum")
- .arg(qualifiedName);
+ const bool rejectionWarning = !m_currentClass
+ || (m_currentClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang);
+
+ if (!typeEntry) {
+ if (rejectionWarning)
+ qCWarning(lcShiboken, "%s", qPrintable(msgNoEnumTypeEntry(enumItem, className)));
+ m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem);
+ return nullptr;
+ }
+
+ if (!typeEntry->isEnum()) {
+ if (rejectionWarning) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgNoEnumTypeConflict(enumItem, className, typeEntry)));
}
m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem);
- return 0;
+ return nullptr;
}
AbstractMetaEnum *metaEnum = new AbstractMetaEnum;
@@ -946,15 +943,9 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
qCDebug(lcShiboken) << " - " << metaEnumValue->name() << " = "
<< metaEnumValue->value() << " = " << metaEnumValue->value();
}
-
- // Add into global register...
- if (enclosing)
- m_enumValues[enclosing->name() + colonColon() + metaEnumValue->name()] = metaEnumValue;
- else
- m_enumValues[metaEnumValue->name()] = metaEnumValue;
}
- m_enums << metaEnum;
+ m_enums.insert(typeEntry, metaEnum);
if (!metaEnum->typeEntry()->include().isValid())
setInclude(metaEnum->typeEntry(), enumItem->fileName());
@@ -962,6 +953,15 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
metaEnum->setOriginalAttributes(metaEnum->attributes());
// Register all enum values on Type database
+ QString prefix;
+ if (enclosing) {
+ prefix += enclosing->typeEntry()->qualifiedCppName();
+ prefix += colonColon();
+ }
+ if (enumItem->enumKind() == EnumClass) {
+ prefix += enumItem->name();
+ prefix += colonColon();
+ }
const EnumeratorList &enumerators = enumItem->enumerators();
for (const EnumeratorModelItem &e : enumerators) {
QString name;
@@ -969,11 +969,12 @@ AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(EnumModelItem enumIte
name += enclosing->name();
name += colonColon();
}
- name += e->name();
EnumValueTypeEntry *enumValue =
- new EnumValueTypeEntry(name, e->stringValue(),
+ new EnumValueTypeEntry(prefix + e->name(), e->stringValue(),
enumTypeEntry, enumTypeEntry->version());
TypeDatabase::instance()->addType(enumValue);
+ if (e->value().isNullValue())
+ enumTypeEntry->setNullValue(enumValue);
}
return metaEnum;
@@ -1014,7 +1015,7 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
AbstractMetaClass *metaClass = new AbstractMetaClass;
metaClass->setTypeDef(true);
metaClass->setTypeEntry(type);
- metaClass->setBaseClassNames(QStringList() << typeDef->type().qualifiedName().join(colonColon()));
+ metaClass->setBaseClassNames(QStringList(typeDef->type().toString()));
*metaClass += AbstractMetaAttributes::Public;
// Set the default include file name
@@ -1026,6 +1027,22 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
return metaClass;
}
+// Add the typedef'ed classes
+void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
+{
+ const auto &entries = TypeDatabase::instance()->typedefEntries();
+ for (auto it = entries.begin(), end = entries.end(); it != end; ++it) {
+ TypedefEntry *te = it.value();
+ AbstractMetaClass *metaClass = new AbstractMetaClass;
+ metaClass->setTypeDef(true);
+ metaClass->setTypeEntry(te->target());
+ metaClass->setBaseClassNames(QStringList(te->sourceType()));
+ *metaClass += AbstractMetaAttributes::Public;
+ fillAddedFunctions(metaClass);
+ addAbstractMetaClass(metaClass);
+ }
+}
+
AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
const ClassModelItem &classItem)
{
@@ -1197,25 +1214,24 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(NamespaceModelItem ite
traverseScopeMembers(item, metaClass);
// Inner namespaces
- const QSet<NamespaceModelItem> &innerNamespaces = item->uniqueNamespaces();
- for (const NamespaceModelItem &ni : innerNamespaces)
+ for (const NamespaceModelItem &ni : item->namespaces())
traverseNamespaceMembers(ni);
m_currentClass = oldCurrentClass;
}
-static inline QString fieldSignatureWithType(VariableModelItem field)
+static inline QString fieldSignatureWithType(const VariableModelItem &field)
{
return field->name() + QStringLiteral(" -> ") + field->type().toString();
}
static inline QString qualifiedFieldSignatureWithType(const QString &className,
- VariableModelItem field)
+ const VariableModelItem &field)
{
return className + colonColon() + fieldSignatureWithType(field);
}
-AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(VariableModelItem field,
+AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModelItem &field,
const AbstractMetaClass *cls)
{
QString fieldName = field->name();
@@ -1272,7 +1288,7 @@ AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(VariableModelItem f
return metaField;
}
-void AbstractMetaBuilderPrivate::traverseFields(ScopeModelItem scope_item,
+void AbstractMetaBuilderPrivate::traverseFields(const ScopeModelItem &scope_item,
AbstractMetaClass *metaClass)
{
const VariableList &variables = scope_item->variables();
@@ -1327,14 +1343,8 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
static bool _compareAbstractMetaTypes(const AbstractMetaType* type, const AbstractMetaType* other)
{
- if (!type && !other)
- return true;
- if (!type || !other)
- return false;
- return type->typeEntry() == other->typeEntry()
- && type->isConstant() == other->isConstant()
- && type->referenceType() == other->referenceType()
- && type->indirections() == other->indirections();
+ return (type != nullptr) == (other != nullptr)
+ && (type == nullptr || *type == *other);
}
static bool _compareAbstractMetaFunctions(const AbstractMetaFunction* func, const AbstractMetaFunction* other)
@@ -1426,7 +1436,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
}
} else if (QPropertySpec* reset = metaClass->propertySpecForReset(metaFunction->name())) {
// Property resetter must be in the form "void name()"
- if ((!metaFunction->type()) && (metaFunction->arguments().size() == 0)) {
+ if ((!metaFunction->type()) && metaFunction->arguments().isEmpty()) {
*metaFunction += AbstractMetaAttributes::PropertyResetter;
metaFunction->setPropertySpec(reset);
}
@@ -1635,7 +1645,7 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
return true;
}
-void AbstractMetaBuilderPrivate::traverseEnums(ScopeModelItem scopeItem,
+void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
AbstractMetaClass *metaClass,
const QStringList &enumsDeclarations)
{
@@ -1724,13 +1734,9 @@ AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFu
replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1);
if (!replacedExpression.isEmpty()) {
- QString expr = replacedExpression;
if (!metaFunction->removedDefaultExpression(m_currentClass, i + 1)) {
- metaArg->setDefaultValueExpression(expr);
- metaArg->setOriginalDefaultValueExpression(expr);
-
- if (metaArg->type()->isEnum() || metaArg->type()->isFlags())
- m_enumDefaultArguments << QPair<AbstractMetaArgument*, AbstractMetaFunction*>(metaArg, metaFunction);
+ metaArg->setDefaultValueExpression(replacedExpression);
+ metaArg->setOriginalDefaultValueExpression(replacedExpression);
}
}
}
@@ -1784,7 +1790,7 @@ void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func, co
}
}
-static QString functionSignature(FunctionModelItem functionItem)
+static QString functionSignature(const FunctionModelItem &functionItem)
{
QStringList args;
const ArgumentList &arguments = functionItem->arguments();
@@ -1802,50 +1808,6 @@ static inline QString qualifiedFunctionSignatureWithType(const FunctionModelItem
result += functionSignature(functionItem);
return result;
}
-
-static inline QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n)
-{
- QString result;
- QTextStream str(&result);
- str << "unmatched type '" << arg->type().toString() << "' in parameter #"
- << (n + 1);
- if (!arg->name().isEmpty())
- str << " \"" << arg->name() << '"';
- return result;
-}
-
-static inline QString msgUnmatchedReturnType(const FunctionModelItem &functionItem)
-{
- return QLatin1String("unmatched return type '")
- + functionItem->type().toString() + QLatin1Char('\'');
-}
-
-static inline QString msgVoidParameterType(const ArgumentModelItem &arg, int n)
-{
- QString result;
- QTextStream str(&result);
- str << "'void' encountered at parameter #" << (n + 1);
- if (!arg->name().isEmpty())
- str << " \"" << arg->name() << '"';
- return result;
-}
-
-static QString msgSkippingFunction(const FunctionModelItem &functionItem,
- const QString &signature, const QString &why)
-{
- QString result;
- QTextStream str(&result);
- str << "skipping ";
- if (functionItem->isAbstract())
- str << "abstract ";
- str << "function '" << signature << "', " << why;
- if (functionItem->isAbstract()) {
- str << "\nThis will lead to compilation errors due to not "
- "being able to instantiate the wrapper.";
- }
- return result;
-}
-
static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeModel::FunctionType ft)
{
AbstractMetaFunction::FunctionType result = AbstractMetaFunction::NormalFunction;
@@ -1874,12 +1836,6 @@ static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeM
return result;
}
-static inline QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason)
-{
- return function + QLatin1String(": Cannot use parameter ") + QString::number(i + 1)
- + QLatin1String(" as an array: ") + reason;
-}
-
bool AbstractMetaBuilderPrivate::setArrayArgumentType(AbstractMetaFunction *func,
const FunctionModelItem &functionItem,
int i)
@@ -1911,12 +1867,40 @@ bool AbstractMetaBuilderPrivate::setArrayArgumentType(AbstractMetaFunction *func
return true;
}
-AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModelItem functionItem)
+static bool generateExceptionHandling(const AbstractMetaFunction *func,
+ ExceptionSpecification spec,
+ TypeSystem::ExceptionHandling handling)
+{
+ switch (func->functionType()) {
+ case AbstractMetaFunction::CopyConstructorFunction:
+ case AbstractMetaFunction::MoveConstructorFunction:
+ case AbstractMetaFunction::AssignmentOperatorFunction:
+ case AbstractMetaFunction::MoveAssignmentOperatorFunction:
+ case AbstractMetaFunction::DestructorFunction:
+ return false;
+ default:
+ break;
+ }
+ switch (handling) {
+ case TypeSystem::ExceptionHandling::On:
+ return true;
+ case TypeSystem::ExceptionHandling::AutoDefaultToOn:
+ return spec != ExceptionSpecification::NoExcept;
+ case TypeSystem::ExceptionHandling::AutoDefaultToOff:
+ return spec == ExceptionSpecification::Throws;
+ default:
+ break;
+ }
+ return false;
+}
+
+AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem)
{
if (functionItem->isDeleted() || !functionItem->templateParameters().isEmpty())
return nullptr;
QString functionName = functionItem->name();
QString className;
+ TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
if (m_currentClass) {
// Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT
// and overridden metaObject(), QGADGET helpers
@@ -1925,6 +1909,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
return nullptr;
}
className = m_currentClass->typeEntry()->qualifiedCppName();
+ exceptionHandling = m_currentClass->typeEntry()->exceptionHandling();
if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject"))
return nullptr;
}
@@ -1936,13 +1921,16 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
QString rejectReason;
if (TypeDatabase::instance()->isFunctionRejected(className, functionName, &rejectReason)) {
m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
- return 0;
- }
- else if (TypeDatabase::instance()->isFunctionRejected(className,
- functionSignature(functionItem), &rejectReason)) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
- return 0;
+ return nullptr;
}
+ const QString &signature = functionSignature(functionItem);
+ const bool rejected =
+ TypeDatabase::instance()->isFunctionRejected(className, signature, &rejectReason);
+ qCDebug(lcShiboken).nospace().noquote() << __FUNCTION__
+ << ": Checking rejection for signature \"" << signature << "\" for " << className
+ << ": " << rejected;
+ if (rejected)
+ return nullptr;
if (functionItem->isFriend())
return 0;
@@ -1951,6 +1939,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
// Additional check for assignment/move assignment down below
metaFunction->setFunctionType(functionTypeFromCodeModel(functionItem->functionType()));
metaFunction->setConstant(functionItem->isConstant());
+ metaFunction->setExceptionSpecification(functionItem->exceptionSpecification());
if (ReportHandler::isDebug(ReportHandler::MediumDebug))
qCDebug(lcShiboken).noquote().nospace() << " - " << functionName << "()";
@@ -1987,6 +1976,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
else
*metaFunction += AbstractMetaAttributes::Protected;
+ QString errorMessage;
switch (metaFunction->functionType()) {
case AbstractMetaFunction::DestructorFunction:
break;
@@ -2005,9 +1995,9 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
AbstractMetaType *type = nullptr;
if (!returnType.isVoid()) {
- type = translateType(returnType);
+ type = translateType(returnType, true, &errorMessage);
if (!type) {
- const QString reason = msgUnmatchedReturnType(functionItem);
+ const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
qCWarning(lcShiboken, "%s",
qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType);
@@ -2033,7 +2023,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
AbstractMetaArgumentList metaArguments;
for (int i = 0; i < arguments.size(); ++i) {
- ArgumentModelItem arg = arguments.at(i);
+ const ArgumentModelItem &arg = arguments.at(i);
if (TypeDatabase::instance()->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) {
m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
@@ -2041,7 +2031,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
return nullptr;
}
- AbstractMetaType *metaType = translateType(arg->type());
+ AbstractMetaType *metaType = translateType(arg->type(), true, &errorMessage);
if (!metaType) {
// If an invalid argument has a default value, simply remove it
if (arg->defaultValue()) {
@@ -2058,18 +2048,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
break;
}
Q_ASSERT(metaType == 0);
- const QString reason = msgUnmatchedParameterType(arg, i);
- qCWarning(lcShiboken, "%s",
- qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
- const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn
- + QLatin1String(": ") + reason;
- m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType);
- delete metaFunction;
- return nullptr;
- }
-
- if (metaType == Q_NULLPTR) {
- const QString reason = msgVoidParameterType(arg, i);
+ const QString reason = msgUnmatchedParameterType(arg, i, errorMessage);
qCWarning(lcShiboken, "%s",
qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn
@@ -2089,9 +2068,22 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
metaFunction->setArguments(metaArguments);
+ const FunctionModificationList functionMods = metaFunction->modifications(m_currentClass);
+
+ for (const FunctionModification &mod : functionMods) {
+ if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified) {
+ exceptionHandling = mod.exceptionHandling();
+ break;
+ }
+ }
+
+ metaFunction->setGenerateExceptionHandling(generateExceptionHandling(metaFunction,
+ functionItem->exceptionSpecification(),
+ exceptionHandling));
+
// Find the correct default values
for (int i = 0, size = metaArguments.size(); i < size; ++i) {
- ArgumentModelItem arg = arguments.at(i);
+ const ArgumentModelItem &arg = arguments.at(i);
AbstractMetaArgument* metaArg = metaArguments.at(i);
//use relace-default-expression for set default value
@@ -2099,9 +2091,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
if (m_currentClass) {
replacedExpression = metaFunction->replacedDefaultExpression(m_currentClass, i + 1);
} else {
- FunctionModificationList mods = TypeDatabase::instance()->functionModifications(metaFunction->minimalSignature());
- if (!mods.isEmpty()) {
- QVector<ArgumentModification> argMods = mods.constFirst().argument_mods;
+ if (!functionMods.isEmpty()) {
+ QVector<ArgumentModification> argMods = functionMods.constFirst().argument_mods;
if (!argMods.isEmpty())
replacedExpression = argMods.constFirst().replacedDefaultExpression;
}
@@ -2119,10 +2110,6 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
expr = replacedExpression;
}
metaArg->setDefaultValueExpression(expr);
-
- if (metaArg->type()->isEnum() || metaArg->type()->isFlags())
- m_enumDefaultArguments << QPair<AbstractMetaArgument *, AbstractMetaFunction *>(metaArg, metaFunction);
-
hasDefaultValue = !expr.isEmpty();
}
@@ -2140,9 +2127,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(FunctionModel
}
if (!metaArguments.isEmpty()) {
- const FunctionModificationList &mods = metaFunction->modifications(m_currentClass);
- fixArgumentNames(metaFunction, mods);
- for (const FunctionModification &mod : mods) {
+ fixArgumentNames(metaFunction, functionMods);
+ for (const FunctionModification &mod : functionMods) {
for (const ArgumentModification &argMod : mod.argument_mods) {
if (argMod.array)
setArrayArgumentType(metaFunction, functionItem, argMod.index - 1);
@@ -2202,8 +2188,8 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction:
if (!type) {
QStringList candidates;
- SingleTypeEntryHash entries = typeDb->entries();
- for (SingleTypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
+ const auto &entries = typeDb->entries();
+ for (auto it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
// Let's try to find the type in different scopes.
if (it.key().endsWith(colonColon() + typeName))
candidates.append(it.key());
@@ -2211,15 +2197,17 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction:
QString msg = QStringLiteral("Type '%1' wasn't found in the type database.\n").arg(typeName);
- if (candidates.isEmpty())
- qFatal(qPrintable(QString(msg + QLatin1String("Declare it in the type system using the proper <*-type> tag."))), NULL);
+ if (candidates.isEmpty()) {
+ qFatal("%sDeclare it in the type system using the proper <*-type> tag.",
+ qPrintable(msg));
+ }
msg += QLatin1String("Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n");
candidates.sort();
for (const QString& candidate : qAsConst(candidates)) {
msg += QLatin1String(" ") + candidate + QLatin1Char('\n');
}
- qFatal(qPrintable(msg), NULL);
+ qFatal("%s", qPrintable(msg));
}
AbstractMetaType *metaType = new AbstractMetaType;
@@ -2243,7 +2231,7 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
{
const TypeEntry* type = 0;
QStringList context = metaClass->qualifiedCppName().split(colonColon());
- while(!type && (context.size() > 0) ) {
+ while (!type && !context.isEmpty()) {
type = TypeDatabase::instance()->findType(context.join(colonColon()) + colonColon() + qualifiedName);
context.removeLast();
}
@@ -2251,43 +2239,48 @@ static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaC
}
AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
- bool resolveType)
+ bool resolveType,
+ QString *errorMessage)
+{
+ return translateTypeStatic(_typei, m_currentClass, this, resolveType, errorMessage);
+}
+
+AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ AbstractMetaBuilderPrivate *d,
+ bool resolveType,
+ QString *errorMessageIn)
{
// 1. Test the type info without resolving typedefs in case this is present in the
// type system
- TypeInfo typei;
if (resolveType) {
- if (AbstractMetaType *resolved = translateType(_typei, false))
+ if (AbstractMetaType *resolved = translateTypeStatic(_typei, currentClass, d, false, errorMessageIn))
return resolved;
}
- if (!resolveType) {
- typei = _typei;
- } else {
+ TypeInfo typeInfo = _typei;
+ if (resolveType) {
// Go through all parts of the current scope (including global namespace)
// to resolve typedefs. The parser does not properly resolve typedefs in
// the global scope when they are referenced from inside a namespace.
// This is a work around to fix this bug since fixing it in resolveType
// seemed non-trivial
- int i = m_scopes.size() - 1;
+ int i = d ? d->m_scopes.size() - 1 : -1;
while (i >= 0) {
- typei = TypeInfo::resolveType(_typei, m_scopes.at(i--));
- if (typei.qualifiedName().join(colonColon()) != _typei.qualifiedName().join(colonColon()))
+ typeInfo = TypeInfo::resolveType(_typei, d->m_scopes.at(i--));
+ if (typeInfo.qualifiedName().join(colonColon()) != _typei.qualifiedName().join(colonColon()))
break;
}
}
- if (typei.isFunctionPointer())
+ if (typeInfo.isFunctionPointer()) {
+ if (errorMessageIn)
+ *errorMessageIn = msgUnableToTranslateType(_typei, QLatin1String("Unsupported function pointer."));
return nullptr;
+ }
QString errorMessage;
- TypeInfo typeInfo = TypeParser::parse(typei.toString(), &errorMessage);
- if (typeInfo.qualifiedName().isEmpty()) {
- qWarning().noquote().nospace() << "Unable to translate type \"" << _typei.toString()
- << "\": " << errorMessage;
- return 0;
- }
// 2. Handle arrays.
// 2.1 Handle char arrays with unspecified size (aka "const char[]") as "const char*" with
@@ -2312,16 +2305,22 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
if (!typeInfo.arrayElements().isEmpty() && !isConstCharStarCase) {
TypeInfo newInfo;
//newInfo.setArguments(typeInfo.arguments());
- newInfo.setIndirections(typeInfo.indirections());
+ newInfo.setIndirectionsV(typeInfo.indirectionsV());
newInfo.setConstant(typeInfo.isConstant());
+ newInfo.setVolatile(typeInfo.isVolatile());
newInfo.setFunctionPointer(typeInfo.isFunctionPointer());
newInfo.setQualifiedName(typeInfo.qualifiedName());
newInfo.setReferenceType(typeInfo.referenceType());
newInfo.setVolatile(typeInfo.isVolatile());
- AbstractMetaType *elementType = translateType(newInfo);
- if (!elementType)
+ AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, true, &errorMessage);
+ if (!elementType) {
+ if (errorMessageIn) {
+ errorMessage.prepend(QLatin1String("Unable to translate array element: "));
+ *errorMessageIn = msgUnableToTranslateType(_typei, errorMessage);
+ }
return nullptr;
+ }
for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) {
AbstractMetaType *arrayType = new AbstractMetaType;
@@ -2329,7 +2328,9 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
const QString &arrayElement = typeInfo.arrayElements().at(i);
if (!arrayElement.isEmpty()) {
bool _ok;
- const qint64 elems = findOutValueFromString(arrayElement, _ok);
+ const qint64 elems = d
+ ? d->findOutValueFromString(arrayElement, _ok)
+ : arrayElement.toLongLong(&_ok, 0);
if (_ok)
arrayType->setArrayElementCount(int(elems));
}
@@ -2344,8 +2345,11 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
QStringList qualifierList = typeInfo.qualifiedName();
if (qualifierList.isEmpty()) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("horribly broken type '%1'").arg(_typei.toString());
+ errorMessage = msgUnableToTranslateType(_typei, QLatin1String("horribly broken type"));
+ if (errorMessageIn)
+ *errorMessageIn = errorMessage;
+ else
+ qCWarning(lcShiboken,"%s", qPrintable(errorMessage));
return nullptr;
}
@@ -2353,19 +2357,21 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
QString name = qualifierList.takeLast();
// 4. Special case QFlags (include instantiation in name)
- if (qualifiedName == QLatin1String("QFlags"))
+ if (qualifiedName == QLatin1String("QFlags")) {
qualifiedName = typeInfo.toString();
+ typeInfo.clearInstantiations();
+ }
const TypeEntry *type = 0;
// 5. Try to find the type
// 5.1 - Try first using the current scope
- if (m_currentClass) {
- type = findTypeEntryUsingContext(m_currentClass, qualifiedName);
+ if (currentClass) {
+ type = findTypeEntryUsingContext(currentClass, qualifiedName);
// 5.1.1 - Try using the class parents' scopes
- if (!type && !m_currentClass->baseClassNames().isEmpty()) {
- const AbstractMetaClassList &baseClasses = getBaseClasses(m_currentClass);
+ if (!type && d && !currentClass->baseClassNames().isEmpty()) {
+ const AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
for (const AbstractMetaClass *cls : baseClasses) {
type = findTypeEntryUsingContext(cls, qualifiedName);
if (type)
@@ -2388,36 +2394,40 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
// 8. No? Check if the current class is a template and this type is one
// of the parameters.
- if (!type && m_currentClass) {
- const QVector<TypeEntry *> &template_args = m_currentClass->templateArguments();
+ if (!type && currentClass) {
+ const QVector<TypeEntry *> &template_args = currentClass->templateArguments();
for (TypeEntry *te : template_args) {
if (te->name() == qualifiedName)
type = te;
}
}
- if (!type)
+ if (!type) {
+ if (errorMessageIn) {
+ *errorMessageIn =
+ msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName));
+ }
return nullptr;
-
- // Used to for diagnostics later...
- m_usedTypes << type;
+ }
// These are only implicit and should not appear in code...
Q_ASSERT(!type->isInterface());
AbstractMetaType *metaType = new AbstractMetaType;
metaType->setTypeEntry(type);
- metaType->setIndirections(typeInfo.indirections());
+ metaType->setIndirectionsV(typeInfo.indirectionsV());
metaType->setReferenceType(typeInfo.referenceType());
metaType->setConstant(typeInfo.isConstant());
+ metaType->setVolatile(typeInfo.isVolatile());
metaType->setOriginalTypeDescription(_typei.toString());
- const auto &templateArguments = typeInfo.arguments();
+ const auto &templateArguments = typeInfo.instantiations();
for (int t = 0, size = templateArguments.size(); t < size; ++t) {
- TypeInfo ti = templateArguments.at(t);
- ti.setQualifiedName(ti.instantiationName());
- AbstractMetaType *targType = translateType(ti);
+ const TypeInfo &ti = templateArguments.at(t);
+ AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, true, &errorMessage);
if (!targType) {
+ if (errorMessageIn)
+ *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage);
delete metaType;
return nullptr;
}
@@ -2434,6 +2444,33 @@ AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typ
return metaType;
}
+AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass,
+ bool resolveType,
+ QString *errorMessage)
+{
+ return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass,
+ nullptr, resolveType,
+ errorMessage);
+}
+
+AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t,
+ AbstractMetaClass *currentClass,
+ bool resolveType,
+ QString *errorMessageIn)
+{
+ QString errorMessage;
+ TypeInfo typeInfo = TypeParser::parse(t, &errorMessage);
+ if (typeInfo.qualifiedName().isEmpty()) {
+ errorMessage = msgUnableToTranslateType(t, errorMessage);
+ if (errorMessageIn)
+ *errorMessageIn = errorMessage;
+ else
+ qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ return nullptr;
+ }
+ return translateType(typeInfo, currentClass, resolveType, errorMessageIn);
+}
qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok)
{
@@ -2472,7 +2509,7 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
return 0;
}
-QString AbstractMetaBuilderPrivate::fixDefaultValue(ArgumentModelItem item,
+QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item,
AbstractMetaType *type,
AbstractMetaFunction *fnc,
AbstractMetaClass *implementingClass,
@@ -2676,59 +2713,55 @@ bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const Abstrac
return false;
}
-AbstractMetaType* AbstractMetaBuilderPrivate::inheritTemplateType(const QVector<AbstractMetaType *> &templateTypes,
- const AbstractMetaType *metaType,
- bool *ok)
+AbstractMetaType *
+ AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaType *metaType)
{
- if (ok)
- *ok = true;
- if (!metaType || (!metaType->typeEntry()->isTemplateArgument() && !metaType->hasInstantiations()))
- return metaType ? metaType->copy() : 0;
+ Q_ASSERT(metaType);
+
+ QScopedPointer<AbstractMetaType> returned(metaType->copy());
- AbstractMetaType *returned = metaType->copy();
- returned->setOriginalTemplateType(metaType->copy());
+ if (!metaType->typeEntry()->isTemplateArgument() && !metaType->hasInstantiations())
+ return returned.take();
+
+ returned->setOriginalTemplateType(metaType);
if (returned->typeEntry()->isTemplateArgument()) {
const TemplateArgumentEntry* tae = static_cast<const TemplateArgumentEntry*>(returned->typeEntry());
// If the template is intantiated with void we special case this as rejecting the functions that use this
// parameter from the instantiation.
- if (templateTypes.size() <= tae->ordinal() || templateTypes.at(tae->ordinal())->typeEntry()->name() == QLatin1String("void")) {
- if (ok)
- *ok = false;
- return 0;
- }
+ const AbstractMetaType *templateType = templateTypes.value(tae->ordinal());
+ if (!templateType || templateType->typeEntry()->isVoid())
+ return nullptr;
AbstractMetaType* t = returned->copy();
- t->setTypeEntry(templateTypes.at(tae->ordinal())->typeEntry());
- t->setIndirections(templateTypes.at(tae->ordinal())->indirections() + t->indirections() ? 1 : 0);
+ t->setTypeEntry(templateType->typeEntry());
+ t->setIndirections(templateType->indirections() + t->indirections() ? 1 : 0);
t->decideUsagePattern();
- delete returned;
- returned = inheritTemplateType(templateTypes, t, ok);
- if (ok && !(*ok))
- return 0;
+ return inheritTemplateType(templateTypes, t);
}
if (returned->hasInstantiations()) {
AbstractMetaTypeList instantiations = returned->instantiations();
for (int i = 0; i < instantiations.count(); ++i) {
- AbstractMetaType *type = instantiations[i];
- instantiations[i] = inheritTemplateType(templateTypes, type, ok);
- if (ok && !(*ok))
- return 0;
+ instantiations[i] =
+ inheritTemplateType(templateTypes, instantiations.at(i));
+ if (!instantiations.at(i))
+ return nullptr;
}
returned->setInstantiations(instantiations, true);
}
- return returned;
+ return returned.take();
}
bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
const AbstractMetaClass *templateClass,
const TypeInfo &info)
{
- QVector<TypeInfo> targs = info.arguments();
+ QVector<TypeInfo> targs = info.instantiations();
QVector<AbstractMetaType *> templateTypes;
if (subclass->isTypeDef()) {
@@ -2743,20 +2776,35 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
for (const TypeInfo &i : qAsConst(targs)) {
QString typeName = i.qualifiedName().join(colonColon());
- QStringList possibleNames;
- possibleNames << subclass->qualifiedCppName() + colonColon() + typeName;
- possibleNames << templateClass->qualifiedCppName() + colonColon() + typeName;
- if (subclass->enclosingClass())
- possibleNames << subclass->enclosingClass()->qualifiedCppName() + colonColon() + typeName;
- possibleNames << typeName;
-
- TypeDatabase* typeDb = TypeDatabase::instance();
- TypeEntry* t = 0;
- QString templateParamName;
- for (const QString &possibleName : qAsConst(possibleNames)) {
- t = typeDb->findType(possibleName);
- if (t)
- break;
+ TypeDatabase *typeDb = TypeDatabase::instance();
+ TypeEntry *t = nullptr;
+ // Check for a non-type template integer parameter, that is, for a base
+ // "template <int R, int C> Matrix<R, C>" and subclass
+ // "typedef Matrix<2,3> Matrix2x3;". If so, create dummy entries of
+ // EnumValueTypeEntry for the integer values encountered on the fly.
+ const bool isNumber = std::all_of(typeName.cbegin(), typeName.cend(),
+ [](QChar c) { return c.isDigit(); });
+ if (isNumber) {
+ t = typeDb->findType(typeName);
+ if (!t) {
+ t = new EnumValueTypeEntry(typeName, typeName, nullptr,
+ QVersionNumber(0, 0));
+ t->setCodeGeneration(0);
+ typeDb->addType(t);
+ }
+ } else {
+ QStringList possibleNames;
+ possibleNames << subclass->qualifiedCppName() + colonColon() + typeName;
+ possibleNames << templateClass->qualifiedCppName() + colonColon() + typeName;
+ if (subclass->enclosingClass())
+ possibleNames << subclass->enclosingClass()->qualifiedCppName() + colonColon() + typeName;
+ possibleNames << typeName;
+
+ for (const QString &possibleName : qAsConst(possibleNames)) {
+ t = typeDb->findType(possibleName);
+ if (t)
+ break;
+ }
}
if (t) {
@@ -2764,48 +2812,48 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
temporaryType->setTypeEntry(t);
temporaryType->setConstant(i.isConstant());
temporaryType->setReferenceType(i.referenceType());
- temporaryType->setIndirections(i.indirections());
+ temporaryType->setIndirectionsV(i.indirectionsV());
temporaryType->decideUsagePattern();
templateTypes << temporaryType;
} else {
qCWarning(lcShiboken).noquote().nospace()
- << "Ignoring template parameter " << templateParamName << " from "
- << info.instantiationName() << ", because I don't know what it is.";
+ << "Ignoring template parameter " << typeName << " from "
+ << info.toString() << ". The corresponding type was not found in the typesystem.";
}
}
- AbstractMetaFunctionList funcs = subclass->functions();
+ const AbstractMetaFunctionList &subclassFuncs = subclass->functions();
const AbstractMetaFunctionList &templateClassFunctions = templateClass->functions();
for (const AbstractMetaFunction *function : templateClassFunctions) {
- if (function->isModifiedRemoved(TypeSystem::All))
+ // If the function is modified or the instantiation has an equally named
+ // function we have shadowing, so we need to skip it.
+ if (function->isModifiedRemoved(TypeSystem::All)
+ || AbstractMetaFunction::find(subclassFuncs, function->name()) != nullptr) {
continue;
+ }
- AbstractMetaFunction *f = function->copy();
+ QScopedPointer<AbstractMetaFunction> f(function->copy());
f->setArguments(AbstractMetaArgumentList());
- bool ok = true;
- AbstractMetaType *ftype = function->type();
- f->replaceType(inheritTemplateType(templateTypes, ftype, &ok));
- if (!ok) {
- delete f;
- continue;
+ if (function->type()) { // Non-void
+ AbstractMetaType *returnType = inheritTemplateType(templateTypes, function->type());
+ if (!returnType)
+ continue;
+ f->replaceType(returnType);
}
const AbstractMetaArgumentList &arguments = function->arguments();
for (AbstractMetaArgument *argument : arguments) {
- AbstractMetaType* atype = argument->type();
-
- AbstractMetaArgument *arg = argument->copy();
- arg->replaceType(inheritTemplateType(templateTypes, atype, &ok));
- if (!ok)
+ AbstractMetaType *argType = inheritTemplateType(templateTypes, argument->type());
+ if (!argType)
break;
+ AbstractMetaArgument *arg = argument->copy();
+ arg->replaceType(argType);
f->addArgument(arg);
}
- if (!ok) {
- delete f;
+ if (f->arguments().size() < function->arguments().size())
continue;
- }
// There is no base class in the target language to inherit from here, so
// the template instantiation is the class that implements the function.
@@ -2816,27 +2864,11 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
// on the inherited functions.
f->setDeclaringClass(subclass);
-
- if (f->isConstructor() && subclass->isTypeDef()) {
+ if (f->isConstructor()) {
+ if (!subclass->isTypeDef())
+ continue;
f->setName(subclass->name());
f->setOriginalName(subclass->name());
- } else if (f->isConstructor()) {
- delete f;
- continue;
- }
-
- // if the instantiation has a function named the same as an existing
- // function we have shadowing so we need to skip it.
- bool found = false;
- for (int i = 0; i < funcs.size(); ++i) {
- if (funcs.at(i)->name() == f->name()) {
- found = true;
- continue;
- }
- }
- if (found) {
- delete f;
- continue;
}
ComplexTypeEntry* te = subclass->typeEntry();
@@ -2863,7 +2895,27 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
te->addFunctionModification(mod);
}
- subclass->addFunction(f);
+ subclass->addFunction(f.take());
+ }
+
+ const AbstractMetaFieldList &subClassFields = subclass->fields();
+ const AbstractMetaFieldList &templateClassFields = templateClass->fields();
+ for (const AbstractMetaField *field : templateClassFields) {
+ // If the field is modified or the instantiation has a field named
+ // the same as an existing field we have shadowing, so we need to skip it.
+ if (field->isModifiedRemoved(TypeSystem::All)
+ || field->attributes().testFlag(AbstractMetaAttributes::Static)
+ || AbstractMetaField::find(subClassFields, field->name()) != nullptr) {
+ continue;
+ }
+
+ QScopedPointer<AbstractMetaField> f(field->copy());
+ f->setEnclosingClass(subclass);
+ AbstractMetaType *fieldType = inheritTemplateType(templateTypes, field->type());
+ if (!fieldType)
+ continue;
+ f->replaceType(fieldType);
+ subclass->addField(f.take());
}
subclass->setTemplateBaseClass(templateClass);
@@ -2878,9 +2930,9 @@ void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass,
const QStringList &declarations)
{
for (int i = 0; i < declarations.size(); ++i) {
- QString p = declarations.at(i);
+ const QString &p = declarations.at(i);
- QStringList l = p.split(QLatin1String(" "));
+ QStringList l = p.split(QLatin1Char(' '));
QStringList qualifiedScopeName = currentScope()->qualifiedName();
@@ -2925,8 +2977,8 @@ void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass,
static AbstractMetaFunction* findCopyCtor(AbstractMetaClass* cls)
{
- AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::Invisible);
- functions << cls->queryFunctions(AbstractMetaClass::Visible);
+
+ const auto &functions = cls->functions();
for (AbstractMetaFunction *f : qAsConst(functions)) {
const AbstractMetaFunction::FunctionType t = f->functionType();
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
index a0ca71b94..01806f6b4 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h
@@ -38,7 +38,10 @@ QT_FORWARD_DECLARE_CLASS(QIODevice)
class AbstractMetaBuilderPrivate;
class AbstractMetaClass;
+class AbstractMetaType;
class AbstractMetaEnumValue;
+class TypeInfo;
+class TypeEntry;
class AbstractMetaBuilder
{
@@ -61,6 +64,7 @@ public:
AbstractMetaClassList smartPointers() const;
AbstractMetaFunctionList globalFunctions() const;
AbstractMetaEnumList globalEnums() const;
+ AbstractMetaEnum *findEnum(const TypeEntry *typeEntry) const;
/**
* Sorts a list of classes topologically, if an AbstractMetaClass object
@@ -83,6 +87,16 @@ public:
*/
void setGlobalHeader(const QString& globalHeader);
+ static AbstractMetaType *translateType(const TypeInfo &_typei,
+ AbstractMetaClass *currentClass = nullptr,
+ bool resolveType = true,
+ QString *errorMessage = nullptr);
+ static AbstractMetaType *translateType(const QString &t,
+ AbstractMetaClass *currentClass = nullptr,
+ bool resolveType = true,
+ QString *errorMessage = nullptr);
+
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
#endif
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
index 59e3cfc94..ec55d1b47 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h
@@ -60,11 +60,12 @@ public:
ScopeModelItem currentScope() const { return m_scopes.constLast(); }
- AbstractMetaClass *argumentToClass(ArgumentModelItem);
+ AbstractMetaClass *argumentToClass(const ArgumentModelItem &);
void addAbstractMetaClass(AbstractMetaClass *cls);
AbstractMetaClass *traverseTypeDef(const FileModelItem &dom,
const TypeDefModelItem &typeDef);
+ void traverseTypesystemTypedefs();
AbstractMetaClass *traverseClass(const FileModelItem &dom,
const ClassModelItem &item);
AbstractMetaClass *currentTraversedClass(ScopeModelItem item);
@@ -74,9 +75,9 @@ public:
bool setupInheritance(AbstractMetaClass *metaClass);
AbstractMetaClass *traverseNamespace(const FileModelItem &dom,
const NamespaceModelItem &item);
- AbstractMetaEnum *traverseEnum(EnumModelItem item, AbstractMetaClass *enclosing,
+ AbstractMetaEnum *traverseEnum(const EnumModelItem &item, AbstractMetaClass *enclosing,
const QSet<QString> &enumsDeclarations);
- void traverseEnums(ScopeModelItem item, AbstractMetaClass *parent,
+ void traverseEnums(const ScopeModelItem &item, AbstractMetaClass *parent,
const QStringList &enumsDeclarations);
AbstractMetaFunctionList classFunctionList(const ScopeModelItem &scopeItem,
bool *constructorRejected);
@@ -85,18 +86,18 @@ public:
bool *constructorRejected);
void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
void applyFunctionModifications(AbstractMetaFunction* func);
- void traverseFields(ScopeModelItem item, AbstractMetaClass *parent);
- void traverseStreamOperator(FunctionModelItem functionItem);
- void traverseOperatorFunction(FunctionModelItem item);
+ void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
+ void traverseStreamOperator(const FunctionModelItem &functionItem);
+ void traverseOperatorFunction(const FunctionModelItem &item);
AbstractMetaFunction* traverseFunction(const AddedFunction &addedFunc);
AbstractMetaFunction* traverseFunction(const AddedFunction &addedFunc,
AbstractMetaClass *metaClass);
- AbstractMetaFunction *traverseFunction(FunctionModelItem function);
- AbstractMetaField *traverseField(VariableModelItem field,
+ AbstractMetaFunction *traverseFunction(const FunctionModelItem &function);
+ AbstractMetaField *traverseField(const VariableModelItem &field,
const AbstractMetaClass *cls);
void checkFunctionModifications();
- void registerHashFunction(FunctionModelItem functionItem);
- void registerToStringCapability(FunctionModelItem functionItem);
+ void registerHashFunction(const FunctionModelItem &functionItem);
+ void registerToStringCapability(const FunctionModelItem &functionItem);
/**
* A conversion operator function should not have its owner class as
@@ -118,12 +119,19 @@ public:
void setupFunctionDefaults(AbstractMetaFunction *metaFunction,
AbstractMetaClass *metaClass);
- QString fixDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
+ QString fixDefaultValue(const ArgumentModelItem &item, AbstractMetaType *type,
AbstractMetaFunction *fnc, AbstractMetaClass *,
int argumentIndex);
AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo);
AbstractMetaType *translateType(const TypeInfo &type,
- bool resolveType = true);
+ bool resolveType = true,
+ QString *errorMessage = nullptr);
+ static AbstractMetaType *translateTypeStatic(const TypeInfo &type,
+ AbstractMetaClass *current,
+ AbstractMetaBuilderPrivate *d = nullptr,
+ bool resolveType = true,
+ QString *errorMessageIn = nullptr);
+
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
AbstractMetaClass *findTemplateClass(const QString& name, const AbstractMetaClass *context,
@@ -135,9 +143,8 @@ public:
bool inheritTemplate(AbstractMetaClass *subclass,
const AbstractMetaClass *templateClass,
const TypeInfo &info);
- AbstractMetaType *inheritTemplateType(const QVector<AbstractMetaType *> &templateTypes,
- const AbstractMetaType *metaType,
- bool *ok = Q_NULLPTR);
+ AbstractMetaType *inheritTemplateType(const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaType *metaType);
bool isQObject(const FileModelItem &dom, const QString &qualifiedName);
bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName);
@@ -161,8 +168,6 @@ public:
AbstractMetaFunctionList m_globalFunctions;
AbstractMetaEnumList m_globalEnums;
- QSet<const TypeEntry *> m_usedTypes;
-
typedef QMap<QString, AbstractMetaBuilder::RejectReason> RejectMap;
RejectMap m_rejectedClasses;
@@ -170,11 +175,7 @@ public:
RejectMap m_rejectedFunctions;
RejectMap m_rejectedFields;
- QList<AbstractMetaEnum *> m_enums;
-
- QList<QPair<AbstractMetaArgument *, AbstractMetaFunction *> > m_enumDefaultArguments;
-
- QHash<QString, AbstractMetaEnumValue *> m_enumValues;
+ QHash<const TypeEntry *, AbstractMetaEnum *> m_enums;
AbstractMetaClass *m_currentClass;
QList<ScopeModelItem> m_scopes;
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
index 5be7050bf..c65d7e0bd 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp
@@ -27,10 +27,13 @@
****************************************************************************/
#include "abstractmetalang.h"
+#include "messages.h"
#include "reporthandler.h"
#include "typedatabase.h"
#include "typesystem.h"
+#include <parser/codemodel.h>
+
#ifndef QT_NO_DEBUG_STREAM
# include <QtCore/QMetaEnum>
# include <QtCore/QMetaObject>
@@ -55,6 +58,16 @@ QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa)
}
#endif // !QT_NO_DEBUG_STREAM
+template <class MetaClass>
+MetaClass *findByName(QVector<MetaClass *> haystack, QStringView needle)
+{
+ for (MetaClass *c : haystack) {
+ if (c->name() == needle)
+ return c;
+ }
+ return nullptr;
+}
+
/*******************************************************************************
* AbstractMetaVariable
*/
@@ -112,8 +125,8 @@ void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes &
AbstractMetaType::AbstractMetaType() :
m_constant(false),
+ m_volatile(false),
m_cppInstantiation(true),
- m_indirections(0),
m_reserved(0)
{
}
@@ -155,8 +168,9 @@ AbstractMetaType *AbstractMetaType::copy() const
cpy->setTypeUsagePattern(typeUsagePattern());
cpy->setConstant(isConstant());
+ cpy->setVolatile(isVolatile());
cpy->setReferenceType(referenceType());
- cpy->setIndirections(indirections());
+ cpy->setIndirectionsV(indirectionsV());
cpy->setInstantiations(instantiations());
cpy->setArrayElementCount(arrayElementCount());
cpy->setOriginalTypeDescription(originalTypeDescription());
@@ -278,6 +292,26 @@ bool AbstractMetaType::hasTemplateChildren() const
return false;
}
+bool AbstractMetaType::equals(const AbstractMetaType &rhs) const
+{
+ if (m_typeEntry != rhs.m_typeEntry || m_constant != rhs.m_constant
+ || m_referenceType != rhs.m_referenceType
+ || m_indirections != rhs.m_indirections
+ || m_instantiations.size() != rhs.m_instantiations.size()
+ || m_arrayElementCount != rhs.m_arrayElementCount) {
+ return false;
+ }
+ if ((m_arrayElementType != nullptr) != (rhs.m_arrayElementType != nullptr)
+ || (m_arrayElementType != nullptr && !m_arrayElementType->equals(*rhs.m_arrayElementType))) {
+ return false;
+ }
+ for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
+ if (!m_instantiations.at(i)->equals(*rhs.m_instantiations.at(i)))
+ return false;
+ }
+ return true;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaType *at)
{
@@ -291,16 +325,32 @@ QDebug operator<<(QDebug d, const AbstractMetaType *at)
d << ", typeEntry=" << at->typeEntry() << ", signature=\""
<< at->cppSignature() << "\", pattern="
<< at->typeUsagePattern();
- if (at->indirections())
- d << ", indirections=" << at->indirections();
+ const auto indirections = at->indirectionsV();
+ if (!indirections.isEmpty()) {
+ d << ", indirections=";
+ for (auto i : indirections)
+ d << ' ' << TypeInfo::indirectionKeyword(i);
+ }
if (at->referenceType())
d << ", reftype=" << at->referenceType();
if (at->isConstant())
d << ", [const]";
+ if (at->isVolatile())
+ d << ", [volatile]";
if (at->isArray()) {
d << ", array of \"" << at->arrayElementType()->cppSignature()
<< "\", arrayElementCount=" << at->arrayElementCount();
}
+ const auto &instantiations = at->instantiations();
+ if (const int instantiationsSize = instantiations.size()) {
+ d << ", instantiations[" << instantiationsSize << "]=<";
+ for (int i = 0; i < instantiationsSize; ++i) {
+ if (i)
+ d << ", ";
+ d << instantiations.at(i);
+ }
+ }
+ d << '>';
}
} else {
d << '0';
@@ -357,7 +407,8 @@ AbstractMetaFunction::AbstractMetaFunction()
m_userAdded(false),
m_explicit(false),
m_pointerOperator(false),
- m_isCallOperator(false)
+ m_isCallOperator(false),
+ m_generateExceptionHandling(false)
{
}
@@ -475,6 +526,8 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
if (type())
cpy->setType(type()->copy());
cpy->setConstant(isConstant());
+ cpy->setExceptionSpecification(m_exceptionSpecification);
+ cpy->setGenerateExceptionHandling(m_generateExceptionHandling);
for (AbstractMetaArgument *arg : m_arguments)
cpy->addArgument(arg->copy());
@@ -504,18 +557,17 @@ QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStrin
if (arguments.size() == resolvedArguments.size()) {
QString signature = name() + QLatin1Char('(') + resolvedArguments.join(QLatin1Char(',')) + QLatin1Char(')');
return QStringList(TypeDatabase::normalizedSignature(signature));
- } else {
- QStringList returned;
-
- AbstractMetaArgument *argument = arguments.at(resolvedArguments.size());
- QStringList minimalTypeSignature = argument->type()->minimalSignature().split(QLatin1String("::"));
- for (int i = 0; i < minimalTypeSignature.size(); ++i) {
- returned += introspectionCompatibleSignatures(QStringList(resolvedArguments)
- << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::")));
- }
+ }
+ QStringList returned;
- return returned;
+ AbstractMetaArgument *argument = arguments.at(resolvedArguments.size());
+ QStringList minimalTypeSignature = argument->type()->minimalSignature().split(QLatin1String("::"));
+ for (int i = 0; i < minimalTypeSignature.size(); ++i) {
+ returned += introspectionCompatibleSignatures(QStringList(resolvedArguments)
+ << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::")));
}
+
+ return returned;
}
QString AbstractMetaFunction::signature() const
@@ -674,38 +726,54 @@ bool AbstractMetaFunction::argumentRemoved(int key) const
return false;
}
-bool AbstractMetaFunction::isVirtualSlot() const
+bool AbstractMetaFunction::isDeprecated() const
{
const FunctionModificationList &modifications = this->modifications(declaringClass());
for (const FunctionModification &modification : modifications) {
- if (modification.isVirtualSlot())
+ if (modification.isDeprecated())
return true;
}
-
return false;
}
-bool AbstractMetaFunction::isDeprecated() const
+// Auto-detect whether a function should be wrapped into
+// Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS, that is, temporarily release
+// the GIL (global interpreter lock). Doing so is required for any thread-wait
+// functions, anything that might call a virtual function (potentially
+// reimplemented in Python), and recommended for lengthy I/O or similar.
+// It has performance costs, though.
+bool AbstractMetaFunction::autoDetectAllowThread() const
{
- const FunctionModificationList &modifications = this->modifications(declaringClass());
- for (const FunctionModification &modification : modifications) {
- if (modification.isDeprecated())
- return true;
- }
- return false;
+ // Disallow for simple getter functions.
+ const bool maybeGetter = m_constant != 0 && m_type != nullptr
+ && m_arguments.isEmpty();
+ return !maybeGetter;
}
bool AbstractMetaFunction::allowThread() const
{
- const FunctionModificationList &modifications = this->modifications(declaringClass());
- for (const FunctionModification &modification : modifications) {
- if (modification.allowThread())
- return true;
+ using AllowThread = TypeSystem::AllowThread;
+
+ if (m_cachedAllowThread < 0) {
+ AllowThread allowThread = AllowThread::Auto;
+ // Find a modification that specifies allowThread
+ const FunctionModificationList &modifications = this->modifications(declaringClass());
+ for (const FunctionModification &modification : modifications) {
+ if (modification.allowThread() != AllowThread::Unspecified) {
+ allowThread = modification.allowThread();
+ break;
+ }
+ }
+
+ m_cachedAllowThread = allowThread == AllowThread::Allow
+ || (allowThread == AllowThread::Auto && autoDetectAllowThread()) ? 1 : 0;
+
+ if (m_cachedAllowThread == 0)
+ qCDebug(lcShiboken).noquote() << msgDisallowThread(this);
}
- return false;
+ return m_cachedAllowThread > 0;
}
-
TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const
{
const FunctionModificationList &modifications = this->modifications(cls);
@@ -751,6 +819,18 @@ QString AbstractMetaFunction::typeReplaced(int key) const
return QString();
}
+bool AbstractMetaFunction::isModifiedToArray(int argumentIndex) const
+{
+ const FunctionModificationList &modifications = this->modifications(declaringClass());
+ for (const FunctionModification &modification : modifications) {
+ for (const ArgumentModification &argumentModification : modification.argument_mods) {
+ if (argumentModification.index == argumentIndex && argumentModification.array != 0)
+ return true;
+ }
+ }
+ return false;
+}
+
QString AbstractMetaFunction::minimalSignature() const
{
if (!m_cachedMinimalSignature.isEmpty())
@@ -809,8 +889,9 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC
while (implementor) {
mods += implementor->typeEntry()->functionModifications(minimalSignature());
if ((implementor == implementor->baseClass()) ||
- (implementor == implementingClass() && (mods.size() > 0)))
+ (implementor == implementingClass() && !mods.isEmpty())) {
break;
+ }
const AbstractMetaClassList &interfaces = implementor->interfaces();
for (const AbstractMetaClass *interface : interfaces)
mods += this->modifications(interface);
@@ -873,14 +954,24 @@ bool AbstractMetaFunction::hasSignatureModifications() const
return false;
}
-bool AbstractMetaFunction::isConversionOperator(QString funcName)
+bool AbstractMetaFunction::isConversionOperator(const QString& funcName)
{
static const QRegularExpression opRegEx(QStringLiteral("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$"));
Q_ASSERT(opRegEx.isValid());
return opRegEx.match(funcName).hasMatch();
}
-bool AbstractMetaFunction::isOperatorOverload(QString funcName)
+ExceptionSpecification AbstractMetaFunction::exceptionSpecification() const
+{
+ return m_exceptionSpecification;
+}
+
+void AbstractMetaFunction::setExceptionSpecification(ExceptionSpecification e)
+{
+ m_exceptionSpecification = e;
+}
+
+bool AbstractMetaFunction::isOperatorOverload(const QString& funcName)
{
if (isConversionOperator(funcName))
return true;
@@ -1038,6 +1129,13 @@ bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b)
return a->signature() < b->signature();
}
+AbstractMetaFunction *
+AbstractMetaFunction::find(const AbstractMetaFunctionList &haystack,
+ const QString &needle)
+{
+ return findByName(haystack, needle);
+}
+
#ifndef QT_NO_DEBUG_STREAM
static inline void formatMetaFunctionBrief(QDebug &d, const AbstractMetaFunction *af)
{
@@ -1046,7 +1144,20 @@ static inline void formatMetaFunctionBrief(QDebug &d, const AbstractMetaFunction
void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const
{
- d << m_functionType << ' ' << m_type << ' ' << m_name << '(';
+ d << m_functionType << ' ' << m_type << ' ' << m_name;
+ switch (m_exceptionSpecification) {
+ case ExceptionSpecification::Unknown:
+ break;
+ case ExceptionSpecification::NoExcept:
+ d << " noexcept";
+ break;
+ case ExceptionSpecification::Throws:
+ d << " throw(...)";
+ break;
+ }
+ if (m_generateExceptionHandling)
+ d << "[generate-exception-handling]";
+ d << '(';
for (int i = 0, count = m_arguments.size(); i < count; ++i) {
if (i)
d << ", ";
@@ -1106,7 +1217,6 @@ AbstractMetaClass::AbstractMetaClass()
: m_hasVirtuals(false),
m_isPolymorphic(false),
m_hasNonpublic(false),
- m_hasVirtualSlots(false),
m_hasNonPrivateConstructor(false),
m_hasPrivateConstructor(false),
m_functionsFixed(false),
@@ -1330,11 +1440,8 @@ void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions)
for (AbstractMetaFunction *f : qAsConst(m_functions)) {
f->setOwnerClass(this);
-
- m_hasVirtualSlots = m_hasVirtualSlots || f->isVirtualSlot();
- m_hasVirtuals = m_hasVirtuals || f->isVirtualSlot() || hasVirtualDestructor();
- m_isPolymorphic = m_isPolymorphic || m_hasVirtuals;
- m_hasNonpublic = m_hasNonpublic || !f->isPublic();
+ if (!f->isPublic())
+ m_hasNonpublic = true;
}
}
@@ -1368,8 +1475,7 @@ void AbstractMetaClass::addFunction(AbstractMetaFunction *function)
else
Q_ASSERT(false); //memory leak
- m_hasVirtualSlots |= function->isVirtualSlot();
- m_hasVirtuals |= function->isVirtual() || function->isVirtualSlot() || hasVirtualDestructor();
+ m_hasVirtuals |= function->isVirtual() || hasVirtualDestructor();
m_isPolymorphic |= m_hasVirtuals;
m_hasNonpublic |= !function->isPublic();
}
@@ -1432,11 +1538,7 @@ bool AbstractMetaClass::hasFunction(const QString &str) const
const AbstractMetaFunction* AbstractMetaClass::findFunction(const QString& functionName) const
{
- for (const AbstractMetaFunction *f : m_functions) {
- if (f->name() == functionName)
- return f;
- }
- return 0;
+ return AbstractMetaFunction::find(m_functions, functionName);
}
bool AbstractMetaClass::hasProtectedFunctions() const
@@ -1511,6 +1613,13 @@ void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList&
metaClassBaseTemplateInstantiations()->insert(this, instantiations);
}
+// Does any of the base classes require deletion in the main thread?
+bool AbstractMetaClass::deleteInMainThread() const
+{
+ return typeEntry()->deleteInMainThread()
+ || (m_baseClass && m_baseClass->deleteInMainThread());
+}
+
static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func)
{
for (const AbstractMetaFunction *f : l) {
@@ -1537,6 +1646,11 @@ AbstractMetaField *AbstractMetaField::copy() const
return returned;
}
+AbstractMetaField *AbstractMetaField::find(const AbstractMetaFieldList &haystack,
+ const QString &needle)
+{
+ return findByName(haystack, needle);
+}
/*******************************************************************************
* Indicates that this field has a modification that removes it
*/
@@ -1723,27 +1837,22 @@ QDebug operator<<(QDebug d, const AbstractMetaEnum *ae)
bool AbstractMetaClass::hasConstructors() const
{
- return queryFunctions(Constructors).size();
+ return AbstractMetaClass::queryFirstFunction(m_functions, Constructors) != nullptr;
}
-bool AbstractMetaClass::hasCopyConstructor() const
+const AbstractMetaFunction *AbstractMetaClass::copyConstructor() const
{
- const AbstractMetaFunctionList &ctors = queryFunctions(Constructors);
- for (const AbstractMetaFunction* ctor : ctors) {
- if (ctor->functionType() == AbstractMetaFunction::CopyConstructorFunction)
- return true;
+ for (const AbstractMetaFunction *f : m_functions) {
+ if (f->functionType() == AbstractMetaFunction::CopyConstructorFunction)
+ return f;
}
- return false;
+ return nullptr;
}
bool AbstractMetaClass::hasPrivateCopyConstructor() const
{
- const AbstractMetaFunctionList &ctors = queryFunctions(Constructors);
- for (const AbstractMetaFunction *ctor : ctors) {
- if (ctor->functionType() == AbstractMetaFunction::CopyConstructorFunction && ctor->isPrivate())
- return true;
- }
- return false;
+ const AbstractMetaFunction *copyCt = copyConstructor();
+ return copyCt && copyCt->isPrivate();
}
void AbstractMetaClass::addDefaultConstructor()
@@ -1801,85 +1910,122 @@ bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const
return functions_contains(m_functions, f);
}
+bool AbstractMetaClass::generateExceptionHandling() const
+{
+ return queryFirstFunction(m_functions, AbstractMetaClass::Visible
+ | AbstractMetaClass::GenerateExceptionHandling) != nullptr;
+}
/* Goes through the list of functions and returns a list of all
functions matching all of the criteria in \a query.
*/
-AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions query) const
+bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQueryOptions query)
{
- AbstractMetaFunctionList functions;
-
- for (AbstractMetaFunction *f : m_functions) {
- if ((query & NotRemovedFromTargetLang) && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode))
- continue;
+ if ((query & NotRemovedFromTargetLang)
+ && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode)) {
+ return false;
+ }
- if ((query & NotRemovedFromTargetLang) && f->isVirtual() && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode))
- continue;
+ if ((query & NotRemovedFromTargetLang) && f->isVirtual()
+ && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) {
+ return false;
+ }
- if ((query & Visible) && f->isPrivate())
- continue;
+ if ((query & Visible) && f->isPrivate())
+ return false;
- if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang())
- continue;
+ if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang())
+ return false;
- if ((query & Invisible) && !f->isPrivate())
- continue;
+ if ((query & Invisible) && !f->isPrivate())
+ return false;
- if ((query & Empty) && !f->isEmptyFunction())
- continue;
+ if ((query & Empty) && !f->isEmptyFunction())
+ return false;
- if ((query & WasPublic) && !f->wasPublic())
- continue;
+ if ((query & WasPublic) && !f->wasPublic())
+ return false;
- if ((query & ClassImplements) && f->ownerClass() != f->implementingClass())
- continue;
+ if ((query & ClassImplements) && f->ownerClass() != f->implementingClass())
+ return false;
- if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang())
- continue;
+ if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang())
+ return false;
- if ((query & VirtualInCppFunctions) && !f->isVirtual())
- continue;
+ if ((query & VirtualInCppFunctions) && !f->isVirtual())
+ return false;
- if ((query & Signals) && (!f->isSignal()))
- continue;
+ if ((query & Signals) && (!f->isSignal()))
+ return false;
- if ((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass()))
- continue;
+ if ((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass()))
+ return false;
- if (!(query & Constructors) && f->isConstructor())
- continue;
+ if (!(query & Constructors) && f->isConstructor())
+ return false;
- // Destructors are never included in the functions of a class currently
- /*
+ // Destructors are never included in the functions of a class currently
+ /*
if ((query & Destructors) && (!f->isDestructor()
|| f->ownerClass() != f->implementingClass())
|| f->isDestructor() && (query & Destructors) == 0) {
- continue;
+ return false;
}*/
- if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal()))
- continue;
+ if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal()))
+ return false;
- if ((query & NonStaticFunctions) && (f->isStatic()))
- continue;
+ if ((query & NonStaticFunctions) && (f->isStatic()))
+ return false;
- if ((query & NormalFunctions) && (f->isSignal()))
- continue;
+ if ((query & NormalFunctions) && (f->isSignal()))
+ return false;
- if ((query & OperatorOverloads) && !f->isOperatorOverload())
- continue;
+ if ((query & OperatorOverloads) && !f->isOperatorOverload())
+ return false;
+
+ if ((query & GenerateExceptionHandling) && !f->generateExceptionHandling())
+ return false;
+
+ return true;
+}
- functions << f;
+AbstractMetaFunctionList AbstractMetaClass::queryFunctionList(const AbstractMetaFunctionList &list,
+ FunctionQueryOptions query)
+{
+ AbstractMetaFunctionList result;
+ for (AbstractMetaFunction *f : list) {
+ if (queryFunction(f, query))
+ result.append(f);
+ }
+ return result;
+}
+
+const AbstractMetaFunction *AbstractMetaClass::queryFirstFunction(const AbstractMetaFunctionList &list,
+ FunctionQueryOptions query)
+{
+ AbstractMetaFunctionList result;
+ for (AbstractMetaFunction *f : list) {
+ if (queryFunction(f, query))
+ return f;
}
+ return nullptr;
+}
- return functions;
+AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions query) const
+{
+ return AbstractMetaClass::queryFunctionList(m_functions, query);
}
bool AbstractMetaClass::hasSignals() const
{
- return cppSignalFunctions().size() > 0;
+ return queryFirstFunction(m_functions, Signals | Visible | NotRemovedFromTargetLang) != nullptr;
}
+AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const
+{
+ return queryFunctions(Signals | Visible | NotRemovedFromTargetLang);
+}
/**
* Adds the specified interface to this class by adding all the
@@ -1932,13 +2078,15 @@ void AbstractMetaClass::setInterfaces(const AbstractMetaClassList &interfaces)
}
}
+AbstractMetaField *AbstractMetaClass::findField(const QString &name) const
+{
+ return AbstractMetaField::find(m_fields, name);
+}
AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName)
{
- for (AbstractMetaEnum *e : qAsConst(m_enums)) {
- if (e->name() == enumName)
- return e;
- }
+ if (AbstractMetaEnum *e = findByName(m_enums, enumName))
+ return e;
if (typeEntry()->designatedInterface())
return extractInterface()->findEnum(enumName);
@@ -2002,8 +2150,8 @@ void AbstractMetaClass::fixFunctions()
{
if (m_functionsFixed)
return;
- else
- m_functionsFixed = true;
+
+ m_functionsFixed = true;
AbstractMetaClass *superClass = baseClass();
AbstractMetaFunctionList funcs = functions();
@@ -2046,8 +2194,7 @@ void AbstractMetaClass::fixFunctions()
// we generally don't care about private functions, but we have to get the ones that are
// virtual in case they override abstract functions.
bool add = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction());
- for (int fi = 0; fi < funcs.size(); ++fi) {
- AbstractMetaFunction *f = funcs.at(fi);
+ for (AbstractMetaFunction *f : funcs) {
if (f->isRemovedFromAllLanguages(f->implementingClass()))
continue;
@@ -2114,7 +2261,8 @@ void AbstractMetaClass::fixFunctions()
if (mod.isNonFinal()) {
hasNonFinalModifier = true;
break;
- } else if (mod.isPrivate()) {
+ }
+ if (mod.isPrivate()) {
isBaseImplPrivate = true;
break;
}
@@ -2222,6 +2370,8 @@ QString AbstractMetaType::formatSignature(bool minimal) const
QString result;
if (isConstant())
result += QLatin1String("const ");
+ if (isVolatile())
+ result += QLatin1String("volatile ");
if (isArray()) {
// Build nested array dimensions a[2][3] in correct order
result += m_arrayElementType->minimalSignature();
@@ -2245,10 +2395,10 @@ QString AbstractMetaType::formatSignature(bool minimal) const
result += QLatin1String(" >");
}
- if (!minimal && (m_indirections != 0 || m_referenceType != NoReference))
+ if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference))
result += QLatin1Char(' ');
- if (m_indirections)
- result += QString(m_indirections, QLatin1Char('*'));
+ for (Indirection i : m_indirections)
+ result += TypeInfo::indirectionKeyword(i);
switch (referenceType()) {
case NoReference:
break;
@@ -2376,6 +2526,8 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
d << " [final]";
if (ac->m_baseClass)
d << ", inherits \"" << ac->m_baseClass->name() << '"';
+ if (ac->m_templateBaseClass)
+ d << ", inherits template \"" << ac->m_templateBaseClass->name() << '"';
const AbstractMetaEnumList &enums = ac->enums();
if (!enums.isEmpty())
d << ", enums[" << enums.size() << "]=" << enums;
@@ -2406,6 +2558,18 @@ QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
}
d << ')';
}
+ const auto &templateArguments = ac->templateArguments();
+ if (const int count = templateArguments.size()) {
+ d << ", templateArguments=[" << count << "](";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ d << ", ";
+ d << templateArguments.at(i);
+ }
+ d << ')';
+ }
+
+
} else {
d << '0';
}
diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h
index d1a0fbf88..aaefa32d5 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken2/ApiExtractor/abstractmetalang.h
@@ -288,6 +288,7 @@ class AbstractMetaType
{
Q_GADGET
public:
+ typedef QVector<Indirection> Indirections;
enum TypeUsagePattern {
InvalidPattern,
@@ -436,6 +437,9 @@ public:
m_constant = constant;
}
+ bool isVolatile() const { return m_volatile; }
+ void setVolatile(bool v) { m_volatile = v; }
+
bool isConstRef() const;
ReferenceType referenceType() const { return m_referenceType; }
@@ -443,16 +447,21 @@ public:
int actualIndirections() const
{
- return m_indirections + (m_referenceType == LValueReference ? 1 : 0);
- }
- int indirections() const
- {
- return m_indirections;
+ return m_indirections.size() + (m_referenceType == LValueReference ? 1 : 0);
}
+
+ Indirections indirectionsV() const { return m_indirections; }
+ void setIndirectionsV(const Indirections &i) { m_indirections = i; }
+ void clearIndirections() { m_indirections.clear(); }
+
+ // "Legacy"?
+ int indirections() const { return m_indirections.size(); }
void setIndirections(int indirections)
{
- m_indirections = indirections;
+ m_indirections = Indirections(indirections, Indirection::Pointer);
}
+ void addIndirection(Indirection i = Indirection::Pointer)
+ { m_indirections.append(i); }
void setArrayElementCount(int n)
{
@@ -527,6 +536,8 @@ public:
bool hasTemplateChildren() const;
+ bool equals(const AbstractMetaType &rhs) const;
+
private:
TypeUsagePattern determineUsagePattern() const;
QString formatSignature(bool minimal) const;
@@ -541,18 +552,25 @@ private:
int m_arrayElementCount = -1;
const AbstractMetaType *m_arrayElementType = nullptr;
const AbstractMetaType *m_originalTemplateType = nullptr;
+ Indirections m_indirections;
TypeUsagePattern m_pattern = InvalidPattern;
uint m_constant : 1;
+ uint m_volatile : 1;
uint m_cppInstantiation : 1;
- int m_indirections : 4;
- uint m_reserved : 26; // unused
+ uint m_reserved : 29; // unused
+
ReferenceType m_referenceType = NoReference;
AbstractMetaTypeList m_children;
Q_DISABLE_COPY(AbstractMetaType)
};
+inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2)
+{ return t1.equals(t2); }
+inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2)
+{ return !t1.equals(t2); }
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaType *at);
#endif
@@ -650,6 +668,13 @@ public:
m_originalExpression = expr;
}
+ bool hasDefaultValueExpression() const
+ { return !m_originalExpression.isEmpty() || !m_expression.isEmpty(); }
+ bool hasUnmodifiedDefaultValueExpression() const
+ { return !m_originalExpression.isEmpty() && m_originalExpression == m_expression; }
+ bool hasModifiedDefaultValueExpression() const
+ { return !m_expression.isEmpty() && m_originalExpression != m_expression; }
+
QString toString() const
{
return type()->name() + QLatin1Char(' ') + AbstractMetaVariable::name() +
@@ -709,6 +734,9 @@ public:
AbstractMetaField *copy() const;
+ static AbstractMetaField *
+ find(const AbstractMetaFieldList &haystack, const QString &needle);
+
private:
mutable AbstractMetaFunction *m_getter = nullptr;
mutable AbstractMetaFunction *m_setter = nullptr;
@@ -816,13 +844,20 @@ public:
return m_explicit;
}
- static bool isConversionOperator(QString funcName);
+ static bool isConversionOperator(const QString& funcName);
+
+ ExceptionSpecification exceptionSpecification() const;
+ void setExceptionSpecification(ExceptionSpecification e);
+
+ bool generateExceptionHandling() const { return m_generateExceptionHandling; }
+ void setGenerateExceptionHandling(bool g) { m_generateExceptionHandling = g; }
+
bool isConversionOperator() const
{
return isConversionOperator(originalName());
}
- static bool isOperatorOverload(QString funcName);
+ static bool isOperatorOverload(const QString& funcName);
bool isOperatorOverload() const
{
return isOperatorOverload(originalName());
@@ -1000,9 +1035,8 @@ public:
// Returns the ownership rules for the given argument in the given context
TypeSystem::Ownership ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int idx) const;
- bool isVirtualSlot() const;
-
QString typeReplaced(int argument_index) const;
+ bool isModifiedToArray(int argumentIndex) const;
bool isRemovedFromAllLanguages(const AbstractMetaClass *) const;
bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const;
bool argumentRemoved(int) const;
@@ -1057,11 +1091,16 @@ public:
bool isCallOperator() const;
+ static AbstractMetaFunction *
+ find(const AbstractMetaFunctionList &haystack, const QString &needle);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebugVerbose(QDebug &d) const;
#endif
private:
+ bool autoDetectAllowThread() const;
+
QString m_name;
QString m_originalName;
mutable QString m_cachedMinimalSignature;
@@ -1082,6 +1121,9 @@ private:
uint m_explicit : 1;
uint m_pointerOperator : 1;
uint m_isCallOperator : 1;
+ uint m_generateExceptionHandling: 1;
+ mutable int m_cachedAllowThread = -1;
+ ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::CompareResult)
@@ -1246,7 +1288,8 @@ public:
VirtualInCppFunctions = 0x0020000, // Only functions that are virtual in C++
VirtualInTargetLangFunctions = 0x0080000, // Only functions which are virtual in TargetLang
NotRemovedFromTargetLang = 0x0400000, // Only functions that have not been removed from TargetLang
- OperatorOverloads = 0x2000000 // Only functions that are operator overloads
+ OperatorOverloads = 0x2000000, // Only functions that are operator overloads
+ GenerateExceptionHandling = 0x4000000
};
Q_DECLARE_FLAGS(FunctionQueryOptions, FunctionQueryOption)
Q_FLAG(FunctionQueryOption)
@@ -1286,7 +1329,8 @@ public:
bool hasSignal(const AbstractMetaFunction *f) const;
bool hasConstructors() const;
- bool hasCopyConstructor() const;
+ const AbstractMetaFunction *copyConstructor() const;
+ bool hasCopyConstructor() const { return copyConstructor() != nullptr; }
bool hasPrivateCopyConstructor() const;
void addDefaultConstructor();
@@ -1347,10 +1391,18 @@ public:
return (hasNonPrivateConstructor() || !hasPrivateConstructor()) && !hasPrivateDestructor();
}
+ bool generateExceptionHandling() const;
+
AbstractMetaFunctionList queryFunctionsByName(const QString &name) const;
+ static bool queryFunction(const AbstractMetaFunction *f, FunctionQueryOptions query);
+ static AbstractMetaFunctionList queryFunctionList(const AbstractMetaFunctionList &list,
+ FunctionQueryOptions query);
+ static const AbstractMetaFunction *queryFirstFunction(const AbstractMetaFunctionList &list,
+ FunctionQueryOptions query);
+
AbstractMetaFunctionList queryFunctions(FunctionQueryOptions query) const;
AbstractMetaFunctionList functionsInTargetLang() const;
- inline AbstractMetaFunctionList cppSignalFunctions() const;
+ AbstractMetaFunctionList cppSignalFunctions() const;
AbstractMetaFunctionList implicitConversions() const;
/**
@@ -1383,6 +1435,8 @@ public:
m_fields << field;
}
+ AbstractMetaField *findField(const QString &name) const;
+
AbstractMetaEnumList enums() const
{
return m_enums;
@@ -1478,11 +1532,6 @@ public:
m_forceShellClass = on;
}
- bool hasVirtualSlots() const
- {
- return m_hasVirtualSlots;
- }
-
/**
* Says if the class that declares or inherits a virtual function.
* \return true if the class implements or inherits any virtual methods
@@ -1650,6 +1699,8 @@ public:
return m_hasToStringCapability;
}
+ bool deleteInMainThread() const;
+
static AbstractMetaClass *findClass(const AbstractMetaClassList &classes,
const QString &name);
static AbstractMetaClass *findClass(const AbstractMetaClassList &classes,
@@ -1666,7 +1717,6 @@ private:
uint m_hasVirtuals : 1;
uint m_isPolymorphic : 1;
uint m_hasNonpublic : 1;
- uint m_hasVirtualSlots : 1;
uint m_hasNonPrivateConstructor : 1;
uint m_hasPrivateConstructor : 1;
uint m_functionsFixed : 1;
@@ -1784,11 +1834,4 @@ private:
int m_index = -1;
};
-inline AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const
-{
- return queryFunctions(Signals
- | Visible
- | NotRemovedFromTargetLang);
-}
-
#endif // ABSTRACTMETALANG_H
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp
index 171011cd4..775485c81 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken2/ApiExtractor/apiextractor.cpp
@@ -177,41 +177,9 @@ static const AbstractMetaEnum* findEnumOnClasses(AbstractMetaClassList metaClass
return result;
}
-const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const
-{
- if (!typeEntry)
- return 0;
- const AbstractMetaEnumList &globalEnums = m_builder->globalEnums();
- for (AbstractMetaEnum* metaEnum : globalEnums) {
- if (metaEnum->typeEntry() == typeEntry)
- return metaEnum;
- }
- return findEnumOnClasses(m_builder->classes(), typeEntry);
-}
-
const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const TypeEntry* typeEntry) const
{
- if (!typeEntry)
- return 0;
- if (typeEntry->isFlags())
- return findAbstractMetaEnum(reinterpret_cast<const FlagsTypeEntry*>(typeEntry));
- if (typeEntry->isEnum())
- return findAbstractMetaEnum(reinterpret_cast<const EnumTypeEntry*>(typeEntry));
- return 0;
-}
-
-const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const FlagsTypeEntry* typeEntry) const
-{
- if (!typeEntry)
- return 0;
- return findAbstractMetaEnum(typeEntry->originator());
-}
-
-const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const AbstractMetaType* metaType) const
-{
- if (!metaType)
- return 0;
- return findAbstractMetaEnum(metaType->typeEntry());
+ return m_builder->findEnum(typeEntry);
}
int ApiExtractor::classCount() const
diff --git a/sources/shiboken2/ApiExtractor/apiextractor.h b/sources/shiboken2/ApiExtractor/apiextractor.h
index 674e5a742..ab520c9de 100644
--- a/sources/shiboken2/ApiExtractor/apiextractor.h
+++ b/sources/shiboken2/ApiExtractor/apiextractor.h
@@ -87,10 +87,7 @@ public:
PrimitiveTypeEntryList primitiveTypes() const;
ContainerTypeEntryList containerTypes() const;
- const AbstractMetaEnum* findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const;
const AbstractMetaEnum* findAbstractMetaEnum(const TypeEntry* typeEntry) const;
- const AbstractMetaEnum* findAbstractMetaEnum(const FlagsTypeEntry* typeEntry) const;
- const AbstractMetaEnum* findAbstractMetaEnum(const AbstractMetaType* metaType) const;
int classCount() const;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
index af7f96068..40f915028 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp
@@ -146,6 +146,7 @@ class BuilderPrivate {
public:
typedef QHash<CXCursor, ClassModelItem> CursorClassHash;
typedef QHash<CXCursor, TypeDefModelItem> CursorTypedefHash;
+ typedef QHash<CXType, TypeInfo> TypeInfoHash;
explicit BuilderPrivate(BaseVisitor *bv) : m_baseVisitor(bv), m_model(new CodeModel)
{
@@ -180,9 +181,16 @@ public:
CodeModel::FunctionType t = CodeModel::Normal) const;
FunctionModelItem createMemberFunction(const CXCursor &cursor) const;
void qualifyConstructor(const CXCursor &cursor);
+ TypeInfo createTypeInfoHelper(const CXType &type) const; // uncashed
TypeInfo createTypeInfo(const CXType &type) const;
TypeInfo createTypeInfo(const CXCursor &cursor) const
{ return createTypeInfo(clang_getCursorType(cursor)); }
+ void addTemplateInstantiations(const CXType &type,
+ QString *typeName,
+ TypeInfo *t) const;
+ bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const;
+
+ void addTypeDef(const CXCursor &cursor, const TypeInfo &ti);
TemplateParameterModelItem createTemplateParameter(const CXCursor &cursor) const;
TemplateParameterModelItem createNonTypeTemplateParameter(const CXCursor &cursor) const;
@@ -205,6 +213,8 @@ public:
CursorClassHash m_cursorClassHash;
CursorTypedefHash m_cursorTypedefHash;
+ mutable TypeInfoHash m_typeInfoHash; // Cache type information
+
ClassModelItem m_currentClass;
EnumModelItem m_currentEnum;
FunctionModelItem m_currentFunction;
@@ -247,6 +257,25 @@ bool BuilderPrivate::addClass(const CXCursor &cursor, CodeModel::ClassType t)
return true;
}
+static inline ExceptionSpecification exceptionSpecificationFromClang(int ce)
+{
+ switch (ce) {
+ case CXCursor_ExceptionSpecificationKind_BasicNoexcept:
+ case CXCursor_ExceptionSpecificationKind_ComputedNoexcept:
+ case CXCursor_ExceptionSpecificationKind_DynamicNone: // throw()
+ return ExceptionSpecification::NoExcept;
+ case CXCursor_ExceptionSpecificationKind_Dynamic: // throw(t1..)
+ case CXCursor_ExceptionSpecificationKind_MSAny: // throw(...)
+ return ExceptionSpecification::Throws;
+ default:
+ // CXCursor_ExceptionSpecificationKind_None,
+ // CXCursor_ExceptionSpecificationKind_Unevaluated,
+ // CXCursor_ExceptionSpecificationKind_Uninstantiated
+ break;
+ }
+ return ExceptionSpecification::Unknown;
+}
+
FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
CodeModel::FunctionType t) const
{
@@ -256,10 +285,11 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
name = fixTypeName(name);
FunctionModelItem result(new _FunctionModelItem(m_model, name));
setFileName(cursor, result.data());
- result->setType(createTypeInfo(clang_getCursorResultType(cursor)));
+ result->setType(createTypeInfoHelper(clang_getCursorResultType(cursor)));
result->setFunctionType(t);
result->setScope(m_scope);
result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static);
+ result->setExceptionSpecification(exceptionSpecificationFromClang(clang_getCursorExceptionSpecificationType(cursor)));
switch (clang_getCursorAvailability(cursor)) {
case CXAvailability_Available:
break;
@@ -335,7 +365,7 @@ TemplateParameterModelItem BuilderPrivate::createTemplateParameter(const CXCurso
TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const
{
TemplateParameterModelItem result = createTemplateParameter(cursor);
- result->setType(createTypeInfo(cursor));
+ result->setType(createTypeInfoHelper(clang_getCursorType(cursor)));
return result;
}
@@ -359,38 +389,6 @@ struct ArrayDimensionResult
int position;
};
-static ArrayDimensionResult arrayDimensions(const QString &typeName)
-{
- ArrayDimensionResult result;
- result.position = typeName.indexOf(QLatin1Char('['));
- for (int openingPos = result.position; openingPos != -1; ) {
- const int closingPos = typeName.indexOf(QLatin1Char(']'), openingPos + 1);
- if (closingPos == -1)
- break;
- result.dimensions.append(typeName.midRef(openingPos + 1, closingPos - openingPos - 1));
- openingPos = typeName.indexOf(QLatin1Char('['), closingPos + 1);
- }
- return result;
-}
-
-// Array helpers: Parse "a[2][4]" into a list of dimensions or "" for none
-static QStringList parseArrayArgs(const CXType &type, QString *typeName)
-{
- const ArrayDimensionResult dimensions = arrayDimensions(*typeName);
- Q_ASSERT(!dimensions.dimensions.isEmpty());
-
- QStringList result;
- // get first dimension from clang, preferably.
- // "a[]" is seen as pointer by Clang, set special indicator ""
- const long long size = clang_getArraySize(type);
- result.append(size >= 0 ? QString::number(size) : QString());
- // Parse out remaining dimensions
- for (int i = 1, count = dimensions.dimensions.size(); i < count; ++i)
- result.append(dimensions.dimensions.at(i).toString());
- typeName->truncate(dimensions.position);
- return result;
-}
-
// Create qualified name "std::list<std::string>" -> ("std", "list<std::string>")
static QStringList qualifiedName(const QString &t)
{
@@ -412,71 +410,143 @@ static QStringList qualifiedName(const QString &t)
return result;
}
-TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const
+static bool isArrayType(CXTypeKind k)
+{
+ return k == CXType_ConstantArray || k == CXType_IncompleteArray
+ || k == CXType_VariableArray || k == CXType_DependentSizedArray;
+}
+
+static bool isPointerType(CXTypeKind k)
+{
+ return k == CXType_Pointer || k == CXType_LValueReference || k == CXType_RValueReference;
+}
+
+bool BuilderPrivate::addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const
+{
+ // Template arguments
+ switch (type.kind) {
+ case CXType_Elaborated:
+ case CXType_Record:
+ case CXType_Unexposed:
+ if (const int numTemplateArguments = qMax(0, clang_Type_getNumTemplateArguments(type))) {
+ for (unsigned tpl = 0; tpl < unsigned(numTemplateArguments); ++tpl) {
+ const CXType argType = clang_Type_getTemplateArgumentAsType(type, tpl);
+ // CXType_Invalid is returned when hitting on a specialization
+ // of a non-type template (template <int v>).
+ if (argType.kind == CXType_Invalid)
+ return false;
+ t->addInstantiation(createTypeInfoHelper(argType));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+static void dummyTemplateArgumentHandler(int, const QStringRef &) {}
+
+void BuilderPrivate::addTemplateInstantiations(const CXType &type,
+ QString *typeName,
+ TypeInfo *t) const
+{
+ // In most cases, for templates like "Vector<A>", Clang will give us the
+ // arguments by recursing down the type. However this will fail for example
+ // within template classes (for functions like the copy constructor):
+ // template <class T>
+ // class Vector {
+ // Vector(const Vector&);
+ // };
+ // In that case, have TypeInfo parse the list from the spelling.
+ // Finally, remove the list "<>" from the type name.
+ const bool parsed = addTemplateInstantiationsRecursion(type, t)
+ && !t->instantiations().isEmpty();
+ const QPair<int, int> pos = parsed
+ ? parseTemplateArgumentList(*typeName, dummyTemplateArgumentHandler)
+ : t->parseTemplateArgumentList(*typeName);
+ if (pos.first != -1 && pos.second != -1 && pos.second > pos.first)
+ typeName->remove(pos.first, pos.second - pos.first);
+}
+
+TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const
{
if (type.kind == CXType_Pointer) { // Check for function pointers, first.
const CXType pointeeType = clang_getPointeeType(type);
const int argCount = clang_getNumArgTypes(pointeeType);
if (argCount >= 0) {
- TypeInfo result = createTypeInfo(clang_getResultType(pointeeType));
+ TypeInfo result = createTypeInfoHelper(clang_getResultType(pointeeType));
result.setFunctionPointer(true);
for (int a = 0; a < argCount; ++a)
- result.addArgument(createTypeInfo(clang_getArgType(pointeeType, unsigned(a))));
+ result.addArgument(createTypeInfoHelper(clang_getArgType(pointeeType, unsigned(a))));
return result;
}
}
TypeInfo typeInfo;
- QString typeName = fixTypeName(getTypeName(type));
- int indirections = 0;
- // "int **"
- for ( ; typeName.endsWith(QLatin1Char('*')) ; ++indirections)
- typeName.chop(1);
- typeInfo.setIndirections(indirections);
- // "int &&"
- if (typeName.endsWith(QLatin1String("&&"))) {
- typeName.chop(2);
- typeInfo.setReferenceType(RValueReference);
- } else if (typeName.endsWith(QLatin1Char('&'))) { // "int &"
- typeName.chop(1);
- typeInfo.setReferenceType(LValueReference);
+ CXType nestedType = type;
+ for (; isArrayType(nestedType.kind); nestedType = clang_getArrayElementType(nestedType)) {
+ const long long size = clang_getArraySize(nestedType);
+ typeInfo.addArrayElement(size >= 0 ? QString::number(size) : QString());
}
- // "int [3], int[]"
- if (type.kind == CXType_ConstantArray || type.kind == CXType_IncompleteArray
- || type.kind == CXType_VariableArray || type.kind == CXType_DependentSizedArray) {
- typeInfo.setArrayElements(parseArrayArgs(type, &typeName));
+ TypeInfo::Indirections indirections;
+ for (; isPointerType(nestedType.kind); nestedType = clang_getPointeeType(nestedType)) {
+ switch (nestedType.kind) {
+ case CXType_Pointer:
+ indirections.prepend(clang_isConstQualifiedType(nestedType) != 0
+ ? Indirection::ConstPointer : Indirection::Pointer);
+ break;
+ case CXType_LValueReference:
+ typeInfo.setReferenceType(LValueReference);
+ break;
+ case CXType_RValueReference:
+ typeInfo.setReferenceType(RValueReference);
+ break;
+ default:
+ break;
+ }
}
+ typeInfo.setIndirectionsV(indirections);
- bool isConstant = clang_isConstQualifiedType(type) != 0;
- // A "char *const" parameter, is considered to be const-qualified by Clang, but
- // not in the TypeInfo sense (corresponds to "char *" and not "const char *").
- if (type.kind == CXType_Pointer && isConstant && typeName.endsWith(QLatin1String("const"))) {
- typeName.chop(5);
- typeName = typeName.trimmed();
- isConstant = false;
- }
- // Clang has been observed to return false for "const int .."
- if (!isConstant && typeName.startsWith(QLatin1String("const "))) {
- typeName.remove(0, 6);
- isConstant = true;
- }
- typeInfo.setConstant(isConstant);
+ typeInfo.setConstant(clang_isConstQualifiedType(nestedType) != 0);
+ typeInfo.setVolatile(clang_isVolatileQualifiedType(nestedType) != 0);
- // clang_isVolatileQualifiedType() returns true for "volatile int", but not for "volatile int *"
- if (typeName.startsWith(QLatin1String("volatile "))) {
- typeName.remove(0, 9);
- typeInfo.setVolatile(true);
+ QString typeName = getTypeName(nestedType);
+ while (TypeInfo::stripLeadingConst(&typeName)
+ || TypeInfo::stripLeadingVolatile(&typeName)) {
}
- typeName = typeName.trimmed();
+ // Obtain template instantiations if the name has '<' (thus excluding
+ // typedefs like "std::string".
+ if (typeName.contains(QLatin1Char('<')))
+ addTemplateInstantiations(nestedType, &typeName, &typeInfo);
typeInfo.setQualifiedName(qualifiedName(typeName));
// 3320:CINDEX_LINKAGE int clang_getNumArgTypes(CXType T); function ptr types?
+ typeInfo.simplifyStdType();
return typeInfo;
}
+TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const
+{
+ TypeInfoHash::iterator it = m_typeInfoHash.find(type);
+ if (it == m_typeInfoHash.end())
+ it = m_typeInfoHash.insert(type, createTypeInfoHelper(type));
+ return it.value();
+}
+
+void BuilderPrivate::addTypeDef(const CXCursor &cursor, const TypeInfo &ti)
+{
+ TypeDefModelItem item(new _TypeDefModelItem(m_model, getCursorSpelling(cursor)));
+ setFileName(cursor, item.data());
+ item->setType(ti);
+ item->setScope(m_scope);
+ m_scopeStack.back()->addTypeDef(item);
+ m_cursorTypedefHash.insert(cursor, item);
+}
+
// extract an expression from the cursor via source
// CXCursor_EnumConstantDecl, ParmDecl (a = Flag1 | Flag2)
QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const
@@ -795,9 +865,8 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
d->m_currentFunction = d->createMemberFunction(cursor);
d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
- } else {
- return Skip; // inline member functions outside class
}
+ return Skip; // inline member functions outside class
}
}
Q_FALLTHROUGH(); // fall through to free template function.
@@ -868,17 +937,14 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
}
break;
case CXCursor_TypeAliasDecl:
- case CXCursor_TypeAliasTemplateDecl: // May contain nested CXCursor_TemplateTypeParameter
- return Skip;
- case CXCursor_TypedefDecl: {
- const QString name = getCursorSpelling(cursor);
- TypeDefModelItem item(new _TypeDefModelItem(d->m_model, name));
- setFileName(cursor, item.data());
- item->setType(d->createTypeInfo(clang_getTypedefDeclUnderlyingType(cursor)));
- item->setScope(d->m_scope);
- d->m_scopeStack.back()->addTypeDef(item);
- d->m_cursorTypedefHash.insert(cursor, item);
+ case CXCursor_TypeAliasTemplateDecl: { // May contain nested CXCursor_TemplateTypeParameter
+ const CXType type = clang_getCanonicalType(clang_getCursorType(cursor));
+ if (type.kind > CXType_Unexposed)
+ d->addTypeDef(cursor, d->createTypeInfo(type));
}
+ return Skip;
+ case CXCursor_TypedefDecl:
+ d->addTypeDef(cursor, d->createTypeInfo(clang_getTypedefDeclUnderlyingType(cursor)));
break;
case CXCursor_TypeRef:
if (!d->m_currentFunction.isNull()) {
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp
index ce0b6554d..e116f8b83 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp
@@ -166,7 +166,7 @@ static inline const char **byteArrayListToFlatArgV(const QByteArrayList &bl)
return result;
}
-static QByteArray msgCreateTranslationUnit(const QByteArrayList clangArgs, unsigned flags)
+static QByteArray msgCreateTranslationUnit(const QByteArrayList &clangArgs, unsigned flags)
{
QByteArray result = "clang_parseTranslationUnit2(0x";
result += QByteArray::number(flags, 16);
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
index 2ff18b23b..8bee28cdf 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp
@@ -46,6 +46,18 @@ uint qHash(const CXCursor &c, uint seed)
^ qHash(c.data[1]) ^ qHash(c.data[2]) ^ seed;
}
+bool operator==(const CXType &t1, const CXType &t2)
+{
+ return t1.kind == t2.kind && t1.data[0] == t2.data[0]
+ && t1.data[1] == t2.data[1];
+}
+
+uint qHash(const CXType &ct, uint seed)
+{
+ return uint(ct.kind) ^ uint(0xFFFFFFFF & quintptr(ct.data[0]))
+ ^ uint(0xFFFFFFFF & quintptr(ct.data[1])) ^ seed;
+}
+
namespace clang {
SourceLocation getExpansionLocation(const CXSourceLocation &location)
@@ -160,6 +172,43 @@ QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu)
return result;
}
+QPair<int, int> parseTemplateArgumentList(const QString &l,
+ const TemplateArgumentHandler &handler,
+ int from)
+{
+ const int ltPos = l.indexOf(QLatin1Char('<'), from);
+ if (ltPos == - 1)
+ return qMakePair(-1, -1);
+ int startPos = ltPos + 1;
+ int level = 1;
+ for (int p = startPos, end = l.size(); p < end; ) {
+ const char c = l.at(p).toLatin1();
+ switch (c) {
+ case ',':
+ case '>':
+ handler(level, l.midRef(startPos, p - startPos).trimmed());
+ ++p;
+ if (c == '>') {
+ if (--level == 0)
+ return qMakePair(ltPos, p);
+ // Skip over next ',': "a<b<c,d>,e>"
+ for (; p < end && (l.at(p).isSpace() || l.at(p) == QLatin1Char(',')); ++p) {}
+ }
+ startPos = p;
+ break;
+ case '<':
+ handler(level, l.midRef(startPos, p - startPos).trimmed());
+ ++level;
+ startPos = ++p;
+ break;
+ default:
+ ++p;
+ break;
+ }
+ }
+ return qMakePair(-1, -1);
+}
+
CXDiagnosticSeverity maxSeverity(const QVector<Diagnostic> &ds)
{
CXDiagnosticSeverity result = CXDiagnostic_Ignored;
diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
index 98d0c9752..db2db6267 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h
@@ -32,13 +32,19 @@
#include <clang-c/Index.h>
#include <QtCore/QPair>
#include <QtCore/QString>
+#include <QtCore/QStringList>
#include <QtCore/QVector>
+#include <functional>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
bool operator==(const CXCursor &c1, const CXCursor &c2);
uint qHash(const CXCursor &c, uint seed = 0);
+bool operator==(const CXType &t1, const CXType &t2);
+uint qHash(const CXType &ct, uint seed);
+
namespace clang {
QString getCursorKindName(CXCursorKind cursorKind);
@@ -92,6 +98,14 @@ struct Diagnostic {
QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu);
CXDiagnosticSeverity maxSeverity(const QVector<Diagnostic> &ds);
+// Parse a template argument list "a<b<c,d>,e>" and invoke a handler
+// with each match (level and string). Return begin and end of the list.
+typedef std::function<void(int /*level*/, const QStringRef &)> TemplateArgumentHandler;
+
+QPair<int, int> parseTemplateArgumentList(const QString &l,
+ const TemplateArgumentHandler &handler,
+ int from = 0);
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug, const SourceLocation &);
QDebug operator<<(QDebug, const Diagnostic &);
diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
index 74cad05ae..d3d5c8da8 100644
--- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp
@@ -239,11 +239,11 @@ static QByteArray noStandardIncludeOption() { return QByteArrayLiteral("-nostdin
#endif
#if NEED_CLANG_BUILTIN_INCLUDES
-static QString findClang()
+static QString findClangLibDir()
{
for (const char *envVar : {"LLVM_INSTALL_DIR", "CLANG_INSTALL_DIR"}) {
if (qEnvironmentVariableIsSet(envVar)) {
- const QString path = QFile::decodeName(qgetenv(envVar));
+ const QString path = QFile::decodeName(qgetenv(envVar)) + QLatin1String("/lib");
if (QFileInfo::exists(path))
return path;
}
@@ -252,7 +252,7 @@ static QString findClang()
QStandardPaths::findExecutable(QLatin1String("llvm-config"));
if (!llvmConfig.isEmpty()) {
QByteArray stdOut;
- if (runProcess(llvmConfig, QStringList{QLatin1String("--prefix")}, &stdOut)) {
+ if (runProcess(llvmConfig, QStringList{QLatin1String("--libdir")}, &stdOut)) {
const QString path = QFile::decodeName(stdOut.trimmed());
if (QFileInfo::exists(path))
return path;
@@ -264,11 +264,11 @@ static QString findClang()
static QString findClangBuiltInIncludesDir()
{
// Find the include directory of the highest version.
- const QString clangPath = findClang();
- if (!clangPath.isEmpty()) {
+ const QString clangPathLibDir = findClangLibDir();
+ if (!clangPathLibDir.isEmpty()) {
QString candidate;
QVersionNumber lastVersionNumber(1, 0, 0);
- QDir clangDir(clangPath + QLatin1String("/lib/clang"));
+ QDir clangDir(clangPathLibDir + QLatin1String("/clang"));
const QFileInfoList versionDirs =
clangDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QFileInfo &fi : versionDirs) {
diff --git a/sources/shiboken2/ApiExtractor/doc/conf.py.in b/sources/shiboken2/ApiExtractor/doc/conf.py.in
index 7251aaccd..185709590 100644
--- a/sources/shiboken2/ApiExtractor/doc/conf.py.in
+++ b/sources/shiboken2/ApiExtractor/doc/conf.py.in
@@ -43,7 +43,7 @@ source_encoding = 'utf-8'
# General information about the project.
project = u'API Extractor'
-copyright = u'2009-2010, Nokia Corporation'
+copyright = u'© 2018 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/license/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -132,10 +132,6 @@ html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes']
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-html_use_smartypants = True
-
# Custom sidebar templates, maps document names to template names.
#html_sidebars = { '' : ''}
diff --git a/sources/shiboken2/ApiExtractor/doc/typesystem_conversionrule.rst b/sources/shiboken2/ApiExtractor/doc/typesystem_conversionrule.rst
index c62d5bbf6..27e7a72de 100644
--- a/sources/shiboken2/ApiExtractor/doc/typesystem_conversionrule.rst
+++ b/sources/shiboken2/ApiExtractor/doc/typesystem_conversionrule.rst
@@ -63,6 +63,7 @@ native-to-target
**%INTYPE_#**, should be replaced by the types used in the container template
(e.g. **%INTYPE_0** correspondes to **"int"** for **"list<int>"**).
+ The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
.. _target-to-native:
@@ -111,3 +112,5 @@ add-conversion
**%in**, **%out**, **%INTYPE**, **%INTYPE_#**, and **%OUTTYPE**, must be provided by
the generator as in the ``native-to-target`` tag.
+ The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
+
diff --git a/sources/shiboken2/ApiExtractor/doc/typesystem_documentation.rst b/sources/shiboken2/ApiExtractor/doc/typesystem_documentation.rst
index 43f72a1ba..d73e43cb1 100644
--- a/sources/shiboken2/ApiExtractor/doc/typesystem_documentation.rst
+++ b/sources/shiboken2/ApiExtractor/doc/typesystem_documentation.rst
@@ -30,9 +30,9 @@ modify-documentation
^^^^^^^^^^^^^^^^^^^^
The modify-documentation node allows you to change the auto-generated
- documentation. API Extractor transforms XML's from qdoc3 (the Qt documentation
- tool) into .rst files to be processed later using Sphinx. So you can modify
- the XML before the transformation occur.
+ documentation. API Extractor transforms XML's from qdoc (the Qt documentation
+ tool) into .rst files to be processed later using Sphinx. You can modify
+ the XML before the transformation takes place.
.. code-block:: xml
diff --git a/sources/shiboken2/ApiExtractor/doc/typesystem_manipulating_objects.rst b/sources/shiboken2/ApiExtractor/doc/typesystem_manipulating_objects.rst
index ff6ea5317..12b866ad7 100644
--- a/sources/shiboken2/ApiExtractor/doc/typesystem_manipulating_objects.rst
+++ b/sources/shiboken2/ApiExtractor/doc/typesystem_manipulating_objects.rst
@@ -11,6 +11,9 @@ inject-code
given type or function, and it is a child of the :ref:`object-type`, :ref:`value-type`,
:ref:`modify-function` and :ref:`add-function` nodes.
+ The code can be embedded into XML (be careful to use the correct XML entities
+ for characters like '<', '>', '&'):
+
.. code-block:: xml
<value-type>
@@ -20,6 +23,18 @@ inject-code
</inject-code>
</value-type>
+ or obtained from an external file:
+
+ .. code-block:: xml
+
+ <value-type>
+ <inject-code class="native | target | target-declaration"
+ position="beginning | end" since="..."
+ file="external_source.cpp"
+ snippet="label"/>
+ </value-type>
+
+
The ``class`` attribute specifies which module of the generated code that
will be affected by the code injection. The ``class`` attribute accepts the
following values:
@@ -28,6 +43,8 @@ inject-code
* target: The binding code
* target-declaration: The code will be injected into the generated header
file containing the c++ wrapper class definition.
+ * file: The file name
+ * snippet: The snippet label (optional)
If the ``position`` attribute is set to *beginning* (the default), the code
is inserted at the beginning of the function. If it is set to *end*, the code
@@ -35,6 +52,16 @@ inject-code
The ``since`` attribute specify the API version where this code was injected.
+ If a ``snippet`` label is given, the code between annotations of the form
+
+ .. code-block:: c++
+
+ // @snippet label
+ ...
+ // @snippet label
+
+ will be extracted.
+
modify-field
^^^^^^^^^^^^
@@ -74,6 +101,8 @@ modify-function
since="..."
remove="all | c++"
access="public | private | protected"
+ allow-thread="true | auto | false"
+ exception-handling="off | auto-off | auto-on | on"
rename="..." />
</object-type>
@@ -82,6 +111,26 @@ modify-function
The ``since`` attribute specify the API version when this function was modified.
+ The ``allow-thread`` attribute specifies whether a function should be wrapped
+ into ``Py_BEGIN_ALLOW_THREADS`` and ``Py_END_ALLOW_THREADS``, that is,
+ temporarily release the GIL (global interpreter lock). Doing so is required
+ for any thread-related function (wait operations), functions that might call
+ a virtual function (potentially reimplemented in Python), and recommended for
+ lengthy I/O operations or similar. It has performance costs, though.
+ The value ``auto`` means that it will be turned off for functions for which
+ it is deemed to be safe, for example, simple getters.
+
+ The ``exception-handling`` attribute specifies whether to generate exception
+ handling code (nest the function call into try / catch statements). It accepts
+ the following values:
+
+ * no, false: Do not generate exception handling code
+ * auto-off: Generate exception handling code for functions
+ declaring a non-empty ``throw`` list
+ * auto-on: Generate exception handling code unless function
+ declares ``noexcept``
+ * yes, true: Always generate exception handling code
+
The ``remove``, ``access`` and ``rename`` attributes are *optional* attributes
for added convenience; they serve the same purpose as the deprecated tags :ref:`remove`, :ref:`access` and :ref:`rename`.
@@ -130,3 +179,4 @@ conversion-rule
.. note:: You can also use the conversion-rule node to specify :ref:`how the conversion of a single function argument should be done in a function <conversion-rule>`.
+ The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
diff --git a/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst b/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst
index 322f9bca6..c3180ae88 100644
--- a/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken2/ApiExtractor/doc/typesystem_specifying_types.rst
@@ -11,7 +11,7 @@ typesystem
.. code-block:: xml
- <typesystem package="..." default-superclass="...">
+ <typesystem package="..." default-superclass="..." exception-handling="...">
</typesystem>
The **package** attribute is a string describing the package to be used,
@@ -19,6 +19,9 @@ typesystem
The *optional* **default-superclass** attribute is the canonical C++ base class
name of all objects, e.g., "object".
+ The *optional* **exception-handling** attribute specifies the default exception
+ handling mode of all objects (see :ref:`modify-function`).
+
load-typesystem
^^^^^^^^^^^^^^^
@@ -216,6 +219,7 @@ value-type
<typesystem>
<value-type name="..." since="..."
copyable="yes | no"
+ exception-handling="..."
hash-function="..."
stream="yes | no"
default-constructor="..."
@@ -243,6 +247,9 @@ value-type
The **revision** attribute can be used to specify a revision for each type, easing the
production of ABI compatible bindings.
+ The *optional* **exception-handling** attribute specifies the default exception
+ handling mode of all functions (see :ref:`modify-function`).
+
.. _object-type:
object-type
@@ -258,6 +265,7 @@ object-type
<object-type name="..."
since="..."
copyable="yes | no"
+ exception-handling="..."
hash-function="..."
stream="yes | no"
revision="..." />
@@ -278,6 +286,9 @@ object-type
The **revision** attribute can be used to specify a revision for each type, easing the
production of ABI compatible bindings.
+ The *optional* **exception-handling** attribute specifies the default exception
+ handling mode of all functions (see :ref:`modify-function`).
+
interface-type
^^^^^^^^^^^^^^
@@ -329,6 +340,38 @@ container-type
The *optional* **since** value is used to specify the API version of this container.
+typedef-type
+^^^^^^^^^^^^
+
+ The typedef-type allows for specifying typedefs in the typesystem. They
+ are mostly equivalent to spelling out the typedef in the included header, which
+ is often complicated when trying to wrap libraries whose source code cannot be
+ easily extended.
+
+ .. code-block:: xml
+
+ <typesystem>
+ <typedef-type name="..."
+ source="..."
+ since="..."
+ </typesystem>
+
+ The **source** attribute is the source. Example:
+
+ .. code-block:: xml
+
+ <namespace-type name='std'>
+ <value-type name='optional' generate='no'/>\n"
+ </namespace-type>
+ <typedef-type name="IntOptional" source="std::optional&lt;int&gt;"/>
+
+ is equivalent to
+
+ .. code-block:: c++
+
+ typedef std::optional<int> IntOptional;
+
+ The *optional* **since** value is used to specify the API version of this type.
.. _custom-type:
@@ -348,6 +391,26 @@ custom-type
The **name** attribute is the name of the custom type, e.g., "PyObject".
+.. _smart-pointer-type:
+
+smart-pointer-type
+^^^^^^^^^^^^^^^^^^
+
+ The smart pointer type node indicates that the given class is a smart pointer
+ and requires inserting calls to **getter** to access the pointeee.
+ Currently, only the **type** *shared* is supported and the usage is limited
+ to function return values.
+ **ref-count-method** specifies the name of the method used to do reference counting.
+
+ .. code-block:: xml
+
+ <typesystem>
+ <smart-pointer-type name="..."
+ since="..."
+ type="..."
+ getter="..."
+ ref-count-method="..."/>
+ </typesystem>
.. _function:
diff --git a/sources/shiboken2/ApiExtractor/docparser.cpp b/sources/shiboken2/ApiExtractor/docparser.cpp
index 9305332ba..99921e7d3 100644
--- a/sources/shiboken2/ApiExtractor/docparser.cpp
+++ b/sources/shiboken2/ApiExtractor/docparser.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "docparser.h"
#include "abstractmetalang.h"
+#include "messages.h"
#include "reporthandler.h"
#include "typesystem.h"
#include <QtCore/QDebug>
@@ -50,9 +51,7 @@ DocParser::DocParser()
#endif
}
-DocParser::~DocParser()
-{
-}
+DocParser::~DocParser() = default;
QString DocParser::getDocumentation(QXmlQuery& xquery, const QString& query,
const DocModificationList& mods) const
@@ -109,58 +108,21 @@ AbstractMetaFunctionList DocParser::documentableFunctions(const AbstractMetaClas
return result;
}
-QString DocParser::msgCannotFindDocumentation(const QString &fileName,
- const char *what, const QString &name,
- const QString &query)
-{
- QString result;
- QTextStream(&result) << "Cannot find documentation for " << what
- << ' ' << name << " in:\n " << QDir::toNativeSeparators(fileName)
- << "\n using query:\n " << query;
- return result;
-}
-
-QString DocParser::msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
- const AbstractMetaFunction *function,
- const QString &query)
-{
- const QString name = metaClass->name() + QLatin1String("::")
- + function->minimalSignature();
- return msgCannotFindDocumentation(fileName, "function", name, query);
-}
-
-QString DocParser::msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
- const AbstractMetaEnum *e,
- const QString &query)
-{
- return msgCannotFindDocumentation(fileName, "enum",
- metaClass->name() + QLatin1String("::") + e->name(),
- query);
-}
-
-QString DocParser::msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
- const AbstractMetaField *f,
- const QString &query)
-{
- return msgCannotFindDocumentation(fileName, "field",
- metaClass->name() + QLatin1String("::") + f->name(),
- query);
-}
#ifdef HAVE_LIBXSLT
namespace
{
-struct XslResources
+class XslResources
{
- xmlDocPtr xmlDoc;
- xsltStylesheetPtr xslt;
- xmlDocPtr xslResult;
+ Q_DISABLE_COPY(XslResources)
+
+public:
+ xmlDocPtr xmlDoc = nullptr;
+ xsltStylesheetPtr xslt = nullptr;
+ xmlDocPtr xslResult = nullptr;
- XslResources() : xmlDoc(0), xslt(0), xslResult(0) {}
+ XslResources() = default;
~XslResources()
{
@@ -186,27 +148,6 @@ static inline bool isXpathDocModification(const DocModification &mod)
return mod.mode() == TypeSystem::DocModificationXPathReplace;
}
-QString msgXpathDocModificationError(const DocModificationList& mods,
- const QString &what)
-{
- QString result;
- QTextStream str(&result);
- str << "Error when applying modifications (";
- for (const DocModification &mod : mods) {
- if (isXpathDocModification(mod)) {
- str << '"' << mod.xpath() << "\" -> \"";
- const QString simplified = mod.code().simplified();
- if (simplified.size() > 20)
- str << simplified.leftRef(20) << "...";
- else
- str << simplified;
- str << '"';
- }
- }
- str << "): " << what;
- return result;
-}
-
QString DocParser::applyDocModifications(const DocModificationList& mods, const QString& xml) const
{
if (mods.isEmpty() || xml.isEmpty()
diff --git a/sources/shiboken2/ApiExtractor/docparser.h b/sources/shiboken2/ApiExtractor/docparser.h
index fff71a877..7cbbef28e 100644
--- a/sources/shiboken2/ApiExtractor/docparser.h
+++ b/sources/shiboken2/ApiExtractor/docparser.h
@@ -120,22 +120,6 @@ protected:
static AbstractMetaFunctionList documentableFunctions(const AbstractMetaClass *metaClass);
- static QString msgCannotFindDocumentation(const QString &fileName,
- const char *what, const QString &name,
- const QString &query);
- static QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
- const AbstractMetaFunction *function,
- const QString &query);
- static QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
- const AbstractMetaEnum *e,
- const QString &query);
- static QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
- const AbstractMetaField *f,
- const QString &query);
-
private:
QString m_packageName;
QString m_docDataDir;
diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp
index dfdb37a47..e238aa1f7 100644
--- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp
+++ b/sources/shiboken2/ApiExtractor/doxygenparser.cpp
@@ -28,6 +28,7 @@
#include "doxygenparser.h"
#include "abstractmetalang.h"
+#include "messages.h"
#include "reporthandler.h"
#include "typesystem.h"
@@ -35,23 +36,17 @@
#include <QtCore/QFile>
#include <QtCore/QDir>
-namespace
+static QString getSectionKindAttr(const AbstractMetaFunction *func)
{
-
-QString getSectionKindAttr(const AbstractMetaFunction* func)
-{
- if (func->isSignal()) {
+ if (func->isSignal())
return QLatin1String("signal");
- } else {
- QString kind = func->isPublic() ? QLatin1String("public") : QLatin1String("protected");
- if (func->isStatic())
- kind += QLatin1String("-static");
- else if (func->isSlot())
- kind += QLatin1String("-slot");
- return kind;
- }
-}
-
+ QString kind = func->isPublic()
+ ? QLatin1String("public") : QLatin1String("protected");
+ if (func->isStatic())
+ kind += QLatin1String("-static");
+ else if (func->isSlot())
+ kind += QLatin1String("-slot");
+ return kind;
}
Documentation DoxygenParser::retrieveModuleDocumentation()
@@ -73,13 +68,12 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
doxyFileSuffix += QLatin1String(".xml");
const char* prefixes[] = { "class", "struct", "namespace" };
- const int numPrefixes = sizeof(prefixes) / sizeof(const char*);
bool isProperty = false;
QString doxyFilePath;
- for (int i = 0; i < numPrefixes; ++i) {
+ for (const char *prefix : prefixes) {
doxyFilePath = documentationDataDirectory() + QLatin1Char('/')
- + QLatin1String(prefixes[i]) + doxyFileSuffix;
+ + QLatin1String(prefix) + doxyFileSuffix;
if (QFile::exists(doxyFilePath))
break;
doxyFilePath.clear();
diff --git a/sources/shiboken2/ApiExtractor/fileout.cpp b/sources/shiboken2/ApiExtractor/fileout.cpp
index e3c96d57b..10a8f6be8 100644
--- a/sources/shiboken2/ApiExtractor/fileout.cpp
+++ b/sources/shiboken2/ApiExtractor/fileout.cpp
@@ -27,11 +27,13 @@
****************************************************************************/
#include "fileout.h"
+#include "messages.h"
#include "reporthandler.h"
#include <QtCore/QTextCodec>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
+#include <QtCore/QDebug>
#include <cstdio>
@@ -50,24 +52,25 @@ static const char colorInfo[] = "";
static const char colorReset[] = "";
#endif
-FileOut::FileOut(QString n):
- name(n),
- stream(&tmp),
- isDone(false)
-{}
+FileOut::FileOut(QString n) :
+ name(std::move(n)),
+ stream(&tmp),
+ isDone(false)
+{
+}
+
+FileOut::~FileOut()
+{
+ if (!isDone)
+ done();
+}
-static int* lcsLength(QList<QByteArray> a, QList<QByteArray> b)
+static QVector<int> lcsLength(const QByteArrayList &a, const QByteArrayList &b)
{
const int height = a.size() + 1;
const int width = b.size() + 1;
- int *res = new int[width * height];
-
- for (int row = 0; row < height; row++)
- res[width * row] = 0;
-
- for (int col = 0; col < width; col++)
- res[col] = 0;
+ QVector<int> res(width * height, 0);
for (int row = 1; row < height; row++) {
for (int col = 1; col < width; col++) {
@@ -89,88 +92,84 @@ enum Type {
struct Unit
{
- Unit(Type type, int pos) :
- type(type),
- start(pos),
- end(pos) {}
-
Type type;
int start;
int end;
- void print(QList<QByteArray> a, QList<QByteArray> b)
- {
- if (type == Unchanged) {
- if ((end - start) > 9) {
- for (int i = start; i <= start + 2; i++)
- std::printf(" %s\n", a[i].data());
- std::printf("%s=\n= %d more lines\n=%s\n", colorInfo, end - start - 6, colorReset);
- for (int i = end - 2; i <= end; i++)
- std::printf(" %s\n", a[i].data());
- } else {
- for (int i = start; i <= end; i++)
- std::printf(" %s\n", a[i].data());
- }
- } else if (type == Add) {
- std::printf("%s", colorAdd);
- for (int i = start; i <= end; i++)
- std::printf("+ %s\n", b[i].data());
- std::printf("%s", colorReset);
- } else if (type == Delete) {
- std::printf("%s", colorDelete);
- for (int i = start; i <= end; i++)
- std::printf("- %s\n", a[i].data());
- std::printf("%s", colorReset);
- }
- }
+ void print(const QByteArrayList &a, const QByteArrayList &b) const;
};
-static QList<Unit*> *unitAppend(QList<Unit*> *res, Type type, int pos)
+void Unit::print(const QByteArrayList &a, const QByteArrayList &b) const
{
- if (!res) {
- res = new QList<Unit*>;
- res->append(new Unit(type, pos));
- return res;
+ switch (type) {
+ case Unchanged:
+ if ((end - start) > 9) {
+ for (int i = start; i <= start + 2; i++)
+ std::printf(" %s\n", a.at(i).constData());
+ std::printf("%s=\n= %d more lines\n=%s\n",
+ colorInfo, end - start - 6, colorReset);
+ for (int i = end - 2; i <= end; i++)
+ std::printf(" %s\n", a.at(i).constData());
+ } else {
+ for (int i = start; i <= end; i++)
+ std::printf(" %s\n", a.at(i).constData());
+ }
+ break;
+ case Add:
+ std::fputs(colorAdd, stdout);
+ for (int i = start; i <= end; i++)
+ std::printf("+ %s\n", b.at(i).constData());
+ std::fputs(colorReset, stdout);
+ break;
+ case Delete:
+ std::fputs(colorDelete, stdout);
+ for (int i = start; i <= end; i++)
+ std::printf("- %s\n", a.at(i).constData());
+ std::fputs(colorReset, stdout);
+ break;
}
+}
- Unit *last = res->last();
- if (last->type == type)
- last->end = pos;
+static void unitAppend(Type type, int pos, QVector<Unit> *units)
+{
+ if (!units->isEmpty() && units->last().type == type)
+ units->last().end = pos;
else
- res->append(new Unit(type, pos));
-
- return res;
+ units->append(Unit{type, pos, pos});
}
-static QList<Unit*> *diffHelper(int *lcs, QList<QByteArray> a, QList<QByteArray> b, int row, int col)
+static QVector<Unit> diffHelper(const QVector<int> &lcs,
+ const QByteArrayList &a, const QByteArrayList &b,
+ int row, int col)
{
- if (row > 0 && col > 0 && (a[row-1] == b[col-1])) {
- return unitAppend(diffHelper(lcs, a, b, row - 1, col - 1), Unchanged, row - 1);
- } else {
- int width = b.size() + 1;
- if ((col > 0)
- && (row == 0 || lcs[width * row + col-1] >= lcs[width *(row-1) + col])) {
- return unitAppend(diffHelper(lcs, a, b, row, col - 1), Add, col - 1);
- } else if ((row > 0)
- && (col == 0 || lcs[width * row + col-1] < lcs[width *(row-1) + col])) {
- return unitAppend(diffHelper(lcs, a, b, row - 1, col), Delete, row - 1);
- }
+ if (row > 0 && col > 0 && a.at(row - 1) == b.at(col - 1)) {
+ QVector<Unit> result = diffHelper(lcs, a, b, row - 1, col - 1);
+ unitAppend(Unchanged, row - 1, &result);
+ return result;
}
- delete lcs;
- return 0;
-}
-static void diff(QList<QByteArray> a, QList<QByteArray> b)
-{
- QList<Unit*> *res = diffHelper(lcsLength(a, b), a, b, a.size(), b.size());
- for (int i = 0; i < res->size(); i++) {
- Unit *unit = res->at(i);
- unit->print(a, b);
- delete(unit);
+ const int width = b.size() + 1;
+ if (col > 0
+ && (row == 0 || lcs.at(width * row + col -1 ) >= lcs.at(width * (row - 1) + col))) {
+ QVector<Unit> result = diffHelper(lcs, a, b, row, col - 1);
+ unitAppend(Add, col - 1, &result);
+ return result;
}
- delete(res);
+ if (row > 0
+ && (col == 0 || lcs.at(width * row + col-1) < lcs.at(width * (row - 1) + col))) {
+ QVector<Unit> result = diffHelper(lcs, a, b, row - 1, col);
+ unitAppend(Delete, row - 1, &result);
+ return result;
+ }
+ return QVector<Unit>{};
}
+static void diff(const QByteArrayList &a, const QByteArrayList &b)
+{
+ const QVector<Unit> res = diffHelper(lcsLength(a, b), a, b, a.size(), b.size());
+ for (const Unit &unit : res)
+ unit.print(a, b);
+}
FileOut::State FileOut::done()
{
@@ -181,18 +180,6 @@ FileOut::State FileOut::done()
return result;
}
-QString FileOut::msgCannotOpenForReading(const QFile &f)
-{
- return QStringLiteral("Failed to open file '%1' for reading: %2")
- .arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
-}
-
-QString FileOut::msgCannotOpenForWriting(const QFile &f)
-{
- return QStringLiteral("Failed to open file '%1' for writing: %2")
- .arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
-}
-
FileOut::State FileOut::done(QString *errorMessage)
{
Q_ASSERT(!isDone);
@@ -245,3 +232,18 @@ FileOut::State FileOut::done(QString *errorMessage)
return Success;
}
+
+void FileOut::touchFile(const QString &filePath)
+{
+ QFile toucher(filePath);
+ qint64 size = toucher.size();
+ if (!toucher.open(QIODevice::ReadWrite)) {
+ qCWarning(lcShiboken).noquote().nospace()
+ << QStringLiteral("Failed to touch file '%1'")
+ .arg(QDir::toNativeSeparators(filePath));
+ return;
+ }
+ toucher.resize(size+1);
+ toucher.resize(size);
+ toucher.close();
+}
diff --git a/sources/shiboken2/ApiExtractor/fileout.h b/sources/shiboken2/ApiExtractor/fileout.h
index 539ae7a43..aace70131 100644
--- a/sources/shiboken2/ApiExtractor/fileout.h
+++ b/sources/shiboken2/ApiExtractor/fileout.h
@@ -43,18 +43,17 @@ private:
public:
enum State { Failure, Unchanged, Success };
- FileOut(QString name);
- ~FileOut()
- {
- if (!isDone)
- done();
- }
+ explicit FileOut(QString name);
+ ~FileOut();
+
+ QString filePath() const { return name; }
State done();
State done(QString *errorMessage);
- static QString msgCannotOpenForReading(const QFile &f);
- static QString msgCannotOpenForWriting(const QFile &f);
+ void touch() { touchFile(name); }
+
+ static void touchFile(const QString &filePath);
QTextStream stream;
diff --git a/sources/shiboken2/ApiExtractor/include.cpp b/sources/shiboken2/ApiExtractor/include.cpp
index 963999b9d..d6a451992 100644
--- a/sources/shiboken2/ApiExtractor/include.cpp
+++ b/sources/shiboken2/ApiExtractor/include.cpp
@@ -36,10 +36,9 @@ QString Include::toString() const
{
if (m_type == IncludePath)
return QLatin1String("#include <") + m_name + QLatin1Char('>');
- else if (m_type == LocalPath)
+ if (m_type == LocalPath)
return QLatin1String("#include \"") + m_name + QLatin1Char('"');
- else
- return QLatin1String("import ") + m_name + QLatin1Char(';');
+ return QLatin1String("import ") + m_name + QLatin1Char(';');
}
uint qHash(const Include& inc)
diff --git a/sources/shiboken2/ApiExtractor/include.h b/sources/shiboken2/ApiExtractor/include.h
index 16059876a..4890eea2c 100644
--- a/sources/shiboken2/ApiExtractor/include.h
+++ b/sources/shiboken2/ApiExtractor/include.h
@@ -42,7 +42,8 @@ public:
enum IncludeType {
IncludePath,
LocalPath,
- TargetLangImport
+ TargetLangImport,
+ InvalidInclude
};
Include() : m_type(IncludePath) {}
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
new file mode 100644
index 000000000..fa4c75743
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -0,0 +1,446 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "messages.h"
+#include "abstractmetalang.h"
+#include "typesystem.h"
+#include <codemodel.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QStringList>
+#include <QtCore/QXmlStreamReader>
+
+static inline QString colonColon() { return QStringLiteral("::"); }
+
+// abstractmetabuilder.cpp
+
+QString msgNoFunctionForModification(const QString &signature,
+ const QString &originalSignature,
+ const QString &className,
+ const QStringList &possibleSignatures,
+ const AbstractMetaFunctionList &allFunctions)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "signature '" << signature << '\'';
+ if (!originalSignature.isEmpty() && originalSignature != signature)
+ str << " (specified as '" << originalSignature << "')";
+ str << " for function modification in '"
+ << className << "' not found.";
+ if (!possibleSignatures.isEmpty()) {
+ str << "\n Possible candidates:\n";
+ for (const auto &s : possibleSignatures)
+ str << " " << s << '\n';
+ } else if (!allFunctions.isEmpty()) {
+ str << "\n No candidates were found. Member functions:\n";
+ const int maxCount = qMin(10, allFunctions.size());
+ for (int f = 0; f < maxCount; ++f)
+ str << " " << allFunctions.at(f)->minimalSignature() << '\n';
+ if (maxCount < allFunctions.size())
+ str << " ...\n";
+ }
+ return result;
+}
+
+template <class Stream>
+static void msgFormatEnumType(Stream &str,
+ const EnumModelItem &enumItem,
+ const QString &className)
+{
+ switch (enumItem->enumKind()) {
+ case CEnum:
+ str << "Enum '" << enumItem->qualifiedName().join(colonColon()) << '\'';
+ break;
+ case AnonymousEnum: {
+ const EnumeratorList &values = enumItem->enumerators();
+ str << "Anonymous enum (";
+ switch (values.size()) {
+ case 0:
+ break;
+ case 1:
+ str << values.constFirst()->name();
+ break;
+ case 2:
+ str << values.at(0)->name() << ", " << values.at(1)->name();
+ break;
+ default:
+ str << values.at(0)->name() << ", ... , "
+ << values.at(values.size() - 1)->name();
+ break;
+ }
+ str << ')';
+ }
+ break;
+ case EnumClass:
+ str << "Scoped enum '" << enumItem->qualifiedName().join(colonColon()) << '\'';
+ break;
+ }
+ if (!className.isEmpty())
+ str << " (class: " << className << ')';
+}
+
+QString msgNoEnumTypeEntry(const EnumModelItem &enumItem,
+ const QString &className)
+{
+ QString result;
+ QTextStream str(&result);
+ msgFormatEnumType(str, enumItem, className);
+ str << " does not have a type entry";
+ return result;
+}
+
+QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
+ const QString &className,
+ const TypeEntry *t)
+{
+ QString result;
+ QDebug debug(&result); // Use the debug operator for TypeEntry::Type
+ debug.noquote();
+ debug.nospace();
+ msgFormatEnumType(debug, enumItem, className);
+ debug << " is not an enum (type: " << t->type() << ')';
+ return result;
+}
+
+QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
+ const QString &why)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "unmatched type '" << arg->type().toString() << "' in parameter #"
+ << (n + 1);
+ if (!arg->name().isEmpty())
+ str << " \"" << arg->name() << '"';
+ str << ": " << why;
+ return result;
+}
+
+QString msgUnmatchedReturnType(const FunctionModelItem &functionItem,
+ const QString &why)
+{
+ return QLatin1String("unmatched return type '")
+ + functionItem->type().toString()
+ + QLatin1String("': ") + why;
+}
+
+QString msgSkippingFunction(const FunctionModelItem &functionItem,
+ const QString &signature, const QString &why)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "skipping ";
+ if (functionItem->isAbstract())
+ str << "abstract ";
+ str << "function '" << signature << "', " << why;
+ if (functionItem->isAbstract()) {
+ str << "\nThis will lead to compilation errors due to not "
+ "being able to instantiate the wrapper.";
+ }
+ return result;
+}
+
+QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason)
+{
+ return function + QLatin1String(": Cannot use parameter ")
+ + QString::number(i + 1) + QLatin1String(" as an array: ") + reason;
+}
+
+QString msgUnableToTranslateType(const QString &t, const QString &why)
+{
+ return QLatin1String("Unable to translate type \"")
+ + t + QLatin1String("\": ") + why;
+}
+
+QString msgUnableToTranslateType(const TypeInfo &typeInfo,
+ const QString &why)
+{
+ return msgUnableToTranslateType(typeInfo.toString(), why);
+}
+
+QString msgCannotFindTypeEntry(const QString &t)
+{
+ return QLatin1String("Cannot find type entry for \"") + t + QLatin1String("\".");
+}
+
+QString msgCannotTranslateTemplateArgument(int i,
+ const TypeInfo &typeInfo,
+ const QString &why)
+{
+ QString result;
+ QTextStream(&result) << "Unable to translate template argument "
+ << (i + 1) << typeInfo.toString() << ": " << why;
+ return result;
+}
+
+// abstractmetalang.cpp
+
+QString msgDisallowThread(const AbstractMetaFunction *f)
+{
+ QString result;
+ QTextStream str(&result);
+ str <<"Disallowing threads for ";
+ if (auto c = f->declaringClass())
+ str << c->name() << "::";
+ str << f->name() << "().";
+ return result;
+}
+
+// docparser.cpp
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const char *what, const QString &name,
+ const QString &query)
+{
+ QString result;
+ QTextStream(&result) << "Cannot find documentation for " << what
+ << ' ' << name << " in:\n " << QDir::toNativeSeparators(fileName)
+ << "\n using query:\n " << query;
+ return result;
+}
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const AbstractMetaClass *metaClass,
+ const AbstractMetaFunction *function,
+ const QString &query)
+{
+ const QString name = metaClass->name() + QLatin1String("::")
+ + function->minimalSignature();
+ return msgCannotFindDocumentation(fileName, "function", name, query);
+}
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const AbstractMetaClass *metaClass,
+ const AbstractMetaEnum *e,
+ const QString &query)
+{
+ return msgCannotFindDocumentation(fileName, "enum",
+ metaClass->name() + QLatin1String("::") + e->name(),
+ query);
+}
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const AbstractMetaClass *metaClass,
+ const AbstractMetaField *f,
+ const QString &query)
+{
+ return msgCannotFindDocumentation(fileName, "field",
+ metaClass->name() + QLatin1String("::") + f->name(),
+ query);
+}
+
+QString msgXpathDocModificationError(const DocModificationList& mods,
+ const QString &what)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Error when applying modifications (";
+ for (const DocModification &mod : mods) {
+ if (mod.mode() == TypeSystem::DocModificationXPathReplace) {
+ str << '"' << mod.xpath() << "\" -> \"";
+ const QString simplified = mod.code().simplified();
+ if (simplified.size() > 20)
+ str << simplified.leftRef(20) << "...";
+ else
+ str << simplified;
+ str << '"';
+ }
+ }
+ str << "): " << what;
+ return result;
+}
+
+// fileout.cpp
+
+QString msgCannotOpenForReading(const QFile &f)
+{
+ return QStringLiteral("Failed to open file '%1' for reading: %2")
+ .arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
+}
+
+QString msgCannotOpenForWriting(const QFile &f)
+{
+ return QStringLiteral("Failed to open file '%1' for writing: %2")
+ .arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
+}
+
+// generator.cpp
+
+QString msgCannotUseEnumAsInt(const QString &name)
+{
+ return QLatin1String("Cannot convert the protected scoped enum \"") + name
+ + QLatin1String("\" to type int when generating wrappers for the protected hack. "
+ "Compilation errors may occur when used as a function argument.");
+}
+
+// main.cpp
+
+QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs)
+{
+ QString message;
+ QTextStream str(&message);
+ str << "shiboken: Called with wrong arguments:";
+ for (auto it = remainingArgs.cbegin(), end = remainingArgs.cend(); it != end; ++it) {
+ str << ' ' << it.key();
+ if (!it.value().isEmpty())
+ str << ' ' << it.value();
+ }
+ str << "\nCommand line: " << QCoreApplication::arguments().join(QLatin1Char(' '));
+ return message;
+}
+
+QString msgInvalidVersion(const QString &package, const QString &version)
+{
+ return QLatin1String("Invalid version \"") + version
+ + QLatin1String("\" specified for package ") + package + QLatin1Char('.');
+}
+
+QString msgCyclicDependency(const QString &funcName, const QString &graphName,
+ const QVector<const AbstractMetaFunction *> &involvedConversions)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Cyclic dependency found on overloaddata for \"" << funcName
+ << "\" method! The graph boy saved the graph at \""
+ << QDir::toNativeSeparators(graphName) << "\".";
+ if (const int count = involvedConversions.size()) {
+ str << " Implicit conversions (" << count << "): ";
+ for (int i = 0; i < count; ++i) {
+ if (i)
+ str << ", \"";
+ str << involvedConversions.at(i)->signature() << '"';
+ if (const AbstractMetaClass *c = involvedConversions.at(i)->implementingClass())
+ str << '(' << c->name() << ')';
+ }
+ }
+ return result;
+}
+
+// shibokengenerator.cpp
+
+QString msgUnknownOperator(const AbstractMetaFunction* func)
+{
+ QString result = QLatin1String("Unknown operator: \"") + func->originalName()
+ + QLatin1Char('"');
+ if (const AbstractMetaClass *c = func->implementingClass())
+ result += QLatin1String(" in class: ") + c->name();
+ return result;
+}
+
+QString msgWrongIndex(const char *varName, const QString &capture,
+ const AbstractMetaFunction *func)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Wrong index for " << varName << " variable (" << capture << ") on ";
+ if (const AbstractMetaClass *c = func->implementingClass())
+ str << c->name() << "::";
+ str << func->signature();
+ return result;
+}
+
+QString msgCannotFindType(const QString &type, const QString &variable,
+ const QString &why)
+{
+ QString result;
+ QTextStream(&result) << "Could not find type '"
+ << type << "' for use in '" << variable << "' conversion: " << why
+ << "\nMake sure to use the full C++ name, e.g. 'Namespace::Class'.";
+ return result;
+}
+
+QString msgCannotBuildMetaType(const QString &s)
+{
+ return QLatin1String("Unable to build meta type for \"")
+ + s + QLatin1String("\": ");
+}
+
+QString msgCouldNotFindMinimalConstructor(const QString &where, const QString &type)
+{
+ return where + QLatin1String(": Could not find a minimal constructor for type '")
+ + type + QLatin1String("'. This will result in a compilation error.");
+}
+
+// typedatabase.cpp
+
+QString msgRejectReason(const TypeRejection &r, const QString &needle)
+{
+ QString result;
+ QTextStream str(&result);
+ switch (r.matchType) {
+ case TypeRejection::ExcludeClass:
+ str << " matches class exclusion \"" << r.className.pattern() << '"';
+ break;
+ case TypeRejection::Function:
+ case TypeRejection::Field:
+ case TypeRejection::Enum:
+ str << " matches class \"" << r.className.pattern() << "\" and \""
+ << r.pattern.pattern() << '"';
+ break;
+ case TypeRejection::ArgumentType:
+ case TypeRejection::ReturnType:
+ str << " matches class \"" << r.className.pattern() << "\" and \""
+ << needle << "\" matches \"" << r.pattern.pattern() << '"';
+ break;
+ case TypeRejection::Invalid:
+ break;
+ }
+ return result;
+}
+
+// qtdocgenerator.cpp
+
+QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &message)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "While handling <";
+ const QStringRef currentTag = reader.name();
+ if (currentTag.isEmpty())
+ str << tag;
+ else
+ str << currentTag;
+ str << "> in " << context << ", line "<< reader.lineNumber()
+ << ": " << message;
+ return result;
+}
+
+QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &location,
+ const QString &identifier, const QString &fallback)
+{
+ QString message = QLatin1String("Falling back to \"")
+ + QDir::toNativeSeparators(fallback) + QLatin1String("\" for \"")
+ + location + QLatin1Char('"');
+ if (!identifier.isEmpty())
+ message += QLatin1String(" [") + identifier + QLatin1Char(']');
+ return msgTagWarning(reader, context, tag, message);
+}
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
new file mode 100644
index 000000000..539332aef
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESSAGES_H
+#define MESSAGES_H
+
+#include "abstractmetalang_typedefs.h"
+#include "parser/codemodel_fwd.h"
+#include "typesystem_typedefs.h"
+
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QVector>
+
+class TypeEntry;
+class TypeInfo;
+struct TypeRejection;
+
+QT_FORWARD_DECLARE_CLASS(QDir)
+QT_FORWARD_DECLARE_CLASS(QFile)
+QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
+
+QString msgNoFunctionForModification(const QString &signature,
+ const QString &originalSignature,
+ const QString &className,
+ const QStringList &possibleSignatures,
+ const AbstractMetaFunctionList &allFunctions);
+
+QString msgNoEnumTypeEntry(const EnumModelItem &enumItem,
+ const QString &className);
+
+
+QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
+ const QString &className,
+ const TypeEntry *t);
+
+QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
+ const QString &why);
+
+QString msgUnmatchedReturnType(const FunctionModelItem &functionItem,
+ const QString &why);
+
+QString msgSkippingFunction(const FunctionModelItem &functionItem,
+ const QString &signature, const QString &why);
+
+QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason);
+
+QString msgUnableToTranslateType(const QString &t, const QString &why);
+
+QString msgUnableToTranslateType(const TypeInfo &typeInfo,
+ const QString &why);
+
+QString msgCannotFindTypeEntry(const QString &t);
+
+QString msgCannotTranslateTemplateArgument(int i,
+ const TypeInfo &typeInfo,
+ const QString &why);
+
+QString msgDisallowThread(const AbstractMetaFunction *f);
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const char *what, const QString &name,
+ const QString &query);
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const AbstractMetaClass *metaClass,
+ const AbstractMetaFunction *function,
+ const QString &query);
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const AbstractMetaClass *metaClass,
+ const AbstractMetaEnum *e,
+ const QString &query);
+
+QString msgCannotFindDocumentation(const QString &fileName,
+ const AbstractMetaClass *metaClass,
+ const AbstractMetaField *f,
+ const QString &query);
+
+QString msgXpathDocModificationError(const DocModificationList& mods,
+ const QString &what);
+
+QString msgCannotOpenForReading(const QFile &f);
+
+QString msgCannotOpenForWriting(const QFile &f);
+
+QString msgCannotUseEnumAsInt(const QString &name);
+
+QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs);
+
+QString msgInvalidVersion(const QString &package, const QString &version);
+
+QString msgCyclicDependency(const QString &funcName, const QString &graphName,
+ const QVector<const AbstractMetaFunction *> &involvedConversions);
+
+QString msgUnknownOperator(const AbstractMetaFunction* func);
+
+QString msgWrongIndex(const char *varName, const QString &capture,
+ const AbstractMetaFunction *func);
+
+QString msgCannotFindType(const QString &type, const QString &variable,
+ const QString &why);
+
+QString msgCannotBuildMetaType(const QString &s);
+
+QString msgCouldNotFindMinimalConstructor(const QString &where, const QString &type);
+
+QString msgRejectReason(const TypeRejection &r, const QString &needle = QString());
+
+QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &message);
+
+QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context,
+ const QString &tag, const QString &location,
+ const QString &identifier, const QString &fallback);
+
+#endif // MESSAGES_H
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
index d862692dd..8bc9b24ac 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp
@@ -29,11 +29,15 @@
#include "codemodel.h"
+
+#include <clangparser/clangutils.h>
+
#include <algorithm>
#include <functional>
#include <iostream>
#include <QDebug>
#include <QDir>
+#include <QtCore/QStack>
// Predicate to find an item by name in a list of QSharedPointer<Item>
template <class T> class ModelItemNamePredicate : public std::unary_function<bool, QSharedPointer<T> >
@@ -140,16 +144,18 @@ TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs)
__result.setVolatile(__result.isVolatile() || __rhs.isVolatile());
if (__rhs.referenceType() > __result.referenceType())
__result.setReferenceType(__rhs.referenceType());
- __result.setIndirections(__result.indirections() + __rhs.indirections());
+ __result.m_indirections.append(__rhs.m_indirections);
__result.setArrayElements(__result.arrayElements() + __rhs.arrayElements());
+ __result.m_instantiations.append(__rhs.m_instantiations);
return __result;
}
bool TypeInfo::isVoid() const
{
- return m_indirections == 0 && m_referenceType == NoReference
+ return m_indirections.isEmpty() && m_referenceType == NoReference
&& m_arguments.isEmpty() && m_arrayElements.isEmpty()
+ && m_instantiations.isEmpty()
&& m_qualifiedName.size() == 1
&& m_qualifiedName.constFirst() == QLatin1String("void");
}
@@ -193,19 +199,76 @@ TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, Cod
return otherType;
}
+// Handler for clang::parseTemplateArgumentList() that populates
+// TypeInfo::m_instantiations
+class TypeInfoTemplateArgumentHandler :
+ public std::binary_function<void, int, const QStringRef &>
+{
+public:
+ explicit TypeInfoTemplateArgumentHandler(TypeInfo *t)
+ {
+ m_parseStack.append(t);
+ }
+
+ void operator()(int level, const QStringRef &name)
+ {
+ if (level > m_parseStack.size()) {
+ Q_ASSERT(!top()->m_instantiations.isEmpty());
+ m_parseStack.push(&top()->m_instantiations.back());
+ }
+ while (level < m_parseStack.size())
+ m_parseStack.pop();
+ TypeInfo instantiation;
+ instantiation.setQualifiedName(qualifiedName(name));
+ top()->addInstantiation(instantiation);
+ }
+
+private:
+ TypeInfo *top() const { return m_parseStack.back(); }
+
+ static QStringList qualifiedName(const QStringRef &name)
+ {
+ QStringList result;
+ const QVector<QStringRef> nameParts = name.split(QLatin1String("::"));
+ result.reserve(nameParts.size());
+ for (const QStringRef &p : nameParts)
+ result.append(p.toString());
+ return result;
+ }
+
+ QStack<TypeInfo *> m_parseStack;
+};
+
+QPair<int, int> TypeInfo::parseTemplateArgumentList(const QString &l, int from)
+{
+ return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from);
+}
+
QString TypeInfo::toString() const
{
QString tmp;
-
- tmp += m_qualifiedName.join(QLatin1String("::"));
if (isConstant())
- tmp += QLatin1String(" const");
+ tmp += QLatin1String("const ");
if (isVolatile())
- tmp += QLatin1String(" volatile");
+ tmp += QLatin1String("volatile ");
- if (indirections())
- tmp += QString(indirections(), QLatin1Char('*'));
+ tmp += m_qualifiedName.join(QLatin1String("::"));
+
+ if (const int instantiationCount = m_instantiations.size()) {
+ tmp += QLatin1Char('<');
+ for (int i = 0; i < instantiationCount; ++i) {
+ if (i)
+ tmp += QLatin1String(", ");
+ tmp += m_instantiations.at(i).toString();
+ }
+ if (tmp.endsWith(QLatin1Char('>')))
+ tmp += QLatin1Char(' ');
+ tmp += QLatin1Char('>');
+ }
+
+ for (Indirection i : m_indirections)
+ tmp.append(indirectionKeyword(i));
switch (referenceType()) {
case NoReference:
@@ -238,20 +301,6 @@ QString TypeInfo::toString() const
return tmp;
}
-QStringList TypeInfo::instantiationName() const
-{
- QStringList result = m_qualifiedName;
- if (const int argumentCount = m_arguments.size()) {
- QString &last = result.last();
- for (int i = 0; i < argumentCount; ++i) {
- last += i ? QLatin1String(", ") : QLatin1String("< ");
- last += m_arguments.at(i).toString();
- }
- last += QLatin1String(" >");
- }
- return result;
-}
-
bool TypeInfo::operator==(const TypeInfo &other) const
{
if (arrayElements().count() != other.arrayElements().count())
@@ -269,7 +318,73 @@ bool TypeInfo::operator==(const TypeInfo &other) const
return flags == other.flags
&& m_qualifiedName == other.m_qualifiedName
- && (!m_functionPointer || m_arguments == other.m_arguments);
+ && (!m_functionPointer || m_arguments == other.m_arguments)
+ && m_instantiations == other.m_instantiations;
+}
+
+QString TypeInfo::indirectionKeyword(Indirection i)
+{
+ return i == Indirection::Pointer
+ ? QStringLiteral("*") : QStringLiteral("*const");
+}
+
+static inline QString constQualifier() { return QStringLiteral("const"); }
+static inline QString volatileQualifier() { return QStringLiteral("volatile"); }
+
+bool TypeInfo::stripLeadingConst(QString *s)
+{
+ return stripLeadingQualifier(constQualifier(), s);
+}
+
+bool TypeInfo::stripLeadingVolatile(QString *s)
+{
+ return stripLeadingQualifier(volatileQualifier(), s);
+}
+
+bool TypeInfo::stripLeadingQualifier(const QString &qualifier, QString *s)
+{
+ // "const int x"
+ const int qualifierSize = qualifier.size();
+ if (s->size() < qualifierSize + 1 || !s->startsWith(qualifier)
+ || !s->at(qualifierSize).isSpace()) {
+ return false;
+ }
+ s->remove(0, qualifierSize + 1);
+ while (!s->isEmpty() && s->at(0).isSpace())
+ s->remove(0, 1);
+ return true;
+}
+
+// Helper functionality to simplify a raw standard type as returned by
+// clang_getCanonicalType() for g++ standard containers from
+// "std::__cxx11::list<int, std::allocator<int> >" or
+// "std::__1::list<int, std::allocator<int> >" -> "std::list<int>".
+
+bool TypeInfo::isStdType() const
+{
+ return m_qualifiedName.size() > 1
+ && m_qualifiedName.constFirst() == QLatin1String("std");
+}
+
+static inline bool discardStdType(const QString &name)
+{
+ return name == QLatin1String("allocator") || name == QLatin1String("less");
+}
+
+void TypeInfo::simplifyStdType()
+{
+ if (isStdType()) {
+ if (m_qualifiedName.at(1).startsWith(QLatin1String("__")))
+ m_qualifiedName.removeAt(1);
+ for (int t = m_instantiations.size() - 1; t >= 0; --t) {
+ if (m_instantiations.at(t).isStdType()) {
+ if (discardStdType(m_instantiations.at(t).m_qualifiedName.constLast()))
+ m_instantiations.removeAt(t);
+ else
+ m_instantiations[t].simplifyStdType();
+ }
+ }
+ }
}
#ifndef QT_NO_DEBUG_STREAM
@@ -292,8 +407,11 @@ void TypeInfo::formatDebug(QDebug &d) const
d << ", [const]";
if (m_volatile)
d << ", [volatile]";
- if (m_indirections)
- d << ", indirections=" << m_indirections;
+ if (!m_indirections.isEmpty()) {
+ d << ", indirections=";
+ for (auto i : m_indirections)
+ d << ' ' << TypeInfo::indirectionKeyword(i);
+ }
switch (m_referenceType) {
case NoReference:
break;
@@ -304,6 +422,11 @@ void TypeInfo::formatDebug(QDebug &d) const
d << ", [rvalref]";
break;
}
+ if (!m_instantiations.isEmpty()) {
+ d << ", template<";
+ formatSequence(d, m_instantiations.begin(), m_instantiations.end());
+ d << '>';
+ }
if (m_functionPointer) {
d << ", function ptr(";
formatSequence(d, m_arguments.begin(), m_arguments.end());
@@ -358,9 +481,7 @@ _CodeModelItem::_CodeModelItem(CodeModel *model, const QString &name, int kind)
{
}
-_CodeModelItem::~_CodeModelItem()
-{
-}
+_CodeModelItem::~_CodeModelItem() = default;
int _CodeModelItem::kind() const
{
@@ -532,9 +653,7 @@ QDebug operator<<(QDebug d, const _CodeModelItem *t)
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
-_ClassModelItem::~_ClassModelItem()
-{
-}
+_ClassModelItem::~_ClassModelItem() = default;
TemplateParameterList _ClassModelItem::templateParameters() const
{
@@ -624,9 +743,7 @@ FunctionModelItem _ScopeModelItem::declaredFunction(FunctionModelItem item)
return FunctionModelItem();
}
-_ScopeModelItem::~_ScopeModelItem()
-{
-}
+_ScopeModelItem::~_ScopeModelItem() = default;
void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration)
{
@@ -770,14 +887,6 @@ _NamespaceModelItem::~_NamespaceModelItem()
{
}
-QSet<NamespaceModelItem> _NamespaceModelItem::uniqueNamespaces() const
-{
- QSet<NamespaceModelItem> result;
- for (const NamespaceModelItem &n : m_namespaces)
- result.insert(n);
- return result;
-}
-
void _NamespaceModelItem::addNamespace(NamespaceModelItem item)
{
m_namespaces.append(item);
@@ -835,11 +944,9 @@ void _ArgumentModelItem::formatDebug(QDebug &d) const
}
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
-_FunctionModelItem::~_FunctionModelItem()
-{
-}
+_FunctionModelItem::~_FunctionModelItem() = default;
-bool _FunctionModelItem::isSimilar(FunctionModelItem other) const
+bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const
{
if (name() != other->name())
return false;
@@ -871,7 +978,7 @@ ArgumentList _FunctionModelItem::arguments() const
return m_arguments;
}
-void _FunctionModelItem::addArgument(ArgumentModelItem item)
+void _FunctionModelItem::addArgument(const ArgumentModelItem& item)
{
m_arguments.append(item);
}
@@ -896,6 +1003,21 @@ void _FunctionModelItem::setVariadics(bool isVariadics)
m_isVariadics = isVariadics;
}
+bool _FunctionModelItem::isNoExcept() const
+{
+ return m_exceptionSpecification == ExceptionSpecification::NoExcept;
+}
+
+ExceptionSpecification _FunctionModelItem::exceptionSpecification() const
+{
+ return m_exceptionSpecification;
+}
+
+void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e)
+{
+ m_exceptionSpecification = e;
+}
+
bool _FunctionModelItem::isDeleted() const
{
return m_isDeleted;
@@ -991,7 +1113,7 @@ void _FunctionModelItem::setInvokable(bool isInvokable)
void _FunctionModelItem::formatDebug(QDebug &d) const
{
_MemberModelItem::formatDebug(d);
- d << ", type=" << m_functionType;
+ d << ", type=" << m_functionType << ", exspec=" << int(m_exceptionSpecification);
if (m_isDeleted)
d << " [deleted!]";
if (m_isInline)
@@ -1091,9 +1213,7 @@ void _EnumModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
-_EnumeratorModelItem::~_EnumeratorModelItem()
-{
-}
+_EnumeratorModelItem::~_EnumeratorModelItem() = default;
QString _EnumeratorModelItem::stringValue() const
{
@@ -1114,9 +1234,7 @@ void _EnumeratorModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
-_TemplateParameterModelItem::~_TemplateParameterModelItem()
-{
-}
+_TemplateParameterModelItem::~_TemplateParameterModelItem() = default;
TypeInfo _TemplateParameterModelItem::type() const
{
@@ -1164,9 +1282,7 @@ CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const
return m_accessPolicy;
}
-_MemberModelItem::~_MemberModelItem()
-{
-}
+_MemberModelItem::~_MemberModelItem() = default;
void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy)
{
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index ac1fe26c1..0296a8cb2 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -36,6 +36,7 @@
#include "enumvalue.h"
#include <QtCore/QHash>
+#include <QtCore/QPair>
#include <QtCore/QSet>
#include <QtCore/QString>
#include <QtCore/QStringList>
@@ -100,6 +101,8 @@ class TypeInfo
{
friend class TypeParser;
public:
+ typedef QVector<Indirection> Indirections;
+
TypeInfo() : flags(0), m_referenceType(NoReference) {}
QStringList qualifiedName() const
@@ -137,14 +140,16 @@ public:
ReferenceType referenceType() const { return m_referenceType; }
void setReferenceType(ReferenceType r) { m_referenceType = r; }
- int indirections() const
- {
- return m_indirections;
- }
+ Indirections indirectionsV() const { return m_indirections; }
+ void setIndirectionsV(const Indirections &i) { m_indirections = i; }
+ void addIndirection(Indirection i) { m_indirections.append(i); }
+
+ // "Legacy", rename?
+ int indirections() const { return m_indirections.size(); }
void setIndirections(int indirections)
{
- m_indirections = indirections;
+ m_indirections = Indirections(indirections, Indirection::Pointer);
}
bool isFunctionPointer() const
@@ -165,6 +170,8 @@ public:
m_arrayElements = arrayElements;
}
+ void addArrayElement(const QString &a) { m_arrayElements.append(a); }
+
QVector<TypeInfo> arguments() const { return m_arguments; }
void setArguments(const QVector<TypeInfo> &arguments);
@@ -174,6 +181,15 @@ public:
m_arguments.append(arg);
}
+ QVector<TypeInfo> instantiations() const { return m_instantiations; }
+ void setInstantiations(const QVector<TypeInfo> &i) { m_instantiations = i; }
+ void addInstantiation(const TypeInfo &i) { m_instantiations.append(i); }
+ void clearInstantiations() { m_instantiations.clear(); }
+
+ bool isStdType() const;
+
+ QPair<int, int> parseTemplateArgumentList(const QString &l, int from = 0);
+
bool operator==(const TypeInfo &other) const;
bool operator!=(const TypeInfo &other) const
@@ -185,8 +201,6 @@ public:
QString toString() const;
- QStringList instantiationName() const;
-
static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs);
static TypeInfo resolveType(TypeInfo const &__type, CodeModelItem __scope);
@@ -194,12 +208,24 @@ public:
void formatDebug(QDebug &d) const;
#endif
+ static QString indirectionKeyword(Indirection i);
+
+ static bool stripLeadingConst(QString *s);
+ static bool stripLeadingVolatile(QString *s);
+ static bool stripLeadingQualifier(const QString &qualifier, QString *s);
+
+ void simplifyStdType();
+
private:
+ friend class TypeInfoTemplateArgumentHandler;
+
static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, CodeModelItem __scope);
QStringList m_qualifiedName;
QStringList m_arrayElements;
QVector<TypeInfo> m_arguments;
+ QVector<TypeInfo> m_instantiations;
+ Indirections m_indirections;
union {
uint flags;
@@ -208,8 +234,7 @@ private:
uint m_constant: 1;
uint m_volatile: 1;
uint m_functionPointer: 1;
- uint m_indirections: 6;
- uint m_padding: 23;
+ uint m_padding: 29;
};
};
@@ -409,8 +434,7 @@ public:
: _ScopeModelItem(model, name, kind) {}
~_NamespaceModelItem();
- NamespaceList namespaces() const { return m_namespaces; }
- QSet<NamespaceModelItem> uniqueNamespaces() const;
+ const NamespaceList &namespaces() const { return m_namespaces; }
void addNamespace(NamespaceModelItem item);
@@ -547,7 +571,7 @@ public:
ArgumentList arguments() const;
- void addArgument(ArgumentModelItem item);
+ void addArgument(const ArgumentModelItem& item);
CodeModel::FunctionType functionType() const;
void setFunctionType(CodeModel::FunctionType functionType);
@@ -582,7 +606,13 @@ public:
bool isVariadics() const;
void setVariadics(bool isVariadics);
- bool isSimilar(FunctionModelItem other) const;
+
+ bool isSimilar(const FunctionModelItem &other) const;
+
+ bool isNoExcept() const;
+
+ ExceptionSpecification exceptionSpecification() const;
+ void setExceptionSpecification(ExceptionSpecification e);
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
@@ -606,6 +636,7 @@ private:
};
uint m_flags;
};
+ ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown;
};
class _VariableModelItem: public _MemberModelItem
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
index b8a10ba93..1713ba42f 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h
@@ -41,4 +41,17 @@ enum EnumKind {
EnumClass // C++ 11 : enum class Foo { value1, value2 }
};
+enum class Indirection
+{
+ Pointer, // int *
+ ConstPointer // int *const
+};
+
+enum class ExceptionSpecification
+{
+ Unknown,
+ NoExcept,
+ Throws
+};
+
#endif // CODEMODEL_ENUMS_H
diff --git a/sources/shiboken2/ApiExtractor/parser/enumvalue.h b/sources/shiboken2/ApiExtractor/parser/enumvalue.h
index 4905e89ba..ea30c39bb 100644
--- a/sources/shiboken2/ApiExtractor/parser/enumvalue.h
+++ b/sources/shiboken2/ApiExtractor/parser/enumvalue.h
@@ -49,6 +49,7 @@ public:
Type type() { return m_type; }
qint64 value() const { return m_value; }
quint64 unsignedValue() const { return m_unsignedValue; }
+ bool isNullValue() const { return m_type == Signed ? m_value == 0 : m_unsignedValue == 0u; }
void setValue(qint64 v);
void setUnsignedValue(quint64 v);
diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
index b0058d6ea..809760450 100644
--- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken2/ApiExtractor/qtdocparser.cpp
@@ -28,6 +28,7 @@
#include "qtdocparser.h"
#include "abstractmetalang.h"
+#include "messages.h"
#include "reporthandler.h"
#include "typesystem.h"
diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
index 860a37d9d..e100ef493 100644
--- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
+++ b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt
@@ -4,13 +4,18 @@ find_package(Qt5Test)
find_package(Qt5Xml)
find_package(Qt5XmlPatterns)
+set(CMAKE_AUTORCC ON)
+
macro(declare_test testname)
# gone: qt4_automoc("${testname}.cpp")
- if (EXISTS "${testname}.h")
- add_executable(${testname} "${testname}.h ${testname}.cpp")
- else ()
- add_executable(${testname} "${testname}.cpp")
+ set(SOURCES "${testname}.cpp")
+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.h")
+ list(APPEND SOURCES "${testname}.h")
+ endif ()
+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.qrc")
+ list(APPEND SOURCES "${testname}.qrc")
endif ()
+ add_executable(${testname} ${SOURCES})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
@@ -35,8 +40,6 @@ declare_test(testabstractmetatype)
declare_test(testaddfunction)
declare_test(testarrayargument)
declare_test(testcodeinjection)
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/utf8code.txt"
- "${CMAKE_CURRENT_BINARY_DIR}/utf8code.txt" COPYONLY)
declare_test(testcontainer)
declare_test(testconversionoperator)
declare_test(testconversionruletag)
@@ -68,7 +71,5 @@ declare_test(testvoidarg)
declare_test(testtyperevision)
if (NOT DISABLE_DOCSTRINGS)
declare_test(testmodifydocumentation)
- configure_file("${CMAKE_CURRENT_SOURCE_DIR}/a.xml"
- "${CMAKE_CURRENT_BINARY_DIR}/a.xml" COPYONLY)
endif()
diff --git a/sources/shiboken2/ApiExtractor/tests/injectedcode.txt b/sources/shiboken2/ApiExtractor/tests/injectedcode.txt
new file mode 100644
index 000000000..872898810
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/injectedcode.txt
@@ -0,0 +1,5 @@
+// Bla
+// @snippet label
+code line
+// @snippet label
+// Bla
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
index 7f1361a7d..fc67ebba5 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp
@@ -31,6 +31,37 @@
#include "testutil.h"
#include <abstractmetalang.h>
#include <typesystem.h>
+#include <parser/codemodel.h>
+#include <typeparser.h>
+
+void TestAbstractMetaType::parsing_data()
+{
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("output");
+ QTest::newRow("primitive")
+ << QString::fromLatin1("int") << QString::fromLatin1("int");
+ QTest::newRow("ref")
+ << QString::fromLatin1("int &") << QString::fromLatin1("int&");
+ QTest::newRow("pointer")
+ << QString::fromLatin1("int **") << QString::fromLatin1("int**");
+ QTest::newRow("const ref")
+ << QString::fromLatin1("const int &") << QString::fromLatin1("const int&");
+ QTest::newRow("const pointer")
+ << QString::fromLatin1("const int **") << QString::fromLatin1("const int**");
+ QTest::newRow("const pointer const")
+ << QString::fromLatin1("const int *const*") << QString::fromLatin1("const int*const*");
+}
+
+void TestAbstractMetaType::parsing()
+{
+ QFETCH(QString, input);
+ QFETCH(QString, output);
+ QString errorMessage;
+ const TypeInfo ti = TypeParser::parse(input, &errorMessage);
+ QVERIFY2(errorMessage.isEmpty(), qPrintable(errorMessage));
+ const QString actual = ti.toString();
+ QCOMPARE(actual, output);
+}
void TestAbstractMetaType::testConstCharPtrType()
{
@@ -72,7 +103,8 @@ void TestAbstractMetaType::testApiVersionSupported()
<function signature='justAtest2()' since='1.1'/>\n\
<function signature='justAtest3()'/>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "1.0"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("1.0")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -90,7 +122,8 @@ void TestAbstractMetaType::testApiVersionNotSupported()
const char* xmlCode = "<typesystem package='Foo'>\n\
<value-type name='object' since='0.1'/>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
index b2aa7544f..b39a27a54 100644
--- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
+++ b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h
@@ -35,6 +35,8 @@ class TestAbstractMetaType : public QObject
{
Q_OBJECT
private slots:
+ void parsing_data();
+ void parsing();
void testConstCharPtrType();
void testCharType();
void testTypedef();
diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
index 2a953243e..db49942c9 100644
--- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp
@@ -366,7 +366,8 @@ void TestAddFunction::testAddFunctionWithApiVersion()
<inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
</add-function>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaFunctionList globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.count(), 1);
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
index 7bbde3bd4..9f71b495a 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp
@@ -34,19 +34,43 @@
#include <abstractmetalang.h>
#include <typesystem.h>
-void TestCodeInjections::testReadFileUtf8()
+void TestCodeInjections::testReadFile_data()
{
+ QTest::addColumn<QString>("filePath");
+ QTest::addColumn<QString>("snippet");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("utf8")
+ << QString::fromLatin1(":/utf8code.txt")
+ << QString()
+ << QString::fromUtf8("\xC3\xA1\xC3\xA9\xC3\xAD\xC3\xB3\xC3\xBA");
+
+ QTest::newRow("snippet")
+ << QString::fromLatin1(":/injectedcode.txt")
+ << QString::fromLatin1("label")
+ << QString::fromLatin1("code line");
+}
+
+void TestCodeInjections::testReadFile()
+{
+ QFETCH(QString, filePath);
+ QFETCH(QString, snippet);
+ QFETCH(QString, expected);
+
const char* cppCode ="struct A {};\n";
int argc = 0;
char *argv[] = {NULL};
QCoreApplication app(argc, argv);
- QString filePath = QDir::currentPath();
+
+ QString attribute = QLatin1String("file='") + filePath + QLatin1Char('\'');
+ if (!snippet.isEmpty())
+ attribute += QLatin1String(" snippet='") + snippet + QLatin1Char('\'');
+
QString xmlCode = QLatin1String("\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
- <conversion-rule file='") + filePath + QLatin1String("/utf8code.txt'/>\n\
- <inject-code class='target' file='") + filePath
- + QLatin1String("/utf8code.txt'/>\n\
+ <conversion-rule ") + attribute + QLatin1String("/>\n\
+ <inject-code class='target' ") + attribute + QLatin1String("/>\n\
</value-type>\n\
<value-type name='A::B'/>\n\
</typesystem>\n");
@@ -56,10 +80,9 @@ void TestCodeInjections::testReadFileUtf8()
const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
QString code = classA->typeEntry()->codeSnips().first().code();
- QString utf8Data = QString::fromUtf8("\xC3\xA1\xC3\xA9\xC3\xAD\xC3\xB3\xC3\xBA");
- QVERIFY(code.indexOf(utf8Data) != -1);
+ QVERIFY(code.indexOf(expected) != -1);
code = classA->typeEntry()->conversionRule();
- QVERIFY(code.indexOf(utf8Data) != -1);
+ QVERIFY(code.indexOf(expected) != -1);
}
void TestCodeInjections::testInjectWithValidApiVersion()
@@ -74,7 +97,8 @@ void TestCodeInjections::testInjectWithValidApiVersion()
</value-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "1.0"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("1.0")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
@@ -93,7 +117,8 @@ void TestCodeInjections::testInjectWithInvalidApiVersion()
</value-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
index bd5e7ece1..1ac873970 100644
--- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h
@@ -37,7 +37,8 @@ class TestCodeInjections : public QObject
{
Q_OBJECT
private slots:
- void testReadFileUtf8();
+ void testReadFile_data();
+ void testReadFile();
void testInjectWithValidApiVersion();
void testInjectWithInvalidApiVersion();
};
diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc
new file mode 100644
index 000000000..fd7616bd2
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource>
+ <file>utf8code.txt</file>
+ <file>injectedcode.txt</file>
+ </qresource>
+</RCC>
diff --git a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
index b46c23f56..6abebb922 100644
--- a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp
@@ -70,7 +70,8 @@ void TestDropTypeEntries::testDropEntries()
droppedEntries << QLatin1String("Foo.ObjectB") << QLatin1String("Foo.NamespaceA.InnerClassA");
droppedEntries << QLatin1String("Foo.NamespaceB") << QLatin1String("Foo.EnumB") << QLatin1String("Foo.funcB()");
droppedEntries << QLatin1String("Foo.NamespaceA.InnerNamespaceA");
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, Q_NULLPTR, droppedEntries));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false,
+ QString(), droppedEntries));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
@@ -129,7 +130,8 @@ static const char* xmlCode2 = "\
void TestDropTypeEntries::testDropEntryWithChildTags()
{
QStringList droppedEntries(QLatin1String("Foo.ValueA"));
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false, Q_NULLPTR, droppedEntries));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false,
+ QString(), droppedEntries));
QVERIFY(!builder.isNull());
QVERIFY(!AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA")));
}
diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
index 87f2608a1..ebdcf8d81 100644
--- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testenum.cpp
@@ -104,7 +104,8 @@ void TestEnum::testEnumWithApiVersion()
</value-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ true, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.count(), 1);
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
index 7911a5eb1..f615befb4 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -60,7 +60,7 @@ R"(<typesystem package="Foo">
QCOMPARE(docMods[1].code().trimmed(), QLatin1String("<para>Some changed contents here</para>"));
QCOMPARE(docMods[1].signature(), QString());
QtDocParser docParser;
- docParser.setDocumentationDataDirectory(QDir::currentPath());
+ docParser.setDocumentationDataDirectory(QLatin1String(":"));
docParser.fillDocumentation(classA);
const QString actualDocSimplified = classA->documentation().value().simplified();
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc
new file mode 100644
index 000000000..76b1bfc61
--- /dev/null
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource>
+ <file>a.xml</file>
+ </qresource>
+</RCC>
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
index d0a0c9c7a..af24689fe 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp
@@ -136,7 +136,8 @@ void TestModifyFunction::invalidateAfterUse()
</object-type>\n\
<object-type name='E' />\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
@@ -208,7 +209,8 @@ void TestModifyFunction::testWithApiVersion()
</modify-function>\n\
</object-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
@@ -220,6 +222,61 @@ void TestModifyFunction::testWithApiVersion()
QVERIFY(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0) != TypeSystem::CppOwnership);
}
+void TestModifyFunction::testAllowThread()
+{
+ const char cppCode[] =R"CPP(\
+struct A {
+ void f1();
+ void f2();
+ void f3();
+ int getter1() const;
+ int getter2() const;
+};
+)CPP";
+
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <object-type name='A'>
+ <modify-function signature='f2()' allow-thread='auto'/>
+ <modify-function signature='f3()' allow-thread='no'/>
+ <modify-function signature='getter2()const' allow-thread='yes'/>
+ </object-type>
+</typesystem>
+)XML";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QVERIFY(classA);
+
+ // Nothing specified, true
+ const AbstractMetaFunction *f1 = classA->findFunction(QLatin1String("f1"));
+ QVERIFY(f1);
+ QVERIFY(f1->allowThread());
+
+ // 'auto' specified, should be true for nontrivial function
+ const AbstractMetaFunction *f2 = classA->findFunction(QLatin1String("f2"));
+ QVERIFY(f2);
+ QVERIFY(f2->allowThread());
+
+ // 'no' specified, should be false
+ const AbstractMetaFunction *f3 = classA->findFunction(QLatin1String("f3"));
+ QVERIFY(f3);
+ QVERIFY(!f3->allowThread());
+
+ // Nothing specified, should be false for simple getter
+ const AbstractMetaFunction *getter1 = classA->findFunction(QLatin1String("getter1"));
+ QVERIFY(getter1);
+ QVERIFY(!getter1->allowThread());
+
+ // Forced to true simple getter
+ const AbstractMetaFunction *getter2 = classA->findFunction(QLatin1String("getter2"));
+ QVERIFY(getter2);
+ QVERIFY(getter2->allowThread()); // Forced to true simple getter
+}
+
void TestModifyFunction::testGlobalFunctionModification()
{
const char* cppCode ="\
@@ -258,4 +315,42 @@ void TestModifyFunction::testGlobalFunctionModification()
QCOMPARE(arg->defaultValueExpression(), QLatin1String("A()"));
}
+void TestModifyFunction::testExceptionSpecification()
+{
+ const char cppCode[] = R"CPP(
+struct A {
+ void unspecified();
+ void nonThrowing() noexcept;
+ void throwing() throw(int);
+};
+)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package="Foo">
+ <primitive-type name='int'/>
+ <object-type name='A'>
+ <modify-function signature='throwing()' exception-handling='auto-on'/>
+ </object-type>
+</typesystem>)XML";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(!builder.isNull());
+
+ const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(classA);
+
+ const AbstractMetaFunction *f = classA->findFunction(QStringLiteral("unspecified"));
+ QVERIFY(f);
+ QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Unknown);
+ QVERIFY(!f->generateExceptionHandling());
+
+ f = classA->findFunction(QStringLiteral("nonThrowing"));
+ QVERIFY(f);
+ QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::NoExcept);
+ QVERIFY(!f->generateExceptionHandling());
+
+ f = classA->findFunction(QStringLiteral("throwing"));
+ QVERIFY(f);
+ QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Throws);
+ QVERIFY(f->generateExceptionHandling());
+}
+
QTEST_APPLESS_MAIN(TestModifyFunction)
diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
index f116b5124..494f31991 100644
--- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
+++ b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h
@@ -37,10 +37,12 @@ class TestModifyFunction : public QObject
private slots:
void testOwnershipTransfer();
void testWithApiVersion();
+ void testAllowThread();
void testRenameArgument_data();
void testRenameArgument();
void invalidateAfterUse();
void testGlobalFunctionModification();
+ void testExceptionSpecification();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
index 11cda3317..38099c455 100644
--- a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp
@@ -82,7 +82,8 @@ void TestRefCountTag::testWithApiVersion()
</object-type>\n\
</typesystem>\n";
- QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, "0.1"));
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
+ false, QLatin1String("0.1")));
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
index 8d869e3f9..b1b171bae 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp
@@ -28,6 +28,7 @@
#include "testtemplates.h"
#include <QtTest/QTest>
+#include <QtCore/QTextStream>
#include <QTemporaryFile>
#include "testutil.h"
#include <abstractmetalang.h>
@@ -438,4 +439,122 @@ typedef Vector<int> IntVector;
QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >"));
}
+// Perform checks on template inheritance; a typedef of a template class
+// should result in rewritten types.
+void TestTemplates::testTemplateTypeDefs_data()
+{
+ QTest::addColumn<QString>("cpp");
+ QTest::addColumn<QString>("xml");
+
+ const char optionalClassDef[] = R"CPP(
+template<class T> // Some value type similar to std::optional
+class Optional {
+public:
+ T value() const { return m_value; }
+ operator bool() const { return m_success; }
+
+ T m_value;
+ bool m_success = false;
+};
+)CPP";
+
+ const char xmlPrefix[] = R"XML(
+<typesystem package='Foo'>
+ <primitive-type name='int'/>
+ <primitive-type name='bool'/>
+)XML";
+
+ const char xmlOptionalDecl[] = "<value-type name='Optional' generate='no'/>\n";
+ const char xmlOptionalIntDecl[] = "<value-type name='IntOptional'/>\n";
+ const char xmlPostFix[] = "</typesystem>\n";
+
+ // Flat, global namespace
+ QString cpp;
+ QTextStream(&cpp) << optionalClassDef
+ << "typedef Optional<int> IntOptional;\n";
+ QString xml;
+ QTextStream(&xml) << xmlPrefix << xmlOptionalDecl << xmlOptionalIntDecl
+ << "<typedef-type name='XmlIntOptional' source='Optional&lt;int&gt;'/>"
+ << xmlPostFix;
+ QTest::newRow("global-namespace")
+ << cpp << xml;
+
+ // Typedef from namespace Std
+ cpp.clear();
+ QTextStream(&cpp) << "namespace Std {\n" << optionalClassDef << "}\n"
+ << "typedef Std::Optional<int> IntOptional;\n";
+ xml.clear();
+ QTextStream(&xml) << xmlPrefix
+ << "<namespace-type name='Std'>\n" << xmlOptionalDecl
+ << "</namespace-type>\n" << xmlOptionalIntDecl
+ << "<typedef-type name='XmlIntOptional' source='Std::Optional&lt;int&gt;'/>"
+ << xmlPostFix;
+ QTest::newRow("namespace-Std")
+ << cpp << xml;
+
+ // Typedef from nested class
+ cpp.clear();
+ QTextStream(&cpp) << "class Outer {\npublic:\n" << optionalClassDef << "\n};\n"
+ << "typedef Outer::Optional<int> IntOptional;\n";
+ xml.clear();
+ QTextStream(&xml) << xmlPrefix
+ << "<object-type name='Outer'>\n" << xmlOptionalDecl
+ << "</object-type>\n" << xmlOptionalIntDecl
+ << "<typedef-type name='XmlIntOptional' source='Outer::Optional&lt;int&gt;'/>"
+ << xmlPostFix;
+ QTest::newRow("nested-class")
+ << cpp << xml;
+}
+
+void TestTemplates::testTemplateTypeDefs()
+{
+ QFETCH(QString, cpp);
+ QFETCH(QString, xml);
+
+ const QByteArray cppBa = cpp.toLocal8Bit();
+ const QByteArray xmlBa = xml.toLocal8Bit();
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppBa.constData(), xmlBa.constData(), true));
+ QVERIFY(!builder.isNull());
+ AbstractMetaClassList classes = builder->classes();
+
+ const AbstractMetaClass *optional = AbstractMetaClass::findClass(classes, QLatin1String("Optional"));
+ QVERIFY(optional);
+
+ // Find the typedef'ed class
+ const AbstractMetaClass *optionalInt =
+ AbstractMetaClass::findClass(classes, QLatin1String("IntOptional"));
+ QVERIFY(optionalInt);
+ QCOMPARE(optionalInt->templateBaseClass(), optional);
+
+ // Find the class typedef'ed in the typesystem XML
+ const AbstractMetaClass *xmlOptionalInt =
+ AbstractMetaClass::findClass(classes, QLatin1String("XmlIntOptional"));
+ QVERIFY(xmlOptionalInt);
+ QCOMPARE(xmlOptionalInt->templateBaseClass(), optional);
+
+ // Check whether the value() method now has an 'int' return
+ const AbstractMetaFunction *valueMethod =
+ optionalInt->findFunction(QLatin1String("value"));
+ QVERIFY(valueMethod);
+ QCOMPARE(valueMethod->type()->cppSignature(), QLatin1String("int"));
+
+ // ditto for typesystem XML
+ const AbstractMetaFunction *xmlValueMethod =
+ xmlOptionalInt->findFunction(QLatin1String("value"));
+ QVERIFY(xmlValueMethod);
+ QCOMPARE(xmlValueMethod->type()->cppSignature(), QLatin1String("int"));
+
+ // Check whether the m_value field is of type 'int'
+ const AbstractMetaField *valueField =
+ optionalInt->findField(QLatin1String("m_value"));
+ QVERIFY(valueField);
+ QCOMPARE(valueField->type()->cppSignature(), QLatin1String("int"));
+
+ // ditto for typesystem XML
+ const AbstractMetaField *xmlValueField =
+ xmlOptionalInt->findField(QLatin1String("m_value"));
+ QVERIFY(xmlValueField);
+ QCOMPARE(xmlValueField->type()->cppSignature(), QLatin1String("int"));
+}
+
QTEST_APPLESS_MAIN(TestTemplates)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.h b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
index 3e1565933..df3de18b9 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtemplates.h
+++ b/sources/shiboken2/ApiExtractor/tests/testtemplates.h
@@ -46,6 +46,8 @@ private slots:
void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration();
void testTypedefOfInstantiationOfTemplateClass();
void testContainerTypeIncompleteArgument();
+ void testTemplateTypeDefs_data();
+ void testTemplateTypeDefs();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
index 1ec7ce025..a7e88e437 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
+++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp
@@ -31,6 +31,7 @@
#include "testutil.h"
#include <abstractmetalang.h>
#include <typesystem.h>
+#include <typedatabase.h>
void TestTypeRevision::testRevisionAttr()
{
@@ -49,21 +50,55 @@ void TestTypeRevision::testRevisionAttr()
QVERIFY(!builder.isNull());
AbstractMetaClassList classes = builder->classes();
const AbstractMetaClass *rev0 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_0"));
- QCOMPARE(getTypeRevision(rev0->typeEntry()), 0);
+ QCOMPARE(rev0->typeEntry()->revision(), 0);
const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_1"));
- QCOMPARE(getTypeRevision(rev1->typeEntry()), 1);
+ QCOMPARE(rev1->typeEntry()->revision(), 1);
AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_2"));
- QCOMPARE(getTypeRevision(rev2->typeEntry()), 2);
+ QCOMPARE(rev2->typeEntry()->revision(), 2);
AbstractMetaEnum* rev3 = rev2->findEnum(QLatin1String("Rev_3"));
- QCOMPARE(getTypeRevision(rev3->typeEntry()), 3);
+ QCOMPARE(rev3->typeEntry()->revision(), 3);
FlagsTypeEntry* rev4 = rev3->typeEntry()->flags();
- QCOMPARE(getTypeRevision(rev4), 4);
+ QCOMPARE(rev4->revision(), 4);
AbstractMetaEnum* rev5 = rev2->findEnum(QLatin1String("Rev_5"));
- QCOMPARE(getTypeRevision(rev5->typeEntry()), 5);
- QCOMPARE(getTypeRevision(rev5->typeEntry()->flags()), 5);
+ const EnumTypeEntry *revEnumTypeEntry = rev5->typeEntry();
+ QCOMPARE(revEnumTypeEntry->revision(), 5);
+ QCOMPARE(revEnumTypeEntry->flags()->revision(), 5);
+}
+
+
+void TestTypeRevision::testVersion_data()
+{
+ QTest::addColumn<QString>("version");
+ QTest::addColumn<int>("expectedClassCount");
+
+ QTest::newRow("none") << QString() << 2;
+ QTest::newRow("1.0") << QString::fromLatin1("1.0") << 1; // Bar20 excluded
+ QTest::newRow("2.0") << QString::fromLatin1("2.0") << 2;
+}
+
+void TestTypeRevision::testVersion()
+{
+ QFETCH(QString, version);
+ QFETCH(int, expectedClassCount);
+
+ const char cppCode[] = R"CPP(
+class Bar {};
+class Bar20 {};
+)CPP";
+ const char xmlCode[] = R"XML(
+<typesystem package="Foo">
+ <value-type name="Bar"/>
+ <value-type name="Bar20" since="2.0"/>
+</typesystem>
+)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, version));
+ QVERIFY(!builder.isNull());
+
+ QCOMPARE(builder->classes().size(), expectedClassCount);
}
QTEST_APPLESS_MAIN(TestTypeRevision)
diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
index 4dfa241e3..3832c3883 100644
--- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
+++ b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h
@@ -37,6 +37,8 @@ class TestTypeRevision : public QObject
private slots:
void testRevisionAttr();
+ void testVersion_data();
+ void testVersion();
};
#endif
diff --git a/sources/shiboken2/ApiExtractor/tests/testutil.h b/sources/shiboken2/ApiExtractor/tests/testutil.h
index 6152793f5..c6ad19d7e 100644
--- a/sources/shiboken2/ApiExtractor/tests/testutil.h
+++ b/sources/shiboken2/ApiExtractor/tests/testutil.h
@@ -40,20 +40,23 @@ namespace TestUtil
{
static AbstractMetaBuilder *parse(const char *cppCode, const char *xmlCode,
bool silent = true,
- const char *apiVersion = Q_NULLPTR,
+ const QString &apiVersion = QString(),
const QStringList &dropTypeEntries = QStringList())
{
ReportHandler::setSilent(silent);
TypeDatabase* td = TypeDatabase::instance(true);
- if (apiVersion && !td->setApiVersion(QLatin1String("*"), QLatin1String(apiVersion)))
- return Q_NULLPTR;
+ if (apiVersion.isEmpty())
+ TypeDatabase::clearApiVersions();
+ else if (!td->setApiVersion(QLatin1String("*"), apiVersion))
+ return nullptr;
td->setDropTypeEntries(dropTypeEntries);
QBuffer buffer;
// parse typesystem
buffer.setData(xmlCode);
if (!buffer.open(QIODevice::ReadOnly))
return Q_NULLPTR;
- td->parseFile(&buffer);
+ if (!td->parseFile(&buffer))
+ return nullptr;
buffer.close();
// parse C++ code
QTemporaryFile tempSource(QDir::tempPath() + QLatin1String("/st_XXXXXX_main.cpp"));
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp
index 9529de40a..c0999e7ab 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken2/ApiExtractor/typedatabase.cpp
@@ -166,64 +166,66 @@ ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
return 0;
}
-FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
+static bool inline useType(const TypeEntry *t)
{
- TypeEntry* entry = findType(name);
- if (entry && entry->type() == TypeEntry::FunctionType)
- return static_cast<FunctionTypeEntry*>(entry);
- return 0;
+ return !t->isPrimitive()
+ || static_cast<const PrimitiveTypeEntry *>(t)->preferredTargetLangType();
}
-TypeEntry* TypeDatabase::findType(const QString& name) const
+FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
{
- const TypeEntryList &entries = findTypes(name);
+ const auto entries = findTypes(name);
for (TypeEntry *entry : entries) {
- if (entry &&
- (!entry->isPrimitive() || static_cast<PrimitiveTypeEntry *>(entry)->preferredTargetLangType())) {
- return entry;
- }
+ if (entry->type() == TypeEntry::FunctionType && useType(entry))
+ return static_cast<FunctionTypeEntry*>(entry);
}
return 0;
}
-TypeEntryList TypeDatabase::findTypes(const QString &name) const
+const TypeSystemTypeEntry *TypeDatabase::findTypeSystemType(const QString &name) const
{
- return m_entries.value(name);
+ const auto entries = findTypes(name);
+ for (const TypeEntry *entry : entries) {
+ if (entry->type() == TypeEntry::TypeSystemType)
+ return static_cast<const TypeSystemTypeEntry *>(entry);
+ }
+ return nullptr;
}
-SingleTypeEntryHash TypeDatabase::entries() const
+TypeEntry* TypeDatabase::findType(const QString& name) const
{
- TypeEntryHash entries = allEntries();
-
- SingleTypeEntryHash returned;
- for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it)
- returned.insert(it.key(), findType(it.key()));
+ const auto entries = findTypes(name);
+ for (TypeEntry *entry : entries) {
+ if (useType(entry))
+ return entry;
+ }
+ return nullptr;
+}
- return returned;
+TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypes(const QString &name) const
+{
+ const auto range = m_entries.equal_range(name);
+ return {range.first, range.second};
}
PrimitiveTypeEntryList TypeDatabase::primitiveTypes() const
{
- TypeEntryHash entries = allEntries();
PrimitiveTypeEntryList returned;
- for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
- for (TypeEntry *typeEntry : it.value()) {
- if (typeEntry->isPrimitive())
- returned.append(static_cast<PrimitiveTypeEntry *>(typeEntry));
- }
+ for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) {
+ TypeEntry *typeEntry = it.value();
+ if (typeEntry->isPrimitive())
+ returned.append(static_cast<PrimitiveTypeEntry *>(typeEntry));
}
return returned;
}
ContainerTypeEntryList TypeDatabase::containerTypes() const
{
- TypeEntryHash entries = allEntries();
ContainerTypeEntryList returned;
- for (TypeEntryHash::const_iterator it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
- for (TypeEntry *typeEntry : it.value()) {
- if (typeEntry->isContainer())
- returned.append(static_cast<ContainerTypeEntry *>(typeEntry));
- }
+ for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) {
+ TypeEntry *typeEntry = it.value();
+ if (typeEntry->isContainer())
+ returned.append(static_cast<ContainerTypeEntry *>(typeEntry));
}
return returned;
}
@@ -263,6 +265,8 @@ static inline QString msgRejectReason(const TypeRejection &r, const QString &nee
str << " matches class \"" << r.className.pattern() << "\" and \"" << needle
<< "\" matches \"" << r.pattern.pattern() << '"';
break;
+ case TypeRejection::Invalid:
+ break;
}
return result;
}
@@ -303,9 +307,52 @@ bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumN
return findRejection(m_rejections, TypeRejection::Enum, className, enumName, reason);
}
-void TypeDatabase::addType(TypeEntry *e)
+TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry,
+ QString *errorMessage)
+{
+ QString sourceName = typedefEntry->sourceType();
+ const int lessThanPos = sourceName.indexOf(QLatin1Char('<'));
+ if (lessThanPos != -1)
+ sourceName.truncate(lessThanPos);
+ ComplexTypeEntry *source = nullptr;
+ for (TypeEntry *e : findTypes(sourceName)) {
+ switch (e->type()) {
+ case TypeEntry::BasicValueType:
+ case TypeEntry::ContainerType:
+ case TypeEntry::InterfaceType:
+ case TypeEntry::ObjectType:
+ case TypeEntry::SmartPointerType:
+ source = dynamic_cast<ComplexTypeEntry *>(e);
+ Q_ASSERT(source);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!source) {
+ if (errorMessage)
+ *errorMessage = QLatin1String("Unable to resolve typedef \"")
+ + typedefEntry->sourceType() + QLatin1Char('"');
+ return nullptr;
+ }
+
+ ComplexTypeEntry *result = static_cast<ComplexTypeEntry *>(source->clone());
+ result->useAsTypedef(typedefEntry);
+ typedefEntry->setSource(source);
+ typedefEntry->setTarget(result);
+ m_typedefEntries.insert(typedefEntry->qualifiedCppName(), typedefEntry);
+ return result;
+}
+
+bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage)
{
- m_entries[e->qualifiedCppName()].append(e);
+ if (e->type() == TypeEntry::TypedefType) {
+ e = resolveTypeDefEntry(static_cast<TypedefEntry *>(e), errorMessage);
+ if (Q_UNLIKELY(!e))
+ return false;
+ }
+ m_entries.insert(e->qualifiedCppName(), e);
+ return true;
}
bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName,
@@ -339,7 +386,7 @@ FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const
fte = m_flagsEntries.value(name);
if (!fte) {
//last hope, search for flag without scope inside of flags hash
- for (SingleTypeEntryHash::const_iterator it = m_flagsEntries.cbegin(), end = m_flagsEntries.cend(); it != end; ++it) {
+ for (auto it = m_flagsEntries.cbegin(), end = m_flagsEntries.cend(); it != end; ++it) {
if (it.key().endsWith(name)) {
fte = it.value();
break;
@@ -427,12 +474,13 @@ bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMe
pattern.append(QLatin1Char('$'));
}
- const QRegularExpression expression(pattern);
+ QRegularExpression expression(pattern);
if (!expression.isValid()) {
*errorMessage = QLatin1String("Invalid message pattern \"") + warning
+ QLatin1String("\": ") + expression.errorString();
return false;
}
+ expression.setPatternOptions(expression.patternOptions() | QRegularExpression::MultilineOption);
m_suppressedWarnings.append(expression);
return true;
@@ -518,16 +566,21 @@ bool TypeDatabase::parseFile(QIODevice* device, bool generate)
{
QXmlStreamReader reader(device);
Handler handler(this, generate);
- return handler.parse(reader);
+ const bool result = handler.parse(reader);
+ if (!result)
+ qCWarning(lcShiboken, "%s", qPrintable(handler.errorString()));
+ return result;
}
PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
{
- const TypeEntryList &entries = findTypes(name);
-
+ const auto entries = findTypes(name);
for (TypeEntry *entry : entries) {
- if (entry && entry->isPrimitive() && static_cast<PrimitiveTypeEntry*>(entry)->preferredTargetLangType())
- return static_cast<PrimitiveTypeEntry*>(entry);
+ if (entry->isPrimitive()) {
+ PrimitiveTypeEntry *pe = static_cast<PrimitiveTypeEntry *>(entry);
+ if (pe->preferredTargetLangType())
+ return pe;
+ }
}
return 0;
@@ -535,9 +588,9 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
{
- const TypeEntryList &entries = findTypes(name);
+ const auto entries = findTypes(name);
for (TypeEntry *entry : entries) {
- if (entry && entry->isComplex())
+ if (entry->isComplex() && useType(entry))
return static_cast<ComplexTypeEntry*>(entry);
}
return 0;
@@ -545,9 +598,9 @@ ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
{
- const TypeEntryList &entries = findTypes(name);
+ const auto entries = findTypes(name);
for (TypeEntry *entry : entries) {
- if (entry && entry->isObject())
+ if (entry && entry->isObject() && useType(entry))
return static_cast<ObjectTypeEntry*>(entry);
}
return 0;
@@ -555,9 +608,9 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
NamespaceTypeEntry* TypeDatabase::findNamespaceType(const QString& name) const
{
- const TypeEntryList &entries = findTypes(name);
+ const auto entries = findTypes(name);
for (TypeEntry *entry : entries) {
- if (entry && entry->isNamespace())
+ if (entry->isNamespace() && useType(entry))
return static_cast<NamespaceTypeEntry*>(entry);
}
return 0;
@@ -574,75 +627,64 @@ void TypeDatabase::setDropTypeEntries(QStringList dropTypeEntries)
m_dropTypeEntries.sort();
}
-// Using std::pair to save some memory
-// the pair means (revision, typeIndex)
-// This global variable exists only because we can't break the ABI
-typedef QHash<const TypeEntry*, std::pair<int, int> > TypeRevisionMap;
-Q_GLOBAL_STATIC(TypeRevisionMap, typeEntryFields);
static bool computeTypeIndexes = true;
static int maxTypeIndex;
-int getTypeRevision(const TypeEntry* typeEntry)
+static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2)
{
- return typeEntryFields()->value(typeEntry).first;
-}
-
-void setTypeRevision(TypeEntry* typeEntry, int revision)
-{
- (*typeEntryFields())[typeEntry].first = revision;
- computeTypeIndexes = true;
-}
-
-static bool compareTypeEntriesByName(const TypeEntry* t1, const TypeEntry* t2)
-{
- return t1->qualifiedCppName() < t2->qualifiedCppName();
+ if (t1->revision() < t2->revision())
+ return true;
+ return t1->revision() == t2->revision()
+ && t1->qualifiedCppName() < t2->qualifiedCppName();
}
static void _computeTypeIndexes()
{
TypeDatabase* tdb = TypeDatabase::instance();
- typedef QMap<int, TypeEntryList> GroupedTypeEntries;
- GroupedTypeEntries groupedEntries;
+
+ TypeEntryList list;
// Group type entries by revision numbers
- const TypeEntryHash &allEntries = tdb->allEntries();
- for (TypeEntryHash::const_iterator tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) {
- for (TypeEntry *entry : tit.value()) {
- if (entry->isPrimitive()
- || entry->isContainer()
- || entry->isFunction()
- || !entry->generateCode()
- || entry->isEnumValue()
- || entry->isVarargs()
- || entry->isTypeSystem()
- || entry->isVoid()
- || entry->isCustom())
- continue;
- groupedEntries[getTypeRevision(entry)] << entry;
- }
- }
+ const auto &allEntries = tdb->entries();
+ list.reserve(allEntries.size());
+ for (auto tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) {
+ TypeEntry *entry = tit.value();
+ if (entry->isPrimitive()
+ || entry->isContainer()
+ || entry->isFunction()
+ || !entry->generateCode()
+ || entry->isEnumValue()
+ || entry->isVarargs()
+ || entry->isTypeSystem()
+ || entry->isVoid()
+ || entry->isCustom())
+ continue;
+ if (!list.contains(entry)) // Remove duplicates
+ list.append(entry);
+ }
+
+ // Sort the type entries by revision, name
+ std::sort(list.begin(), list.end(), typeEntryLessThan);
maxTypeIndex = 0;
- GroupedTypeEntries::iterator it = groupedEntries.begin();
- for (; it != groupedEntries.end(); ++it) {
- // Remove duplicates
- TypeEntryList::iterator newEnd = std::unique(it.value().begin(), it.value().end());
- it.value().erase(newEnd, it.value().end());
- // Sort the type entries by name
- qSort(it.value().begin(), newEnd, compareTypeEntriesByName);
-
- for (TypeEntry *entry : qAsConst(it.value())) {
- (*typeEntryFields())[entry].second = maxTypeIndex++;
- }
- }
+ for (TypeEntry *e : qAsConst(list))
+ e->setSbkIndex(maxTypeIndex++);
computeTypeIndexes = false;
}
-int getTypeIndex(const TypeEntry* typeEntry)
+void TypeEntry::setRevision(int r)
+{
+ if (m_revision != r) {
+ m_revision = r;
+ computeTypeIndexes = true;
+ }
+}
+
+int TypeEntry::sbkIndex() const
{
if (computeTypeIndexes)
_computeTypeIndexes();
- return typeEntryFields()->value(typeEntry).second;
+ return m_sbkIndex;
}
int getMaxTypeIndex()
@@ -652,6 +694,11 @@ int getMaxTypeIndex()
return maxTypeIndex;
}
+void TypeDatabase::clearApiVersions()
+{
+ apiVersions()->clear();
+}
+
bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QString &version)
{
const QString packagePattern = wildcardToRegExp(packageWildcardPattern.trimmed());
@@ -673,9 +720,11 @@ bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QS
}
bool TypeDatabase::checkApiVersion(const QString &package,
- const QVersionNumber &versionNumber) const
+ const QVersionNumber &versionNumber)
{
const ApiVersions &versions = *apiVersions();
+ if (versions.isEmpty()) // Nothing specified: use latest.
+ return true;
for (int i = 0, size = versions.size(); i < size; ++i) {
if (versions.at(i).first.match(package).hasMatch())
return versions.at(i).second >= versionNumber;
@@ -684,33 +733,111 @@ bool TypeDatabase::checkApiVersion(const QString &package,
}
#ifndef QT_NO_DEBUG_STREAM
+
+#define FORMAT_BOOL(name, var) \
+ if (var) \
+ d << ", [" << name << ']';
+
+#define FORMAT_NONEMPTY_STRING(name, var) \
+ if (!var.isEmpty()) \
+ d << ", " << name << "=\"" << var << '"';
+
+#define FORMAT_LIST_SIZE(name, var) \
+ if (!var.isEmpty()) \
+ d << ", " << var.size() << ' ' << name;
+
+template <class Container, class Separator>
+static void formatList(QDebug &d, const char *name, const Container &c, Separator sep)
+{
+ if (const int size = c.size()) {
+ d << ", " << name << '[' << size << "]=(";
+ for (int i = 0; i < size; ++i) {
+ if (i)
+ d << sep;
+ d << c.at(i);
+ }
+ d << ')';
+ }
+}
+
+void TypeEntry::formatDebug(QDebug &d) const
+{
+ const QString cppName = qualifiedCppName();
+ d << '"' << m_name << '"';
+ if (m_name != cppName)
+ d << "\", cppName=\"" << cppName << '"';
+ d << ", type=" << m_type << ", codeGeneration=0x"
+ << hex << m_codeGeneration << dec;
+ FORMAT_NONEMPTY_STRING("package", m_targetLangPackage)
+ FORMAT_BOOL("stream", m_stream)
+ FORMAT_LIST_SIZE("codeSnips", m_codeSnips)
+ FORMAT_NONEMPTY_STRING("conversionRule", m_conversionRule)
+ if (!m_version.isNull() && m_version > QVersionNumber(0, 0))
+ d << ", version=" << m_version;
+ if (m_revision)
+ d << ", revision=" << m_revision;
+ if (m_sbkIndex)
+ d << ", sbkIndex=" << m_sbkIndex;
+ if (m_include.isValid())
+ d << ", include=" << m_include;
+ formatList(d, "extraIncludes", m_extraIncludes, ", ");
+}
+
+void ComplexTypeEntry::formatDebug(QDebug &d) const
+{
+ TypeEntry::formatDebug(d);
+ FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
+ FORMAT_BOOL("QObject", m_qobject)
+ FORMAT_BOOL("polymorphicBase", m_polymorphicBase)
+ FORMAT_BOOL("genericClass", m_genericClass)
+ FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread)
+ if (m_typeFlags != 0)
+ d << ", typeFlags=" << m_typeFlags;
+ d << ", copyableFlag=" << m_copyableFlag
+ << ", except=" << int(m_exceptionHandling);
+ FORMAT_NONEMPTY_STRING("defaultSuperclass", m_defaultSuperclass)
+ FORMAT_NONEMPTY_STRING("polymorphicIdValue", m_polymorphicIdValue)
+ FORMAT_NONEMPTY_STRING("lookupName", m_lookupName)
+ FORMAT_NONEMPTY_STRING("targetType", m_targetType)
+ FORMAT_NONEMPTY_STRING("hash", m_hashFunction)
+ FORMAT_LIST_SIZE("addedFunctions", m_addedFunctions)
+ formatList(d, "functionMods", m_functionMods, ", ");
+ FORMAT_LIST_SIZE("fieldMods", m_fieldMods)
+}
+
+void TypedefEntry::formatDebug(QDebug &d) const
+{
+ ComplexTypeEntry::formatDebug(d);
+ d << ", sourceType=\"" << m_sourceType << '"'
+ << ", source=" << m_source << ", target=" << m_target;
+}
+
+void EnumTypeEntry::formatDebug(QDebug &d) const
+{
+ TypeEntry::formatDebug(d);
+ FORMAT_NONEMPTY_STRING("package", m_packageName)
+ FORMAT_NONEMPTY_STRING("qualifier", m_qualifier)
+ FORMAT_NONEMPTY_STRING("targetLangName", m_targetLangName)
+ if (m_flags)
+ d << ", flags=(" << m_flags << ')';
+}
+
+void ContainerTypeEntry::formatDebug(QDebug &d) const
+{
+ ComplexTypeEntry::formatDebug(d);
+ d << ", type=" << m_type << ",\"" << typeName() << '"';
+}
+
QDebug operator<<(QDebug d, const TypeEntry *te)
{
QDebugStateSaver saver(d);
d.noquote();
d.nospace();
d << "TypeEntry(";
- if (te) {
- const QString name = te->name();
- const QString cppName = te->qualifiedCppName();
- d << '"' << name << '"';
- if (name != cppName)
- d << "\", cppName=\"" << cppName << '"';
- d << ", type=" << te->type();
- if (te->include().isValid())
- d << ", include=" << te->include();
- const IncludeList &extraIncludes = te->extraIncludes();
- if (const int count = extraIncludes.size()) {
- d << ", extraIncludes[" << count << "]=";
- for (int i = 0; i < count; ++i) {
- if (i)
- d << ", ";
- d << extraIncludes.at(i);
- }
- }
- } else {
+ if (te)
+ te->formatDebug(d);
+ else
d << '0';
- }
d << ')';
return d;
}
@@ -732,25 +859,14 @@ QDebug operator<<(QDebug d, const TemplateEntry *te)
void TypeDatabase::formatDebug(QDebug &d) const
{
- typedef TypeEntryHash::ConstIterator Eit;
- typedef SingleTypeEntryHash::ConstIterator Sit;
- typedef TemplateEntryHash::ConstIterator TplIt;
d << "TypeDatabase("
<< "entries[" << m_entries.size() << "]=";
- for (Eit it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) {
- const int count = it.value().size();
- d << '"' << it.key() << "\" [" << count << "]: (";
- for (int t = 0; t < count; ++t) {
- if (t)
- d << ", ";
- d << it.value().at(t);
- }
- d << ")\n";
- }
+ for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it)
+ d << " " << it.value() << '\n';
if (!m_templates.isEmpty()) {
d << "templates[" << m_templates.size() << "]=(";
- const TplIt begin = m_templates.cbegin();
- for (TplIt it = begin, end = m_templates.cend(); it != end; ++it) {
+ const auto begin = m_templates.cbegin();
+ for (auto it = begin, end = m_templates.cend(); it != end; ++it) {
if (it != begin)
d << ", ";
d << it.value();
@@ -759,15 +875,17 @@ void TypeDatabase::formatDebug(QDebug &d) const
}
if (!m_flagsEntries.isEmpty()) {
d << "flags[" << m_flagsEntries.size() << "]=(";
- const Sit begin = m_flagsEntries.cbegin();
- for (Sit it = begin, end = m_flagsEntries.cend(); it != end; ++it) {
+ const auto begin = m_flagsEntries.cbegin();
+ for (auto it = begin, end = m_flagsEntries.cend(); it != end; ++it) {
if (it != begin)
d << ", ";
d << it.value();
}
d << ")\n";
}
- d <<"\nglobalUserFunctions=" << m_globalUserFunctions << ')';
+ d <<"\nglobalUserFunctions=" << m_globalUserFunctions << '\n';
+ formatList(d, "globalFunctionMods", m_functionMods, '\n');
+ d << ')';
}
QDebug operator<<(QDebug d, const TypeDatabase &db)
diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h
index 2e7b009c2..247d74362 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase.h
@@ -54,13 +54,12 @@ struct TypeRejection;
QT_FORWARD_DECLARE_CLASS(QDebug)
-void setTypeRevision(TypeEntry* typeEntry, int revision);
-int getTypeRevision(const TypeEntry* typeEntry);
-int getTypeIndex(const TypeEntry* typeEntry);
int getMaxTypeIndex();
class ContainerTypeEntry;
class PrimitiveTypeEntry;
+class TypeSystemTypeEntry;
+
class TypeDatabase
{
TypeDatabase();
@@ -91,12 +90,12 @@ public:
NamespaceTypeEntry* findNamespaceType(const QString& name) const;
ContainerTypeEntry* findContainerType(const QString& name) const;
FunctionTypeEntry* findFunctionType(const QString& name) const;
+ const TypeSystemTypeEntry *findTypeSystemType(const QString &name) const;
TypeEntry* findType(const QString& name) const;
- TypeEntryHash allEntries() const { return m_entries; }
-
- SingleTypeEntryHash entries() const;
+ const TypeEntryMultiMap &entries() const { return m_entries; }
+ const TypedefEntryMap &typedefEntries() const { return m_typedefEntries; }
PrimitiveTypeEntryList primitiveTypes() const;
@@ -115,7 +114,7 @@ public:
bool isReturnTypeRejected(const QString& className, const QString& typeName,
QString *reason = nullptr) const;
- void addType(TypeEntry* e);
+ bool addType(TypeEntry* e, QString *errorMessage = nullptr);
FlagsTypeEntry* findFlagsType(const QString& name) const;
void addFlagsType(FlagsTypeEntry* fte);
@@ -147,9 +146,10 @@ public:
bool parseFile(QIODevice* device, bool generate = true);
- bool setApiVersion(const QString& package, const QString& version);
+ static bool setApiVersion(const QString& package, const QString& version);
+ static void clearApiVersions();
- bool checkApiVersion(const QString &package, const QVersionNumber &version) const;
+ static bool checkApiVersion(const QString &package, const QVersionNumber &version);
bool hasDroppedTypeEntries() const { return !m_dropTypeEntries.isEmpty(); }
@@ -163,12 +163,14 @@ public:
void formatDebug(QDebug &d) const;
#endif
private:
- TypeEntryList findTypes(const QString &name) const;
+ TypeEntryMultiMapConstIteratorRange findTypes(const QString &name) const;
+ TypeEntry *resolveTypeDefEntry(TypedefEntry *typedefEntry, QString *errorMessage);
bool m_suppressWarnings;
- TypeEntryHash m_entries;
- SingleTypeEntryHash m_flagsEntries;
- TemplateEntryHash m_templates;
+ TypeEntryMultiMap m_entries;
+ TypeEntryMap m_flagsEntries;
+ TypedefEntryMap m_typedefEntries;
+ TemplateEntryMap m_templates;
QVector<QRegularExpression> m_suppressedWarnings;
AddedFunctionList m_globalUserFunctions;
diff --git a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
index 083602322..fbbbabe43 100644
--- a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
+++ b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h
@@ -29,7 +29,7 @@
#ifndef TYPEDATABASE_TYPEDEFS_H
#define TYPEDATABASE_TYPEDEFS_H
-#include <QtCore/QHash>
+#include <QtCore/QMultiMap>
#include <QtCore/QString>
#include <QtCore/QVector>
@@ -37,11 +37,28 @@ class ContainerTypeEntry;
class PrimitiveTypeEntry;
class TemplateEntry;
class TypeEntry;
+class TypedefEntry;
typedef QVector<TypeEntry *> TypeEntryList;
-typedef QHash<QString, TypeEntryList> TypeEntryHash;
-typedef QHash<QString, TypeEntry *> SingleTypeEntryHash;
-typedef QHash<QString, TemplateEntry *> TemplateEntryHash;
+typedef QMap<QString, TemplateEntry *> TemplateEntryMap;
+
+template <class Key, class Value>
+struct QMultiMapConstIteratorRange // A range of iterator for a range-based for loop
+{
+ using ConstIterator = typename QMultiMap<Key, Value>::const_iterator;
+
+ ConstIterator begin() const { return m_begin; }
+ ConstIterator end() const { return m_end; }
+
+ ConstIterator m_begin;
+ ConstIterator m_end;
+};
+
+typedef QMultiMap<QString, TypeEntry *> TypeEntryMultiMap;
+typedef QMultiMapConstIteratorRange<QString, TypeEntry *> TypeEntryMultiMapConstIteratorRange;
+
+typedef QMap<QString, TypeEntry *> TypeEntryMap;
+typedef QMap<QString, TypedefEntry *> TypedefEntryMap;
typedef QVector<const ContainerTypeEntry *> ContainerTypeEntryList;
typedef QVector<const PrimitiveTypeEntry *> PrimitiveTypeEntryList;
diff --git a/sources/shiboken2/ApiExtractor/typeparser.cpp b/sources/shiboken2/ApiExtractor/typeparser.cpp
index 02c85421b..c440fb66d 100644
--- a/sources/shiboken2/ApiExtractor/typeparser.cpp
+++ b/sources/shiboken2/ApiExtractor/typeparser.cpp
@@ -49,13 +49,14 @@ public:
GreaterThanToken,
ConstToken,
+ VolatileToken,
Identifier,
NoToken,
InvalidToken
};
Scanner(const QString &s)
- : m_pos(0), m_length(s.length()), m_chars(s.constData())
+ : m_pos(0), m_length(s.length()), m_tokenStart(-1), m_chars(s.constData())
{
}
@@ -137,13 +138,30 @@ Scanner::Token Scanner::nextToken(QString *errorMessage)
}
}
- if (tok == Identifier && m_pos - m_tokenStart == 5) {
- if (m_chars[m_tokenStart] == QLatin1Char('c')
- && m_chars[m_tokenStart + 1] == QLatin1Char('o')
- && m_chars[m_tokenStart + 2] == QLatin1Char('n')
- && m_chars[m_tokenStart + 3] == QLatin1Char('s')
- && m_chars[m_tokenStart + 4] == QLatin1Char('t'))
- tok = ConstToken;
+ if (tok == Identifier) {
+ switch (m_pos - m_tokenStart) {
+ case 5:
+ if (m_chars[m_tokenStart] == QLatin1Char('c')
+ && m_chars[m_tokenStart + 1] == QLatin1Char('o')
+ && m_chars[m_tokenStart + 2] == QLatin1Char('n')
+ && m_chars[m_tokenStart + 3] == QLatin1Char('s')
+ && m_chars[m_tokenStart + 4] == QLatin1Char('t')) {
+ tok = ConstToken;
+ }
+ break;
+ case 8:
+ if (m_chars[m_tokenStart] == QLatin1Char('v')
+ && m_chars[m_tokenStart + 1] == QLatin1Char('o')
+ && m_chars[m_tokenStart + 2] == QLatin1Char('l')
+ && m_chars[m_tokenStart + 3] == QLatin1Char('a')
+ && m_chars[m_tokenStart + 4] == QLatin1Char('t')
+ && m_chars[m_tokenStart + 5] == QLatin1Char('i')
+ && m_chars[m_tokenStart + 6] == QLatin1Char('l')
+ && m_chars[m_tokenStart + 7] == QLatin1Char('e')) {
+ tok = VolatileToken;
+ }
+ break;
+ }
}
return tok;
@@ -167,6 +185,7 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
bool colon_prefix = false;
bool in_array = false;
QString array;
+ bool seenStar = false;
Scanner::Token tok = scanner.nextToken(errorMessage);
while (tok != Scanner::NoToken) {
@@ -191,7 +210,8 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
switch (tok) {
case Scanner::StarToken:
- ++stack.top()->m_indirections;
+ seenStar = true;
+ stack.top()->addIndirection(Indirection::Pointer);
break;
case Scanner::AmpersandToken:
@@ -212,14 +232,14 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
}
break;
case Scanner::LessThanToken:
- stack.top()->m_arguments << TypeInfo();
- stack.push(&stack.top()->m_arguments.last());
+ stack.top()->m_instantiations << TypeInfo();
+ stack.push(&stack.top()->m_instantiations.last());
break;
case Scanner::CommaToken:
stack.pop();
- stack.top()->m_arguments << TypeInfo();
- stack.push(&stack.top()->m_arguments.last());
+ stack.top()->m_instantiations << TypeInfo();
+ stack.push(&stack.top()->m_instantiations.last());
break;
case Scanner::GreaterThanToken:
@@ -231,7 +251,16 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
break;
case Scanner::ConstToken:
- stack.top()->m_constant = true;
+ if (seenStar) { // "int *const": Last indirection is const.
+ Q_ASSERT(!stack.top()->m_indirections.isEmpty());
+ *stack.top()->m_indirections.rbegin() = Indirection::ConstPointer;
+ } else {
+ stack.top()->m_constant = true;
+ }
+ break;
+
+ case Scanner::VolatileToken:
+ stack.top()->m_volatile = true;
break;
case Scanner::OpenParenToken: // function pointers not supported
diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp
index 8e0e4437a..e82221a40 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken2/ApiExtractor/typesystem.cpp
@@ -29,35 +29,75 @@
#include "typesystem.h"
#include "typesystem_p.h"
#include "typedatabase.h"
+#include "messages.h"
#include "reporthandler.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QRegularExpression>
#include <QtCore/QSet>
+#include <QtCore/QStringView>
+#include <QtCore/QStringAlgorithms>
#include <QtCore/QXmlStreamAttributes>
#include <QtCore/QXmlStreamReader>
+#include <algorithm>
+
+const char *TARGET_CONVERSION_RULE_FLAG = "0";
+const char *NATIVE_CONVERSION_RULE_FLAG = "1";
+
static QString strings_Object = QLatin1String("Object");
static QString strings_String = QLatin1String("String");
static QString strings_char = QLatin1String("char");
static QString strings_jchar = QLatin1String("jchar");
static QString strings_jobject = QLatin1String("jobject");
+static inline QString allowThreadAttribute() { return QStringLiteral("allow-thread"); }
static inline QString colonColon() { return QStringLiteral("::"); }
+static inline QString copyableAttribute() { return QStringLiteral("copyable"); }
+static inline QString accessAttribute() { return QStringLiteral("access"); }
+static inline QString actionAttribute() { return QStringLiteral("action"); }
static inline QString quoteAfterLineAttribute() { return QStringLiteral("quote-after-line"); }
static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote-before-line"); }
static inline QString textAttribute() { return QStringLiteral("text"); }
static inline QString nameAttribute() { return QStringLiteral("name"); }
static inline QString sinceAttribute() { return QStringLiteral("since"); }
+static inline QString defaultSuperclassAttribute() { return QStringLiteral("default-superclass"); }
+static inline QString deleteInMainThreadAttribute() { return QStringLiteral("delete-in-main-thread"); }
+static inline QString deprecatedAttribute() { return QStringLiteral("deprecated"); }
+static inline QString exceptionHandlingAttribute() { return QStringLiteral("exception-handling"); }
+static inline QString extensibleAttribute() { return QStringLiteral("extensible"); }
static inline QString flagsAttribute() { return QStringLiteral("flags"); }
+static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); }
+static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); }
+static inline QString formatAttribute() { return QStringLiteral("format"); }
static inline QString classAttribute() { return QStringLiteral("class"); }
-static inline QString functionNameAttribute() { return QStringLiteral("function-name"); }
-static inline QString fieldNameAttribute() { return QStringLiteral("field-name"); }
-static inline QString enumNameAttribute() { return QStringLiteral("enum-name"); }
-static inline QString argumentTypeAttribute() { return QStringLiteral("argument-type"); }
-static inline QString returnTypeAttribute() { return QStringLiteral("return-type"); }
+static inline QString generateAttribute() { return QStringLiteral("generate"); }
+static inline QString genericClassAttribute() { return QStringLiteral("generic-class"); }
+static inline QString indexAttribute() { return QStringLiteral("index"); }
+static inline QString invalidateAfterUseAttribute() { return QStringLiteral("invalidate-after-use"); }
+static inline QString locationAttribute() { return QStringLiteral("location"); }
+static inline QString modifiedTypeAttribute() { return QStringLiteral("modified-type"); }
+static inline QString modifierAttribute() { return QStringLiteral("modifier"); }
+static inline QString ownershipAttribute() { return QStringLiteral("owner"); }
+static inline QString packageAttribute() { return QStringLiteral("package"); }
+static inline QString positionAttribute() { return QStringLiteral("position"); }
+static inline QString preferredConversionAttribute() { return QStringLiteral("preferred-conversion"); }
+static inline QString preferredTargetLangTypeAttribute() { return QStringLiteral("preferred-target-lang-type"); }
+static inline QString removeAttribute() { return QStringLiteral("remove"); }
+static inline QString renameAttribute() { return QStringLiteral("rename"); }
+static inline QString readAttribute() { return QStringLiteral("read"); }
+static inline QString writeAttribute() { return QStringLiteral("write"); }
+static inline QString replaceAttribute() { return QStringLiteral("replace"); }
+static inline QString toAttribute() { return QStringLiteral("to"); }
+static inline QString signatureAttribute() { return QStringLiteral("signature"); }
+static inline QString snippetAttribute() { return QStringLiteral("snippet"); }
+static inline QString staticAttribute() { return QStringLiteral("static"); }
+static inline QString threadAttribute() { return QStringLiteral("thread"); }
+static inline QString sourceAttribute() { return QStringLiteral("source"); }
+static inline QString streamAttribute() { return QStringLiteral("stream"); }
static inline QString xPathAttribute() { return QStringLiteral("xpath"); }
+static inline QString virtualSlotAttribute() { return QStringLiteral("virtual-slot"); }
static inline QString enumIdentifiedByValueAttribute() { return QStringLiteral("identified-by-value"); }
static inline QString noAttributeValue() { return QStringLiteral("no"); }
@@ -90,105 +130,317 @@ static bool setRejectionRegularExpression(const QString &patternIn,
return true;
}
-static bool addRejection(TypeDatabase *database, const QHash<QString, QString> &attributes,
- QString *errorMessage)
+// Extract a snippet from a file within annotation "// @snippet label".
+static QString extractSnippet(const QString &code, const QString &snippetLabel)
{
- typedef QPair<QString, TypeRejection::MatchType> AttributeMatchTypePair;
+ if (snippetLabel.isEmpty())
+ return code;
+ const QString pattern = QStringLiteral(R"(^\s*//\s*@snippet\s+)")
+ + QRegularExpression::escape(snippetLabel)
+ + QStringLiteral(R"(\s*$)");
+ const QRegularExpression snippetRe(pattern);
+ Q_ASSERT(snippetRe.isValid());
- TypeRejection rejection;
+ bool useLine = false;
+ QString result;
+ const auto lines = code.splitRef(QLatin1Char('\n'));
+ for (const QStringRef &line : lines) {
+ if (snippetRe.match(line).hasMatch()) {
+ useLine = !useLine;
+ if (!useLine)
+ break; // End of snippet reached
+ } else if (useLine)
+ result += line.toString() + QLatin1Char('\n');
+ }
+ return result;
+}
- const QString className = attributes.value(classAttribute());
- if (!setRejectionRegularExpression(className, &rejection.className, errorMessage))
- return false;
+template <class EnumType, Qt::CaseSensitivity cs = Qt::CaseInsensitive>
+struct EnumLookup
+{
+ QStringView name;
+ EnumType value;
+};
- static const AttributeMatchTypePair attributeMatchTypeMapping[] =
- {{functionNameAttribute(), TypeRejection::Function},
- {fieldNameAttribute(), TypeRejection::Field},
- {enumNameAttribute(), TypeRejection::Enum},
- {argumentTypeAttribute(), TypeRejection::ArgumentType},
- {returnTypeAttribute(), TypeRejection::ReturnType}
+template <class EnumType, Qt::CaseSensitivity cs>
+bool operator==(const EnumLookup<EnumType, cs> &e1, const EnumLookup<EnumType, cs> &e2)
+{
+ return e1.name.compare(e2.name, cs) == 0;
+}
+
+template <class EnumType, Qt::CaseSensitivity cs>
+bool operator<(const EnumLookup<EnumType, cs> &e1, const EnumLookup<EnumType, cs> &e2)
+{
+ return e1.name.compare(e2.name, cs) < 0;
+}
+
+// Helper macros to define lookup functions that take a QStringView needle
+// and an optional default return value.
+#define ENUM_LOOKUP_BEGIN(EnumType, caseSensitivity, functionName, defaultReturnValue) \
+static EnumType functionName(QStringView needle, EnumType defaultValue = defaultReturnValue) \
+{ \
+ typedef EnumLookup<EnumType, caseSensitivity> HaystackEntry; \
+ static const HaystackEntry haystack[] =
+
+#define ENUM_LOOKUP_LINEAR_SEARCH() \
+ const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \
+ const auto it = std::find(haystack, end, HaystackEntry{needle, defaultValue}); \
+ return it != end ? it->value : defaultValue; \
+}
+
+#define ENUM_LOOKUP_BINARY_SEARCH() \
+ const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \
+ const HaystackEntry needleEntry{needle, defaultValue}; \
+ const auto lb = std::lower_bound(haystack, end, needleEntry); \
+ return lb != end && *lb == needleEntry ? lb->value : defaultValue; \
+}
+
+ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
+ allowThreadFromAttribute, TypeSystem::AllowThread::Unspecified)
+ {
+ {QStringViewLiteral("yes"), TypeSystem::AllowThread::Allow},
+ {QStringViewLiteral("true"), TypeSystem::AllowThread::Allow},
+ {QStringViewLiteral("auto"), TypeSystem::AllowThread::Auto},
+ {QStringViewLiteral("no"), TypeSystem::AllowThread::Disallow},
+ {QStringViewLiteral("false"), TypeSystem::AllowThread::Disallow},
};
+ENUM_LOOKUP_LINEAR_SEARCH()
- // Search for non-empty attribute (function, field, enum)
- const auto aend = attributes.cend();
- for (const AttributeMatchTypePair &mapping : attributeMatchTypeMapping) {
- const auto it = attributes.constFind(mapping.first);
- if (it != aend && !it.value().isEmpty()) {
- if (!setRejectionRegularExpression(it.value(), &rejection.pattern, errorMessage))
- return false;
- rejection.matchType = mapping.second;
- database->addRejection(rejection);
- return true;
- }
- }
+ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
+ languageFromAttribute, TypeSystem::NoLanguage)
+ {
+ {QStringViewLiteral("all"), TypeSystem::All}, // sorted!
+ {QStringViewLiteral("constructors"), TypeSystem::Constructors},
+ {QStringViewLiteral("destructor-function"), TypeSystem::DestructorFunction},
+ {QStringViewLiteral("interface"), TypeSystem::Interface},
+ {QStringViewLiteral("library-initializer"), TypeSystem::PackageInitializer},
+ {QStringViewLiteral("native"), TypeSystem::NativeCode}, // em algum lugar do cpp
+ {QStringViewLiteral("shell"), TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
+ {QStringViewLiteral("shell-declaration"), TypeSystem::ShellDeclaration},
+ {QStringViewLiteral("target"), TypeSystem::TargetLangCode} // em algum lugar do cpp
+ };
+ENUM_LOOKUP_BINARY_SEARCH()
- // Special case: When all fields except class are empty, completely exclude class
- if (className == QLatin1String("*")) {
- *errorMessage = QLatin1String("bad reject entry, neither 'class', 'function-name'"
- " nor 'field' specified");
- return false;
+ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
+ ownershipFromFromAttribute, TypeSystem::InvalidOwnership)
+ {
+ {QStringViewLiteral("target"), TypeSystem::TargetLangOwnership},
+ {QStringViewLiteral("c++"), TypeSystem::CppOwnership},
+ {QStringViewLiteral("default"), TypeSystem::DefaultOwnership}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
+ addedFunctionAccessFromAttribute, AddedFunction::InvalidAccess)
+ {
+ {QStringViewLiteral("public"), AddedFunction::Public},
+ {QStringViewLiteral("protected"), AddedFunction::Protected},
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(Modification::Modifiers, Qt::CaseSensitive,
+ modifierFromAttribute, Modification::InvalidModifier)
+ {
+ {QStringViewLiteral("private"), Modification::Private},
+ {QStringViewLiteral("public"), Modification::Public},
+ {QStringViewLiteral("protected"), Modification::Protected},
+ {QStringViewLiteral("friendly"), Modification::Friendly},
+ {QStringViewLiteral("rename"), Modification::Rename},
+ {QStringViewLiteral("final"), Modification::Final},
+ {QStringViewLiteral("non-final"), Modification::NonFinal}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
+ referenceCountFromAttribute, ReferenceCount::Invalid)
+ {
+ {QStringViewLiteral("add"), ReferenceCount::Add},
+ {QStringViewLiteral("add-all"), ReferenceCount::AddAll},
+ {QStringViewLiteral("remove"), ReferenceCount::Remove},
+ {QStringViewLiteral("set"), ReferenceCount::Set},
+ {QStringViewLiteral("ignore"), ReferenceCount::Ignore}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
+ argumentOwnerActionFromAttribute, ArgumentOwner::Invalid)
+ {
+ {QStringViewLiteral("add"), ArgumentOwner::Add},
+ {QStringViewLiteral("remove"), ArgumentOwner::Remove}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive,
+ codeSnipPositionFromAttribute, TypeSystem::CodeSnipPositionInvalid)
+ {
+ {QStringViewLiteral("beginning"), TypeSystem::CodeSnipPositionBeginning},
+ {QStringViewLiteral("end"), TypeSystem::CodeSnipPositionEnd},
+ {QStringViewLiteral("declaration"), TypeSystem::CodeSnipPositionDeclaration},
+ {QStringViewLiteral("prototype-initialization"), TypeSystem::CodeSnipPositionPrototypeInitialization},
+ {QStringViewLiteral("constructor-initialization"), TypeSystem::CodeSnipPositionConstructorInitialization},
+ {QStringViewLiteral("constructor"), TypeSystem::CodeSnipPositionConstructor}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
+ locationFromAttribute, Include::InvalidInclude)
+ {
+ {QStringViewLiteral("global"), Include::IncludePath},
+ {QStringViewLiteral("local"), Include::LocalPath},
+ {QStringViewLiteral("target"), Include::TargetLangImport}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
+ docModificationFromAttribute, TypeSystem::DocModificationInvalid)
+ {
+ {QStringViewLiteral("append"), TypeSystem::DocModificationAppend},
+ {QStringViewLiteral("prepend"), TypeSystem::DocModificationPrepend},
+ {QStringViewLiteral("replace"), TypeSystem::DocModificationReplace}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(ContainerTypeEntry::Type, Qt::CaseSensitive,
+ containerTypeFromAttribute, ContainerTypeEntry::NoContainer)
+ {
+ {QStringViewLiteral("list"), ContainerTypeEntry::ListContainer},
+ {QStringViewLiteral("string-list"), ContainerTypeEntry::StringListContainer},
+ {QStringViewLiteral("linked-list"), ContainerTypeEntry::LinkedListContainer},
+ {QStringViewLiteral("vector"), ContainerTypeEntry::VectorContainer},
+ {QStringViewLiteral("stack"), ContainerTypeEntry::StackContainer},
+ {QStringViewLiteral("queue"), ContainerTypeEntry::QueueContainer},
+ {QStringViewLiteral("set"), ContainerTypeEntry::SetContainer},
+ {QStringViewLiteral("map"), ContainerTypeEntry::MapContainer},
+ {QStringViewLiteral("multi-map"), ContainerTypeEntry::MultiMapContainer},
+ {QStringViewLiteral("hash"), ContainerTypeEntry::HashContainer},
+ {QStringViewLiteral("multi-hash"), ContainerTypeEntry::MultiHashContainer},
+ {QStringViewLiteral("pair"), ContainerTypeEntry::PairContainer}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
+ typeRejectionFromAttribute, TypeRejection::Invalid)
+ {
+ {QStringViewLiteral("class"), TypeRejection::ExcludeClass},
+ {QStringViewLiteral("function-name"), TypeRejection::Function},
+ {QStringViewLiteral("field-name"), TypeRejection::Field},
+ {QStringViewLiteral("enum-name"), TypeRejection::Enum },
+ {QStringViewLiteral("argument-type"), TypeRejection::ArgumentType},
+ {QStringViewLiteral("return-type"), TypeRejection::ReturnType}
+ };
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
+ exceptionHandlingFromAttribute, TypeSystem::ExceptionHandling::Unspecified)
+{
+ {QStringViewLiteral("no"), TypeSystem::ExceptionHandling::Off},
+ {QStringViewLiteral("false"), TypeSystem::ExceptionHandling::Off},
+ {QStringViewLiteral("auto-off"), TypeSystem::ExceptionHandling::AutoDefaultToOff},
+ {QStringViewLiteral("auto-on"), TypeSystem::ExceptionHandling::AutoDefaultToOn},
+ {QStringViewLiteral("yes"), TypeSystem::ExceptionHandling::On},
+ {QStringViewLiteral("true"), TypeSystem::ExceptionHandling::On},
+};
+ENUM_LOOKUP_LINEAR_SEARCH()
+
+ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
+ elementFromTag, StackElement::None)
+ {
+ {QStringViewLiteral("access"), StackElement::Access}, // sorted!
+ {QStringViewLiteral("add-conversion"), StackElement::AddConversion},
+ {QStringViewLiteral("add-function"), StackElement::AddFunction},
+ {QStringViewLiteral("argument-map"), StackElement::ArgumentMap},
+ {QStringViewLiteral("array"), StackElement::Array},
+ {QStringViewLiteral("container-type"), StackElement::ContainerTypeEntry},
+ {QStringViewLiteral("conversion-rule"), StackElement::ConversionRule},
+ {QStringViewLiteral("custom-constructor"), StackElement::CustomMetaConstructor},
+ {QStringViewLiteral("custom-destructor"), StackElement::CustomMetaDestructor},
+ {QStringViewLiteral("custom-type"), StackElement::CustomTypeEntry},
+ {QStringViewLiteral("define-ownership"), StackElement::DefineOwnership},
+ {QStringViewLiteral("enum-type"), StackElement::EnumTypeEntry},
+ {QStringViewLiteral("extra-includes"), StackElement::ExtraIncludes},
+ {QStringViewLiteral("function"), StackElement::FunctionTypeEntry},
+ {QStringViewLiteral("include"), StackElement::Include},
+ {QStringViewLiteral("inject-code"), StackElement::InjectCode},
+ {QStringViewLiteral("inject-documentation"), StackElement::InjectDocumentation},
+ {QStringViewLiteral("insert-template"), StackElement::TemplateInstanceEnum},
+ {QStringViewLiteral("interface-type"), StackElement::InterfaceTypeEntry},
+ {QStringViewLiteral("load-typesystem"), StackElement::LoadTypesystem},
+ {QStringViewLiteral("modify-argument"), StackElement::ModifyArgument},
+ {QStringViewLiteral("modify-documentation"), StackElement::ModifyDocumentation},
+ {QStringViewLiteral("modify-field"), StackElement::ModifyField},
+ {QStringViewLiteral("modify-function"), StackElement::ModifyFunction},
+ {QStringViewLiteral("namespace-type"), StackElement::NamespaceTypeEntry},
+ {QStringViewLiteral("native-to-target"), StackElement::NativeToTarget},
+ {QStringViewLiteral("no-null-pointer"), StackElement::NoNullPointers},
+ {QStringViewLiteral("object-type"), StackElement::ObjectTypeEntry},
+ {QStringViewLiteral("parent"), StackElement::ParentOwner},
+ {QStringViewLiteral("primitive-type"), StackElement::PrimitiveTypeEntry},
+ {QStringViewLiteral("reference-count"), StackElement::ReferenceCount},
+ {QStringViewLiteral("reject-enum-value"), StackElement::RejectEnumValue},
+ {QStringViewLiteral("rejection"), StackElement::Rejection},
+ {QStringViewLiteral("remove"), StackElement::Removal},
+ {QStringViewLiteral("remove-argument"), StackElement::RemoveArgument},
+ {QStringViewLiteral("remove-default-expression"), StackElement::RemoveDefaultExpression},
+ {QStringViewLiteral("rename"), StackElement::Rename},
+ {QStringViewLiteral("replace"), StackElement::Replace},
+ {QStringViewLiteral("replace-default-expression"), StackElement::ReplaceDefaultExpression},
+ {QStringViewLiteral("replace-type"), StackElement::ReplaceType},
+ {QStringViewLiteral("smart-pointer-type"), StackElement::SmartPointerTypeEntry},
+ {QStringViewLiteral("suppress-warning"), StackElement::SuppressedWarning},
+ {QStringViewLiteral("target-to-native"), StackElement::TargetToNative},
+ {QStringViewLiteral("template"), StackElement::Template},
+ {QStringViewLiteral("typedef-type"), StackElement::TypedefTypeEntry},
+ {QStringViewLiteral("typesystem"), StackElement::Root},
+ {QStringViewLiteral("value-type"), StackElement::ValueTypeEntry},
+ };
+ENUM_LOOKUP_BINARY_SEARCH()
+
+static int indexOfAttribute(const QXmlStreamAttributes &atts,
+ QStringView name)
+{
+ for (int i = 0, size = atts.size(); i < size; ++i) {
+ if (atts.at(i).qualifiedName() == name)
+ return i;
}
- rejection.matchType = TypeRejection::ExcludeClass;
- database->addRejection(rejection);
- return true;
+ return -1;
}
+static QString msgMissingAttribute(const QString &a)
+{
+ return QLatin1String("Required attribute '") + a
+ + QLatin1String("' missing.");
+}
-Handler::Handler(TypeDatabase* database, bool generate)
- : m_database(database), m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
-{
- m_currentEnum = 0;
- m_current = 0;
- m_currentDroppedEntry = 0;
- m_currentDroppedEntryDepth = 0;
- m_ignoreDepth = 0;
-
- tagNames.insert(QLatin1String("rejection"), StackElement::Rejection);
- tagNames.insert(QLatin1String("custom-type"), StackElement::CustomTypeEntry);
- tagNames.insert(QLatin1String("primitive-type"), StackElement::PrimitiveTypeEntry);
- tagNames.insert(QLatin1String("container-type"), StackElement::ContainerTypeEntry);
- tagNames.insert(QLatin1String("object-type"), StackElement::ObjectTypeEntry);
- tagNames.insert(QLatin1String("value-type"), StackElement::ValueTypeEntry);
- tagNames.insert(QLatin1String("interface-type"), StackElement::InterfaceTypeEntry);
- tagNames.insert(QLatin1String("namespace-type"), StackElement::NamespaceTypeEntry);
- tagNames.insert(QLatin1String("enum-type"), StackElement::EnumTypeEntry);
- tagNames.insert(QLatin1String("smart-pointer-type"), StackElement::SmartPointerTypeEntry);
- tagNames.insert(QLatin1String("function"), StackElement::FunctionTypeEntry);
- tagNames.insert(QLatin1String("extra-includes"), StackElement::ExtraIncludes);
- tagNames.insert(QLatin1String("include"), StackElement::Include);
- tagNames.insert(QLatin1String("inject-code"), StackElement::InjectCode);
- tagNames.insert(QLatin1String("modify-function"), StackElement::ModifyFunction);
- tagNames.insert(QLatin1String("modify-field"), StackElement::ModifyField);
- tagNames.insert(QLatin1String("access"), StackElement::Access);
- tagNames.insert(QLatin1String("remove"), StackElement::Removal);
- tagNames.insert(QLatin1String("rename"), StackElement::Rename);
- tagNames.insert(QLatin1String("typesystem"), StackElement::Root);
- tagNames.insert(QLatin1String("custom-constructor"), StackElement::CustomMetaConstructor);
- tagNames.insert(QLatin1String("custom-destructor"), StackElement::CustomMetaDestructor);
- tagNames.insert(QLatin1String("argument-map"), StackElement::ArgumentMap);
- tagNames.insert(QLatin1String("suppress-warning"), StackElement::SuppressedWarning);
- tagNames.insert(QLatin1String("load-typesystem"), StackElement::LoadTypesystem);
- tagNames.insert(QLatin1String("define-ownership"), StackElement::DefineOwnership);
- tagNames.insert(QLatin1String("replace-default-expression"), StackElement::ReplaceDefaultExpression);
- tagNames.insert(QLatin1String("reject-enum-value"), StackElement::RejectEnumValue);
- tagNames.insert(QLatin1String("replace-type"), StackElement::ReplaceType);
- tagNames.insert(QLatin1String("conversion-rule"), StackElement::ConversionRule);
- tagNames.insert(QLatin1String("native-to-target"), StackElement::NativeToTarget);
- tagNames.insert(QLatin1String("target-to-native"), StackElement::TargetToNative);
- tagNames.insert(QLatin1String("add-conversion"), StackElement::AddConversion);
- tagNames.insert(QLatin1String("modify-argument"), StackElement::ModifyArgument);
- tagNames.insert(QLatin1String("remove-argument"), StackElement::RemoveArgument);
- tagNames.insert(QLatin1String("remove-default-expression"), StackElement::RemoveDefaultExpression);
- tagNames.insert(QLatin1String("template"), StackElement::Template);
- tagNames.insert(QLatin1String("insert-template"), StackElement::TemplateInstanceEnum);
- tagNames.insert(QLatin1String("replace"), StackElement::Replace);
- tagNames.insert(QLatin1String("no-null-pointer"), StackElement::NoNullPointers);
- tagNames.insert(QLatin1String("reference-count"), StackElement::ReferenceCount);
- tagNames.insert(QLatin1String("parent"), StackElement::ParentOwner);
- tagNames.insert(QLatin1String("array"), StackElement::Array);
- tagNames.insert(QLatin1String("inject-documentation"), StackElement::InjectDocumentation);
- tagNames.insert(QLatin1String("modify-documentation"), StackElement::ModifyDocumentation);
- tagNames.insert(QLatin1String("add-function"), StackElement::AddFunction);
+QTextStream &operator<<(QTextStream &str, const QXmlStreamAttribute &attribute)
+{
+ str << attribute.qualifiedName() << "=\"" << attribute.value() << '"';
+ return str;
+}
+
+static QString msgInvalidAttributeValue(const QXmlStreamAttribute &attribute)
+{
+ QString result;
+ QTextStream(&result) << "Invalid attribute value:" << attribute;
+ return result;
+}
+
+static QString msgUnusedAttributes(const QStringRef &tag, const QXmlStreamAttributes &attributes)
+{
+ QString result;
+ QTextStream str(&result);
+ str << attributes.size() << " attributes(s) unused on <" << tag << ">: ";
+ for (int i = 0, size = attributes.size(); i < size; ++i) {
+ if (i)
+ str << ", ";
+ str << attributes.at(i);
+ }
+ return result;
+}
+
+Handler::Handler(TypeDatabase *database, bool generate) :
+ m_database(database),
+ m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass)
+{
}
static QString readerFileName(const QXmlStreamReader &reader)
@@ -197,22 +449,72 @@ static QString readerFileName(const QXmlStreamReader &reader)
return file != nullptr ? file->fileName() : QString();
}
-static QString msgReaderError(const QXmlStreamReader &reader, const QString &what)
+static QString msgReaderMessage(const QXmlStreamReader &reader,
+ const char *type,
+ const QString &what)
{
QString message;
QTextStream str(&message);
- str << "Error: ";
+ str << type << ": ";
const QString fileName = readerFileName(reader);
- if (!fileName.isEmpty())
- str << "file=" << QDir::toNativeSeparators(fileName) << ", ";
- str << "line=" << reader.lineNumber() << ", column=" << reader.columnNumber()
- << ", message=" << what;
+ if (fileName.isEmpty())
+ str << "<stdin>:";
+ else
+ str << QDir::toNativeSeparators(fileName) << ':';
+ str << reader.lineNumber() << ':' << reader.columnNumber()
+ << ": " << what;
return message;
}
-static QString msgReaderError(const QXmlStreamReader &reader)
+static QString msgReaderWarning(const QXmlStreamReader &reader, const QString &what)
+{
+ return msgReaderMessage(reader, "Warning", what);
+}
+
+static QString msgReaderError(const QXmlStreamReader &reader, const QString &what)
+{
+ return msgReaderMessage(reader, "Error", what);
+}
+
+static QString msgUnimplementedElementWarning(const QXmlStreamReader &reader,
+ const QStringRef &name)
+{
+ const QString message = QLatin1String("The element \"") +
+ name + QLatin1String("\" is not implemented.");
+ return msgReaderMessage(reader, "Warning", message);
+}
+
+static QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader,
+ const QStringRef &name)
+{
+ const QString message = QLatin1String("The attribute \"") +
+ name + QLatin1String("\" is not implemented.");
+ return msgReaderMessage(reader, "Warning", message);
+}
+
+static inline QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader,
+ const QXmlStreamAttribute &attribute)
+{
+ return msgUnimplementedAttributeWarning(reader, attribute.qualifiedName());
+}
+
+static QString
+ msgUnimplementedAttributeValueWarning(const QXmlStreamReader &reader,
+ QStringView name, QStringView value)
+{
+ QString message;
+ QTextStream(&message) << "The value \"" << value
+ << "\" of the attribute \"" << name << "\" is not implemented.";
+ return msgReaderMessage(reader, "Warning", message);
+}
+
+static inline
+ QString msgUnimplementedAttributeValueWarning(const QXmlStreamReader &reader,
+ const QXmlStreamAttribute &attribute)
{
- return msgReaderError(reader, reader.errorString());
+ return msgUnimplementedAttributeValueWarning(reader,
+ attribute.qualifiedName(),
+ attribute.value());
}
static QString msgInvalidVersion(const QStringRef &version, const QString &package = QString())
@@ -226,6 +528,53 @@ static QString msgInvalidVersion(const QStringRef &version, const QString &packa
return result;
}
+static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attributes,
+ QString *errorMessage)
+{
+ const int classIndex = indexOfAttribute(*attributes, classAttribute());
+ if (classIndex == -1) {
+ *errorMessage = msgMissingAttribute(classAttribute());
+ return false;
+ }
+
+ TypeRejection rejection;
+ const QString className = attributes->takeAt(classIndex).value().toString();
+ if (!setRejectionRegularExpression(className, &rejection.className, errorMessage))
+ return false;
+
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ const TypeRejection::MatchType type = typeRejectionFromAttribute(name);
+ switch (type) {
+ case TypeRejection::Function:
+ case TypeRejection::Field:
+ case TypeRejection::Enum:
+ case TypeRejection::ArgumentType:
+ case TypeRejection::ReturnType: {
+ const QString pattern = attributes->takeAt(i).value().toString();
+ if (!setRejectionRegularExpression(pattern, &rejection.pattern, errorMessage))
+ return false;
+ rejection.matchType = type;
+ database->addRejection(rejection);
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Special case: When all fields except class are empty, completely exclude class
+ if (className == QLatin1String("*")) {
+ *errorMessage = QLatin1String("bad reject entry, neither 'class', 'function-name'"
+ " nor 'field' specified");
+ return false;
+ }
+ rejection.matchType = TypeRejection::ExcludeClass;
+ database->addRejection(rejection);
+ return true;
+}
+
bool Handler::parse(QXmlStreamReader &reader)
{
m_error.clear();
@@ -238,10 +587,10 @@ bool Handler::parse(QXmlStreamReader &reader)
switch (reader.readNext()) {
case QXmlStreamReader::NoToken:
case QXmlStreamReader::Invalid:
- qCWarning(lcShiboken).noquote().nospace() << msgReaderError(reader);
+ m_error = msgReaderError(reader, reader.errorString());
return false;
case QXmlStreamReader::StartElement:
- if (!startElement(reader.name(), reader.attributes())) {
+ if (!startElement(reader)) {
m_error = msgReaderError(reader, m_error);
return false;
}
@@ -271,22 +620,6 @@ bool Handler::parse(QXmlStreamReader &reader)
return true;
}
-void Handler::fetchAttributeValues(const QString &name, const QXmlStreamAttributes &atts,
- QHash<QString, QString> *acceptedAttributes)
-{
- Q_ASSERT(acceptedAttributes);
-
- for (int i = 0; i < atts.length(); ++i) {
- const QString key = atts.at(i).name().toString().toLower();
- if (!acceptedAttributes->contains(key)) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("Unknown attribute for '%1': '%2'").arg(name, key);
- } else {
- acceptedAttributes->insert(key, atts.at(i).value().toString());
- }
- }
-}
-
bool Handler::endElement(const QStringRef &localName)
{
if (m_ignoreDepth) {
@@ -416,14 +749,18 @@ bool Handler::endElement(const QStringRef &localName)
break;
}
- if (m_current->type == StackElement::Root
- || m_current->type == StackElement::NamespaceTypeEntry
- || m_current->type == StackElement::InterfaceTypeEntry
- || m_current->type == StackElement::ObjectTypeEntry
- || m_current->type == StackElement::ValueTypeEntry
- || m_current->type == StackElement::PrimitiveTypeEntry) {
- StackElementContext* context = m_contextStack.pop();
- delete context;
+ switch (m_current->type) {
+ case StackElement::Root:
+ case StackElement::NamespaceTypeEntry:
+ case StackElement::InterfaceTypeEntry:
+ case StackElement::ObjectTypeEntry:
+ case StackElement::ValueTypeEntry:
+ case StackElement::PrimitiveTypeEntry:
+ case StackElement::TypedefTypeEntry:
+ delete m_contextStack.pop();
+ break;
+ default:
+ break;
}
StackElement *child = m_current;
@@ -551,8 +888,9 @@ bool Handler::importFileElement(const QXmlStreamAttributes &atts)
return true;
}
-static bool convertBoolean(const QString &value, const QString &attributeName, bool defaultValue)
+static bool convertBoolean(QStringView value, const QString &attributeName, bool defaultValue)
{
+#ifdef QTBUG_69389_FIXED
if (value.compare(trueAttributeValue(), Qt::CaseInsensitive) == 0
|| value.compare(yesAttributeValue(), Qt::CaseInsensitive) == 0) {
return true;
@@ -561,28 +899,47 @@ static bool convertBoolean(const QString &value, const QString &attributeName, b
|| value.compare(noAttributeValue(), Qt::CaseInsensitive) == 0) {
return false;
}
+#else
+ if (QtPrivate::compareStrings(value, trueAttributeValue(), Qt::CaseInsensitive) == 0
+ || QtPrivate::compareStrings(value, yesAttributeValue(), Qt::CaseInsensitive) == 0) {
+ return true;
+ }
+ if (QtPrivate::compareStrings(value, falseAttributeValue(), Qt::CaseInsensitive) == 0
+ || QtPrivate::compareStrings(value, noAttributeValue(), Qt::CaseInsensitive) == 0) {
+ return false;
+ }
+#endif
const QString warn = QStringLiteral("Boolean value '%1' not supported in attribute '%2'. Use 'yes' or 'no'. Defaulting to '%3'.")
- .arg(value, attributeName,
+ .arg(value)
+ .arg(attributeName,
defaultValue ? yesAttributeValue() : noAttributeValue());
qCWarning(lcShiboken).noquote().nospace() << warn;
return defaultValue;
}
-static bool convertRemovalAttribute(const QString& removalAttribute, Modification& mod, QString& errorMsg)
+static bool convertRemovalAttribute(QStringView remove, Modification& mod, QString& errorMsg)
{
- QString remove = removalAttribute.toLower();
- if (!remove.isEmpty()) {
- if (remove == QLatin1String("all")) {
- mod.removal = TypeSystem::All;
- } else if (remove == QLatin1String("target")) {
- mod.removal = TypeSystem::TargetLangAndNativeCode;
- } else {
- errorMsg = QString::fromLatin1("Bad removal type '%1'").arg(remove);
- return false;
- }
+ if (remove.isEmpty())
+ return true;
+#ifdef QTBUG_69389_FIXED
+ if (remove.compare(QStringViewLiteral("all"), Qt::CaseInsensitive) == 0) {
+#else
+ if (QtPrivate::compareStrings(remove, QStringViewLiteral("all"), Qt::CaseInsensitive) == 0) {
+#endif
+ mod.removal = TypeSystem::All;
+ return true;
}
- return true;
+#ifdef QTBUG_69389_FIXED
+ if (remove.compare(QStringViewLiteral("target"), Qt::CaseInsensitive) == 0) {
+#else
+ if (QtPrivate::compareStrings(remove, QStringViewLiteral("target"), Qt::CaseInsensitive) == 0) {
+#endif
+ mod.removal = TypeSystem::TargetLangAndNativeCode;
+ return true;
+ }
+ errorMsg = QString::fromLatin1("Bad removal type '%1'").arg(remove);
+ return false;
}
static void getNamePrefixRecursive(StackElement* element, QStringList& names)
@@ -615,98 +972,1466 @@ static QString checkSignatureError(const QString& signature, const QString& tag)
return QString();
}
-void Handler::addFlags(const QString &name, QString flagName,
- const QHash<QString, QString> &attributes,
- const QVersionNumber &since)
+void Handler::applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const
+{
+ type->setCodeGeneration(m_generate);
+ const int revisionIndex =
+ indexOfAttribute(*attributes, QStringViewLiteral("revision"));
+ if (revisionIndex != -1)
+ type->setRevision(attributes->takeAt(revisionIndex).value().toInt());
+}
+
+FlagsTypeEntry *
+ Handler::parseFlagsEntry(const QXmlStreamReader &,
+ EnumTypeEntry *enumEntry,
+ const QString &name, QString flagName,
+ const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+
{
FlagsTypeEntry *ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + name + QLatin1Char('>'), since);
- ftype->setOriginator(m_currentEnum);
+ ftype->setOriginator(enumEntry);
+ ftype->setTargetLangPackage(enumEntry->targetLangPackage());
// Try to get the guess the qualified flag name
const int lastSepPos = name.lastIndexOf(colonColon());
if (lastSepPos >= 0 && !flagName.contains(colonColon()))
flagName.prepend(name.left(lastSepPos + 2));
ftype->setOriginalName(flagName);
- ftype->setCodeGeneration(m_generate);
+ applyCommonAttributes(ftype, attributes);
QString n = ftype->originalName();
QStringList lst = n.split(colonColon());
- if (QStringList(lst.mid(0, lst.size() - 1)).join(colonColon()) != m_currentEnum->targetLangQualifier()) {
+ const QString &targetLangQualifier = enumEntry->targetLangQualifier();
+ if (QStringList(lst.mid(0, lst.size() - 1)).join(colonColon()) != targetLangQualifier) {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("enum %1 and flags %2 differ in qualifiers")
- .arg(m_currentEnum->targetLangQualifier(), lst.constFirst());
+ .arg(targetLangQualifier, lst.constFirst());
}
ftype->setFlagsName(lst.constLast());
- m_currentEnum->setFlags(ftype);
+ enumEntry->setFlags(ftype);
m_database->addFlagsType(ftype);
m_database->addType(ftype);
- QString revision = attributes.value(QLatin1String("flags-revision"));
- if (revision.isEmpty())
- revision = attributes.value(QLatin1String("revision"));
- setTypeRevision(ftype, revision.toInt());
-}
+ const int revisionIndex =
+ indexOfAttribute(*attributes, QStringViewLiteral("flags-revision"));
+ ftype->setRevision(revisionIndex != -1
+ ? attributes->takeAt(revisionIndex).value().toInt()
+ : enumEntry->revision());
+ return ftype;
+}
+
+SmartPointerTypeEntry *
+ Handler::parseSmartPointerEntry(const QXmlStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ QString smartPointerType;
+ QString getter;
+ QString refCountMethodName;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("type")) {
+ smartPointerType = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("getter")) {
+ getter = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("ref-count-method")) {
+ refCountMethodName = attributes->takeAt(i).value().toString();
+ }
+ }
-bool Handler::handleSmartPointerEntry(StackElement *element,
- QHash<QString, QString> &attributes,
- const QString &name,
- const QVersionNumber &since)
-{
- QString smartPointerType = attributes[QLatin1String("type")];
if (smartPointerType.isEmpty()) {
m_error = QLatin1String("No type specified for the smart pointer. Currently supported types: 'shared',");
- return false;
+ return nullptr;
}
if (smartPointerType != QLatin1String("shared")) {
m_error = QLatin1String("Currently only the 'shared' type is supported.");
- return false;
+ return nullptr;
}
- QString getter = attributes[QLatin1String("getter")];
if (getter.isEmpty()) {
m_error = QLatin1String("No function getter name specified for getting the raw pointer held by the smart pointer.");
- return false;
+ return nullptr;
}
- QString refCountMethodName = attributes[QLatin1String("ref-count-method")];
QString signature = getter + QLatin1String("()");
-
signature = TypeDatabase::normalizedSignature(signature);
if (signature.isEmpty()) {
m_error = QLatin1String("No signature for the smart pointer getter found.");
- return false;
+ return nullptr;
}
QString errorString = checkSignatureError(signature,
QLatin1String("smart-pointer-type"));
if (!errorString.isEmpty()) {
m_error = errorString;
- return false;
+ return nullptr;
+ }
+
+ SmartPointerTypeEntry *type =
+ new SmartPointerTypeEntry(name, getter, smartPointerType, refCountMethodName, since);
+ applyCommonAttributes(type, attributes);
+ return type;
+}
+
+PrimitiveTypeEntry *
+ Handler::parsePrimitiveTypeEntry(const QXmlStreamReader &reader,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ PrimitiveTypeEntry *type = new PrimitiveTypeEntry(name, since);
+ applyCommonAttributes(type, attributes);
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("target-lang-name")) {
+ type->setTargetLangName(attributes->takeAt(i).value().toString());
+ } else if (name == QLatin1String("target-lang-api-name")) {
+ type->setTargetLangApiName(attributes->takeAt(i).value().toString());
+ } else if (name == preferredConversionAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == preferredTargetLangTypeAttribute()) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ preferredTargetLangTypeAttribute(), true);
+ type->setPreferredTargetLangType(v);
+ } else if (name == QLatin1String("default-constructor")) {
+ type->setDefaultConstructor(attributes->takeAt(i).value().toString());
+ }
}
- SmartPointerTypeEntry *type = new SmartPointerTypeEntry(name,
- getter,
- smartPointerType,
- refCountMethodName,
- since);
+ if (type->targetLangName().isEmpty())
+ type->setTargetLangName(type->name());
+ if (type->targetLangApiName().isEmpty())
+ type->setTargetLangApiName(type->name());
type->setTargetLangPackage(m_defaultPackage);
- type->setCodeGeneration(m_generate);
- element->entry = type;
+ return type;
+}
+
+ContainerTypeEntry *
+ Handler::parseContainerTypeEntry(const QXmlStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ const int typeIndex = indexOfAttribute(*attributes, QStringViewLiteral("type"));
+ if (typeIndex == -1) {
+ m_error = QLatin1String("no 'type' attribute specified");
+ return nullptr;
+ }
+ const QStringRef typeName = attributes->takeAt(typeIndex).value();
+ ContainerTypeEntry::Type containerType = containerTypeFromAttribute(typeName);
+ if (containerType == ContainerTypeEntry::NoContainer) {
+ m_error = QLatin1String("there is no container of type ") + typeName.toString();
+ return nullptr;
+ }
+ ContainerTypeEntry *type = new ContainerTypeEntry(name, containerType, since);
+ applyCommonAttributes(type, attributes);
+ return type;
+}
+
+EnumTypeEntry *
+ Handler::parseEnumTypeEntry(const QXmlStreamReader &reader,
+ const QString &fullName, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ QString scope;
+ QString name = fullName;
+ const int sep = fullName.lastIndexOf(colonColon());
+ if (sep != -1) {
+ scope = fullName.left(sep);
+ name = fullName.right(fullName.size() - sep - 2);
+ }
+ EnumTypeEntry *entry = new EnumTypeEntry(scope, name, since);
+ applyCommonAttributes(entry, attributes);
+ entry->setTargetLangPackage(m_defaultPackage);
+
+ QString flagNames;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("upper-bound")) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == QLatin1String("lower-bound")) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == forceIntegerAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == extensibleAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == flagsAttribute()) {
+ flagNames = attributes->takeAt(i).value().toString();
+ }
+ }
+
+ // put in the flags parallel...
+ if (!flagNames.isEmpty()) {
+ const QStringList &flagNameList = flagNames.split(QLatin1Char(','));
+ for (const QString &flagName : flagNameList)
+ parseFlagsEntry(reader, entry, fullName, flagName.trimmed(), since, attributes);
+ }
+ return entry;
+}
+
+ObjectTypeEntry *
+ Handler::parseInterfaceTypeEntry(const QXmlStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ ObjectTypeEntry *otype = new ObjectTypeEntry(name, since);
+ applyCommonAttributes(otype, attributes);
+ QString targetLangName = name;
+ bool generate = true;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("target-lang-name")) {
+ targetLangName = attributes->takeAt(i).value().toString();
+ } else if (name == generateAttribute()) {
+ generate = convertBoolean(attributes->takeAt(i).value(),
+ generateAttribute(), true);
+ }
+ }
+
+ InterfaceTypeEntry *itype =
+ new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName), since);
+
+ if (generate)
+ itype->setCodeGeneration(m_generate);
+ else
+ itype->setCodeGeneration(TypeEntry::GenerateForSubclass);
+
+ otype->setDesignatedInterface(itype);
+ itype->setOrigin(otype);
+ return otype;
+}
+
+ValueTypeEntry *
+ Handler::parseValueTypeEntry(const QXmlStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ ValueTypeEntry *typeEntry = new ValueTypeEntry(name, since);
+ applyCommonAttributes(typeEntry, attributes);
+ const int defaultCtIndex =
+ indexOfAttribute(*attributes, QStringViewLiteral("default-constructor"));
+ if (defaultCtIndex != -1)
+ typeEntry->setDefaultConstructor(attributes->takeAt(defaultCtIndex).value().toString());
+ return typeEntry;
+}
+
+FunctionTypeEntry *
+ Handler::parseFunctionTypeEntry(const QXmlStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ const int signatureIndex = indexOfAttribute(*attributes, signatureAttribute());
+ if (signatureIndex == -1) {
+ m_error = msgMissingAttribute(signatureAttribute());
+ return nullptr;
+ }
+ const QString signature =
+ TypeDatabase::normalizedSignature(attributes->takeAt(signatureIndex).value().toString());
+
+ TypeEntry *existingType = m_database->findType(name);
+
+ if (!existingType) {
+ FunctionTypeEntry *result = new FunctionTypeEntry(name, signature, since);
+ applyCommonAttributes(result, attributes);
+ return result;
+ }
+
+ if (existingType->type() != TypeEntry::FunctionType) {
+ m_error = QStringLiteral("%1 expected to be a function, but isn't! Maybe it was already declared as a class or something else.")
+ .arg(name);
+ return nullptr;
+ }
+
+ FunctionTypeEntry *result = reinterpret_cast<FunctionTypeEntry *>(existingType);
+ result->addSignature(signature);
+ return result;
+}
+
+TypedefEntry *
+ Handler::parseTypedefEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ if (m_current && m_current->type != StackElement::Root
+ && m_current->type != StackElement::NamespaceTypeEntry) {
+ m_error = QLatin1String("typedef entries must be nested in namespaces or type system.");
+ return nullptr;
+ }
+ const int sourceIndex = indexOfAttribute(*attributes, sourceAttribute());
+ if (sourceIndex == -1) {
+ m_error = msgMissingAttribute(sourceAttribute());
+ return nullptr;
+ }
+ const QString sourceType = attributes->takeAt(sourceIndex).value().toString();
+ auto result = new TypedefEntry(name, sourceType, since);
+ applyCommonAttributes(result, attributes);
+ return result;
+}
+
+void Handler::applyComplexTypeAttributes(const QXmlStreamReader &reader,
+ ComplexTypeEntry *ctype,
+ QXmlStreamAttributes *attributes) const
+{
+ bool generate = true;
+ ctype->setCopyable(ComplexTypeEntry::Unknown);
+ auto exceptionHandling = m_exceptionHandling;
+
+ QString package = m_defaultPackage;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == streamAttribute()) {
+ ctype->setStream(convertBoolean(attributes->takeAt(i).value(), streamAttribute(), false));
+ } else if (name == generateAttribute()) {
+ generate = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true);
+ } else if (name ==packageAttribute()) {
+ package = attributes->takeAt(i).value().toString();
+ } else if (name == defaultSuperclassAttribute()) {
+ ctype->setDefaultSuperclass(attributes->takeAt(i).value().toString());
+ } else if (name == genericClassAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ const bool v = convertBoolean(attributes->takeAt(i).value(), genericClassAttribute(), false);
+ ctype->setGenericClass(v);
+ } else if (name == QLatin1String("target-lang-name")) {
+ ctype->setTargetLangName(attributes->takeAt(i).value().toString());
+ } else if (name == QLatin1String("polymorphic-base")) {
+ ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
+ } else if (name == QLatin1String("polymorphic-id-expression")) {
+ ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
+ } else if (name == copyableAttribute()) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(), copyableAttribute(), false);
+ ctype->setCopyable(v ? ComplexTypeEntry::CopyableSet : ComplexTypeEntry::NonCopyableSet);
+ } else if (name == exceptionHandlingAttribute()) {
+ const auto attribute = attributes->takeAt(i);
+ const auto v = exceptionHandlingFromAttribute(attribute.value());
+ if (v != TypeSystem::ExceptionHandling::Unspecified) {
+ exceptionHandling = v;
+ } else {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (name == QLatin1String("held-type")) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == QLatin1String("hash-function")) {
+ ctype->setHashFunction(attributes->takeAt(i).value().toString());
+ } else if (name == forceAbstractAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == deprecatedAttribute()) {
+ if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute(), false))
+ ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated);
+ } else if (name == deleteInMainThreadAttribute()) {
+ if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute(), false))
+ ctype->setDeleteInMainThread(true);
+ } else if (name == QLatin1String("target-type")) {
+ ctype->setTargetType(attributes->takeAt(i).value().toString());
+ }
+ }
+
+ if (exceptionHandling != TypeSystem::ExceptionHandling::Unspecified)
+ ctype->setExceptionHandling(exceptionHandling);
+
+ // The generator code relies on container's package being empty.
+ if (ctype->type() != TypeEntry::ContainerType)
+ ctype->setTargetLangPackage(package);
+
+ if (InterfaceTypeEntry *di = ctype->designatedInterface())
+ di->setTargetLangPackage(package);
+
+ if (generate)
+ ctype->setCodeGeneration(m_generate);
+ else
+ ctype->setCodeGeneration(TypeEntry::GenerateForSubclass);
+}
+
+bool Handler::parseRenameFunction(const QXmlStreamReader &,
+ QString *name, QXmlStreamAttributes *attributes)
+{
+ QString signature;
+ QString rename;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == signatureAttribute()) {
+ // Do not remove as it is needed for the type entry later on
+ signature = attributes->at(i).value().toString();
+ } else if (name == renameAttribute()) {
+ rename = attributes->takeAt(i).value().toString();
+ }
+ }
+
+ if (signature.isEmpty()) {
+ m_error = msgMissingAttribute(signatureAttribute());
+ return false;
+ }
+
+ *name = signature.left(signature.indexOf(QLatin1Char('('))).trimmed();
+
+ QString errorString = checkSignatureError(signature, QLatin1String("function"));
+ if (!errorString.isEmpty()) {
+ m_error = errorString;
+ return false;
+ }
+
+ if (!rename.isEmpty()) {
+ static const QRegularExpression functionNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$"));
+ Q_ASSERT(functionNameRegExp.isValid());
+ if (!functionNameRegExp.match(rename).hasMatch()) {
+ m_error = QLatin1String("can not rename '") + signature + QLatin1String("', '")
+ + rename + QLatin1String("' is not a valid function name");
+ return false;
+ }
+ FunctionModification mod;
+ if (!mod.setSignature(signature, &m_error))
+ return false;
+ mod.renamedToName = rename;
+ mod.modifiers |= Modification::Rename;
+ m_contextStack.top()->functionMods << mod;
+ }
+ return true;
+}
+
+bool Handler::parseInjectDocumentation(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ const int validParent = StackElement::TypeEntryMask
+ | StackElement::ModifyFunction
+ | StackElement::ModifyField;
+ if (!m_current->parent || (m_current->parent->type & validParent) == 0) {
+ m_error = QLatin1String("inject-documentation must be inside modify-function, "
+ "modify-field or other tags that creates a type");
+ return false;
+ }
+
+ TypeSystem::DocModificationMode mode = TypeSystem::DocModificationReplace;
+ TypeSystem::Language lang = TypeSystem::NativeCode;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("mode")) {
+ const QStringRef modeName = attributes->takeAt(i).value();
+ mode = docModificationFromAttribute(modeName);
+ if (mode == TypeSystem::DocModificationInvalid) {
+ m_error = QLatin1String("Unknown documentation injection mode: ") + modeName;
+ return false;
+ }
+ } else if (name == formatAttribute()) {
+ const QStringRef format = attributes->takeAt(i).value();
+ lang = languageFromAttribute(format);
+ if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) {
+ m_error = QStringLiteral("unsupported class attribute: '%1'").arg(format);
+ return false;
+ }
+ }
+ }
+
+ QString signature = m_current->type & StackElement::TypeEntryMask
+ ? QString() : m_currentSignature;
+ DocModification mod(mode, signature);
+ mod.setFormat(lang);
+ m_contextStack.top()->docModifications << mod;
+ return true;
+}
+
+bool Handler::parseModifyDocumentation(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ const int validParent = StackElement::TypeEntryMask
+ | StackElement::ModifyFunction
+ | StackElement::ModifyField;
+ if (!m_current->parent || (m_current->parent->type & validParent) == 0) {
+ m_error = QLatin1String("modify-documentation must be inside modify-function, "
+ "modify-field or other tags that creates a type");
+ return false;
+ }
+
+ const int xpathIndex = indexOfAttribute(*attributes, xPathAttribute());
+ if (xpathIndex == -1) {
+ m_error = msgMissingAttribute(xPathAttribute());
+ return false;
+ }
+
+ const QString xpath = attributes->takeAt(xpathIndex).value().toString();
+ QString signature = (m_current->type & StackElement::TypeEntryMask) ? QString() : m_currentSignature;
+ m_contextStack.top()->docModifications
+ << DocModification(xpath, signature);
+ return true;
+}
+
+// m_exceptionHandling
+TypeSystemTypeEntry *Handler::parseRootElement(const QXmlStreamReader &,
+ const QVersionNumber &since,
+ QXmlStreamAttributes *attributes)
+{
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == packageAttribute()) {
+ m_defaultPackage = attributes->takeAt(i).value().toString();
+ } else if (name == defaultSuperclassAttribute()) {
+ m_defaultSuperclass = attributes->takeAt(i).value().toString();
+ } else if (name == exceptionHandlingAttribute()) {
+ const auto attribute = attributes->takeAt(i);
+ const auto v = exceptionHandlingFromAttribute(attribute.value());
+ if (v != TypeSystem::ExceptionHandling::Unspecified) {
+ m_exceptionHandling = v;
+ } else {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ }
+ }
+
+ TypeSystemTypeEntry *moduleEntry =
+ const_cast<TypeSystemTypeEntry *>(m_database->findTypeSystemType(m_defaultPackage));
+ if (!moduleEntry)
+ moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since);
+ moduleEntry->setCodeGeneration(m_generate);
+
+ if ((m_generate == TypeEntry::GenerateForSubclass ||
+ m_generate == TypeEntry::GenerateNothing) && !m_defaultPackage.isEmpty())
+ TypeDatabase::instance()->addRequiredTargetImport(m_defaultPackage);
+
+ if (!moduleEntry->qualifiedCppName().isEmpty())
+ m_database->addType(moduleEntry);
+ return moduleEntry;
+}
+
+bool Handler::loadTypesystem(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ QString typeSystemName;
+ bool generateChild = true;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute())
+ typeSystemName = attributes->takeAt(i).value().toString();
+ else if (name == generateAttribute())
+ generateChild = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true);
+ }
+ if (typeSystemName.isEmpty()) {
+ m_error = QLatin1String("No typesystem name specified");
+ return false;
+ }
+ const bool result =
+ m_database->parseFile(typeSystemName, m_currentPath, generateChild
+ && m_generate == TypeEntry::GenerateAll);
+ if (!result)
+ m_error = QStringLiteral("Failed to parse: '%1'").arg(typeSystemName);
+ return result;
+}
+
+bool Handler::parseRejectEnumValue(const QXmlStreamReader &,
+ QXmlStreamAttributes *attributes)
+{
+ if (!m_currentEnum) {
+ m_error = QLatin1String("<reject-enum-value> node must be used inside a <enum-type> node");
+ return false;
+ }
+ const int nameIndex = indexOfAttribute(*attributes, nameAttribute());
+ if (nameIndex == -1) {
+ m_error = msgMissingAttribute(nameAttribute());
+ return false;
+ }
+ m_currentEnum->addEnumValueRejection(attributes->takeAt(nameIndex).value().toString());
+ return true;
+}
+
+bool Handler::parseReplaceArgumentType(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyArgument) {
+ m_error = QLatin1String("Type replacement can only be specified for argument modifications");
+ return false;
+ }
+ const int modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute());
+ if (modifiedTypeIndex == -1) {
+ m_error = QLatin1String("Type replacement requires 'modified-type' attribute");
+ return false;
+ }
+ m_contextStack.top()->functionMods.last().argument_mods.last().modified_type =
+ attributes->takeAt(modifiedTypeIndex).value().toString();
return true;
}
-bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts)
+bool Handler::parseCustomConversion(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyArgument
+ && topElement.type != StackElement::ValueTypeEntry
+ && topElement.type != StackElement::PrimitiveTypeEntry
+ && topElement.type != StackElement::ContainerTypeEntry) {
+ m_error = QLatin1String("Conversion rules can only be specified for argument modification, "
+ "value-type, primitive-type or container-type conversion.");
+ return false;
+ }
+
+ QString sourceFile;
+ QString snippetLabel;
+ TypeSystem::Language lang = TypeSystem::NativeCode;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == classAttribute()) {
+ const QStringRef languageAttribute = attributes->takeAt(i).value();
+ lang = languageFromAttribute(languageAttribute);
+ if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) {
+ m_error = QStringLiteral("unsupported class attribute: '%1'").arg(languageAttribute);
+ return false;
+ }
+ } else if (name == QLatin1String("file")) {
+ sourceFile = attributes->takeAt(i).value().toString();
+ } else if (name == snippetAttribute()) {
+ snippetLabel = attributes->takeAt(i).value().toString();
+ }
+ }
+
+ if (topElement.type == StackElement::ModifyArgument) {
+ CodeSnip snip;
+ snip.language = lang;
+ m_contextStack.top()->functionMods.last().argument_mods.last().conversion_rules.append(snip);
+ return true;
+ }
+
+ if (topElement.entry->hasConversionRule() || topElement.entry->hasCustomConversion()) {
+ m_error = QLatin1String("Types can have only one conversion rule");
+ return false;
+ }
+
+ // The old conversion rule tag that uses a file containing the conversion
+ // will be kept temporarily for compatibility reasons.
+ if (!sourceFile.isEmpty()) {
+ if (m_generate != TypeEntry::GenerateForSubclass
+ && m_generate != TypeEntry::GenerateNothing) {
+
+ const char* conversionFlag = NATIVE_CONVERSION_RULE_FLAG;
+ if (lang == TypeSystem::TargetLangCode)
+ conversionFlag = TARGET_CONVERSION_RULE_FLAG;
+
+ QFile conversionSource(sourceFile);
+ if (conversionSource.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ const QString conversionRule =
+ extractSnippet(QString::fromUtf8(conversionSource.readAll()), snippetLabel);
+ topElement.entry->setConversionRule(QLatin1String(conversionFlag) + conversionRule);
+ } else {
+ qCWarning(lcShiboken).noquote().nospace()
+ << "File containing conversion code for "
+ << topElement.entry->name() << " type does not exist or is not readable: "
+ << sourceFile;
+ }
+ }
+ }
+
+ CustomConversion* customConversion = new CustomConversion(m_current->entry);
+ customConversionsForReview.append(customConversion);
+ return true;
+}
+
+bool Handler::parseNativeToTarget(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ConversionRule) {
+ m_error = QLatin1String("Native to Target conversion code can only be specified for custom conversion rules.");
+ return false;
+ }
+ CodeSnip snip;
+ if (!readFileSnippet(attributes, &snip))
+ return false;
+ m_contextStack.top()->codeSnips.append(snip);
+ return true;
+}
+
+bool Handler::parseAddConversion(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::TargetToNative) {
+ m_error = QLatin1String("Target to Native conversions can only be added inside 'target-to-native' tags.");
+ return false;
+ }
+ QString sourceTypeName;
+ QString typeCheck;
+ CodeSnip snip;
+ if (!readFileSnippet(attributes, &snip))
+ return false;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("type"))
+ sourceTypeName = attributes->takeAt(i).value().toString();
+ else if (name == QLatin1String("check"))
+ typeCheck = attributes->takeAt(i).value().toString();
+ }
+ if (sourceTypeName.isEmpty()) {
+ m_error = QLatin1String("Target to Native conversions must specify the input type with the 'type' attribute.");
+ return false;
+ }
+ m_current->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
+ m_contextStack.top()->codeSnips.append(snip);
+ return true;
+}
+
+static bool parseIndex(const QString &index, int *result, QString *errorMessage)
+{
+ bool ok = false;
+ *result = index.toInt(&ok);
+ if (!ok)
+ *errorMessage = QStringLiteral("Cannot convert '%1' to integer").arg(index);
+ return ok;
+}
+
+static bool parseArgumentIndex(const QString &index, int *result, QString *errorMessage)
+{
+ if (index == QLatin1String("return")) {
+ *result = 0;
+ return true;
+ }
+ if (index == QLatin1String("this")) {
+ *result = -1;
+ return true;
+ }
+ return parseIndex(index, result, errorMessage);
+}
+
+bool Handler::parseModifyArgument(const QXmlStreamReader &,
+ const StackElement &topElement, QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyFunction
+ && topElement.type != StackElement::AddFunction) {
+ m_error = QString::fromLatin1("argument modification requires function"
+ " modification as parent, was %1")
+ .arg(topElement.type, 0, 16);
+ return false;
+ }
+
+ QString index;
+ QString replaceValue;
+ bool resetAfterUse = false;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == indexAttribute()) {
+ index = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("replace-value")) {
+ replaceValue = attributes->takeAt(i).value().toString();
+ } else if (name == invalidateAfterUseAttribute()) {
+ resetAfterUse = convertBoolean(attributes->takeAt(i).value(),
+ invalidateAfterUseAttribute(), false);
+ }
+ }
+
+ if (index.isEmpty()) {
+ m_error = msgMissingAttribute(indexAttribute());
+ return false;
+ }
+
+ int idx;
+ if (!parseArgumentIndex(index, &idx, &m_error))
+ return false;
+
+ if (!replaceValue.isEmpty() && idx) {
+ m_error = QLatin1String("replace-value is only supported for return values (index=0).");
+ return false;
+ }
+
+ ArgumentModification argumentModification = ArgumentModification(idx);
+ argumentModification.replace_value = replaceValue;
+ argumentModification.resetAfterUse = resetAfterUse;
+ m_contextStack.top()->functionMods.last().argument_mods.append(argumentModification);
+ return true;
+}
+
+bool Handler::parseNoNullPointer(const QXmlStreamReader &reader,
+ const StackElement &topElement, QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyArgument) {
+ m_error = QLatin1String("no-null-pointer requires argument modification as parent");
+ return false;
+ }
+
+ ArgumentModification &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods.last();
+ lastArgMod.noNullPointers = true;
+
+ const int defaultValueIndex =
+ indexOfAttribute(*attributes, QStringViewLiteral("default-value"));
+ if (defaultValueIndex != -1) {
+ const QXmlStreamAttribute attribute = attributes->takeAt(defaultValueIndex);
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, attribute)));
+ }
+ return true;
+}
+
+bool Handler::parseDefineOwnership(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyArgument) {
+ m_error = QLatin1String("define-ownership requires argument modification as parent");
+ return false;
+ }
+
+ TypeSystem::Language lang = TypeSystem::TargetLangCode;
+ QString ownership;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == classAttribute()) {
+ const QStringRef className = attributes->takeAt(i).value();
+ lang = languageFromAttribute(className);
+ if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) {
+ m_error = QStringLiteral("unsupported class attribute: '%1'").arg(className);
+ return false;
+ }
+ } else if (name == ownershipAttribute()) {
+ ownership = attributes->takeAt(i).value().toString();
+ }
+ }
+ const TypeSystem::Ownership owner = ownershipFromFromAttribute(ownership);
+ if (owner == TypeSystem::InvalidOwnership) {
+ m_error = QStringLiteral("unsupported owner attribute: '%1'").arg(ownership);
+ return false;
+ }
+ m_contextStack.top()->functionMods.last().argument_mods.last().ownerships[lang] = owner;
+ return true;
+}
+
+bool Handler::parseArgumentMap(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!(topElement.type & StackElement::CodeSnipMask)) {
+ m_error = QLatin1String("Argument maps requires code injection as parent");
+ return false;
+ }
+
+ int pos = 1;
+ QString metaName;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == indexAttribute()) {
+ if (!parseIndex(attributes->takeAt(i).value().toString(), &pos, &m_error))
+ return false;
+ if (pos <= 0) {
+ m_error = QStringLiteral("Argument position %1 must be a positive number").arg(pos);
+ return false;
+ }
+ } else if (name == QLatin1String("meta-name")) {
+ metaName = attributes->takeAt(i).value().toString();
+ }
+ }
+
+ if (metaName.isEmpty())
+ qCWarning(lcShiboken) << "Empty meta name in argument map";
+
+ if (topElement.type == StackElement::InjectCodeInFunction) {
+ m_contextStack.top()->functionMods.last().snips.last().argumentMap[pos] = metaName;
+ } else {
+ qCWarning(lcShiboken) << "Argument maps are only useful for injection of code "
+ "into functions.";
+ }
+ return true;
+}
+
+bool Handler::parseRemoval(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyFunction) {
+ m_error = QLatin1String("Function modification parent required");
+ return false;
+ }
+
+ TypeSystem::Language lang = TypeSystem::All;
+ const int classIndex = indexOfAttribute(*attributes, classAttribute());
+ if (classIndex != -1) {
+ const QStringRef value = attributes->takeAt(classIndex).value();
+ lang = languageFromAttribute(value);
+ if (lang == TypeSystem::TargetLangCode) // "target" means TargetLangAndNativeCode here
+ lang = TypeSystem::TargetLangAndNativeCode;
+ if (lang != TypeSystem::TargetLangAndNativeCode && lang != TypeSystem::All) {
+ m_error = QStringLiteral("unsupported class attribute: '%1'").arg(value);
+ return false;
+ }
+ }
+ m_contextStack.top()->functionMods.last().removal = lang;
+ return true;
+}
+
+bool Handler::parseRename(const QXmlStreamReader &reader,
+ StackElement::ElementType type,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyField
+ && topElement.type != StackElement::ModifyFunction
+ && topElement.type != StackElement::ModifyArgument) {
+ m_error = QLatin1String("Function, field or argument modification parent required");
+ return false;
+ }
+
+ Modification *mod = nullptr;
+ if (topElement.type == StackElement::ModifyFunction)
+ mod = &m_contextStack.top()->functionMods.last();
+ else if (topElement.type == StackElement::ModifyField)
+ mod = &m_contextStack.top()->fieldMods.last();
+
+ Modification::Modifiers modifierFlag = Modification::Rename;
+ if (type == StackElement::Rename) {
+ const int toIndex = indexOfAttribute(*attributes, toAttribute());
+ if (toIndex == -1) {
+ m_error = msgMissingAttribute(toAttribute());
+ return false;
+ }
+ const QString renamed_to = attributes->takeAt(toIndex).value().toString();
+ if (topElement.type == StackElement::ModifyFunction)
+ mod->setRenamedTo(renamed_to);
+ else if (topElement.type == StackElement::ModifyField)
+ mod->setRenamedTo(renamed_to);
+ else
+ m_contextStack.top()->functionMods.last().argument_mods.last().renamed_to = renamed_to;
+ } else {
+ const int modifierIndex = indexOfAttribute(*attributes, modifierAttribute());
+ if (modifierIndex == -1) {
+ m_error = msgMissingAttribute(modifierAttribute());
+ return false;
+ }
+ const QStringRef modifier = attributes->takeAt(modifierIndex).value();
+ modifierFlag = modifierFromAttribute(modifier);
+ if (modifierFlag == Modification::InvalidModifier) {
+ m_error = QStringLiteral("Unknown access modifier: '%1'").arg(modifier);
+ return false;
+ }
+ if (modifierFlag == Modification::Friendly) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeValueWarning(reader, modifierAttribute(), modifier)));
+ }
+ }
+
+ if (mod)
+ mod->modifiers |= modifierFlag;
+ return true;
+}
+
+bool Handler::parseModifyField(const QXmlStreamReader &reader,
+ QXmlStreamAttributes *attributes)
+{
+ FieldModification fm;
+ fm.modifiers = FieldModification::Readable | FieldModification::Writable;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute()) {
+ fm.name = attributes->takeAt(i).value().toString();
+ } else if (name == removeAttribute()) {
+ if (!convertRemovalAttribute(attributes->takeAt(i).value(), fm, m_error))
+ return false;
+ } else if (name == readAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ if (!convertBoolean(attributes->takeAt(i).value(), readAttribute(), true))
+ fm.modifiers &= ~FieldModification::Readable;
+ } else if (name == writeAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ if (!convertBoolean(attributes->takeAt(i).value(), writeAttribute(), true))
+ fm.modifiers &= ~FieldModification::Writable;
+ }
+ }
+ if (fm.name.isEmpty()) {
+ m_error = msgMissingAttribute(nameAttribute());
+ return false;
+ }
+ m_contextStack.top()->fieldMods << fm;
+ return true;
+}
+
+bool Handler::parseAddFunction(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!(topElement.type & (StackElement::ComplexTypeEntryMask | StackElement::Root))) {
+ m_error = QString::fromLatin1("Add function requires a complex type or a root tag as parent"
+ ", was=%1").arg(topElement.type, 0, 16);
+ return false;
+ }
+ QString originalSignature;
+ QString returnType = QLatin1String("void");
+ bool staticFunction = false;
+ QString access;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("signature")) {
+ originalSignature = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("return-type")) {
+ returnType = attributes->takeAt(i).value().toString();
+ } else if (name == staticAttribute()) {
+ staticFunction = convertBoolean(attributes->takeAt(i).value(),
+ staticAttribute(), false);
+ } else if (name == accessAttribute()) {
+ access = attributes->takeAt(i).value().toString();
+ }
+ }
+
+ QString signature = TypeDatabase::normalizedSignature(originalSignature);
+ if (signature.isEmpty()) {
+ m_error = QLatin1String("No signature for the added function");
+ return false;
+ }
+
+ QString errorString = checkSignatureError(signature, QLatin1String("add-function"));
+ if (!errorString.isEmpty()) {
+ m_error = errorString;
+ return false;
+ }
+
+ AddedFunction func(signature, returnType);
+ func.setStatic(staticFunction);
+ if (!signature.contains(QLatin1Char('(')))
+ signature += QLatin1String("()");
+ m_currentSignature = signature;
+
+ if (!access.isEmpty()) {
+ const AddedFunction::Access a = addedFunctionAccessFromAttribute(access);
+ if (a == AddedFunction::InvalidAccess) {
+ m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
+ return false;
+ }
+ func.setAccess(a);
+ }
+
+ m_contextStack.top()->addedFunctions << func;
+
+ FunctionModification mod;
+ if (!mod.setSignature(m_currentSignature, &m_error))
+ return false;
+ mod.setOriginalSignature(originalSignature);
+ m_contextStack.top()->functionMods << mod;
+ return true;
+}
+
+bool Handler::parseModifyFunction(const QXmlStreamReader &reader,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!(topElement.type & StackElement::ComplexTypeEntryMask)) {
+ m_error = QString::fromLatin1("Modify function requires complex type as parent"
+ ", was=%1").arg(topElement.type, 0, 16);
+ return false;
+ }
+
+ QString originalSignature;
+ QString access;
+ QString removal;
+ QString rename;
+ QString association;
+ bool deprecated = false;
+ bool isThread = false;
+ TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
+ TypeSystem::AllowThread allowThread = TypeSystem::AllowThread::Unspecified;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("signature")) {
+ originalSignature = attributes->takeAt(i).value().toString();
+ } else if (name == accessAttribute()) {
+ access = attributes->takeAt(i).value().toString();
+ } else if (name == renameAttribute()) {
+ rename = attributes->takeAt(i).value().toString();
+ } else if (name == QLatin1String("associated-to")) {
+ association = attributes->takeAt(i).value().toString();
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ } else if (name == removeAttribute()) {
+ removal = attributes->takeAt(i).value().toString();
+ } else if (name == deprecatedAttribute()) {
+ deprecated = convertBoolean(attributes->takeAt(i).value(),
+ deprecatedAttribute(), false);
+ } else if (name == threadAttribute()) {
+ isThread = convertBoolean(attributes->takeAt(i).value(),
+ threadAttribute(), false);
+ } else if (name == allowThreadAttribute()) {
+ const QXmlStreamAttribute attribute = attributes->takeAt(i);
+ allowThread = allowThreadFromAttribute(attribute.value());
+ if (allowThread == TypeSystem::AllowThread::Unspecified) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ } else if (name == exceptionHandlingAttribute()) {
+ const auto attribute = attributes->takeAt(i);
+ exceptionHandling = exceptionHandlingFromAttribute(attribute.value());
+ if (exceptionHandling == TypeSystem::ExceptionHandling::Unspecified) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (name == virtualSlotAttribute()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeWarning(reader, name)));
+ }
+ }
+
+ const QString signature = TypeDatabase::normalizedSignature(originalSignature);
+ if (signature.isEmpty()) {
+ m_error = QLatin1String("No signature for modified function");
+ return false;
+ }
+
+ QString errorString = checkSignatureError(signature, QLatin1String("modify-function"));
+ if (!errorString.isEmpty()) {
+ m_error = errorString;
+ return false;
+ }
+
+ FunctionModification mod;
+ if (!mod.setSignature(signature, &m_error))
+ return false;
+ mod.setOriginalSignature(originalSignature);
+ mod.setExceptionHandling(exceptionHandling);
+ m_currentSignature = signature;
+
+ if (!access.isEmpty()) {
+ const Modification::Modifiers m = modifierFromAttribute(access);
+ if ((m & (Modification::AccessModifierMask | Modification::FinalMask)) == 0) {
+ m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
+ return false;
+ }
+ if (m == Modification::Final || m == Modification::NonFinal) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeValueWarning(reader,
+ accessAttribute(), access)));
+ }
+ mod.modifiers |= m;
+ }
+
+ if (deprecated)
+ mod.modifiers |= Modification::Deprecated;
+
+ if (!removal.isEmpty() && !convertRemovalAttribute(removal, mod, m_error))
+ return false;
+
+ if (!rename.isEmpty()) {
+ mod.renamedToName = rename;
+ mod.modifiers |= Modification::Rename;
+ }
+
+ if (!association.isEmpty())
+ mod.association = association;
+
+ mod.setIsThread(isThread);
+ if (allowThread != TypeSystem::AllowThread::Unspecified)
+ mod.setAllowThread(allowThread);
+
+ m_contextStack.top()->functionMods << mod;
+ return true;
+}
+
+bool Handler::parseReplaceDefaultExpression(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!(topElement.type & StackElement::ModifyArgument)) {
+ m_error = QLatin1String("Replace default expression only allowed as child of argument modification");
+ return false;
+ }
+ const int withIndex = indexOfAttribute(*attributes, QStringViewLiteral("with"));
+ if (withIndex == -1 || attributes->at(withIndex).value().isEmpty()) {
+ m_error = QLatin1String("Default expression replaced with empty string. Use remove-default-expression instead.");
+ return false;
+ }
+
+ m_contextStack.top()->functionMods.last().argument_mods.last().replacedDefaultExpression =
+ attributes->takeAt(withIndex).value().toString();
+ return true;
+}
+
+CustomFunction *
+ Handler::parseCustomMetaConstructor(const QXmlStreamReader &,
+ StackElement::ElementType type,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ QString functionName = topElement.entry->name().toLower()
+ + (type == StackElement::CustomMetaConstructor
+ ? QLatin1String("_create") : QLatin1String("_delete"));
+ QString paramName = QLatin1String("copy");
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute())
+ functionName = attributes->takeAt(i).value().toString();
+ else if (name == QLatin1String("param-name"))
+ paramName = attributes->takeAt(i).value().toString();
+ }
+ CustomFunction *func = new CustomFunction(functionName);
+ func->paramName = paramName;
+ return func;
+}
+
+bool Handler::parseReferenceCount(const QXmlStreamReader &reader,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyArgument) {
+ m_error = QLatin1String("reference-count must be child of modify-argument");
+ return false;
+ }
+
+ ReferenceCount rc;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == actionAttribute()) {
+ const QXmlStreamAttribute attribute = attributes->takeAt(i);
+ rc.action = referenceCountFromAttribute(attribute.value());
+ switch (rc.action) {
+ case ReferenceCount::Invalid:
+ m_error = QLatin1String("unrecognized value '") + attribute.value()
+ + QLatin1String("' for action attribute.");
+ return false;
+ case ReferenceCount::AddAll:
+ case ReferenceCount::Ignore:
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedAttributeValueWarning(reader, attribute)));
+ break;
+ default:
+ break;
+ }
+ } else if (name == QLatin1String("variable-name")) {
+ rc.varName = attributes->takeAt(i).value().toString();
+ }
+ }
+
+ m_contextStack.top()->functionMods.last().argument_mods.last().referenceCounts.append(rc);
+ return true;
+}
+
+bool Handler::parseParentOwner(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::ModifyArgument) {
+ m_error = QLatin1String("parent-policy must be child of modify-argument");
+ return false;
+ }
+ ArgumentOwner ao;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == indexAttribute()) {
+ const QString index = attributes->takeAt(i).value().toString();
+ if (!parseArgumentIndex(index, &ao.index, &m_error))
+ return false;
+ } else if (name == actionAttribute()) {
+ const QStringRef action = attributes->takeAt(i).value();
+ ao.action = argumentOwnerActionFromAttribute(action);
+ if (ao.action == ArgumentOwner::Invalid) {
+ m_error = QLatin1String("Invalid parent actionr '") + action + QLatin1String("'.");
+ return false;
+ }
+ }
+ }
+ m_contextStack.top()->functionMods.last().argument_mods.last().owner = ao;
+ return true;
+}
+
+bool Handler::readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip)
+{
+ QString fileName;
+ QString snippetLabel;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("file")) {
+ fileName = attributes->takeAt(i).value().toString();
+ } else if (name == snippetAttribute()) {
+ snippetLabel = attributes->takeAt(i).value().toString();
+ }
+ }
+ if (fileName.isEmpty())
+ return true;
+ const QString resolved = m_database->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (!QFile::exists(resolved)) {
+ m_error = QLatin1String("File for inject code not exist: ")
+ + QDir::toNativeSeparators(fileName);
+ return false;
+ }
+ QFile codeFile(resolved);
+ if (!codeFile.open(QIODevice::Text | QIODevice::ReadOnly)) {
+ m_error = msgCannotOpenForReading(codeFile);
+ return false;
+ }
+ QString source = fileName;
+ if (!snippetLabel.isEmpty())
+ source += QLatin1String(" (") + snippetLabel + QLatin1Char(')');
+ QString content;
+ QTextStream str(&content);
+ str << "// ========================================================================\n"
+ "// START of custom code block [file: "
+ << source << "]\n"
+ << extractSnippet(QString::fromUtf8(codeFile.readAll()), snippetLabel)
+ << "\n// END of custom code block [file: " << source
+ << "]\n// ========================================================================\n";
+ snip->addCode(content);
+ return true;
+}
+
+bool Handler::parseInjectCode(const QXmlStreamReader &,
+ const StackElement &topElement,
+ StackElement* element, QXmlStreamAttributes *attributes)
+{
+ if (!(topElement.type & StackElement::ComplexTypeEntryMask)
+ && (topElement.type != StackElement::AddFunction)
+ && (topElement.type != StackElement::ModifyFunction)
+ && (topElement.type != StackElement::Root)) {
+ m_error = QLatin1String("wrong parent type for code injection");
+ return false;
+ }
+
+ TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionBeginning;
+ TypeSystem::Language lang = TypeSystem::TargetLangCode;
+ CodeSnip snip;
+ if (!readFileSnippet(attributes, &snip))
+ return false;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == classAttribute()) {
+ const QStringRef className = attributes->takeAt(i).value();
+ lang = languageFromAttribute(className);
+ if (lang == TypeSystem::NoLanguage) {
+ m_error = QStringLiteral("Invalid class specifier: '%1'").arg(className);
+ return false;
+ }
+ } else if (name == positionAttribute()) {
+ const QStringRef value = attributes->takeAt(i).value();
+ position = codeSnipPositionFromAttribute(value);
+ if (position == TypeSystem::CodeSnipPositionInvalid) {
+ m_error = QStringLiteral("Invalid position: '%1'").arg(value);
+ return false;
+ }
+ }
+ }
+
+ snip.position = position;
+ snip.language = lang;
+
+ if (snip.language == TypeSystem::Interface
+ && topElement.type != StackElement::InterfaceTypeEntry) {
+ m_error = QLatin1String("Interface code injections must be direct child of an interface type entry");
+ return false;
+ }
+
+ if (topElement.type == StackElement::ModifyFunction
+ || topElement.type == StackElement::AddFunction) {
+ if (snip.language == TypeSystem::ShellDeclaration) {
+ m_error = QLatin1String("no function implementation in shell declaration in which to inject code");
+ return false;
+ }
+
+ FunctionModification &mod = m_contextStack.top()->functionMods.last();
+ mod.snips << snip;
+ if (!snip.code().isEmpty())
+ mod.modifiers |= FunctionModification::CodeInjection;
+ element->type = StackElement::InjectCodeInFunction;
+ } else if (topElement.type == StackElement::Root) {
+ element->entry->addCodeSnip(snip);
+ } else if (topElement.type != StackElement::Root) {
+ m_contextStack.top()->codeSnips << snip;
+ }
+ return true;
+}
+
+bool Handler::parseInclude(const QXmlStreamReader &,
+ const StackElement &topElement,
+ TypeEntry *entry, QXmlStreamAttributes *attributes)
+{
+ QString fileName;
+ QString location;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("file-name"))
+ fileName = attributes->takeAt(i).value().toString();
+ else if (name == locationAttribute())
+ location = attributes->takeAt(i).value().toString();
+ }
+ const Include::IncludeType loc = locationFromAttribute(location);
+ if (loc == Include::InvalidInclude) {
+ m_error = QStringLiteral("Location not recognized: '%1'").arg(location);
+ return false;
+ }
+
+ Include inc(loc, fileName);
+ if (topElement.type
+ & (StackElement::ComplexTypeEntryMask | StackElement::PrimitiveTypeEntry)) {
+ entry->setInclude(inc);
+ } else if (topElement.type == StackElement::ExtraIncludes) {
+ entry->addExtraInclude(inc);
+ } else {
+ m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes");
+ return false;
+ }
+ if (InterfaceTypeEntry *di = entry->designatedInterface()) {
+ di->setInclude(entry->include());
+ di->setExtraIncludes(entry->extraIncludes());
+ }
+ return true;
+}
+
+TemplateInstance *
+ Handler::parseTemplateInstanceEnum(const QXmlStreamReader &,
+ const StackElement &topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!(topElement.type & StackElement::CodeSnipMask) &&
+ (topElement.type != StackElement::Template) &&
+ (topElement.type != StackElement::CustomMetaConstructor) &&
+ (topElement.type != StackElement::CustomMetaDestructor) &&
+ (topElement.type != StackElement::NativeToTarget) &&
+ (topElement.type != StackElement::AddConversion) &&
+ (topElement.type != StackElement::ConversionRule)) {
+ m_error = QLatin1String("Can only insert templates into code snippets, templates, custom-constructors, "\
+ "custom-destructors, conversion-rule, native-to-target or add-conversion tags.");
+ return nullptr;
+ }
+ const int nameIndex = indexOfAttribute(*attributes, nameAttribute());
+ if (nameIndex == -1) {
+ m_error = msgMissingAttribute(nameAttribute());
+ return nullptr;
+ }
+ return new TemplateInstance(attributes->takeAt(nameIndex).value().toString());
+}
+
+bool Handler::parseReplace(const QXmlStreamReader &,
+ const StackElement &topElement,
+ StackElement *element, QXmlStreamAttributes *attributes)
+{
+ if (topElement.type != StackElement::TemplateInstanceEnum) {
+ m_error = QLatin1String("Can only insert replace rules into insert-template.");
+ return false;
+ }
+ QString from;
+ QString to;
+ for (int i = attributes->size() - 1; i >= 0; --i) {
+ const QStringRef name = attributes->at(i).qualifiedName();
+ if (name == QLatin1String("from"))
+ from = attributes->takeAt(i).value().toString();
+ else if (name == toAttribute())
+ to = attributes->takeAt(i).value().toString();
+ }
+ element->parent->value.templateInstance->addReplaceRule(from, to);
+ return true;
+}
+
+bool Handler::startElement(const QXmlStreamReader &reader)
{
if (m_ignoreDepth) {
++m_ignoreDepth;
return true;
}
+ const QStringRef tagName = reader.name();
+ QXmlStreamAttributes attributes = reader.attributes();
+
QVersionNumber since(0, 0);
- const QStringRef sinceSpec = atts.value(sinceAttribute());
- if (!sinceSpec.isNull()) {
+ int index = indexOfAttribute(attributes, sinceAttribute());
+ if (index != -1) {
+ const QStringRef sinceSpec = attributes.takeAt(index).value();
since = QVersionNumber::fromString(sinceSpec.toString());
if (since.isNull()) {
m_error = msgInvalidVersion(sinceSpec, m_defaultPackage);
@@ -722,12 +2447,11 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
}
}
- const QString tagName = n.toString().toLower();
- if (tagName == QLatin1String("import-file"))
- return importFileElement(atts);
+ if (tagName.compare(QLatin1String("import-file"), Qt::CaseInsensitive) == 0)
+ return importFileElement(attributes);
- const QHash<QString, StackElement::ElementType>::const_iterator tit = tagNames.constFind(tagName);
- if (tit == tagNames.constEnd()) {
+ const StackElement::ElementType elementType = elementFromTag(tagName);
+ if (elementType == StackElement::None) {
m_error = QStringLiteral("Unknown tag name: '%1'").arg(tagName);
return false;
}
@@ -738,92 +2462,48 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
}
StackElement* element = new StackElement(m_current);
- element->type = tit.value();
+ element->type = elementType;
if (element->type == StackElement::Root && m_generate == TypeEntry::GenerateAll)
customConversionsForReview.clear();
- if (element->type == StackElement::Root
- || element->type == StackElement::NamespaceTypeEntry
- || element->type == StackElement::InterfaceTypeEntry
- || element->type == StackElement::ObjectTypeEntry
- || element->type == StackElement::ValueTypeEntry
- || element->type == StackElement::PrimitiveTypeEntry) {
+ if (element->type == StackElement::CustomMetaConstructor
+ || element->type == StackElement::CustomMetaDestructor) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedElementWarning(reader, tagName)));
+ }
+
+ switch (element->type) {
+ case StackElement::Root:
+ case StackElement::NamespaceTypeEntry:
+ case StackElement::InterfaceTypeEntry:
+ case StackElement::ObjectTypeEntry:
+ case StackElement::ValueTypeEntry:
+ case StackElement::PrimitiveTypeEntry:
+ case StackElement::TypedefTypeEntry:
m_contextStack.push(new StackElementContext());
+ break;
+ default:
+ break;
}
if (element->type & StackElement::TypeEntryMask) {
- QHash<QString, QString> attributes;
- attributes.insert(nameAttribute(), QString());
- attributes.insert(QLatin1String("revision"), QLatin1String("0"));
- attributes.insert(sinceAttribute(), QString()); // dummy for matching allowed attributes
-
- switch (element->type) {
- case StackElement::PrimitiveTypeEntry:
- attributes.insert(QLatin1String("target-lang-name"), QString());
- attributes.insert(QLatin1String("target-lang-api-name"), QString());
- attributes.insert(QLatin1String("preferred-conversion"), yesAttributeValue());
- attributes.insert(QLatin1String("preferred-target-lang-type"), yesAttributeValue());
- attributes.insert(QLatin1String("default-constructor"), QString());
- break;
- case StackElement::ContainerTypeEntry:
- attributes.insert(QLatin1String("type"), QString());
- break;
- case StackElement::SmartPointerTypeEntry:
- attributes.insert(QLatin1String("type"), QString());
- attributes.insert(QLatin1String("getter"), QString());
- attributes.insert(QLatin1String("ref-count-method"), QString());
- break;
- case StackElement::EnumTypeEntry:
- attributes.insert(flagsAttribute(), QString());
- attributes.insert(QLatin1String("flags-revision"), QString());
- attributes.insert(QLatin1String("upper-bound"), QString());
- attributes.insert(QLatin1String("lower-bound"), QString());
- attributes.insert(QLatin1String("force-integer"), noAttributeValue());
- attributes.insert(QLatin1String("extensible"), noAttributeValue());
- attributes.insert(enumIdentifiedByValueAttribute(), QString());
- attributes.insert(classAttribute(), falseAttributeValue());
- break;
- case StackElement::ValueTypeEntry:
- attributes.insert(QLatin1String("default-constructor"), QString());
- Q_FALLTHROUGH();
- case StackElement::ObjectTypeEntry:
- attributes.insert(QLatin1String("force-abstract"), noAttributeValue());
- attributes.insert(QLatin1String("deprecated"), noAttributeValue());
- attributes.insert(QLatin1String("hash-function"), QString());
- attributes.insert(QLatin1String("stream"), noAttributeValue());
- Q_FALLTHROUGH();
- case StackElement::InterfaceTypeEntry:
- attributes[QLatin1String("default-superclass")] = m_defaultSuperclass;
- attributes.insert(QLatin1String("polymorphic-id-expression"), QString());
- attributes.insert(QLatin1String("delete-in-main-thread"), noAttributeValue());
- attributes.insert(QLatin1String("held-type"), QString());
- attributes.insert(QLatin1String("copyable"), QString());
- Q_FALLTHROUGH();
- case StackElement::NamespaceTypeEntry:
- attributes.insert(QLatin1String("target-lang-name"), QString());
- attributes[QLatin1String("package")] = m_defaultPackage;
- attributes.insert(QLatin1String("expense-cost"), QLatin1String("1"));
- attributes.insert(QLatin1String("expense-limit"), QLatin1String("none"));
- attributes.insert(QLatin1String("polymorphic-base"), noAttributeValue());
- attributes.insert(QLatin1String("generate"), yesAttributeValue());
- attributes.insert(QLatin1String("target-type"), QString());
- attributes.insert(QLatin1String("generic-class"), noAttributeValue());
- break;
- case StackElement::FunctionTypeEntry:
- attributes.insert(QLatin1String("signature"), QString());
- attributes.insert(QLatin1String("rename"), QString());
- break;
- default:
- { } // nada
- };
-
- fetchAttributeValues(tagName, atts, &attributes);
- QString name = attributes[nameAttribute()];
+ QString name;
+ if (element->type != StackElement::FunctionTypeEntry) {
+ const int nameIndex = indexOfAttribute(attributes, nameAttribute());
+ if (nameIndex != -1) {
+ name = attributes.takeAt(nameIndex).value().toString();
+ } else if (element->type != StackElement::EnumTypeEntry) { // anonymous enum?
+ m_error = msgMissingAttribute(nameAttribute());
+ return false;
+ }
+ }
if (m_database->hasDroppedTypeEntries()) {
QString identifier = getNamePrefix(element) + QLatin1Char('.');
- identifier += (element->type == StackElement::FunctionTypeEntry ? attributes[QLatin1String("signature")] : name);
+ identifier += element->type == StackElement::FunctionTypeEntry
+ ? attributes.value(signatureAttribute()).toString()
+ : name;
if (m_database->shouldDropTypeEntry(identifier)) {
m_currentDroppedEntry = element;
m_currentDroppedEntryDepth = 1;
@@ -837,30 +2517,9 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
// The top level tag 'function' has only the 'signature' tag
// and we should extract the 'name' value from it.
- if (element->type == StackElement::FunctionTypeEntry) {
- QString signature = attributes[QLatin1String("signature")];
- name = signature.left(signature.indexOf(QLatin1Char('('))).trimmed();
- QString errorString = checkSignatureError(signature, QLatin1String("function"));
- if (!errorString.isEmpty()) {
- m_error = errorString;
+ if (element->type == StackElement::FunctionTypeEntry
+ && !parseRenameFunction(reader, &name, &attributes)) {
return false;
- }
- QString rename = attributes[QLatin1String("rename")];
- if (!rename.isEmpty()) {
- static const QRegularExpression functionNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$"));
- Q_ASSERT(functionNameRegExp.isValid());
- if (!functionNameRegExp.match(rename).hasMatch()) {
- m_error = QLatin1String("can not rename '") + signature + QLatin1String("', '")
- + rename + QLatin1String("' is not a valid function name");
- return false;
- }
- FunctionModification mod;
- if (!mod.setSignature(signature, &m_error))
- return false;
- mod.renamedToName = attributes[QLatin1String("rename")];
- mod.modifiers |= Modification::Rename;
- m_contextStack.top()->functionMods << mod;
- }
}
// We need to be able to have duplicate primitive type entries,
@@ -875,7 +2534,9 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
}
if (element->type == StackElement::EnumTypeEntry) {
- const QString identifiedByValue = attributes.value(enumIdentifiedByValueAttribute());
+ const int enumIdentifiedByIndex = indexOfAttribute(attributes, enumIdentifiedByValueAttribute());
+ const QString identifiedByValue = enumIdentifiedByIndex != -1
+ ? attributes.takeAt(enumIdentifiedByIndex).value().toString() : QString();
if (name.isEmpty()) {
name = identifiedByValue;
} else if (!identifiedByValue.isEmpty()) {
@@ -900,281 +2561,92 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
case StackElement::CustomTypeEntry:
element->entry = new TypeEntry(name, TypeEntry::CustomType, since);
break;
- case StackElement::PrimitiveTypeEntry: {
- QString targetLangName = attributes[QLatin1String("target-lang-name")];
- QString targetLangApiName = attributes[QLatin1String("target-lang-api-name")];
- QString preferredConversion = attributes[QLatin1String("preferred-conversion")].toLower();
- QString preferredTargetLangType = attributes[QLatin1String("preferred-target-lang-type")].toLower();
- QString defaultConstructor = attributes[QLatin1String("default-constructor")];
-
- if (targetLangName.isEmpty())
- targetLangName = name;
- if (targetLangApiName.isEmpty())
- targetLangApiName = name;
-
- PrimitiveTypeEntry *type = new PrimitiveTypeEntry(name, since);
- type->setCodeGeneration(m_generate);
- type->setTargetLangName(targetLangName);
- type->setTargetLangApiName(targetLangApiName);
- type->setTargetLangPackage(m_defaultPackage);
- type->setDefaultConstructor(defaultConstructor);
-
- bool preferred;
- preferred = convertBoolean(preferredConversion, QLatin1String("preferred-conversion"), true);
- type->setPreferredConversion(preferred);
- preferred = convertBoolean(preferredTargetLangType,
- QLatin1String("preferred-target-lang-type"), true);
- type->setPreferredTargetLangType(preferred);
-
- element->entry = type;
- }
- break;
-
- case StackElement::ContainerTypeEntry: {
- QString typeName = attributes[QLatin1String("type")];
- ContainerTypeEntry::Type containerType =
- ContainerTypeEntry::containerTypeFromString(typeName);
- if (typeName.isEmpty()) {
- m_error = QLatin1String("no 'type' attribute specified");
+ case StackElement::PrimitiveTypeEntry:
+ element->entry = parsePrimitiveTypeEntry(reader, name, since, &attributes);
+ if (Q_UNLIKELY(!element->entry))
return false;
- } else if (containerType == ContainerTypeEntry::NoContainer) {
- m_error = QLatin1String("there is no container of type ") + typeName;
+ break;
+ case StackElement::ContainerTypeEntry:
+ if (ContainerTypeEntry *ce = parseContainerTypeEntry(reader, name, since, &attributes)) {
+ applyComplexTypeAttributes(reader, ce, &attributes);
+ element->entry = ce;
+ } else {
return false;
}
+ break;
- ContainerTypeEntry *type = new ContainerTypeEntry(name, containerType, since);
- type->setCodeGeneration(m_generate);
- element->entry = type;
- }
- break;
-
- case StackElement::SmartPointerTypeEntry: {
- bool result = handleSmartPointerEntry(element, attributes, name, since);
- if (!result)
- return result;
- }
- break;
-
- case StackElement::EnumTypeEntry: {
- QStringList names = name.split(colonColon());
- if (names.size() == 1)
- m_currentEnum = new EnumTypeEntry(QString(), name, since);
- else
- m_currentEnum =
- new EnumTypeEntry(QStringList(names.mid(0, names.size() - 1)).join(colonColon()),
- names.constLast(), since);
- element->entry = m_currentEnum;
- m_currentEnum->setCodeGeneration(m_generate);
- m_currentEnum->setTargetLangPackage(m_defaultPackage);
- m_currentEnum->setUpperBound(attributes[QLatin1String("upper-bound")]);
- m_currentEnum->setLowerBound(attributes[QLatin1String("lower-bound")]);
- m_currentEnum->setForceInteger(convertBoolean(attributes[QLatin1String("force-integer")], QLatin1String("force-integer"), false));
- m_currentEnum->setExtensible(convertBoolean(attributes[QLatin1String("extensible")], QLatin1String("extensible"), false));
-
- // put in the flags parallel...
- const QString flagNames = attributes.value(flagsAttribute());
- if (!flagNames.isEmpty()) {
- const QStringList &flagNameList = flagNames.split(QLatin1Char(','));
- for (const QString &flagName : flagNameList)
- addFlags(name, flagName.trimmed(), attributes, since);
+ case StackElement::SmartPointerTypeEntry:
+ if (SmartPointerTypeEntry *se = parseSmartPointerEntry(reader, name, since, &attributes)) {
+ applyComplexTypeAttributes(reader, se, &attributes);
+ element->entry = se;
+ } else {
+ return false;
}
- }
- break;
+ break;
+ case StackElement::EnumTypeEntry:
+ m_currentEnum = parseEnumTypeEntry(reader, name, since, &attributes);
+ if (Q_UNLIKELY(!m_currentEnum))
+ return false;
+ element->entry = m_currentEnum;
+ break;
- case StackElement::InterfaceTypeEntry: {
- ObjectTypeEntry *otype = new ObjectTypeEntry(name, since);
- QString targetLangName = attributes[QLatin1String("target-lang-name")];
- if (targetLangName.isEmpty())
- targetLangName = name;
- InterfaceTypeEntry *itype =
- new InterfaceTypeEntry(InterfaceTypeEntry::interfaceName(targetLangName), since);
-
- if (!convertBoolean(attributes[QLatin1String("generate")], QLatin1String("generate"), true))
- itype->setCodeGeneration(TypeEntry::GenerateForSubclass);
- else
- itype->setCodeGeneration(m_generate);
- otype->setDesignatedInterface(itype);
- itype->setOrigin(otype);
- element->entry = otype;
- }
- Q_FALLTHROUGH();
- case StackElement::ValueTypeEntry: {
- if (!element->entry) {
- ValueTypeEntry* typeEntry = new ValueTypeEntry(name, since);
- QString defaultConstructor = attributes[QLatin1String("default-constructor")];
- if (!defaultConstructor.isEmpty())
- typeEntry->setDefaultConstructor(defaultConstructor);
- element->entry = typeEntry;
+ case StackElement::InterfaceTypeEntry:
+ if (ObjectTypeEntry *oe = parseInterfaceTypeEntry(reader, name, since, &attributes)) {
+ applyComplexTypeAttributes(reader, oe, &attributes);
+ element->entry = oe;
+ } else {
+ return false;
}
-
- Q_FALLTHROUGH();
+ break;
+ case StackElement::ValueTypeEntry:
+ if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, since, &attributes)) {
+ applyComplexTypeAttributes(reader, ve, &attributes);
+ element->entry = ve;
+ } else {
+ return false;
+ }
+ break;
case StackElement::NamespaceTypeEntry:
- if (!element->entry)
- element->entry = new NamespaceTypeEntry(name, since);
-
- Q_FALLTHROUGH();
+ element->entry = new NamespaceTypeEntry(name, since);
+ applyCommonAttributes(element->entry, &attributes);
+ applyComplexTypeAttributes(reader, static_cast<ComplexTypeEntry *>(element->entry), &attributes);
+ break;
case StackElement::ObjectTypeEntry:
- if (!element->entry)
- element->entry = new ObjectTypeEntry(name, since);
-
- element->entry->setStream(attributes[QLatin1String("stream")] == yesAttributeValue());
-
- ComplexTypeEntry *ctype = static_cast<ComplexTypeEntry *>(element->entry);
- ctype->setTargetLangPackage(attributes[QLatin1String("package")]);
- ctype->setDefaultSuperclass(attributes[QLatin1String("default-superclass")]);
- ctype->setGenericClass(convertBoolean(attributes[QLatin1String("generic-class")], QLatin1String("generic-class"), false));
-
- if (!convertBoolean(attributes[QLatin1String("generate")], QLatin1String("generate"), true))
- element->entry->setCodeGeneration(TypeEntry::GenerateForSubclass);
- else
- element->entry->setCodeGeneration(m_generate);
-
- QString targetLangName = attributes[QLatin1String("target-lang-name")];
- if (!targetLangName.isEmpty())
- ctype->setTargetLangName(targetLangName);
-
- ctype->setIsPolymorphicBase(convertBoolean(attributes[QLatin1String("polymorphic-base")], QLatin1String("polymorphic-base"), false));
- ctype->setPolymorphicIdValue(attributes[QLatin1String("polymorphic-id-expression")]);
- //Copyable
- if (attributes[QLatin1String("copyable")].isEmpty())
- ctype->setCopyable(ComplexTypeEntry::Unknown);
- else {
- if (convertBoolean(attributes[QLatin1String("copyable")], QLatin1String("copyable"), false))
- ctype->setCopyable(ComplexTypeEntry::CopyableSet);
- else
- ctype->setCopyable(ComplexTypeEntry::NonCopyableSet);
-
- }
-
- if (element->type == StackElement::ObjectTypeEntry || element->type == StackElement::ValueTypeEntry)
- ctype->setHashFunction(attributes[QLatin1String("hash-function")]);
-
-
- ctype->setHeldType(attributes[QLatin1String("held-type")]);
-
- if (element->type == StackElement::ObjectTypeEntry
- || element->type == StackElement::ValueTypeEntry) {
- if (convertBoolean(attributes[QLatin1String("force-abstract")], QLatin1String("force-abstract"), false))
- ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ForceAbstract);
- if (convertBoolean(attributes[QLatin1String("deprecated")], QLatin1String("deprecated"), false))
- ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated);
- }
-
- if (element->type == StackElement::InterfaceTypeEntry
- || element->type == StackElement::ValueTypeEntry
- || element->type == StackElement::ObjectTypeEntry) {
- if (convertBoolean(attributes[QLatin1String("delete-in-main-thread")], QLatin1String("delete-in-main-thread"), false))
- ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::DeleteInMainThread);
- }
-
- QString targetType = attributes[QLatin1String("target-type")];
- if (!targetType.isEmpty() && element->entry->isComplex())
- static_cast<ComplexTypeEntry *>(element->entry)->setTargetType(targetType);
-
- // ctype->setInclude(Include(Include::IncludePath, ctype->name()));
- ctype = ctype->designatedInterface();
- if (ctype)
- ctype->setTargetLangPackage(attributes[QLatin1String("package")]);
-
- }
- break;
- case StackElement::FunctionTypeEntry: {
- QString signature = attributes[QLatin1String("signature")];
- signature = TypeDatabase::normalizedSignature(signature);
- element->entry = m_database->findType(name);
- if (element->entry) {
- if (element->entry->type() == TypeEntry::FunctionType) {
- reinterpret_cast<FunctionTypeEntry*>(element->entry)->addSignature(signature);
- } else {
- m_error = QStringLiteral("%1 expected to be a function, but isn't! Maybe it was already declared as a class or something else.")
- .arg(name);
- return false;
- }
+ element->entry = new ObjectTypeEntry(name, since);
+ applyCommonAttributes(element->entry, &attributes);
+ applyComplexTypeAttributes(reader, static_cast<ComplexTypeEntry *>(element->entry), &attributes);
+ break;
+ case StackElement::FunctionTypeEntry:
+ element->entry = parseFunctionTypeEntry(reader, name, since, &attributes);
+ if (Q_UNLIKELY(!element->entry))
+ return false;
+ break;
+ case StackElement::TypedefTypeEntry:
+ if (TypedefEntry *te = parseTypedefEntry(reader, name, since, &attributes)) {
+ applyComplexTypeAttributes(reader, te, &attributes);
+ element->entry = te;
} else {
- element->entry = new FunctionTypeEntry(name, signature, since);
- element->entry->setCodeGeneration(m_generate);
+ return false;
}
- }
- break;
+ break;
default:
Q_ASSERT(false);
};
if (element->entry) {
- m_database->addType(element->entry);
- setTypeRevision(element->entry, attributes[QLatin1String("revision")].toInt());
+ if (!m_database->addType(element->entry, &m_error))
+ return false;
} else {
qCWarning(lcShiboken).noquote().nospace()
<< QStringLiteral("Type: %1 was rejected by typesystem").arg(name);
}
} else if (element->type == StackElement::InjectDocumentation) {
- // check the XML tag attributes
- QHash<QString, QString> attributes;
- attributes.insert(QLatin1String("mode"), QLatin1String("replace"));
- attributes.insert(QLatin1String("format"), QLatin1String("native"));
- attributes.insert(sinceAttribute(), QString()); // dummy for matching allowed attributes
-
- fetchAttributeValues(tagName, atts, &attributes);
-
- const int validParent = StackElement::TypeEntryMask
- | StackElement::ModifyFunction
- | StackElement::ModifyField;
- if (m_current->parent && m_current->parent->type & validParent) {
- QString modeName = attributes[QLatin1String("mode")];
- TypeSystem::DocModificationMode mode;
- if (modeName == QLatin1String("append")) {
- mode = TypeSystem::DocModificationAppend;
- } else if (modeName == QLatin1String("prepend")) {
- mode = TypeSystem::DocModificationPrepend;
- } else if (modeName == QLatin1String("replace")) {
- mode = TypeSystem::DocModificationReplace;
- } else {
- m_error = QLatin1String("Unknow documentation injection mode: ") + modeName;
- return false;
- }
-
- static QHash<QString, TypeSystem::Language> languageNames;
- if (languageNames.isEmpty()) {
- languageNames[QLatin1String("target")] = TypeSystem::TargetLangCode;
- languageNames[QLatin1String("native")] = TypeSystem::NativeCode;
- }
-
- QString format = attributes[QLatin1String("format")].toLower();
- TypeSystem::Language lang = languageNames.value(format, TypeSystem::NoLanguage);
- if (lang == TypeSystem::NoLanguage) {
- m_error = QStringLiteral("unsupported class attribute: '%1'").arg(format);
- return false;
- }
-
- QString signature = m_current->type & StackElement::TypeEntryMask ? QString() : m_currentSignature;
- DocModification mod(mode, signature);
- mod.setFormat(lang);
- m_contextStack.top()->docModifications << mod;
- } else {
- m_error = QLatin1String("inject-documentation must be inside modify-function, "
- "modify-field or other tags that creates a type");
+ if (!parseInjectDocumentation(reader, &attributes))
return false;
- }
} else if (element->type == StackElement::ModifyDocumentation) {
- // check the XML tag attributes
- QHash<QString, QString> attributes;
- attributes.insert(xPathAttribute(), QString());
- attributes.insert(sinceAttribute(), QString()); // dummy for matching allowed attributes
- fetchAttributeValues(tagName, atts, &attributes);
-
- const int validParent = StackElement::TypeEntryMask
- | StackElement::ModifyFunction
- | StackElement::ModifyField;
- if (m_current->parent && m_current->parent->type & validParent) {
- QString signature = (m_current->type & StackElement::TypeEntryMask) ? QString() : m_currentSignature;
- m_contextStack.top()->docModifications
- << DocModification(attributes.value(xPathAttribute()), signature);
- } else {
- m_error = QLatin1String("modify-documentation must be inside modify-function, "
- "modify-field or other tags that creates a type");
+ if (!parseModifyDocumentation(reader, &attributes))
return false;
- }
} else if (element->type != StackElement::None) {
bool topLevel = element->type == StackElement::Root
|| element->type == StackElement::SuppressedWarning
@@ -1194,494 +2666,86 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
StackElement topElement = !m_current ? StackElement(0) : *m_current;
element->entry = topElement.entry;
- QHash<QString, QString> attributes;
- attributes.insert(sinceAttribute(), QString()); // dummy for matching allowed attributes
switch (element->type) {
case StackElement::Root:
- attributes.insert(QLatin1String("package"), QString());
- attributes.insert(QLatin1String("default-superclass"), QString());
+ element->entry = parseRootElement(reader, since, &attributes);
+ element->type = StackElement::Root;
break;
case StackElement::LoadTypesystem:
- attributes.insert(nameAttribute(), QString());
- attributes.insert(QLatin1String("generate"), yesAttributeValue());
- break;
- case StackElement::NoNullPointers:
- attributes.insert(QLatin1String("default-value"), QString());
- break;
- case StackElement::SuppressedWarning:
- attributes.insert(textAttribute(), QString());
- break;
- case StackElement::ReplaceDefaultExpression:
- attributes.insert(QLatin1String("with"), QString());
- break;
- case StackElement::DefineOwnership:
- attributes.insert(QLatin1String("class"), QLatin1String("target"));
- attributes.insert(QLatin1String("owner"), QString());
- break;
- case StackElement::AddFunction:
- attributes.insert(QLatin1String("signature"), QString());
- attributes.insert(QLatin1String("return-type"), QLatin1String("void"));
- attributes.insert(QLatin1String("access"), QLatin1String("public"));
- attributes.insert(QLatin1String("static"), noAttributeValue());
- break;
- case StackElement::ModifyFunction:
- attributes.insert(QLatin1String("signature"), QString());
- attributes.insert(QLatin1String("access"), QString());
- attributes.insert(QLatin1String("remove"), QString());
- attributes.insert(QLatin1String("rename"), QString());
- attributes.insert(QLatin1String("deprecated"), noAttributeValue());
- attributes.insert(QLatin1String("associated-to"), QString());
- attributes.insert(QLatin1String("virtual-slot"), noAttributeValue());
- attributes.insert(QLatin1String("thread"), noAttributeValue());
- attributes.insert(QLatin1String("allow-thread"), noAttributeValue());
- break;
- case StackElement::ModifyArgument:
- attributes.insert(QLatin1String("index"), QString());
- attributes.insert(QLatin1String("replace-value"), QString());
- attributes.insert(QLatin1String("invalidate-after-use"), noAttributeValue());
- break;
- case StackElement::ModifyField:
- attributes.insert(nameAttribute(), QString());
- attributes.insert(QLatin1String("write"), trueAttributeValue());
- attributes.insert(QLatin1String("read"), trueAttributeValue());
- attributes.insert(QLatin1String("remove"), QString());
- break;
- case StackElement::Access:
- attributes.insert(QLatin1String("modifier"), QString());
- break;
- case StackElement::Include:
- attributes.insert(QLatin1String("file-name"), QString());
- attributes.insert(QLatin1String("location"), QString());
- break;
- case StackElement::CustomMetaConstructor:
- attributes[nameAttribute()] = topElement.entry->name().toLower() + QLatin1String("_create");
- attributes.insert(QLatin1String("param-name"), QLatin1String("copy"));
+ if (!loadTypesystem(reader, &attributes))
+ return false;
break;
- case StackElement::CustomMetaDestructor:
- attributes[nameAttribute()] = topElement.entry->name().toLower() + QLatin1String("_delete");
- attributes.insert(QLatin1String("param-name"), QLatin1String("copy"));
+ case StackElement::RejectEnumValue:
+ if (!parseRejectEnumValue(reader, &attributes))
+ return false;
break;
case StackElement::ReplaceType:
- attributes.insert(QLatin1String("modified-type"), QString());
- break;
- case StackElement::InjectCode:
- attributes.insert(QLatin1String("class"), QLatin1String("target"));
- attributes.insert(QLatin1String("position"), QLatin1String("beginning"));
- attributes.insert(QLatin1String("file"), QString());
+ if (!parseReplaceArgumentType(reader, topElement, &attributes))
+ return false;
break;
case StackElement::ConversionRule:
- attributes.insert(QLatin1String("class"), QString());
- attributes.insert(QLatin1String("file"), QString());
- break;
- case StackElement::TargetToNative:
- attributes.insert(QLatin1String("replace"), yesAttributeValue());
- break;
- case StackElement::AddConversion:
- attributes.insert(QLatin1String("type"), QString());
- attributes.insert(QLatin1String("check"), QString());
- break;
- case StackElement::RejectEnumValue:
- attributes.insert(nameAttribute(), QString());
- break;
- case StackElement::ArgumentMap:
- attributes.insert(QLatin1String("index"), QLatin1String("1"));
- attributes.insert(QLatin1String("meta-name"), QString());
- break;
- case StackElement::Rename:
- attributes.insert(QLatin1String("to"), QString());
- break;
- case StackElement::Rejection:
- attributes.insert(classAttribute(), QString());
- attributes.insert(functionNameAttribute(), QString());
- attributes.insert(fieldNameAttribute(), QString());
- attributes.insert(enumNameAttribute(), QString());
- attributes.insert(argumentTypeAttribute(), QString());
- attributes.insert(returnTypeAttribute(), QString());
- break;
- case StackElement::Removal:
- attributes.insert(QLatin1String("class"), QLatin1String("all"));
- break;
- case StackElement::Template:
- attributes.insert(nameAttribute(), QString());
- break;
- case StackElement::TemplateInstanceEnum:
- attributes.insert(nameAttribute(), QString());
- break;
- case StackElement::Replace:
- attributes.insert(QLatin1String("from"), QString());
- attributes.insert(QLatin1String("to"), QString());
- break;
- case StackElement::ReferenceCount:
- attributes.insert(QLatin1String("action"), QString());
- attributes.insert(QLatin1String("variable-name"), QString());
- break;
- case StackElement::ParentOwner:
- attributes.insert(QLatin1String("index"), QString());
- attributes.insert(QLatin1String("action"), QString());
- break;
- case StackElement::Array:
- break;
- default:
- { };
- };
-
- if (!attributes.isEmpty())
- fetchAttributeValues(tagName, atts, &attributes);
-
- switch (element->type) {
- case StackElement::Root:
- m_defaultPackage = attributes[QLatin1String("package")];
- m_defaultSuperclass = attributes[QLatin1String("default-superclass")];
- element->type = StackElement::Root;
- {
- TypeSystemTypeEntry* moduleEntry = reinterpret_cast<TypeSystemTypeEntry*>(
- m_database->findType(m_defaultPackage));
- element->entry = moduleEntry ? moduleEntry : new TypeSystemTypeEntry(m_defaultPackage, since);
- element->entry->setCodeGeneration(m_generate);
- }
-
- if ((m_generate == TypeEntry::GenerateForSubclass ||
- m_generate == TypeEntry::GenerateNothing) && !m_defaultPackage.isEmpty())
- TypeDatabase::instance()->addRequiredTargetImport(m_defaultPackage);
-
- if (!element->entry->qualifiedCppName().isEmpty())
- m_database->addType(element->entry);
- break;
- case StackElement::LoadTypesystem: {
- QString name = attributes[nameAttribute()];
- if (name.isEmpty()) {
- m_error = QLatin1String("No typesystem name specified");
+ if (!Handler::parseCustomConversion(reader, topElement, &attributes))
return false;
- }
- bool generateChild = (convertBoolean(attributes[QLatin1String("generate")], QLatin1String("generate"), true) && (m_generate == TypeEntry::GenerateAll));
- if (!m_database->parseFile(name, m_currentPath, generateChild)) {
- m_error = QStringLiteral("Failed to parse: '%1'").arg(name);
- return false;
- }
- }
- break;
- case StackElement::RejectEnumValue:
- if (!m_currentEnum) {
- m_error = QLatin1String("<reject-enum-value> node must be used inside a <enum-type> node");
- return false;
- }
- break;
- case StackElement::ReplaceType: {
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("Type replacement can only be specified for argument modifications");
- return false;
- }
-
- if (attributes[QLatin1String("modified-type")].isEmpty()) {
- m_error = QLatin1String("Type replacement requires 'modified-type' attribute");
- return false;
- }
-
- m_contextStack.top()->functionMods.last().argument_mods.last().modified_type = attributes[QLatin1String("modified-type")];
- }
- break;
- case StackElement::ConversionRule: {
- if (topElement.type != StackElement::ModifyArgument
- && topElement.type != StackElement::ValueTypeEntry
- && topElement.type != StackElement::PrimitiveTypeEntry
- && topElement.type != StackElement::ContainerTypeEntry) {
- m_error = QLatin1String("Conversion rules can only be specified for argument modification, "
- "value-type, primitive-type or container-type conversion.");
- return false;
- }
-
- static QHash<QString, TypeSystem::Language> languageNames;
- if (languageNames.isEmpty()) {
- languageNames[QLatin1String("target")] = TypeSystem::TargetLangCode;
- languageNames[QLatin1String("native")] = TypeSystem::NativeCode;
- }
-
- QString languageAttribute = attributes[QLatin1String("class")].toLower();
- TypeSystem::Language lang = languageNames.value(languageAttribute, TypeSystem::NoLanguage);
-
- if (topElement.type == StackElement::ModifyArgument) {
- if (lang == TypeSystem::NoLanguage) {
- m_error = QStringLiteral("unsupported class attribute: '%1'").arg(lang);
- return false;
- }
-
- CodeSnip snip;
- snip.language = lang;
- m_contextStack.top()->functionMods.last().argument_mods.last().conversion_rules.append(snip);
- } else {
- if (topElement.entry->hasConversionRule() || topElement.entry->hasCustomConversion()) {
- m_error = QLatin1String("Types can have only one conversion rule");
- return false;
- }
-
- // The old conversion rule tag that uses a file containing the conversion
- // will be kept temporarily for compatibility reasons.
- QString sourceFile = attributes[QLatin1String("file")];
- if (!sourceFile.isEmpty()) {
- if (m_generate != TypeEntry::GenerateForSubclass
- && m_generate != TypeEntry::GenerateNothing) {
-
- const char* conversionFlag = NATIVE_CONVERSION_RULE_FLAG;
- if (lang == TypeSystem::TargetLangCode)
- conversionFlag = TARGET_CONVERSION_RULE_FLAG;
-
- QFile conversionSource(sourceFile);
- if (conversionSource.open(QIODevice::ReadOnly | QIODevice::Text)) {
- topElement.entry->setConversionRule(QLatin1String(conversionFlag) + QString::fromUtf8(conversionSource.readAll()));
- } else {
- qCWarning(lcShiboken).noquote().nospace()
- << "File containing conversion code for "
- << topElement.entry->name() << " type does not exist or is not readable: "
- << sourceFile;
- }
- }
- }
-
- CustomConversion* customConversion = new CustomConversion(static_cast<TypeEntry*>(m_current->entry));
- customConversionsForReview.append(customConversion);
- }
- }
- break;
- case StackElement::NativeToTarget: {
- if (topElement.type != StackElement::ConversionRule) {
- m_error = QLatin1String("Native to Target conversion code can only be specified for custom conversion rules.");
+ break;
+ case StackElement::NativeToTarget:
+ if (!parseNativeToTarget(reader, topElement, &attributes))
return false;
- }
- m_contextStack.top()->codeSnips << CodeSnip();
- }
- break;
+ break;
case StackElement::TargetToNative: {
if (topElement.type != StackElement::ConversionRule) {
m_error = QLatin1String("Target to Native conversions can only be specified for custom conversion rules.");
return false;
}
- bool replace = attributes[QLatin1String("replace")] == yesAttributeValue();
- static_cast<TypeEntry*>(m_current->entry)->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
- }
- break;
- case StackElement::AddConversion: {
- if (topElement.type != StackElement::TargetToNative) {
- m_error = QLatin1String("Target to Native conversions can only be added inside 'target-to-native' tags.");
- return false;
- }
- QString sourceTypeName = attributes[QLatin1String("type")];
- if (sourceTypeName.isEmpty()) {
- m_error = QLatin1String("Target to Native conversions must specify the input type with the 'type' attribute.");
- return false;
- }
- QString typeCheck = attributes[QLatin1String("check")];
- static_cast<TypeEntry*>(m_current->entry)->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
- m_contextStack.top()->codeSnips << CodeSnip();
- }
- break;
- case StackElement::ModifyArgument: {
- if (topElement.type != StackElement::ModifyFunction
- && topElement.type != StackElement::AddFunction) {
- m_error = QString::fromLatin1("argument modification requires function"
- " modification as parent, was %1")
- .arg(topElement.type, 0, 16);
- return false;
- }
-
- QString index = attributes[QLatin1String("index")];
- if (index == QLatin1String("return"))
- index = QLatin1String("0");
- else if (index == QLatin1String("this"))
- index = QLatin1String("-1");
-
- bool ok = false;
- int idx = index.toInt(&ok);
- if (!ok) {
- m_error = QStringLiteral("Cannot convert '%1' to integer").arg(index);
- return false;
- }
-
- QString replace_value = attributes[QLatin1String("replace-value")];
-
- if (!replace_value.isEmpty() && idx) {
- m_error = QLatin1String("replace-value is only supported for return values (index=0).");
- return false;
- }
-
- ArgumentModification argumentModification = ArgumentModification(idx);
- argumentModification.replace_value = replace_value;
- argumentModification.resetAfterUse = convertBoolean(attributes[QLatin1String("invalidate-after-use")], QLatin1String("invalidate-after-use"), false);
- m_contextStack.top()->functionMods.last().argument_mods.append(argumentModification);
+ const int replaceIndex = indexOfAttribute(attributes, replaceAttribute());
+ const bool replace = replaceIndex == -1
+ || convertBoolean(attributes.takeAt(replaceIndex).value(),
+ replaceAttribute(), true);
+ m_current->entry->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
}
break;
- case StackElement::NoNullPointers: {
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("no-null-pointer requires argument modification as parent");
+ case StackElement::AddConversion:
+ if (!parseAddConversion(reader, topElement, &attributes))
return false;
- }
-
- m_contextStack.top()->functionMods.last().argument_mods.last().noNullPointers = true;
- if (!m_contextStack.top()->functionMods.last().argument_mods.last().index)
- m_contextStack.top()->functionMods.last().argument_mods.last().nullPointerDefaultValue = attributes[QLatin1String("default-value")];
- else if (!attributes[QLatin1String("default-value")].isEmpty())
- qCWarning(lcShiboken) << "default values for null pointer guards are only effective for return values";
-
- }
- break;
- case StackElement::DefineOwnership: {
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("define-ownership requires argument modification as parent");
+ break;
+ case StackElement::ModifyArgument:
+ if (!parseModifyArgument(reader, topElement, &attributes))
return false;
- }
-
- static QHash<QString, TypeSystem::Language> languageNames;
- if (languageNames.isEmpty()) {
- languageNames[QLatin1String("target")] = TypeSystem::TargetLangCode;
- languageNames[QLatin1String("native")] = TypeSystem::NativeCode;
- }
-
- QString classAttribute = attributes[QLatin1String("class")].toLower();
- TypeSystem::Language lang = languageNames.value(classAttribute, TypeSystem::NoLanguage);
- if (lang == TypeSystem::NoLanguage) {
- m_error = QStringLiteral("unsupported class attribute: '%1'").arg(classAttribute);
+ break;
+ case StackElement::NoNullPointers:
+ if (!parseNoNullPointer(reader, topElement, &attributes))
return false;
- }
-
- static QHash<QString, TypeSystem::Ownership> ownershipNames;
- if (ownershipNames.isEmpty()) {
- ownershipNames[QLatin1String("target")] = TypeSystem::TargetLangOwnership;
- ownershipNames[QLatin1String("c++")] = TypeSystem::CppOwnership;
- ownershipNames[QLatin1String("default")] = TypeSystem::DefaultOwnership;
- }
-
- QString ownershipAttribute = attributes[QLatin1String("owner")].toLower();
- TypeSystem::Ownership owner = ownershipNames.value(ownershipAttribute, TypeSystem::InvalidOwnership);
- if (owner == TypeSystem::InvalidOwnership) {
- m_error = QStringLiteral("unsupported owner attribute: '%1'").arg(ownershipAttribute);
+ break;
+ case StackElement::DefineOwnership:
+ if (!parseDefineOwnership(reader, topElement, &attributes))
return false;
- }
-
- m_contextStack.top()->functionMods.last().argument_mods.last().ownerships[lang] = owner;
- }
- break;
+ break;
case StackElement::SuppressedWarning: {
- const QString suppressedWarning = attributes.value(textAttribute());
- if (suppressedWarning.isEmpty()) {
+ const int textIndex = indexOfAttribute(attributes, textAttribute());
+ if (textIndex == -1) {
qCWarning(lcShiboken) << "Suppressed warning with no text specified";
} else {
+ const QString suppressedWarning =
+ attributes.takeAt(textIndex).value().toString();
if (!m_database->addSuppressedWarning(suppressedWarning, &m_error))
return false;
}
}
break;
- case StackElement::ArgumentMap: {
- if (!(topElement.type & StackElement::CodeSnipMask)) {
- m_error = QLatin1String("Argument maps requires code injection as parent");
- return false;
- }
-
- bool ok;
- int pos = attributes[QLatin1String("index")].toInt(&ok);
- if (!ok) {
- m_error = QStringLiteral("Can't convert position '%1' to integer")
- .arg(attributes[QLatin1String("position")]);
- return false;
- }
-
- if (pos <= 0) {
- m_error = QStringLiteral("Argument position %1 must be a positive number").arg(pos);
- return false;
- }
-
- QString meta_name = attributes[QLatin1String("meta-name")];
- if (meta_name.isEmpty())
- qCWarning(lcShiboken) << "Empty meta name in argument map";
-
-
- if (topElement.type == StackElement::InjectCodeInFunction)
- m_contextStack.top()->functionMods.last().snips.last().argumentMap[pos] = meta_name;
- else {
- qCWarning(lcShiboken) << "Argument maps are only useful for injection of code "
- "into functions.";
- }
- }
- break;
- case StackElement::Removal: {
- if (topElement.type != StackElement::ModifyFunction) {
- m_error = QLatin1String("Function modification parent required");
+ case StackElement::ArgumentMap:
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgUnimplementedElementWarning(reader, tagName)));
+ if (!parseArgumentMap(reader, topElement, &attributes))
return false;
- }
-
- static QHash<QString, TypeSystem::Language> languageNames;
- if (languageNames.isEmpty()) {
- languageNames.insert(QLatin1String("target"), TypeSystem::TargetLangAndNativeCode);
- languageNames.insert(QLatin1String("all"), TypeSystem::All);
- }
-
- QString languageAttribute = attributes[QLatin1String("class")].toLower();
- TypeSystem::Language lang = languageNames.value(languageAttribute, TypeSystem::NoLanguage);
- if (lang == TypeSystem::NoLanguage) {
- m_error = QStringLiteral("unsupported class attribute: '%1'").arg(languageAttribute);
+ break;
+ case StackElement::Removal:
+ if (!parseRemoval(reader, topElement, &attributes))
return false;
- }
-
- m_contextStack.top()->functionMods.last().removal = lang;
- }
- break;
+ break;
case StackElement::Rename:
- case StackElement::Access: {
- if (topElement.type != StackElement::ModifyField
- && topElement.type != StackElement::ModifyFunction
- && topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("Function, field or argument modification parent required");
- return false;
- }
-
- Modification *mod = 0;
- if (topElement.type == StackElement::ModifyFunction)
- mod = &m_contextStack.top()->functionMods.last();
- else if (topElement.type == StackElement::ModifyField)
- mod = &m_contextStack.top()->fieldMods.last();
-
- QString modifier;
- if (element->type == StackElement::Rename) {
- modifier = QLatin1String("rename");
- QString renamed_to = attributes[QLatin1String("to")];
- if (renamed_to.isEmpty()) {
- m_error = QLatin1String("Rename modifier requires 'to' attribute");
- return false;
- }
-
- if (topElement.type == StackElement::ModifyFunction)
- mod->setRenamedTo(renamed_to);
- else if (topElement.type == StackElement::ModifyField)
- mod->setRenamedTo(renamed_to);
- else
- m_contextStack.top()->functionMods.last().argument_mods.last().renamed_to = renamed_to;
- } else
- modifier = attributes[QLatin1String("modifier")].toLower();
-
-
- if (modifier.isEmpty()) {
- m_error = QLatin1String("No access modification specified");
- return false;
- }
-
- static QHash<QString, FunctionModification::Modifiers> modifierNames;
- if (modifierNames.isEmpty()) {
- modifierNames[QLatin1String("private")] = Modification::Private;
- modifierNames[QLatin1String("public")] = Modification::Public;
- modifierNames[QLatin1String("protected")] = Modification::Protected;
- modifierNames[QLatin1String("friendly")] = Modification::Friendly;
- modifierNames[QLatin1String("rename")] = Modification::Rename;
- modifierNames[QLatin1String("final")] = Modification::Final;
- modifierNames[QLatin1String("non-final")] = Modification::NonFinal;
- }
-
- if (!modifierNames.contains(modifier)) {
- m_error = QStringLiteral("Unknown access modifier: '%1'").arg(modifier);
+ case StackElement::Access:
+ if (!parseRename(reader, element->type, topElement, &attributes))
return false;
- }
-
- if (mod)
- mod->modifiers |= modifierNames[modifier];
- }
- break;
+ break;
case StackElement::RemoveArgument:
if (topElement.type != StackElement::ModifyArgument) {
m_error = QLatin1String("Removing argument requires argument modification as parent");
@@ -1691,229 +2755,38 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
m_contextStack.top()->functionMods.last().argument_mods.last().removed = true;
break;
- case StackElement::ModifyField: {
- QString name = attributes[nameAttribute()];
- if (name.isEmpty())
- break;
- FieldModification fm;
- fm.name = name;
- fm.modifiers = 0;
-
- if (!convertRemovalAttribute(attributes[QLatin1String("remove")], fm, m_error))
- return false;
-
- QString read = attributes[QLatin1String("read")];
- QString write = attributes[QLatin1String("write")];
-
- if (read == trueAttributeValue()) fm.modifiers |= FieldModification::Readable;
- if (write == trueAttributeValue()) fm.modifiers |= FieldModification::Writable;
-
- m_contextStack.top()->fieldMods << fm;
- }
- break;
- case StackElement::AddFunction: {
- if (!(topElement.type & (StackElement::ComplexTypeEntryMask | StackElement::Root))) {
- m_error = QString::fromLatin1("Add function requires a complex type or a root tag as parent"
- ", was=%1").arg(topElement.type, 0, 16);
- return false;
- }
- const QString originalSignature = attributes[QLatin1String("signature")];
-
- QString signature = TypeDatabase::normalizedSignature(originalSignature);
- if (signature.isEmpty()) {
- m_error = QLatin1String("No signature for the added function");
- return false;
- }
-
- QString errorString = checkSignatureError(signature, QLatin1String("add-function"));
- if (!errorString.isEmpty()) {
- m_error = errorString;
- return false;
- }
-
- AddedFunction func(signature, attributes[QLatin1String("return-type")]);
- func.setStatic(attributes[QLatin1String("static")] == yesAttributeValue());
- if (!signature.contains(QLatin1Char('(')))
- signature += QLatin1String("()");
- m_currentSignature = signature;
-
- QString access = attributes[QLatin1String("access")].toLower();
- if (!access.isEmpty()) {
- if (access == QLatin1String("protected")) {
- func.setAccess(AddedFunction::Protected);
- } else if (access == QLatin1String("public")) {
- func.setAccess(AddedFunction::Public);
- } else {
- m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
- return false;
- }
- }
-
- m_contextStack.top()->addedFunctions << func;
-
- FunctionModification mod;
- if (!mod.setSignature(m_currentSignature, &m_error))
- return false;
- mod.setOriginalSignature(originalSignature);
- m_contextStack.top()->functionMods << mod;
- }
- break;
- case StackElement::ModifyFunction: {
- if (!(topElement.type & StackElement::ComplexTypeEntryMask)) {
- m_error = QString::fromLatin1("Modify function requires complex type as parent"
- ", was=%1").arg(topElement.type, 0, 16);
- return false;
- }
- const QString originalSignature = attributes[QLatin1String("signature")];
-
- const QString signature = TypeDatabase::normalizedSignature(originalSignature);
- if (signature.isEmpty()) {
- m_error = QLatin1String("No signature for modified function");
- return false;
- }
-
- QString errorString = checkSignatureError(signature, QLatin1String("modify-function"));
- if (!errorString.isEmpty()) {
- m_error = errorString;
+ case StackElement::ModifyField:
+ if (!parseModifyField(reader, &attributes))
return false;
- }
-
- FunctionModification mod;
- if (!mod.setSignature(signature, &m_error))
+ break;
+ case StackElement::AddFunction:
+ if (!parseAddFunction(reader, topElement, &attributes))
return false;
- mod.setOriginalSignature(originalSignature);
- m_currentSignature = signature;
-
- QString access = attributes[QLatin1String("access")].toLower();
- if (!access.isEmpty()) {
- if (access == QLatin1String("private"))
- mod.modifiers |= Modification::Private;
- else if (access == QLatin1String("protected"))
- mod.modifiers |= Modification::Protected;
- else if (access == QLatin1String("public"))
- mod.modifiers |= Modification::Public;
- else if (access == QLatin1String("final"))
- mod.modifiers |= Modification::Final;
- else if (access == QLatin1String("non-final"))
- mod.modifiers |= Modification::NonFinal;
- else {
- m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
- return false;
- }
- }
-
- if (convertBoolean(attributes[QLatin1String("deprecated")], QLatin1String("deprecated"), false))
- mod.modifiers |= Modification::Deprecated;
-
- if (!convertRemovalAttribute(attributes[QLatin1String("remove")], mod, m_error))
+ break;
+ case StackElement::ModifyFunction:
+ if (!parseModifyFunction(reader, topElement, &attributes))
return false;
-
- QString rename = attributes[QLatin1String("rename")];
- if (!rename.isEmpty()) {
- mod.renamedToName = rename;
- mod.modifiers |= Modification::Rename;
- }
-
- QString association = attributes[QLatin1String("associated-to")];
- if (!association.isEmpty())
- mod.association = association;
-
- mod.setIsThread(convertBoolean(attributes[QLatin1String("thread")], QLatin1String("thread"), false));
- mod.setAllowThread(convertBoolean(attributes[QLatin1String("allow-thread")], QLatin1String("allow-thread"), false));
-
- mod.modifiers |= (convertBoolean(attributes[QLatin1String("virtual-slot")], QLatin1String("virtual-slot"), false) ? Modification::VirtualSlot : 0);
-
- m_contextStack.top()->functionMods << mod;
- }
- break;
+ break;
case StackElement::ReplaceDefaultExpression:
- if (!(topElement.type & StackElement::ModifyArgument)) {
- m_error = QLatin1String("Replace default expression only allowed as child of argument modification");
- return false;
- }
-
- if (attributes[QLatin1String("with")].isEmpty()) {
- m_error = QLatin1String("Default expression replaced with empty string. Use remove-default-expression instead.");
+ if (!parseReplaceDefaultExpression(reader, topElement, &attributes))
return false;
- }
-
- m_contextStack.top()->functionMods.last().argument_mods.last().replacedDefaultExpression = attributes[QLatin1String("with")];
break;
case StackElement::RemoveDefaultExpression:
m_contextStack.top()->functionMods.last().argument_mods.last().removedDefaultExpression = true;
break;
case StackElement::CustomMetaConstructor:
- case StackElement::CustomMetaDestructor: {
- CustomFunction *func = new CustomFunction(attributes[nameAttribute()]);
- func->paramName = attributes[QLatin1String("param-name")];
- element->value.customFunction = func;
- }
- break;
- case StackElement::ReferenceCount: {
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("reference-count must be child of modify-argument");
- return false;
- }
-
- ReferenceCount rc;
-
- static QHash<QString, ReferenceCount::Action> actions;
- if (actions.isEmpty()) {
- actions[QLatin1String("add")] = ReferenceCount::Add;
- actions[QLatin1String("add-all")] = ReferenceCount::AddAll;
- actions[QLatin1String("remove")] = ReferenceCount::Remove;
- actions[QLatin1String("set")] = ReferenceCount::Set;
- actions[QLatin1String("ignore")] = ReferenceCount::Ignore;
- }
- rc.action = actions.value(attributes[QLatin1String("action")].toLower(), ReferenceCount::Invalid);
- rc.varName = attributes[QLatin1String("variable-name")];
-
- if (rc.action == ReferenceCount::Invalid) {
- m_error = QLatin1String("unrecognized value for action attribute. supported actions:");
- for (QHash<QString, ReferenceCount::Action>::const_iterator it = actions.cbegin(), end = actions.cend(); it != end; ++it)
- m_error += QLatin1Char(' ') + it.key();
- }
-
- m_contextStack.top()->functionMods.last().argument_mods.last().referenceCounts.append(rc);
- }
- break;
-
- case StackElement::ParentOwner: {
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("parent-policy must be child of modify-argument");
- return false;
- }
-
- ArgumentOwner ao;
-
- QString index = attributes[QLatin1String("index")];
- if (index == QLatin1String("return"))
- index = QLatin1String("0");
- else if (index == QLatin1String("this"))
- index = QLatin1String("-1");
-
- bool ok = false;
- int idx = index.toInt(&ok);
- if (!ok) {
- m_error = QStringLiteral("Cannot convert '%1' to integer").arg(index);
+ case StackElement::CustomMetaDestructor:
+ element->value.customFunction =
+ parseCustomMetaConstructor(reader, element->type, topElement, &attributes);
+ break;
+ case StackElement::ReferenceCount:
+ if (!parseReferenceCount(reader, topElement, &attributes))
return false;
- }
-
- static QHash<QString, ArgumentOwner::Action> actions;
- if (actions.isEmpty()) {
- actions[QLatin1String("add")] = ArgumentOwner::Add;
- actions[QLatin1String("remove")] = ArgumentOwner::Remove;
- }
-
- ao.action = actions.value(attributes[QLatin1String("action")].toLower(), ArgumentOwner::Invalid);
- if (!ao.action) {
- m_error = QLatin1String("Invalid parent actionr");
+ break;
+ case StackElement::ParentOwner:
+ if (!parseParentOwner(reader, topElement, &attributes))
return false;
- }
- ao.index = idx;
- m_contextStack.top()->functionMods.last().argument_mods.last().owner = ao;
- }
- break;
+ break;
case StackElement::Array:
if (topElement.type != StackElement::ModifyArgument) {
m_error = QLatin1String("array must be child of modify-argument");
@@ -1921,185 +2794,54 @@ bool Handler::startElement(const QStringRef &n, const QXmlStreamAttributes &atts
}
m_contextStack.top()->functionMods.last().argument_mods.last().array = true;
break;
- case StackElement::InjectCode: {
- if (!(topElement.type & StackElement::ComplexTypeEntryMask)
- && (topElement.type != StackElement::AddFunction)
- && (topElement.type != StackElement::ModifyFunction)
- && (topElement.type != StackElement::Root)) {
- m_error = QLatin1String("wrong parent type for code injection");
- return false;
- }
-
- static QHash<QString, TypeSystem::Language> languageNames;
- if (languageNames.isEmpty()) {
- languageNames[QLatin1String("target")] = TypeSystem::TargetLangCode; // em algum lugar do cpp
- languageNames[QLatin1String("native")] = TypeSystem::NativeCode; // em algum lugar do cpp
- languageNames[QLatin1String("shell")] = TypeSystem::ShellCode; // coloca no header, mas antes da declaracao da classe
- languageNames[QLatin1String("shell-declaration")] = TypeSystem::ShellDeclaration; // coloca no header, dentro da declaracao da classe
- languageNames[QLatin1String("library-initializer")] = TypeSystem::PackageInitializer;
- languageNames[QLatin1String("destructor-function")] = TypeSystem::DestructorFunction;
- languageNames[QLatin1String("constructors")] = TypeSystem::Constructors;
- languageNames[QLatin1String("interface")] = TypeSystem::Interface;
- }
-
- QString className = attributes[QLatin1String("class")].toLower();
- if (!languageNames.contains(className)) {
- m_error = QStringLiteral("Invalid class specifier: '%1'").arg(className);
- return false;
- }
-
-
- static QHash<QString, TypeSystem::CodeSnipPosition> positionNames;
- if (positionNames.isEmpty()) {
- positionNames.insert(QLatin1String("beginning"), TypeSystem::CodeSnipPositionBeginning);
- positionNames.insert(QLatin1String("end"), TypeSystem::CodeSnipPositionEnd);
- // QtScript
- positionNames.insert(QLatin1String("declaration"), TypeSystem::CodeSnipPositionDeclaration);
- positionNames.insert(QLatin1String("prototype-initialization"), TypeSystem::CodeSnipPositionPrototypeInitialization);
- positionNames.insert(QLatin1String("constructor-initialization"), TypeSystem::CodeSnipPositionConstructorInitialization);
- positionNames.insert(QLatin1String("constructor"), TypeSystem::CodeSnipPositionConstructor);
- }
-
- QString position = attributes[QLatin1String("position")].toLower();
- if (!positionNames.contains(position)) {
- m_error = QStringLiteral("Invalid position: '%1'").arg(position);
+ case StackElement::InjectCode:
+ if (!parseInjectCode(reader, topElement, element, &attributes))
return false;
- }
-
- CodeSnip snip;
- snip.language = languageNames[className];
- snip.position = positionNames[position];
- bool in_file = false;
-
- QString file_name = attributes[QLatin1String("file")];
-
- //Handler constructor....
- if (m_generate != TypeEntry::GenerateForSubclass &&
- m_generate != TypeEntry::GenerateNothing &&
- !file_name.isEmpty()) {
- const QString resolved = m_database->modifiedTypesystemFilepath(file_name, m_currentPath);
- if (QFile::exists(resolved)) {
- QFile codeFile(resolved);
- if (codeFile.open(QIODevice::Text | QIODevice::ReadOnly)) {
- QString content = QLatin1String("// ========================================================================\n"
- "// START of custom code block [file: ");
- content += file_name;
- content += QLatin1String("]\n");
- content += QString::fromUtf8(codeFile.readAll());
- content += QLatin1String("\n// END of custom code block [file: ");
- content += file_name;
- content += QLatin1String("]\n// ========================================================================\n");
- snip.addCode(content);
- in_file = true;
- }
- } else {
- qCWarning(lcShiboken).noquote().nospace()
- << "File for inject code not exist: " << QDir::toNativeSeparators(file_name);
- }
-
- }
-
- if (snip.language == TypeSystem::Interface && topElement.type != StackElement::InterfaceTypeEntry) {
- m_error = QLatin1String("Interface code injections must be direct child of an interface type entry");
+ break;
+ case StackElement::Include:
+ if (!parseInclude(reader, topElement, element->entry, &attributes))
return false;
- }
-
- if (topElement.type == StackElement::ModifyFunction || topElement.type == StackElement::AddFunction) {
- FunctionModification mod = m_contextStack.top()->functionMods.constLast();
- if (snip.language == TypeSystem::ShellDeclaration) {
- m_error = QLatin1String("no function implementation in shell declaration in which to inject code");
- return false;
- }
-
- m_contextStack.top()->functionMods.last().snips << snip;
- if (in_file)
- m_contextStack.top()->functionMods.last().modifiers |= FunctionModification::CodeInjection;
- element->type = StackElement::InjectCodeInFunction;
- } else if (topElement.type == StackElement::Root) {
- element->entry->addCodeSnip(snip);
- } else if (topElement.type != StackElement::Root) {
- m_contextStack.top()->codeSnips << snip;
- }
-
- }
- break;
- case StackElement::Include: {
- QString location = attributes[QLatin1String("location")].toLower();
-
- static QHash<QString, Include::IncludeType> locationNames;
- if (locationNames.isEmpty()) {
- locationNames[QLatin1String("global")] = Include::IncludePath;
- locationNames[QLatin1String("local")] = Include::LocalPath;
- locationNames[QLatin1String("target")] = Include::TargetLangImport;
- }
-
- if (!locationNames.contains(location)) {
- m_error = QStringLiteral("Location not recognized: '%1'").arg(location);
+ break;
+ case StackElement::Rejection:
+ if (!addRejection(m_database, &attributes, &m_error))
return false;
- }
-
- Include::IncludeType loc = locationNames[location];
- Include inc(loc, attributes[QLatin1String("file-name")]);
-
- ComplexTypeEntry *ctype = static_cast<ComplexTypeEntry *>(element->entry);
- if (topElement.type & (StackElement::ComplexTypeEntryMask | StackElement::PrimitiveTypeEntry)) {
- element->entry->setInclude(inc);
- } else if (topElement.type == StackElement::ExtraIncludes) {
- element->entry->addExtraInclude(inc);
- } else {
- m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes");
+ break;
+ case StackElement::Template: {
+ const int nameIndex = indexOfAttribute(attributes, nameAttribute());
+ if (nameIndex == -1) {
+ m_error = msgMissingAttribute(nameAttribute());
return false;
}
-
- inc = ctype->include();
- IncludeList lst = ctype->extraIncludes();
- ctype = ctype->designatedInterface();
- if (ctype) {
- ctype->setExtraIncludes(lst);
- ctype->setInclude(inc);
- }
+ element->value.templateEntry =
+ new TemplateEntry(attributes.takeAt(nameIndex).value().toString());
}
- break;
- case StackElement::Rejection:
- if (!addRejection(m_database, attributes, &m_error))
- return false;
- break;
- case StackElement::Template:
- element->value.templateEntry = new TemplateEntry(attributes.value(nameAttribute()));
break;
case StackElement::TemplateInstanceEnum:
- if (!(topElement.type & StackElement::CodeSnipMask) &&
- (topElement.type != StackElement::Template) &&
- (topElement.type != StackElement::CustomMetaConstructor) &&
- (topElement.type != StackElement::CustomMetaDestructor) &&
- (topElement.type != StackElement::NativeToTarget) &&
- (topElement.type != StackElement::AddConversion) &&
- (topElement.type != StackElement::ConversionRule)) {
- m_error = QLatin1String("Can only insert templates into code snippets, templates, custom-constructors, "\
- "custom-destructors, conversion-rule, native-to-target or add-conversion tags.");
+ element->value.templateInstance =
+ parseTemplateInstanceEnum(reader, topElement, &attributes);
+ if (!element->value.templateInstance)
return false;
- }
- element->value.templateInstance = new TemplateInstance(attributes.value(nameAttribute()));
break;
case StackElement::Replace:
- if (topElement.type != StackElement::TemplateInstanceEnum) {
- m_error = QLatin1String("Can only insert replace rules into insert-template.");
+ if (!parseReplace(reader, topElement, element, &attributes))
return false;
- }
- element->parent->value.templateInstance->addReplaceRule(attributes[QLatin1String("from")], attributes[QLatin1String("to")]);
break;
default:
break; // nada
};
}
+ if (!attributes.isEmpty()) {
+ const QString message = msgUnusedAttributes(tagName, attributes);
+ qCWarning(lcShiboken, "%s", qPrintable(msgReaderWarning(reader, message)));
+ }
+
m_current = element;
return true;
}
PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &name, const QVersionNumber &vr) :
TypeEntry(name, PrimitiveType, vr),
- m_preferredConversion(true),
m_preferredTargetLangType(true)
{
}
@@ -2120,35 +2862,15 @@ PrimitiveTypeEntry *PrimitiveTypeEntry::basicReferencedTypeEntry() const
return 0;
PrimitiveTypeEntry *baseReferencedTypeEntry = m_referencedTypeEntry->basicReferencedTypeEntry();
- if (baseReferencedTypeEntry)
- return baseReferencedTypeEntry;
- else
- return m_referencedTypeEntry;
-}
-
-bool PrimitiveTypeEntry::preferredConversion() const
-{
- return m_preferredConversion;
+ return baseReferencedTypeEntry ? baseReferencedTypeEntry : m_referencedTypeEntry;
}
-void PrimitiveTypeEntry::setPreferredConversion(bool b)
+TypeEntry *PrimitiveTypeEntry::clone() const
{
- m_preferredConversion = b;
+ return new PrimitiveTypeEntry(*this);
}
-typedef QHash<const PrimitiveTypeEntry*, QString> PrimitiveTypeEntryTargetLangPackageMap;
-Q_GLOBAL_STATIC(PrimitiveTypeEntryTargetLangPackageMap, primitiveTypeEntryTargetLangPackages);
-
-void PrimitiveTypeEntry::setTargetLangPackage(const QString& package)
-{
- primitiveTypeEntryTargetLangPackages()->insert(this, package);
-}
-QString PrimitiveTypeEntry::targetLangPackage() const
-{
- if (!primitiveTypeEntryTargetLangPackages()->contains(this))
- return this->::TypeEntry::targetLangPackage();
- return primitiveTypeEntryTargetLangPackages()->value(this);
-}
+PrimitiveTypeEntry::PrimitiveTypeEntry(const PrimitiveTypeEntry &) = default;
CodeSnipList TypeEntry::codeSnips() const
{
@@ -2186,42 +2908,42 @@ FieldModification ComplexTypeEntry::fieldModification(const QString &name) const
return mod;
}
-QString ComplexTypeEntry::targetLangPackage() const
-{
- return m_package;
-}
-
QString ComplexTypeEntry::targetLangName() const
{
return m_targetLangName.isEmpty() ?
TypeEntry::targetLangName() : m_targetLangName;
}
-// The things we do not to break the ABI...
-typedef QHash<const ComplexTypeEntry*, QString> ComplexTypeEntryDefaultConstructorMap;
-Q_GLOBAL_STATIC(ComplexTypeEntryDefaultConstructorMap, complexTypeEntryDefaultConstructors);
-
void ComplexTypeEntry::setDefaultConstructor(const QString& defaultConstructor)
{
- if (!defaultConstructor.isEmpty())
- complexTypeEntryDefaultConstructors()->insert(this, defaultConstructor);
+ m_defaultConstructor = defaultConstructor;
}
QString ComplexTypeEntry::defaultConstructor() const
{
- if (!complexTypeEntryDefaultConstructors()->contains(this))
- return QString();
- return complexTypeEntryDefaultConstructors()->value(this);
+ return m_defaultConstructor;
}
bool ComplexTypeEntry::hasDefaultConstructor() const
{
- return complexTypeEntryDefaultConstructors()->contains(this);
+ return !m_defaultConstructor.isEmpty();
}
-QString ContainerTypeEntry::targetLangPackage() const
+TypeEntry *ComplexTypeEntry::clone() const
{
- return QString();
+ return new ComplexTypeEntry(*this);
}
+// Take over parameters relevant for typedefs
+void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntry *source)
+{
+ TypeEntry::useAsTypedef(source);
+ m_qualifiedCppName = source->m_qualifiedCppName;
+ m_targetLangName = source->m_targetLangName;
+ m_lookupName = source->m_lookupName;
+ m_targetType = source->m_targetType;
+}
+
+ComplexTypeEntry::ComplexTypeEntry(const ComplexTypeEntry &) = default;
+
QString ContainerTypeEntry::targetLangName() const
{
@@ -2252,13 +2974,17 @@ QString ContainerTypeEntry::qualifiedCppName() const
return ComplexTypeEntry::qualifiedCppName();
}
+TypeEntry *ContainerTypeEntry::clone() const
+{
+ return new ContainerTypeEntry(*this);
+}
+
+ContainerTypeEntry::ContainerTypeEntry(const ContainerTypeEntry &) = default;
+
QString EnumTypeEntry::targetLangQualifier() const
{
TypeEntry *te = TypeDatabase::instance()->findType(m_qualifier);
- if (te)
- return te->targetLangName();
- else
- return m_qualifier;
+ return te ? te->targetLangName() : m_qualifier;
}
QString EnumTypeEntry::qualifiedTargetLangName() const
@@ -2281,26 +3007,25 @@ QString EnumTypeEntry::targetLangApiName() const
return QLatin1String("jint");
}
-bool EnumTypeEntry::preferredConversion() const
-{
- return false;
-}
-
QString FlagsTypeEntry::targetLangApiName() const
{
return QLatin1String("jint");
}
-bool FlagsTypeEntry::preferredConversion() const
+TypeEntry *EnumTypeEntry::clone() const
{
- return false;
+ return new EnumTypeEntry(*this);
}
-QString FlagsTypeEntry::targetLangPackage() const
+EnumTypeEntry::EnumTypeEntry(const EnumTypeEntry &) = default;
+
+TypeEntry *FlagsTypeEntry::clone() const
{
- return m_enum->targetLangPackage();
+ return new FlagsTypeEntry(*this);
}
+FlagsTypeEntry::FlagsTypeEntry(const FlagsTypeEntry &) = default;
+
QString FlagsTypeEntry::qualifiedTargetLangName() const
{
return targetLangPackage() + QLatin1Char('.') + m_enum->targetLangQualifier()
@@ -2320,7 +3045,7 @@ QString fixCppTypeName(const QString &name)
{
if (name == QLatin1String("long long"))
return QLatin1String("qint64");
- else if (name == QLatin1String("unsigned long long"))
+ if (name == QLatin1String("unsigned long long"))
return QLatin1String("quint64");
return name;
}
@@ -2341,11 +3066,9 @@ QString TemplateInstance::expandCode() const
result += code;
result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END");
return result;
- } else {
- qCWarning(lcShiboken).noquote().nospace()
- << "insert-template referring to non-existing template '" << m_name << '\'';
}
-
+ qCWarning(lcShiboken).noquote().nospace()
+ << "insert-template referring to non-existing template '" << m_name << '\'';
return QString();
}
@@ -2361,10 +3084,7 @@ QString CodeSnipAbstract::code() const
QString CodeSnipFragment::code() const
{
- if (m_instance)
- return m_instance->expandCode();
- else
- return m_code;
+ return m_instance ? m_instance->expandCode() : m_code;
}
bool FunctionModification::setSignature(const QString &s, QString *errorMessage)
@@ -2513,6 +3233,122 @@ AddedFunction::AddedFunction(QString signature, const QString &returnType) :
}
#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const ReferenceCount &r)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "ReferenceCount(" << r.varName << ", action=" << r.action << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const CodeSnip &s)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "CodeSnip(language=" << s.language << ", position=" << s.position << ", \"";
+ for (const auto &f : s.codeList) {
+ const QString &code = f.code();
+ const auto lines = code.splitRef(QLatin1Char('\n'));
+ for (int i = 0, size = lines.size(); i < size; ++i) {
+ if (i)
+ d << "\\n";
+ d << lines.at(i).trimmed();
+ }
+ }
+ d << '"';
+ if (!s.argumentMap.isEmpty()) {
+ d << ", argumentMap{";
+ for (auto it = s.argumentMap.cbegin(), end = s.argumentMap.cend(); it != end; ++it)
+ d << it.key() << "->\"" << it.value() << '"';
+ d << '}';
+ }
+ d << ')';
+ return d;
+}
+
+void Modification::formatDebug(QDebug &d) const
+{
+ d << "modifiers=" << hex << showbase << modifiers << noshowbase << dec;
+ if (removal)
+ d << ", removal";
+ if (!renamedToName.isEmpty())
+ d << ", renamedToName=\"" << renamedToName << '"';
+}
+
+void FunctionModification::formatDebug(QDebug &d) const
+{
+ if (m_signature.isEmpty())
+ d << "pattern=\"" << m_signaturePattern.pattern();
+ else
+ d << "signature=\"" << m_signature;
+ d << "\", ";
+ Modification::formatDebug(d);
+ if (!association.isEmpty())
+ d << ", association=\"" << association << '"';
+ if (m_allowThread != TypeSystem::AllowThread::Unspecified)
+ d << ", allowThread=" << int(m_allowThread);
+ if (m_thread)
+ d << ", thread";
+ if (m_exceptionHandling != TypeSystem::ExceptionHandling::Unspecified)
+ d << ", exceptionHandling=" << int(m_exceptionHandling);
+ if (!snips.isEmpty())
+ d << ", snips=(" << snips << ')';
+ if (!argument_mods.isEmpty())
+ d << ", argument_mods=(" << argument_mods << ')';
+}
+
+QDebug operator<<(QDebug d, const ArgumentOwner &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "ArgumentOwner(index=" << a.index << ", action=" << a.action << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const ArgumentModification &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "ArgumentModification(index=" << a.index;
+ if (a.removedDefaultExpression)
+ d << ", removedDefaultExpression";
+ if (a.removed)
+ d << ", removed";
+ if (a.noNullPointers)
+ d << ", noNullPointers";
+ if (a.array)
+ d << ", array";
+ if (!a.referenceCounts.isEmpty())
+ d << ", referenceCounts=" << a.referenceCounts;
+ if (!a.modified_type.isEmpty())
+ d << ", modified_type=\"" << a.modified_type << '"';
+ if (!a.replace_value.isEmpty())
+ d << ", replace_value=\"" << a.replace_value << '"';
+ if (!a.replacedDefaultExpression.isEmpty())
+ d << ", replacedDefaultExpression=\"" << a.replacedDefaultExpression << '"';
+ if (!a.ownerships.isEmpty())
+ d << ", ownerships=" << a.ownerships;
+ if (!a.renamed_to.isEmpty())
+ d << ", renamed_to=\"" << a.renamed_to << '"';
+ d << ", owner=" << a.owner << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const FunctionModification &fm)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "FunctionModification(";
+ fm.formatDebug(d);
+ d << ')';
+ return d;
+}
+
QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti)
{
QDebugStateSaver saver(d);
@@ -2556,11 +3392,12 @@ AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& si
ComplexTypeEntry::ComplexTypeEntry(const QString &name, TypeEntry::Type t,
const QVersionNumber &vr) :
- TypeEntry(QString(name).replace(QLatin1String(".*::"), QString()), t, vr),
+ TypeEntry(name, t, vr),
m_qualifiedCppName(name),
m_qobject(false),
m_polymorphicBase(false),
- m_genericClass(false)
+ m_genericClass(false),
+ m_deleteInMainThread(false)
{
}
@@ -2578,71 +3415,6 @@ QString ComplexTypeEntry::targetLangApiName() const
{
return strings_jobject;
}
-QString StringTypeEntry::targetLangApiName() const
-{
- return strings_jobject;
-}
-QString StringTypeEntry::targetLangName() const
-{
- return strings_String;
-}
-QString StringTypeEntry::targetLangPackage() const
-{
- return QString();
-}
-
-bool StringTypeEntry::isNativeIdBased() const
-{
- return false;
-}
-
-CharTypeEntry::CharTypeEntry(const QString &name, const QVersionNumber &vr) :
- ValueTypeEntry(name, CharType, vr)
-{
- setCodeGeneration(GenerateNothing);
-}
-
-QString CharTypeEntry::targetLangApiName() const
-{
- return strings_jchar;
-}
-QString CharTypeEntry::targetLangName() const
-{
- return strings_char;
-}
-
-QString CharTypeEntry::targetLangPackage() const
-{
- return QString();
-}
-
-bool CharTypeEntry::isNativeIdBased() const
-{
- return false;
-}
-
-VariantTypeEntry::VariantTypeEntry(const QString &name, const QVersionNumber &vr) :
- ValueTypeEntry(name, VariantType, vr)
-{
-}
-
-QString VariantTypeEntry::targetLangApiName() const
-{
- return strings_jobject;
-}
-QString VariantTypeEntry::targetLangName() const
-{
- return strings_Object;
-}
-QString VariantTypeEntry::targetLangPackage() const
-{
- return QString();
-}
-
-bool VariantTypeEntry::isNativeIdBased() const
-{
- return false;
-}
QString ContainerTypeEntry::typeName() const
{
@@ -2706,10 +3478,6 @@ bool TypeEntry::isCppPrimitive() const
return typeName.contains(QLatin1Char(' ')) || primitiveCppTypes().contains(typeName);
}
-// Again, stuff to avoid ABI breakage.
-typedef QHash<const TypeEntry*, CustomConversion*> TypeEntryCustomConversionMap;
-Q_GLOBAL_STATIC(TypeEntryCustomConversionMap, typeEntryCustomConversionMap);
-
TypeEntry::TypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumber &vr) :
m_name(name),
m_type(t),
@@ -2719,51 +3487,88 @@ TypeEntry::TypeEntry(const QString &name, TypeEntry::Type t, const QVersionNumbe
TypeEntry::~TypeEntry()
{
- if (typeEntryCustomConversionMap()->contains(this)) {
- CustomConversion* customConversion = typeEntryCustomConversionMap()->value(this);
- typeEntryCustomConversionMap()->remove(this);
- delete customConversion;
- }
+ delete m_customConversion;
}
bool TypeEntry::hasCustomConversion() const
{
- return typeEntryCustomConversionMap()->contains(this);
+ return m_customConversion != nullptr;
}
+
void TypeEntry::setCustomConversion(CustomConversion* customConversion)
{
- if (customConversion)
- typeEntryCustomConversionMap()->insert(this, customConversion);
- else if (typeEntryCustomConversionMap()->contains(this))
- typeEntryCustomConversionMap()->remove(this);
+ m_customConversion = customConversion;
}
+
CustomConversion* TypeEntry::customConversion() const
{
- if (typeEntryCustomConversionMap()->contains(this))
- return typeEntryCustomConversionMap()->value(this);
- return 0;
+ return m_customConversion;
+}
+
+TypeEntry *TypeEntry::clone() const
+{
+ return new TypeEntry(*this);
+}
+
+// Take over parameters relevant for typedefs
+void TypeEntry::useAsTypedef(const TypeEntry *source)
+{
+ m_name = source->m_name;
+ m_targetLangPackage = source->m_targetLangPackage;
+ m_codeGeneration = source->m_codeGeneration;
+ m_version = source->m_version;
}
+TypeEntry::TypeEntry(const TypeEntry &) = default;
+
TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr) :
TypeEntry(name, TypeSystemType, vr)
{
}
+TypeEntry *TypeSystemTypeEntry::clone() const
+{
+ return new TypeSystemTypeEntry(*this);
+}
+
+TypeSystemTypeEntry::TypeSystemTypeEntry(const TypeSystemTypeEntry &) = default;
+
VoidTypeEntry::VoidTypeEntry() :
TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0))
{
}
+TypeEntry *VoidTypeEntry::clone() const
+{
+ return new VoidTypeEntry(*this);
+}
+
+VoidTypeEntry::VoidTypeEntry(const VoidTypeEntry &) = default;
+
VarargsTypeEntry::VarargsTypeEntry() :
TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0))
{
}
+TypeEntry *VarargsTypeEntry::clone() const
+{
+ return new VarargsTypeEntry(*this);
+}
+
+VarargsTypeEntry::VarargsTypeEntry(const VarargsTypeEntry &) = default;
+
TemplateArgumentEntry::TemplateArgumentEntry(const QString &name, const QVersionNumber &vr) :
TypeEntry(name, TemplateArgumentType, vr)
{
}
+TypeEntry *TemplateArgumentEntry::clone() const
+{
+ return new TemplateArgumentEntry(*this);
+}
+
+TemplateArgumentEntry::TemplateArgumentEntry(const TemplateArgumentEntry &) = default;
+
ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr) :
TypeEntry(QLatin1String("Array"), ArrayType, vr),
m_nestedType(nested_type)
@@ -2778,12 +3583,18 @@ QString ArrayTypeEntry::targetLangName() const
QString ArrayTypeEntry::targetLangApiName() const
{
- if (m_nestedType->isPrimitive())
- return m_nestedType->targetLangApiName() + QLatin1String("Array");
- else
- return QLatin1String("jobjectArray");
+ return m_nestedType->isPrimitive()
+ ? m_nestedType->targetLangApiName() + QLatin1String("Array")
+ : QLatin1String("jobjectArray");
}
+TypeEntry *ArrayTypeEntry::clone() const
+{
+ return new ArrayTypeEntry(*this);
+}
+
+ArrayTypeEntry::ArrayTypeEntry(const ArrayTypeEntry &) = default;
+
EnumTypeEntry::EnumTypeEntry(const QString &nspace, const QString &enumName,
const QVersionNumber &vr) :
TypeEntry(nspace.isEmpty() ? enumName : nspace + QLatin1String("::") + enumName,
@@ -2793,16 +3604,6 @@ EnumTypeEntry::EnumTypeEntry(const QString &nspace, const QString &enumName,
{
}
-QString EnumTypeEntry::targetLangPackage() const
-{
- return m_packageName;
-}
-
-void EnumTypeEntry::setTargetLangPackage(const QString &package)
-{
- m_packageName = package;
-}
-
QString EnumTypeEntry::targetLangName() const
{
return m_targetLangName;
@@ -2817,11 +3618,34 @@ EnumValueTypeEntry::EnumValueTypeEntry(const QString &name, const QString &value
{
}
+TypeEntry *EnumValueTypeEntry::clone() const
+{
+ return new EnumValueTypeEntry(*this);
+}
+
+EnumValueTypeEntry::EnumValueTypeEntry(const EnumValueTypeEntry &) = default;
+
FlagsTypeEntry::FlagsTypeEntry(const QString &name, const QVersionNumber &vr) :
TypeEntry(name, FlagsType, vr)
{
}
+/* A typedef entry allows for specifying template specializations in the
+ * typesystem XML file. */
+TypedefEntry::TypedefEntry(const QString &name, const QString &sourceType,
+ const QVersionNumber &vr) :
+ ComplexTypeEntry(name, TypedefType, vr),
+ m_sourceType(sourceType)
+{
+}
+
+TypeEntry *TypedefEntry::clone() const
+{
+ return new TypedefEntry(*this);
+}
+
+TypedefEntry::TypedefEntry(const TypedefEntry &) = default;
+
ContainerTypeEntry::ContainerTypeEntry(const QString &name, Type type,
const QVersionNumber &vr) :
ComplexTypeEntry(name, ContainerType, vr),
@@ -2842,11 +3666,25 @@ SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &name,
{
}
+TypeEntry *SmartPointerTypeEntry::clone() const
+{
+ return new SmartPointerTypeEntry(*this);
+}
+
+SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default;
+
NamespaceTypeEntry::NamespaceTypeEntry(const QString &name, const QVersionNumber &vr) :
ComplexTypeEntry(name, NamespaceType, vr)
{
}
+TypeEntry *NamespaceTypeEntry::clone() const
+{
+ return new NamespaceTypeEntry(*this);
+}
+
+NamespaceTypeEntry::NamespaceTypeEntry(const NamespaceTypeEntry &) = default;
+
ValueTypeEntry::ValueTypeEntry(const QString &name, const QVersionNumber &vr) :
ComplexTypeEntry(name, BasicValueType, vr)
{
@@ -2862,35 +3700,17 @@ bool ValueTypeEntry::isNativeIdBased() const
return true;
}
-ValueTypeEntry::ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr) :
- ComplexTypeEntry(name, t, vr)
+TypeEntry *ValueTypeEntry::clone() const
{
+ return new ValueTypeEntry(*this);
}
-StringTypeEntry::StringTypeEntry(const QString &name, const QVersionNumber &vr) :
- ValueTypeEntry(name, StringType, vr)
-{
- setCodeGeneration(GenerateNothing);
-}
+ValueTypeEntry::ValueTypeEntry(const ValueTypeEntry &) = default;
-/*
-static void injectCode(ComplexTypeEntry *e,
- const char *signature,
- const QByteArray &code,
- const ArgumentMap &args)
+ValueTypeEntry::ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr) :
+ ComplexTypeEntry(name, t, vr)
{
- CodeSnip snip;
- snip.language = TypeSystem::NativeCode;
- snip.position = CodeSnip::Beginning;
- snip.addCode(QString::fromLatin1(code));
- snip.argumentMap = args;
-
- FunctionModification mod;
- mod.signature = QMetaObject::normalizedSignature(signature);
- mod.snips << snip;
- mod.modifiers = Modification::CodeInjection;
}
-*/
struct CustomConversion::CustomConversionPrivate
{
@@ -3042,6 +3862,13 @@ QString InterfaceTypeEntry::qualifiedCppName() const
return ComplexTypeEntry::qualifiedCppName().left(len);
}
+TypeEntry *InterfaceTypeEntry::clone() const
+{
+ return new InterfaceTypeEntry(*this);
+}
+
+InterfaceTypeEntry::InterfaceTypeEntry(const InterfaceTypeEntry &) = default;
+
FunctionTypeEntry::FunctionTypeEntry(const QString &name, const QString &signature,
const QVersionNumber &vr) :
TypeEntry(name, FunctionType, vr)
@@ -3049,6 +3876,13 @@ FunctionTypeEntry::FunctionTypeEntry(const QString &name, const QString &signatu
addSignature(signature);
}
+TypeEntry *FunctionTypeEntry::clone() const
+{
+ return new FunctionTypeEntry(*this);
+}
+
+FunctionTypeEntry::FunctionTypeEntry(const FunctionTypeEntry &) = default;
+
ObjectTypeEntry::ObjectTypeEntry(const QString &name, const QVersionNumber &vr)
: ComplexTypeEntry(name, ObjectType, vr)
{
@@ -3063,3 +3897,10 @@ bool ObjectTypeEntry::isNativeIdBased() const
{
return true;
}
+
+TypeEntry *ObjectTypeEntry::clone() const
+{
+ return new ObjectTypeEntry(*this);
+}
+
+ObjectTypeEntry::ObjectTypeEntry(const ObjectTypeEntry &) = default;
diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h
index 186c4b24d..b0144923a 100644
--- a/sources/shiboken2/ApiExtractor/typesystem.h
+++ b/sources/shiboken2/ApiExtractor/typesystem.h
@@ -43,8 +43,8 @@
#include <QtCore/QVersionNumber>
//Used to identify the conversion rule to avoid break API
-#define TARGET_CONVERSION_RULE_FLAG "0"
-#define NATIVE_CONVERSION_RULE_FLAG "1"
+extern const char *TARGET_CONVERSION_RULE_FLAG;
+extern const char *NATIVE_CONVERSION_RULE_FLAG;
class Indentor;
@@ -203,12 +203,6 @@ struct ArgumentModification
QString replace_value;
- // The code to be used to construct a return value when noNullPointers is true and
- // the returned value is null. If noNullPointers is true and this string is
- // empty, then the base class implementation will be used (or a default construction
- // if there is no implementation)
- QString nullPointerDefaultValue;
-
// The text of the new default expression of the argument
QString replacedDefaultExpression;
@@ -237,6 +231,7 @@ struct ArgumentModification
struct Modification
{
enum Modifiers {
+ InvalidModifier = 0x0000,
Private = 0x0001,
Protected = 0x0002,
Public = 0x0003,
@@ -253,8 +248,7 @@ struct Modification
CodeInjection = 0x1000,
Rename = 0x2000,
Deprecated = 0x4000,
- ReplaceExpression = 0x8000,
- VirtualSlot = 0x10000 | NonFinal
+ ReplaceExpression = 0x8000
};
bool isAccessModifier() const
@@ -289,10 +283,6 @@ struct Modification
{
return modifiers & NonFinal;
}
- bool isVirtualSlot() const
- {
- return (modifiers & VirtualSlot) == VirtualSlot;
- }
QString accessModifierString() const;
bool isDeprecated() const
@@ -318,6 +308,10 @@ struct Modification
return removal != TypeSystem::NoLanguage;
}
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const;
+#endif
+
QString renamedToName;
uint modifiers = 0;
TypeSystem::Language removal = TypeSystem::NoLanguage;
@@ -325,6 +319,8 @@ struct Modification
struct FunctionModification: public Modification
{
+ using AllowThread = TypeSystem::AllowThread;
+
bool isCodeInjection() const
{
return modifiers & CodeInjection;
@@ -337,14 +333,9 @@ struct FunctionModification: public Modification
{
return m_thread;
}
- bool allowThread() const
- {
- return m_allowThread;
- }
- void setAllowThread(bool allow)
- {
- m_allowThread = allow;
- }
+
+ AllowThread allowThread() const { return m_allowThread; }
+ void setAllowThread(AllowThread allow) { m_allowThread = allow; }
bool matches(const QString &functionSignature) const
{
@@ -359,8 +350,15 @@ struct FunctionModification: public Modification
void setOriginalSignature(const QString &s) { m_originalSignature = s; }
QString originalSignature() const { return m_originalSignature; }
+ TypeSystem::ExceptionHandling exceptionHandling() const { return m_exceptionHandling; }
+ void setExceptionHandling(TypeSystem::ExceptionHandling e) { m_exceptionHandling = e; }
+
QString toString() const;
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const;
+#endif
+
QString association;
CodeSnipList snips;
@@ -371,9 +369,17 @@ private:
QString m_originalSignature;
QRegularExpression m_signaturePattern;
bool m_thread = false;
- bool m_allowThread = false;
+ AllowThread m_allowThread = AllowThread::Unspecified;
+ TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
};
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const ReferenceCount &);
+QDebug operator<<(QDebug d, const ArgumentOwner &a);
+QDebug operator<<(QDebug d, const ArgumentModification &a);
+QDebug operator<<(QDebug d, const FunctionModification &fm);
+#endif
+
struct FieldModification: public Modification
{
bool isReadable() const
@@ -398,6 +404,7 @@ struct AddedFunction
{
/// Function access types.
enum Access {
+ InvalidAccess = 0,
Protected = 0x1,
Public = 0x2
};
@@ -532,7 +539,6 @@ class CustomConversion;
class TypeEntry
{
- Q_DISABLE_COPY(TypeEntry)
Q_GADGET
public:
enum Type {
@@ -558,7 +564,8 @@ public:
CustomType,
TargetLangType,
FunctionType,
- SmartPointerType
+ SmartPointerType,
+ TypedefType
};
Q_ENUM(Type)
@@ -670,15 +677,6 @@ public:
return m_type == EnumValue;
}
- virtual bool preferredConversion() const
- {
- return m_preferredConversion;
- }
- virtual void setPreferredConversion(bool b)
- {
- m_preferredConversion = b;
- }
-
bool stream() const
{
return m_stream;
@@ -715,6 +713,11 @@ public:
&& m_codeGeneration != TypeEntry::GenerateNothing;
}
+ int revision() const { return m_revision; }
+ void setRevision(int r); // see typedatabase.cpp
+ int sbkIndex() const;
+ void setSbkIndex(int i) { m_sbkIndex = i; }
+
virtual QString qualifiedCppName() const
{
return m_name;
@@ -747,10 +750,8 @@ public:
}
// The package
- virtual QString targetLangPackage() const
- {
- return QString();
- }
+ QString targetLangPackage() const { return m_targetLangPackage; }
+ void setTargetLangPackage(const QString &p) { m_targetLangPackage = p; }
virtual QString qualifiedTargetLangName() const
{
@@ -889,13 +890,29 @@ public:
bool hasCustomConversion() const;
void setCustomConversion(CustomConversion* customConversion);
CustomConversion* customConversion() const;
+
+ virtual TypeEntry *clone() const;
+
+ void useAsTypedef(const TypeEntry *source);
+
+#ifndef QT_NO_DEBUG_STREAM
+ virtual void formatDebug(QDebug &d) const;
+#endif
+
+protected:
+ TypeEntry(const TypeEntry &);
+
private:
+ TypeEntry &operator=(const TypeEntry &) = delete;
+ TypeEntry &operator=(TypeEntry &&) = delete;
+ TypeEntry(TypeEntry &&) = delete;
+
QString m_name;
+ QString m_targetLangPackage;
Type m_type;
uint m_codeGeneration = GenerateAll;
CustomFunction m_customConstructor;
CustomFunction m_customDestructor;
- bool m_preferredConversion = true;
CodeSnipList m_codeSnips;
DocModificationList m_docModifications;
IncludeList m_extraIncludes;
@@ -904,24 +921,42 @@ private:
QString m_conversionRule;
bool m_stream = false;
QVersionNumber m_version;
+ CustomConversion *m_customConversion = nullptr;
+ int m_revision = 0;
+ int m_sbkIndex = 0;
};
class TypeSystemTypeEntry : public TypeEntry
{
public:
explicit TypeSystemTypeEntry(const QString &name, const QVersionNumber &vr);
+
+ TypeEntry *clone() const override;
+
+protected:
+ TypeSystemTypeEntry(const TypeSystemTypeEntry &);
};
class VoidTypeEntry : public TypeEntry
{
public:
VoidTypeEntry();
+
+ TypeEntry *clone() const override;
+
+protected:
+ VoidTypeEntry(const VoidTypeEntry &);
};
class VarargsTypeEntry : public TypeEntry
{
public:
VarargsTypeEntry();
+
+ TypeEntry *clone() const override;
+
+protected:
+ VarargsTypeEntry(const VarargsTypeEntry &);
};
class TemplateArgumentEntry : public TypeEntry
@@ -938,6 +973,11 @@ public:
m_ordinal = o;
}
+ TypeEntry *clone() const override;
+
+protected:
+ TemplateArgumentEntry(const TemplateArgumentEntry &);
+
private:
int m_ordinal = 0;
};
@@ -959,6 +999,11 @@ public:
QString targetLangName() const override;
QString targetLangApiName() const override;
+ TypeEntry *clone() const override;
+
+protected:
+ ArrayTypeEntry(const ArrayTypeEntry &);
+
private:
const TypeEntry *m_nestedType;
};
@@ -1019,9 +1064,6 @@ public:
*/
PrimitiveTypeEntry* basicReferencedTypeEntry() const;
- bool preferredConversion() const override;
- void setPreferredConversion(bool b) override;
-
bool preferredTargetLangType() const
{
return m_preferredTargetLangType;
@@ -1031,26 +1073,27 @@ public:
m_preferredTargetLangType = b;
}
- void setTargetLangPackage(const QString& package);
- QString targetLangPackage() const override;
+ TypeEntry *clone() const override;
+
+protected:
+ PrimitiveTypeEntry(const PrimitiveTypeEntry &);
+
private:
QString m_targetLangName;
QString m_targetLangApiName;
QString m_defaultConstructor;
- uint m_preferredConversion : 1;
uint m_preferredTargetLangType : 1;
PrimitiveTypeEntry* m_referencedTypeEntry = nullptr;
};
+class EnumValueTypeEntry;
+
class EnumTypeEntry : public TypeEntry
{
public:
explicit EnumTypeEntry(const QString &nspace, const QString &enumName,
const QVersionNumber &vr);
- QString targetLangPackage() const override;
- void setTargetLangPackage(const QString &package);
-
QString targetLangName() const override;
QString targetLangQualifier() const;
QString qualifiedTargetLangName() const override;
@@ -1066,30 +1109,8 @@ public:
m_qualifier = q;
}
- bool preferredConversion() const override;
-
- bool isBoundsChecked() const
- {
- return m_lowerBound.isEmpty() && m_upperBound.isEmpty();
- }
-
- QString upperBound() const
- {
- return m_upperBound;
- }
- void setUpperBound(const QString &bound)
- {
- m_upperBound = bound;
- }
-
- QString lowerBound() const
- {
- return m_lowerBound;
- }
- void setLowerBound(const QString &bound)
- {
- m_lowerBound = bound;
- }
+ const EnumValueTypeEntry *nullValue() const { return m_nullValue; }
+ void setNullValue(const EnumValueTypeEntry *n) { m_nullValue = n; }
void setFlags(FlagsTypeEntry *flags)
{
@@ -1100,15 +1121,6 @@ public:
return m_flags;
}
- bool isExtensible() const
- {
- return m_extensible;
- }
- void setExtensible(bool is)
- {
- m_extensible = is;
- }
-
bool isEnumValueRejected(const QString &name) const
{
return m_rejectedEnums.contains(name);
@@ -1122,33 +1134,27 @@ public:
return m_rejectedEnums;
}
- bool forceInteger() const
- {
- return m_forceInteger;
- }
- void setForceInteger(bool force)
- {
- m_forceInteger = force;
- }
+ TypeEntry *clone() const override;
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+protected:
+ EnumTypeEntry(const EnumTypeEntry &);
private:
QString m_packageName;
QString m_qualifier;
QString m_targetLangName;
-
- QString m_lowerBound;
- QString m_upperBound;
+ const EnumValueTypeEntry *m_nullValue = nullptr;
QStringList m_rejectedEnums;
FlagsTypeEntry *m_flags = nullptr;
-
- bool m_extensible = false;
- bool m_forceInteger = false;
};
// EnumValueTypeEntry is used for resolving integer type templates
-// like array<EnumValue>.
+// like array<EnumValue>. Note: Dummy entries for integer values will
+// be created for non-type template parameters, where m_enclosingEnum==nullptr.
class EnumValueTypeEntry : public TypeEntry
{
public:
@@ -1156,6 +1162,12 @@ public:
QString value() const { return m_value; }
const EnumTypeEntry* enclosingEnum() const { return m_enclosingEnum; }
+
+ TypeEntry *clone() const override;
+
+protected:
+ EnumValueTypeEntry(const EnumValueTypeEntry &);
+
private:
QString m_value;
const EnumTypeEntry* m_enclosingEnum;
@@ -1169,7 +1181,6 @@ public:
QString qualifiedTargetLangName() const override;
QString targetLangName() const override;
QString targetLangApiName() const override;
- bool preferredConversion() const override;
QString originalName() const
{
@@ -1189,11 +1200,6 @@ public:
m_targetLangName = name;
}
- bool forceInteger() const
- {
- return m_enum->forceInteger();
- }
-
EnumTypeEntry *originator() const
{
return m_enum;
@@ -1203,7 +1209,10 @@ public:
m_enum = e;
}
- QString targetLangPackage() const override;
+ TypeEntry *clone() const override;
+
+protected:
+ FlagsTypeEntry(const FlagsTypeEntry &);
private:
QString m_originalName;
@@ -1216,8 +1225,6 @@ class ComplexTypeEntry : public TypeEntry
{
public:
enum TypeFlag {
- ForceAbstract = 0x1,
- DeleteInMainThread = 0x2,
Deprecated = 0x4
};
typedef QFlags<TypeFlag> TypeFlags;
@@ -1288,12 +1295,6 @@ public:
return m_fieldMods;
}
- QString targetLangPackage() const override;
- void setTargetLangPackage(const QString &package)
- {
- m_package = package;
- }
-
bool isQObject() const
{
return m_qobject;
@@ -1336,15 +1337,6 @@ public:
return m_polymorphicIdValue;
}
- void setHeldType(const QString &value)
- {
- m_heldTypeValue = value;
- }
- QString heldTypeValue() const
- {
- return m_heldTypeValue;
- }
-
QString targetType() const
{
return m_targetType;
@@ -1369,6 +1361,9 @@ public:
m_genericClass = isGeneric;
}
+ bool deleteInMainThread() const { return m_deleteInMainThread; }
+ void setDeleteInMainThread(bool d) { m_deleteInMainThread = d; }
+
CopyableFlag copyable() const
{
return m_copyableFlag;
@@ -1397,15 +1392,28 @@ public:
return m_baseContainerType;
}
+ TypeSystem::ExceptionHandling exceptionHandling() const { return m_exceptionHandling; }
+ void setExceptionHandling(TypeSystem::ExceptionHandling e) { m_exceptionHandling = e; }
+
QString defaultConstructor() const;
void setDefaultConstructor(const QString& defaultConstructor);
bool hasDefaultConstructor() const;
+ TypeEntry *clone() const override;
+
+ void useAsTypedef(const ComplexTypeEntry *source);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+protected:
+ ComplexTypeEntry(const ComplexTypeEntry &);
+
private:
AddedFunctionList m_addedFunctions;
FunctionModificationList m_functionMods;
FieldModificationList m_fieldMods;
- QString m_package;
+ QString m_defaultConstructor;
QString m_defaultSuperclass;
QString m_qualifiedCppName;
QString m_targetLangName;
@@ -1413,9 +1421,9 @@ private:
uint m_qobject : 1;
uint m_polymorphicBase : 1;
uint m_genericClass : 1;
+ uint m_deleteInMainThread : 1;
QString m_polymorphicIdValue;
- QString m_heldTypeValue;
QString m_lookupName;
QString m_targetType;
TypeFlags m_typeFlags;
@@ -1423,6 +1431,38 @@ private:
QString m_hashFunction;
const ComplexTypeEntry* m_baseContainerType = nullptr;
+ // For class functions
+ TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
+};
+
+class TypedefEntry : public ComplexTypeEntry
+{
+public:
+ explicit TypedefEntry(const QString &name,
+ const QString &sourceType,
+ const QVersionNumber &vr);
+
+ QString sourceType() const { return m_sourceType; }
+ void setSourceType(const QString &s) { m_sourceType =s; }
+
+ TypeEntry *clone() const override;
+
+ ComplexTypeEntry *source() const { return m_source; }
+ void setSource(ComplexTypeEntry *source) { m_source = source; }
+
+ ComplexTypeEntry *target() const { return m_target; }
+ void setTarget(ComplexTypeEntry *target) { m_target = target; }
+
+#ifndef QT_NO_DEBUG_STREAM
+ virtual void formatDebug(QDebug &d) const override;
+#endif
+protected:
+ TypedefEntry(const TypedefEntry &);
+
+private:
+ QString m_sourceType;
+ ComplexTypeEntry *m_source = nullptr;
+ ComplexTypeEntry *m_target = nullptr;
};
class ContainerTypeEntry : public ComplexTypeEntry
@@ -1455,28 +1495,15 @@ public:
QString typeName() const;
QString targetLangName() const override;
- QString targetLangPackage() const override;
QString qualifiedCppName() const override;
- static Type containerTypeFromString(QString typeName)
- {
- static QHash<QString, Type> m_stringToContainerType;
- if (m_stringToContainerType.isEmpty()) {
- m_stringToContainerType.insert(QLatin1String("list"), ListContainer);
- m_stringToContainerType.insert(QLatin1String("string-list"), StringListContainer);
- m_stringToContainerType.insert(QLatin1String("linked-list"), LinkedListContainer);
- m_stringToContainerType.insert(QLatin1String("vector"), VectorContainer);
- m_stringToContainerType.insert(QLatin1String("stack"), StackContainer);
- m_stringToContainerType.insert(QLatin1String("queue"), QueueContainer);
- m_stringToContainerType.insert(QLatin1String("set"), SetContainer);
- m_stringToContainerType.insert(QLatin1String("map"), MapContainer);
- m_stringToContainerType.insert(QLatin1String("multi-map"), MultiMapContainer);
- m_stringToContainerType.insert(QLatin1String("hash"), HashContainer);
- m_stringToContainerType.insert(QLatin1String("multi-hash"), MultiHashContainer);
- m_stringToContainerType.insert(QLatin1String("pair"), PairContainer);
- }
- return m_stringToContainerType.value(typeName, NoContainer);
- }
+ TypeEntry *clone() const override;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+protected:
+ ContainerTypeEntry(const ContainerTypeEntry &);
private:
Type m_type;
@@ -1501,6 +1528,11 @@ public:
return m_refCountMethodName;
}
+ TypeEntry *clone() const override;
+
+protected:
+ SmartPointerTypeEntry(const SmartPointerTypeEntry &);
+
private:
QString m_getterName;
QString m_smartPointerType;
@@ -1511,6 +1543,11 @@ class NamespaceTypeEntry : public ComplexTypeEntry
{
public:
explicit NamespaceTypeEntry(const QString &name, const QVersionNumber &vr);
+
+ TypeEntry *clone() const override;
+
+protected:
+ NamespaceTypeEntry(const NamespaceTypeEntry &);
};
@@ -1523,48 +1560,13 @@ public:
bool isNativeIdBased() const override;
+ TypeEntry *clone() const override;
+
protected:
explicit ValueTypeEntry(const QString &name, Type t, const QVersionNumber &vr);
+ ValueTypeEntry(const ValueTypeEntry &);
};
-
-class StringTypeEntry : public ValueTypeEntry
-{
-public:
- explicit StringTypeEntry(const QString &name, const QVersionNumber &vr);
-
- QString targetLangApiName() const override;
- QString targetLangName() const override;
- QString targetLangPackage() const override;
-
- bool isNativeIdBased() const override;
-};
-
-class CharTypeEntry : public ValueTypeEntry
-{
-public:
- explicit CharTypeEntry(const QString &name, const QVersionNumber &vr);
-
- QString targetLangApiName() const override;
- QString targetLangName() const override;
- QString targetLangPackage() const override;
-
- bool isNativeIdBased() const override;
-};
-
-class VariantTypeEntry: public ValueTypeEntry
-{
-public:
- explicit VariantTypeEntry(const QString &name, const QVersionNumber &vr);
-
- QString targetLangApiName() const override;
- QString targetLangName() const override;
- QString targetLangPackage() const override;
-
- bool isNativeIdBased() const override;
-};
-
-
class InterfaceTypeEntry : public ComplexTypeEntry
{
public:
@@ -1587,6 +1589,11 @@ public:
bool isNativeIdBased() const override;
QString qualifiedCppName() const override;
+ TypeEntry *clone() const override;
+
+protected:
+ InterfaceTypeEntry(const InterfaceTypeEntry &);
+
private:
ObjectTypeEntry *m_origin;
};
@@ -1611,6 +1618,12 @@ public:
{
return m_signatures.contains(signature);
}
+
+ TypeEntry *clone() const override;
+
+protected:
+ FunctionTypeEntry(const FunctionTypeEntry &);
+
private:
QStringList m_signatures;
};
@@ -1628,6 +1641,11 @@ public:
bool isNativeIdBased() const override;
+ TypeEntry *clone() const override;
+
+protected:
+ ObjectTypeEntry(const ObjectTypeEntry &);
+
private:
InterfaceTypeEntry *m_interface = nullptr;
};
@@ -1641,7 +1659,8 @@ struct TypeRejection
Field, // Match className and field name
Enum, // Match className and enum name
ArgumentType, // Match className and argument type
- ReturnType // Match className and return type
+ ReturnType, // Match className and return type
+ Invalid
};
QRegularExpression className;
diff --git a/sources/shiboken2/ApiExtractor/typesystem_enums.h b/sources/shiboken2/ApiExtractor/typesystem_enums.h
index 6bfc94368..df83429d0 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_enums.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_enums.h
@@ -55,6 +55,13 @@ enum Language {
TargetLangAndNativeCode = TargetLangCode | NativeCode
};
+enum class AllowThread {
+ Allow,
+ Disallow,
+ Auto,
+ Unspecified
+};
+
enum Ownership {
InvalidOwnership,
DefaultOwnership,
@@ -71,14 +78,24 @@ enum CodeSnipPosition {
CodeSnipPositionPrototypeInitialization,
CodeSnipPositionConstructorInitialization,
CodeSnipPositionConstructor,
- CodeSnipPositionAny
+ CodeSnipPositionAny,
+ CodeSnipPositionInvalid
};
enum DocModificationMode {
DocModificationAppend,
DocModificationPrepend,
DocModificationReplace,
- DocModificationXPathReplace
+ DocModificationXPathReplace,
+ DocModificationInvalid
+};
+
+enum class ExceptionHandling {
+ Unspecified,
+ Off,
+ AutoDefaultToOff,
+ AutoDefaultToOn,
+ On
};
} // namespace TypeSystem
diff --git a/sources/shiboken2/ApiExtractor/typesystem_p.h b/sources/shiboken2/ApiExtractor/typesystem_p.h
index 882cf3fab..a617110d6 100644
--- a/sources/shiboken2/ApiExtractor/typesystem_p.h
+++ b/sources/shiboken2/ApiExtractor/typesystem_p.h
@@ -55,6 +55,7 @@ class StackElement
FunctionTypeEntry = 0xb,
CustomTypeEntry = 0xc,
SmartPointerTypeEntry = 0xd,
+ TypedefTypeEntry = 0xe,
TypeEntryMask = 0xf,
// Documentation tags
@@ -140,37 +141,117 @@ public:
bool parse(QXmlStreamReader &reader);
+ QString errorString() const { return m_error; }
+
private:
- bool startElement(const QStringRef& localName, const QXmlStreamAttributes& atts);
- bool handleSmartPointerEntry(StackElement *element,
- QHash<QString, QString> &attributes,
- const QString &name,
- const QVersionNumber &since);
+ bool startElement(const QXmlStreamReader &reader);
+ SmartPointerTypeEntry *parseSmartPointerEntry(const QXmlStreamReader &,
+ const QString &name,
+ const QVersionNumber &since,
+ QXmlStreamAttributes *attributes);
bool endElement(const QStringRef& localName);
template <class String> // QString/QStringRef
bool characters(const String &ch);
- void fetchAttributeValues(const QString &name, const QXmlStreamAttributes &atts,
- QHash<QString, QString> *acceptedAttributes);
bool importFileElement(const QXmlStreamAttributes &atts);
- void addFlags(const QString &name, QString flagName,
- const QHash<QString, QString> &attributes,
- const QVersionNumber &since);
+
+ void applyCommonAttributes(TypeEntry *type, QXmlStreamAttributes *attributes) const;
+ PrimitiveTypeEntry *
+ parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ ContainerTypeEntry *
+ parseContainerTypeEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ EnumTypeEntry *
+ parseEnumTypeEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ FlagsTypeEntry *
+ parseFlagsEntry(const QXmlStreamReader &, EnumTypeEntry *enumEntry,
+ const QString &name, QString flagName,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ ObjectTypeEntry *
+ parseInterfaceTypeEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ ValueTypeEntry *
+ parseValueTypeEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ FunctionTypeEntry *
+ parseFunctionTypeEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ TypedefEntry *
+ parseTypedefEntry(const QXmlStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ void applyComplexTypeAttributes(const QXmlStreamReader &, ComplexTypeEntry *ctype,
+ QXmlStreamAttributes *) const;
+ bool parseRenameFunction(const QXmlStreamReader &, QString *name,
+ QXmlStreamAttributes *);
+ bool parseInjectDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *);
+ bool parseModifyDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *);
+ TypeSystemTypeEntry *
+ parseRootElement(const QXmlStreamReader &, const QVersionNumber &since,
+ QXmlStreamAttributes *);
+ bool loadTypesystem(const QXmlStreamReader &, QXmlStreamAttributes *);
+ bool parseRejectEnumValue(const QXmlStreamReader &, QXmlStreamAttributes *);
+ bool parseReplaceArgumentType(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseCustomConversion(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseAddConversion(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseNativeToTarget(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *attributes);
+ bool parseModifyArgument(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *attributes);
+ bool parseNoNullPointer(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *attributes);
+ bool parseDefineOwnership(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseArgumentMap(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseRemoval(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseRename(const QXmlStreamReader &, StackElement::ElementType type,
+ const StackElement &topElement, QXmlStreamAttributes *);
+ bool parseModifyField(const QXmlStreamReader &, QXmlStreamAttributes *);
+ bool parseAddFunction(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseModifyFunction(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseReplaceDefaultExpression(const QXmlStreamReader &,
+ const StackElement &topElement, QXmlStreamAttributes *);
+ CustomFunction *
+ parseCustomMetaConstructor(const QXmlStreamReader &,
+ StackElement::ElementType type,
+ const StackElement &topElement, QXmlStreamAttributes *);
+ bool parseReferenceCount(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseParentOwner(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip);
+ bool parseInjectCode(const QXmlStreamReader &, const StackElement &topElement,
+ StackElement* element, QXmlStreamAttributes *);
+ bool parseInclude(const QXmlStreamReader &, const StackElement &topElement,
+ TypeEntry *entry, QXmlStreamAttributes *);
+ TemplateInstance
+ *parseTemplateInstanceEnum(const QXmlStreamReader &, const StackElement &topElement,
+ QXmlStreamAttributes *);
+ bool parseReplace(const QXmlStreamReader &, const StackElement &topElement,
+ StackElement *element, QXmlStreamAttributes *);
TypeDatabase* m_database;
- StackElement* m_current;
- StackElement* m_currentDroppedEntry;
- int m_currentDroppedEntryDepth;
- int m_ignoreDepth;
+ StackElement* m_current = nullptr;
+ StackElement* m_currentDroppedEntry = nullptr;
+ int m_currentDroppedEntryDepth = 0;
+ int m_ignoreDepth = 0;
QString m_defaultPackage;
QString m_defaultSuperclass;
+ TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
QString m_error;
- TypeEntry::CodeGeneration m_generate;
+ const TypeEntry::CodeGeneration m_generate;
- EnumTypeEntry* m_currentEnum;
+ EnumTypeEntry* m_currentEnum = nullptr;
QStack<StackElementContext*> m_contextStack;
- QHash<QString, StackElement::ElementType> tagNames;
QString m_currentSignature;
QString m_currentPath;
};
diff --git a/sources/shiboken2/CMakeLists.txt b/sources/shiboken2/CMakeLists.txt
index 1af84fca1..619c0f08c 100644
--- a/sources/shiboken2/CMakeLists.txt
+++ b/sources/shiboken2/CMakeLists.txt
@@ -5,8 +5,9 @@ include(CheckIncludeFileCXX)
cmake_minimum_required(VERSION 3.1)
cmake_policy(VERSION 3.1)
-set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules/
+set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake_helpers/
${CMAKE_MODULE_PATH})
+include(helpers)
find_package(Qt5 5.7 REQUIRED COMPONENTS Core Xml XmlPatterns)
@@ -15,6 +16,25 @@ add_definitions(${Qt5Core_DEFINITIONS})
option(BUILD_TESTS "Build tests." TRUE)
option(USE_PYTHON_VERSION "Use specific python version to build shiboken2." "")
+# Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
+if (QUIET_BUILD)
+ set(CMAKE_INSTALL_MESSAGE NEVER)
+endif()
+
+# Override message not to display info messages when doing a quiet build.
+if (QUIET_BUILD)
+ function(message)
+ list(GET ARGV 0 MessageType)
+ if (MessageType STREQUAL FATAL_ERROR OR
+ MessageType STREQUAL SEND_ERROR OR
+ MessageType STREQUAL WARNING OR
+ MessageType STREQUAL AUTHOR_WARNING)
+ list(REMOVE_AT ARGV 0)
+ _message(${MessageType} "${ARGV}")
+ endif()
+ endfunction()
+endif()
+
if (USE_PYTHON_VERSION)
find_package(PythonInterp ${USE_PYTHON_VERSION} REQUIRED)
find_package(PythonLibs ${USE_PYTHON_VERSION} REQUIRED)
@@ -158,6 +178,8 @@ list(GET SHIBOKEN_VERSION_OUTPUT 4 shiboken_PRE_RELEASE_VERSION)
set(shiboken2_VERSION "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}.${shiboken_MICRO_VERSION}")
set(shiboken2_library_so_version "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}")
+compute_config_py_values(shiboken2_VERSION)
+
## For debugging the PYTHON* variables
message("PYTHONLIBS_FOUND: " ${PYTHONLIBS_FOUND})
message("PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES})
diff --git a/sources/shiboken2/data/generatorrunner.1 b/sources/shiboken2/data/generatorrunner.1
index 045b55ad4..f5a61f139 100644
--- a/sources/shiboken2/data/generatorrunner.1
+++ b/sources/shiboken2/data/generatorrunner.1
@@ -13,9 +13,9 @@ are two generators available:
.B qtdoc
\- Generates Sphinx-based documentation for C++ libraries documented using
-.B qdoc3
+.B qdoc
documentation syntax, using the XML files created by the documentation tool
-.B (qdoc3).
+.B (qdoc).
Can be called supplying
.B \-\-generator-set=qtdoc
to
@@ -65,7 +65,7 @@ Drops support for named args.
.IP \-\-documentation\-code\-snippets\-dir
Directory used to search code snippets used by the documentation
.IP \-\-documentation\-data\-dir
-Directory with XML files generated by documentation tool (qdoc3 or Doxygen)
+Directory with XML files generated by documentation tool (qdoc or Doxygen)
.IP \-\-documentation\-out\-dir
The directory where the generated documentation files will be written
.IP \-\-library\-source\-dir
diff --git a/sources/shiboken2/doc/commandlineoptions.rst b/sources/shiboken2/doc/commandlineoptions.rst
index d373561cd..c335fab75 100644
--- a/sources/shiboken2/doc/commandlineoptions.rst
+++ b/sources/shiboken2/doc/commandlineoptions.rst
@@ -37,16 +37,22 @@ Options
Enable heuristics to detect parent relationship on return values.
For more info, check :ref:`return-value-heuristics`.
+.. _avoid-protected-hack:
+
+``--avoid-protected-hack``
+ Avoid the use of the '#define protected public' hack.
+
+.. _use-isnull-as-nb_nonzero:
+
+``--use-isnull-as-nb_nonzero``
+ If a class have an isNull() const method, it will be used to
+ compute the value of boolean casts
+
.. _api-version:
``--api-version=<version>``
Specify the supported api version used to generate the bindings.
-.. _debug-level:
-
-``--debug-level=[sparse|medium|full]``
- Set the debug level.
-
.. _documentation-only:
``--documentation-only``
@@ -63,16 +69,52 @@ Options
``--generation-set``
Generator set to be used (e.g. qtdoc).
-.. _help:
+.. _diff:
-``--help``
- Display this help and exit.
+``--diff``
+ Print a diff of wrapper files.
+
+.. _dryrun:
+
+``--dryrun``
+ Dry run, do not generate wrapper files.
+
+.. _--project-file:
+
+``--project-file=<file>``
+ Text file containing a description of the binding project.
+ Replaces and overrides command line arguments.
.. _include-paths:
-``--include-paths=<path>[:<path>:...]``
+``-I<path>, --include-paths=<path>[:<path>:...]``
Include paths used by the C++ parser.
+... _system-include-paths:
+
+``-isystem<path>, --system-include-paths=<path>[:<path>:...]``
+ System include paths used by the C++ parser
+
+.. _framework-include-paths:
+
+``-F<path>, --framework-include-paths=<path>[:<path>:...]``
+ Framework include paths used by the C++ parser
+
+.. _language-level:
+
+``--language-level=, -std=<level>``
+ C++ Language level (c++11..c++17, default=c++14)
+
+.. _typesystem-paths:
+
+``-T<path>, --typesystem-paths=<path>[:<path>:...]``
+ Paths used when searching for type system files.
+
+.. _output-directory:
+
+``--output-directory=[dir]``
+ The directory where the generated files will be written.
+
.. _license-file=[license-file]:
``--license-file=[license-file]``
@@ -83,23 +125,57 @@ Options
``--no-suppress-warnings``
Show all warnings.
-.. _output-directory:
-
-``--output-directory=[dir]``
- The directory where the generated files will be written.
-
.. _silent:
``--silent``
Avoid printing any message.
-.. _typesystem-paths:
+.. _debug-level:
-``--typesystem-paths=<path>[:<path>:...]``
- Paths used when searching for type system files.
+``--debug-level=[sparse|medium|full]``
+ Set the debug level.
+
+.. _help:
+
+``--help``
+ Display this help and exit.
.. _version:
``--version``
Output version information and exit.
+QtDocGenerator Options
+----------------------
+
+.. _doc-parser:
+
+``--doc-parser=<parser>``
+ The documentation parser used to interpret the documentation
+ input files (qdoc|doxygen).
+
+.. _documentation-code-snippets-dir:
+
+``--documentation-code-snippets-dir=<dir>``
+ Directory used to search code snippets used by the documentation.
+
+.. _documentation-data-dir:
+
+``--documentation-data-dir=<dir>``
+ Directory with XML files generated by documentation tool.
+
+.. _documentation-extra-sections-dir=<dir>:
+
+``--documentation-extra-sections-dir=<dir>``
+ Directory used to search for extra documentation sections.
+
+.. _library-source-dir:
+
+``--library-source-dir=<dir>``
+ Directory where library source code is located.
+
+.. _additional-documentation:
+
+``--additional-documentation=<file>``
+ List of additional XML files to be converted to .rst files
+ (for example, tutorials).
diff --git a/sources/shiboken2/doc/conf.py.in b/sources/shiboken2/doc/conf.py.in
index 57c2f94b9..d3aa95c0b 100644
--- a/sources/shiboken2/doc/conf.py.in
+++ b/sources/shiboken2/doc/conf.py.in
@@ -39,11 +39,11 @@ source_suffix = '.rst'
source_encoding = 'utf-8'
# The master toctree document.
-#master_doc = 'contents'
+master_doc = 'index'
# General information about the project.
project = u'Shiboken'
-copyright = u'Copyright (C) 2016 The Qt Company Ltd.'
+copyright = u'© 2018 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/license/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -137,7 +137,7 @@ html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes']
# Additional templates that should be rendered to pages, maps page names to
# template names.
-html_additional_pages = { 'index' : 'index.html'}
+#html_additional_pages = { 'index' : 'index.html'}
# If false, no module index is generated.
html_use_modindex = False
@@ -159,4 +159,4 @@ html_show_sourcelink = False
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
-intersphinx_mapping = {'apiextractor': ('@CMAKE_BINARY_DIR@/ApiExtractor/doc/html','@CMAKE_BINARY_DIR@/ApiExtractor/doc/html/objects.inv')}
+intersphinx_mapping = {'apiextractor': ('ApiExtractor','@CMAKE_BINARY_DIR@/ApiExtractor/doc/html/objects.inv')}
diff --git a/sources/shiboken2/doc/contents.rst b/sources/shiboken2/doc/contents.rst
index 24adb1c68..a0b40effb 100644
--- a/sources/shiboken2/doc/contents.rst
+++ b/sources/shiboken2/doc/contents.rst
@@ -1,11 +1,10 @@
Table of contents
*****************
.. toctree::
- :numbered:
:maxdepth: 3
- faq.rst
overview.rst
+ samplebinding.rst
commandlineoptions.rst
projectfile.rst
typesystemvariables.rst
@@ -15,3 +14,4 @@ Table of contents
ownership.rst
wordsofadvice.rst
shibokenmodule.rst
+ faq.rst
diff --git a/sources/shiboken2/doc/images/icecream.png b/sources/shiboken2/doc/images/icecream.png
new file mode 100644
index 000000000..41d1a25fa
--- /dev/null
+++ b/sources/shiboken2/doc/images/icecream.png
Binary files differ
diff --git a/sources/shiboken2/doc/images/qtforpython-underthehood.png b/sources/shiboken2/doc/images/qtforpython-underthehood.png
new file mode 100644
index 000000000..64e30b1c5
--- /dev/null
+++ b/sources/shiboken2/doc/images/qtforpython-underthehood.png
Binary files differ
diff --git a/sources/shiboken2/doc/index.rst b/sources/shiboken2/doc/index.rst
new file mode 100644
index 000000000..4cc5b204e
--- /dev/null
+++ b/sources/shiboken2/doc/index.rst
@@ -0,0 +1,28 @@
+Shiboken the Binding Generator
+*******************************
+
+Shiboken is the CPython-based binding code generator for C or C++ libraries.
+It uses an ApiExtractor library to parse the C or C++ headers and get the
+type information, using Clang. The library can also be used to parse non-Qt
+projects. The following diagram summarizes Shiboken's role in the PySide
+project.
+
+.. image:: images/qtforpython-underthehood.png
+
+A typesystem file (XML) is used to specify the types to be exposed to Python
+and to apply modifications to properly represent and manipulate the types in
+the Python World. For example, you can remove and add methods to certain types,
+and also modify the arguments of each method. Such actions are inevitable to
+properly handle the data structures or types.
+
+The final outcome of this process is a set of wrappers written in CPython,
+which can be used as a module in your python code.
+
+Refer to the following topics for more information and examples:
+
+.. toctree::
+ :maxdepth: 1
+
+ overview
+ samplebinding
+ contents
diff --git a/sources/shiboken2/doc/samplebinding.rst b/sources/shiboken2/doc/samplebinding.rst
new file mode 100644
index 000000000..be8dd3ae5
--- /dev/null
+++ b/sources/shiboken2/doc/samplebinding.rst
@@ -0,0 +1,250 @@
+SampleBinding Example
+***********************
+
+The example showcases how you can generate CPython-based binding code for a
+C++ library using Shiboken. The C++ library is called :code:`Universe`,
+with two classes: :code:`Icecream` and :code:`Truck`. Ice creams are
+characterized by their flavor, and :code:`Truck` serves as a vehicle of
+:code:`Icecream` distribution for kids in a neighborhood.
+
+First, let's look at the definition of the two classes:
+
+.. code-block:: cpp
+ :caption: icecream.h
+
+ class Icecream
+ {
+ public:
+ Icecream(const std::string &flavor);
+ virtual Icecream *clone();
+ virtual ~Icecream();
+ virtual const std::string getFlavor();
+
+ private:
+ std::string m_flavor;
+ };
+
+.. code-block:: cpp
+ :caption: truck.h
+
+ class Truck {
+ public:
+ Truck(bool leaveOnDestruction = false);
+ Truck(const Truck &other);
+ Truck& operator=(const Truck &other);
+ ~Truck();
+
+ void addIcecreamFlavor(Icecream *icecream);
+ void printAvailableFlavors() const;
+
+ bool deliver() const;
+ void arrive() const;
+ void leave() const;
+
+ void setLeaveOnDestruction(bool value);
+ void setArrivalMessage(const std::string &message);
+
+ private:
+ void clearFlavors();
+
+ bool m_leaveOnDestruction = false;
+ std::string m_arrivalMessage = "A new icecream truck has arrived!\n";
+ std::vector m_flavors;
+ };
+
+Here is a summary of what the :code:`Universe` library includes:
+
+* The :code:`Icecream` polymorphic type, which is intended to be overridden.
+* The :code:`Icecream::getFlavor()` method returns the flavor depending on the
+ actual derived type.
+* The :code:`Truck` value type that contains pointers, hence the copy
+ constructor.
+* :code:`Truck` stores the :code:`Icecream` objects in a vector, which can be
+ modified via :code:`Truck::addIcecreamFlavor()`.
+* The :code:`Truck’s` arrival message can be customized using its
+ :code:`setArrivalMessage()` method.
+* The :code:`Truck::deliver()` method tells us if the ice cream delivery was
+ successful.
+
+Shiboken typesystem
+====================
+
+Now that the library definitions are in place, Shiboken generator needs a header
+file that includes the types we are interested in:
+
+.. code-block:: cpp
+ :caption: bindings.h
+
+ #ifndef BINDINGS_H
+ #define BINDINGS_H
+ #include "icecream.h"
+ #include "truck.h"
+ #endif // BINDINGS_H
+
+In addition, Shiboken also requires an XML-based typesystem file that defines the
+relationship between C++ and Python types:
+
+.. code-block:: xml
+ :caption: bindings.xml
+
+ <?xml version="1.0"?>
+ <typesystem package="Universe">
+ <primitive-type name="bool"/>
+ <primitive-type name="std::string"/>
+ <object-type name="Icecream">
+ <modify-function signature="clone()">
+ <modify-argument index="0">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </object-type>
+ <value-type name="Truck">
+ <modify-function signature="addIcecreamFlavor(Icecream*)">
+ <modify-argument index="1">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+ </typesystem>
+
+The first important thing to notice here is that we declare :code:`"bool"` and
+:code:`"std::string"` as primitive types. These types are used by some of the
+C++ methods as parameters or return types, so Shiboken must know about them.
+It can then generate relevant conversion code between C++ and Python, although
+most C++ primitive types are handled by Shiboken without additional code.
+
+Next, we declare the two aforementioned classes. One of them as an
+“object-type” and the other as a “value-type”. The main difference is that
+object-types are passed around in generated code as pointers, whereas
+value-types are copied (value semantics).
+
+By specifying the names of these classes in the typesystem file, Shiboken
+automatically tries to generate bindings for all methods of those
+classes. You need not mention all the methods manually in the XML file, unless
+you want to modify them.
+
+Object ownership rules
+=======================
+
+Shiboken cannot magically know who is responsible for freeing the C++ objects
+allocated in the Python code. It can guess, but it’s not always correct. There
+can be cases where Python should release the C++ memory when the ref count
+of the Python object becomes zero. It should never delete the C++ object assuming
+that it will not be deleted by the C++ library or maybe it’s parented to another
+object (like QWidgets).
+
+In our case, the :code:`clone()` method is only called inside the C++ library,
+and we assume that the C++ code takes care of releasing the cloned object.
+
+As for :code:`addIcecreamFlavor()`, we know that a :code:`Truck` owns the
+:code:`Icecream` object, and will remove it once the :code:`Truck` is
+destroyed. That's why the ownership is set to “c++” in the typesystem file,
+so that the C++ objects are not deleted when the corresponding Python names
+go out of scope.
+
+Building
+=========
+
+To build the :code:`Universe` custom library and then generate bindings for it,
+use the :file:`CMakeLists.txt` file provided with the example. You can reuse the
+file for your own libraries with minor changes.
+
+Now, run the command :command:`"cmake ."` from the prompt to configure the
+project and build with the toolchain of your choice (we recommend the
+‘(N)Makefiles’ generator though).
+
+As a result, you end up with two shared libraries:
+:file:`libuniverse.(so/dylib/dll)` and :file:`Universe.(so/pyd)`. The former is
+the custom C++ library, and the latter is the Python module that can be
+imported in your Python script.
+
+Refer to the :file:`README.md` file for more details about the Windows-specific
+build instructions.
+
+Using the Python module
+========================
+
+The following script uses the :code:`Universe` module, derives a few types from
+:code:`Icecream`, implements virtual methods, instantiates objects, and much more:
+
+.. code-block:: python
+ :caption: main.py
+
+ from Universe import Icecream, Truck
+
+ class VanillaChocolateIcecream(Icecream):
+ def __init__(self, flavor=""):
+ super(VanillaChocolateIcecream, self).__init__(flavor)
+
+ def clone(self):
+ return VanillaChocolateIcecream(self.getFlavor())
+
+ def getFlavor(self):
+ return "vanilla sprinked with chocolate"
+
+ class VanillaChocolateCherryIcecream(VanillaChocolateIcecream):
+ def __init__(self, flavor=""):
+ super(VanillaChocolateIcecream, self).__init__(flavor)
+
+ def clone(self):
+ return VanillaChocolateCherryIcecream(self.getFlavor())
+
+ def getFlavor(self):
+ base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor()
+ return base_flavor + " and a cherry"
+
+ if __name__ == '__main__':
+ leave_on_destruction = True
+ truck = Truck(leave_on_destruction)
+
+ flavors = ["vanilla", "chocolate", "strawberry"]
+ for f in flavors:
+ icecream = Icecream(f)
+ truck.addIcecreamFlavor(icecream)
+
+ truck.addIcecreamFlavor(VanillaChocolateIcecream())
+ truck.addIcecreamFlavor(VanillaChocolateCherryIcecream())
+
+ truck.arrive()
+ truck.printAvailableFlavors()
+ result = truck.deliver()
+
+ if result:
+ print("All the kids got some icecream!")
+ else:
+ print("Aww, someone didn't get the flavor they wanted...")
+
+ if not result:
+ special_truck = Truck(truck)
+ del truck
+
+ print("")
+ special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n")
+ special_truck.arrive()
+ special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream"))
+ special_truck.printAvailableFlavors()
+ special_truck.deliver()
+ print("Now everyone got the flavor they wanted!")
+ special_truck.leave()
+
+After importing the classes from the :code:`Universe` module, it derives two
+types from :code:`Icecream` for different “flavors”. It then creates a
+:code:`truck` to deliver some regular flavored Icecreams and two special ones.
+
+If the delivery fails, a new :code:`truck` is created with the old flavors
+copied over, and a new *magical* flavor that will surely satisfy all customers.
+
+The script above shows how to derive from C++ types, override virtual methods,
+create and destroy objects, and more. Try running it to see if the ice creams
+are delivered.
+
+.. note::
+ You can find the sources for this example under
+ :file:`<PYTHON_ENV_ROOT>/site-packages/lib/PySide2/examples/samplebinding`.
+
+Refer to the following topics for detailed information about using Shiboken:
+ * :doc:`Shiboken module <shibokenmodule>`
+ * :doc:`Type System Variables <typesystemvariables>`
+ * :doc:`User Defined Type Conversion <typeconverters>`
+ * :doc:`Object ownership <ownership>`
+ * :doc:`Frequently Asked Questions <faq>`
diff --git a/sources/shiboken2/generator/CMakeLists.txt b/sources/shiboken2/generator/CMakeLists.txt
index 032118666..fb8058b2d 100644
--- a/sources/shiboken2/generator/CMakeLists.txt
+++ b/sources/shiboken2/generator/CMakeLists.txt
@@ -38,3 +38,33 @@ target_link_libraries(shiboken2
configure_file(shibokenconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/shibokenconfig.h" @ONLY)
install(TARGETS shiboken2 DESTINATION bin)
+
+set(shiboken_generator_package_name "shiboken2_generator")
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${shiboken_generator_package_name}")
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/__init__.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${shiboken_generator_package_name}")
+
+# shiboken2 setuptools entry point
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../shiboken_tool.py
+ DESTINATION bin
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ)
+
+# Use absolute path instead of relative path, to avoid ninja build errors due to
+# duplicate file dependency inconsistency.
+set(shiboken_version_relative_path "${CMAKE_CURRENT_SOURCE_DIR}/../shiboken_version.py")
+get_filename_component(shiboken_version_path ${shiboken_version_relative_path} ABSOLUTE)
+configure_file("${shiboken_version_path}"
+ "${CMAKE_CURRENT_BINARY_DIR}/_git_shiboken_generator_version.py" @ONLY)
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_git_shiboken_generator_version.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/${shiboken_generator_package_name}")
diff --git a/sources/shiboken2/generator/__init__.py.in b/sources/shiboken2/generator/__init__.py.in
new file mode 100644
index 000000000..4be6a833b
--- /dev/null
+++ b/sources/shiboken2/generator/__init__.py.in
@@ -0,0 +1,2 @@
+__version__ = "@FINAL_PACKAGE_VERSION@"
+__version_info__ = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MICRO_VERSION@, "@shiboken_PRE_RELEASE_VERSION_TYPE@", "@shiboken_PRE_RELEASE_VERSION@")
diff --git a/sources/shiboken2/generator/_config.py.in b/sources/shiboken2/generator/_config.py.in
new file mode 100644
index 000000000..985735fa4
--- /dev/null
+++ b/sources/shiboken2/generator/_config.py.in
@@ -0,0 +1,9 @@
+version = "@FINAL_PACKAGE_VERSION@"
+version_info = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MICRO_VERSION@, "@shiboken_PRE_RELEASE_VERSION_TYPE@", "@shiboken_PRE_RELEASE_VERSION@")
+
+@PACKAGE_BUILD_DATE@
+@PACKAGE_BUILD_COMMIT_DATE@
+@PACKAGE_BUILD_COMMIT_HASH@
+@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@
+@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
+@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@
diff --git a/sources/shiboken2/generator/generator.cpp b/sources/shiboken2/generator/generator.cpp
index 1e2f03932..ec227bd83 100644
--- a/sources/shiboken2/generator/generator.cpp
+++ b/sources/shiboken2/generator/generator.cpp
@@ -28,6 +28,7 @@
#include "generator.h"
#include "abstractmetalang.h"
+#include "messages.h"
#include "reporthandler.h"
#include "fileout.h"
#include "apiextractor.h"
@@ -40,8 +41,118 @@
#include <QDebug>
#include <typedatabase.h>
-struct Generator::GeneratorPrivate {
- const ApiExtractor* apiextractor;
+/**
+ * DefaultValue is used for storing default values of types for which code is
+ * generated in different contexts:
+ *
+ * Context | Example: "Class *" | Example: "Class" with default Constructor
+ * --------------------+-------------------------------+------------------------------------------
+ * Variable | var{nullptr}; | var;
+ * initializations | |
+ * --------------------+-------------------------------+------------------------------------------
+ * Return values | return nullptr; | return {}
+ * --------------------+-------------------------------+------------------------------------------
+ * constructor | static_cast<Class *>(nullptr) | Class()
+ * arguments lists | |
+ * (recursive, precise | |
+ * matching). | |
+ */
+
+DefaultValue::DefaultValue(Type t, QString value) :
+ m_type(t), m_value(std::move(value))
+{
+}
+
+DefaultValue::DefaultValue(QString customValue) :
+ m_type(Custom), m_value(std::move(customValue))
+{
+}
+
+QString DefaultValue::returnValue() const
+{
+ switch (m_type) {
+ case DefaultValue::Error:
+ return QLatin1String("#error");
+ case DefaultValue::Boolean:
+ return QLatin1String("false");
+ case DefaultValue::CppScalar:
+ return QLatin1String("0");
+ case DefaultValue::Custom:
+ case DefaultValue::Enum:
+ return m_value;
+ case DefaultValue::Pointer:
+ return QLatin1String("nullptr");
+ case DefaultValue::Void:
+ return QString();
+ case DefaultValue::DefaultConstructorWithDefaultValues:
+ return m_value + QLatin1String("()");
+ case DefaultValue::DefaultConstructor:
+ break;
+ }
+ return QLatin1String("{}");
+}
+
+QString DefaultValue::initialization() const
+{
+ switch (m_type) {
+ case DefaultValue::Error:
+ return QLatin1String("#error");
+ case DefaultValue::Boolean:
+ return QLatin1String("{false}");
+ case DefaultValue::CppScalar:
+ return QLatin1String("{0}");
+ case DefaultValue::Custom:
+ return QLatin1String(" = ") + m_value;
+ case DefaultValue::Enum:
+ return QLatin1Char('{') + m_value + QLatin1Char('}');
+ case DefaultValue::Pointer:
+ return QLatin1String("{nullptr}");
+ case DefaultValue::Void:
+ Q_ASSERT(false);
+ break;
+ case DefaultValue::DefaultConstructor:
+ case DefaultValue::DefaultConstructorWithDefaultValues:
+ break;
+ }
+ return QString();
+}
+
+QString DefaultValue::constructorParameter() const
+{
+ switch (m_type) {
+ case DefaultValue::Error:
+ return QLatin1String("#error");
+ case DefaultValue::Boolean:
+ return QLatin1String("false");
+ case DefaultValue::CppScalar: {
+ // PYSIDE-846: Use static_cast in case of "unsigned long" and similar
+ const QString cast = m_value.contains(QLatin1Char(' '))
+ ? QLatin1String("static_cast<") + m_value + QLatin1Char('>')
+ : m_value;
+ return cast + QLatin1String("(0)");
+ }
+ case DefaultValue::Custom:
+ case DefaultValue::Enum:
+ return m_value;
+ case DefaultValue::Pointer:
+ // Be precise here to be able to differentiate between constructors
+ // taking different pointer types, cf
+ // QTreeWidgetItemIterator(QTreeWidget *) and
+ // QTreeWidgetItemIterator(QTreeWidgetItemIterator *).
+ return QLatin1String("static_cast<") + m_value + QLatin1String("*>(nullptr)");
+ case DefaultValue::Void:
+ Q_ASSERT(false);
+ break;
+ case DefaultValue::DefaultConstructor:
+ case DefaultValue::DefaultConstructorWithDefaultValues:
+ break;
+ }
+ return m_value + QLatin1String("()");
+}
+
+struct Generator::GeneratorPrivate
+{
+ const ApiExtractor* apiextractor = nullptr;
QString outDir;
// License comment
QString licenseComment;
@@ -62,20 +173,17 @@ Generator::~Generator()
delete m_d;
}
-bool Generator::setup(const ApiExtractor& extractor, const QMap< QString, QString > args)
+bool Generator::setup(const ApiExtractor& extractor)
{
m_d->apiextractor = &extractor;
- TypeEntryHash allEntries = TypeDatabase::instance()->allEntries();
+ const auto &allEntries = TypeDatabase::instance()->entries();
TypeEntry* entryFound = 0;
- for (TypeEntryHash::const_iterator it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
- for (TypeEntry *entry : it.value()) {
- if (entry->type() == TypeEntry::TypeSystemType && entry->generateCode()) {
- entryFound = entry;
- break;
- }
- }
- if (entryFound)
+ for (auto it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
+ TypeEntry *entry = it.value();
+ if (entry->type() == TypeEntry::TypeSystemType && entry->generateCode()) {
+ entryFound = entry;
break;
+ }
}
if (entryFound)
m_d->packageName = entryFound->name();
@@ -84,7 +192,7 @@ bool Generator::setup(const ApiExtractor& extractor, const QMap< QString, QStrin
collectInstantiatedContainersAndSmartPointers();
- return doSetup(args);
+ return doSetup();
}
QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType* type)
@@ -197,6 +305,11 @@ Generator::OptionDescriptions Generator::options() const
return OptionDescriptions();
}
+bool Generator::handleOption(const QString & /* key */, const QString & /* value */)
+{
+ return false;
+}
+
AbstractMetaClassList Generator::classes() const
{
return m_d->apiextractor->classes();
@@ -227,24 +340,14 @@ ContainerTypeEntryList Generator::containerTypes() const
return m_d->apiextractor->containerTypes();
}
-const AbstractMetaEnum* Generator::findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const
-{
- return m_d->apiextractor->findAbstractMetaEnum(typeEntry);
-}
-
const AbstractMetaEnum* Generator::findAbstractMetaEnum(const TypeEntry* typeEntry) const
{
return m_d->apiextractor->findAbstractMetaEnum(typeEntry);
}
-const AbstractMetaEnum* Generator::findAbstractMetaEnum(const FlagsTypeEntry* typeEntry) const
-{
- return m_d->apiextractor->findAbstractMetaEnum(typeEntry);
-}
-
const AbstractMetaEnum* Generator::findAbstractMetaEnum(const AbstractMetaType* metaType) const
{
- return m_d->apiextractor->findAbstractMetaEnum(metaType);
+ return m_d->apiextractor->findAbstractMetaEnum(metaType->typeEntry());
}
QString Generator::licenseComment() const
@@ -278,21 +381,6 @@ void Generator::setOutputDirectory(const QString &outDir)
m_d->outDir = outDir;
}
-inline void touchFile(const QString &filePath)
-{
- QFile toucher(filePath);
- qint64 size = toucher.size();
- if (!toucher.open(QIODevice::ReadWrite)) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("Failed to touch file '%1'")
- .arg(QDir::toNativeSeparators(filePath));
- return;
- }
- toucher.resize(size+1);
- toucher.resize(size);
- toucher.close();
-}
-
bool Generator::generateFileForContext(GeneratorContext &context)
{
AbstractMetaClass *cls = context.metaClass();
@@ -312,20 +400,7 @@ bool Generator::generateFileForContext(GeneratorContext &context)
generateClass(fileOut.stream, context);
- FileOut::State state = fileOut.done();
- switch (state) {
- case FileOut::Failure:
- return false;
- case FileOut::Unchanged:
- // Even if contents is unchanged, the last file modification time should be updated,
- // so that the build system can rely on the fact the generated file is up-to-date.
- touchFile(filePath);
- break;
- case FileOut::Success:
- break;
- }
-
- return true;
+ return fileOut.done() != FileOut::Failure;
}
QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType *smartPointerType,
@@ -369,9 +444,9 @@ bool Generator::shouldGenerate(const AbstractMetaClass* metaClass) const
return shouldGenerateTypeEntry(metaClass->typeEntry());
}
-void verifyDirectoryFor(const QFile &file)
+void verifyDirectoryFor(const QString &file)
{
- QDir dir = QFileInfo(file).dir();
+ QDir dir = QFileInfo(file).absoluteDir();
if (!dir.exists()) {
if (!dir.mkpath(dir.absolutePath())) {
qCWarning(lcShiboken).noquote().nospace()
@@ -463,7 +538,7 @@ AbstractMetaFunctionList Generator::implicitConversions(const AbstractMetaType*
bool Generator::isObjectType(const TypeEntry* type)
{
if (type->isComplex())
- return Generator::isObjectType((const ComplexTypeEntry*)type);
+ return Generator::isObjectType(static_cast<const ComplexTypeEntry *>(type));
return type->isObject();
}
bool Generator::isObjectType(const ComplexTypeEntry* type)
@@ -557,184 +632,178 @@ QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType* type)
return QLatin1String("::") + typeName;
}
-QString Generator::minimalConstructor(const AbstractMetaType* type) const
+DefaultValue Generator::minimalConstructor(const AbstractMetaType* type) const
{
if (!type || (type->referenceType() == LValueReference && Generator::isObjectType(type)))
- return QString();
+ return DefaultValue(DefaultValue::Error);
if (type->isContainer()) {
QString ctor = type->cppSignature();
- if (ctor.endsWith(QLatin1Char('*')))
- return QLatin1String("0");
+ if (ctor.endsWith(QLatin1Char('*'))) {
+ ctor.chop(1);
+ return DefaultValue(DefaultValue::Pointer, ctor.trimmed());
+ }
if (ctor.startsWith(QLatin1String("const ")))
ctor.remove(0, sizeof("const ") / sizeof(char) - 1);
if (ctor.endsWith(QLatin1Char('&'))) {
ctor.chop(1);
ctor = ctor.trimmed();
}
- return QLatin1String("::") + ctor + QLatin1String("()");
+ return DefaultValue(DefaultValue::DefaultConstructor, QLatin1String("::") + ctor);
}
if (type->isNativePointer())
- return QLatin1String("static_cast<") + type->typeEntry()->qualifiedCppName() + QLatin1String(" *>(0)");
+ return DefaultValue(DefaultValue::Pointer, type->typeEntry()->qualifiedCppName());
if (Generator::isPointer(type))
- return QLatin1String("static_cast< ::") + type->typeEntry()->qualifiedCppName() + QLatin1String(" *>(0)");
+ return DefaultValue(DefaultValue::Pointer, QLatin1String("::") + type->typeEntry()->qualifiedCppName());
if (type->typeEntry()->isComplex()) {
- const ComplexTypeEntry* cType = reinterpret_cast<const ComplexTypeEntry*>(type->typeEntry());
- QString ctor = cType->defaultConstructor();
- if (!ctor.isEmpty())
- return ctor;
- ctor = minimalConstructor(AbstractMetaClass::findClass(classes(), cType));
- if (type->hasInstantiations())
- ctor = ctor.replace(getFullTypeName(cType), getFullTypeNameWithoutModifiers(type));
+ const ComplexTypeEntry* cType = static_cast<const ComplexTypeEntry*>(type->typeEntry());
+ if (cType->hasDefaultConstructor())
+ return DefaultValue(DefaultValue::Custom, cType->defaultConstructor());
+ auto ctor = minimalConstructor(AbstractMetaClass::findClass(classes(), cType));
+ if (ctor.isValid() && type->hasInstantiations()) {
+ QString v = ctor.value();
+ v.replace(getFullTypeName(cType), getFullTypeNameWithoutModifiers(type));
+ ctor.setValue(v);
+ }
return ctor;
}
return minimalConstructor(type->typeEntry());
}
-QString Generator::minimalConstructor(const TypeEntry* type) const
+DefaultValue Generator::minimalConstructor(const TypeEntry* type) const
{
if (!type)
- return QString();
+ return DefaultValue(DefaultValue::Error);
if (type->isCppPrimitive()) {
const QString &name = type->qualifiedCppName();
return name == QLatin1String("bool")
- ? QLatin1String("false") : name + QLatin1String("(0)");
+ ? DefaultValue(DefaultValue::Boolean)
+ : DefaultValue(DefaultValue::CppScalar, name);
}
- if (type->isEnum())
- return QLatin1String("static_cast< ::") + type->qualifiedCppName() + QLatin1String(">(0)");
+ if (type->isEnum()) {
+ const auto enumEntry = static_cast<const EnumTypeEntry *>(type);
+ if (const auto *nullValue = enumEntry->nullValue())
+ return DefaultValue(DefaultValue::Enum, nullValue->name());
+ return DefaultValue(DefaultValue::Custom,
+ QLatin1String("static_cast< ::") + type->qualifiedCppName()
+ + QLatin1String(">(0)"));
+ }
- if (type->isFlags())
- return type->qualifiedCppName() + QLatin1String("(0)");
+ if (type->isFlags()) {
+ return DefaultValue(DefaultValue::Custom,
+ type->qualifiedCppName() + QLatin1String("(0)"));
+ }
if (type->isPrimitive()) {
- QString ctor = reinterpret_cast<const PrimitiveTypeEntry*>(type)->defaultConstructor();
+ QString ctor = static_cast<const PrimitiveTypeEntry*>(type)->defaultConstructor();
// If a non-C++ (i.e. defined by the user) primitive type does not have
// a default constructor defined by the user, the empty constructor is
// heuristically returned. If this is wrong the build of the generated
// bindings will tell.
return ctor.isEmpty()
- ? (QLatin1String("::") + type->qualifiedCppName() + QLatin1String("()"))
- : ctor;
+ ? DefaultValue(DefaultValue::DefaultConstructorWithDefaultValues, QLatin1String("::")
+ + type->qualifiedCppName())
+ : DefaultValue(DefaultValue::Custom, ctor);
}
if (type->isComplex())
return minimalConstructor(AbstractMetaClass::findClass(classes(), type));
- return QString();
+ return DefaultValue(DefaultValue::Error);
}
-QString Generator::minimalConstructor(const AbstractMetaClass* metaClass) const
+static QString constructorCall(const QString &qualifiedCppName, const QStringList &args)
+{
+ return QLatin1String("::") + qualifiedCppName + QLatin1Char('(')
+ + args.join(QLatin1String(", ")) + QLatin1Char(')');
+}
+
+DefaultValue Generator::minimalConstructor(const AbstractMetaClass* metaClass) const
{
if (!metaClass)
- return QString();
+ return DefaultValue(DefaultValue::Error);
- const ComplexTypeEntry* cType = reinterpret_cast<const ComplexTypeEntry*>(metaClass->typeEntry());
+ const ComplexTypeEntry* cType = static_cast<const ComplexTypeEntry*>(metaClass->typeEntry());
if (cType->hasDefaultConstructor())
- return cType->defaultConstructor();
+ return DefaultValue(DefaultValue::Custom, cType->defaultConstructor());
+ const QString qualifiedCppName = cType->qualifiedCppName();
+ // Obtain a list of constructors sorted by complexity and number of arguments
+ QMultiMap<int, const AbstractMetaFunction *> candidates;
const AbstractMetaFunctionList &constructors = metaClass->queryFunctions(AbstractMetaClass::Constructors);
- int maxArgs = 0;
for (const AbstractMetaFunction *ctor : constructors) {
- if (ctor->isUserAdded() || ctor->isPrivate() || ctor->functionType() != AbstractMetaFunction::ConstructorFunction)
- continue;
-
- int numArgs = ctor->arguments().size();
- if (numArgs == 0) {
- maxArgs = 0;
- break;
- }
- if (numArgs > maxArgs)
- maxArgs = numArgs;
- }
-
- QString qualifiedCppName = metaClass->typeEntry()->qualifiedCppName();
- QStringList templateTypes;
- const QVector<TypeEntry *> &templateArguments = metaClass->templateArguments();
- for (TypeEntry *templateType : templateArguments)
- templateTypes << templateType->qualifiedCppName();
-
- // Empty constructor.
- if (maxArgs == 0)
- return QLatin1String("::") + qualifiedCppName + QLatin1String("()");
-
- QVector<const AbstractMetaFunction *> candidates;
-
- // Constructors with C++ primitive types, enums or pointers only.
- // Start with the ones with fewer arguments.
- for (int i = 1; i <= maxArgs; ++i) {
- for (const AbstractMetaFunction *ctor : constructors) {
- if (ctor->isUserAdded() || ctor->isPrivate() || ctor->functionType() != AbstractMetaFunction::ConstructorFunction)
- continue;
-
- const AbstractMetaArgumentList &arguments = ctor->arguments();
- if (arguments.size() != i)
- continue;
-
- QStringList args;
- for (const AbstractMetaArgument *arg : arguments) {
- const TypeEntry* type = arg->type()->typeEntry();
- if (type == metaClass->typeEntry()) {
- args.clear();
- break;
- }
-
- if (!arg->originalDefaultValueExpression().isEmpty()) {
- if (!arg->defaultValueExpression().isEmpty()
- && arg->defaultValueExpression() != arg->originalDefaultValueExpression()) {
- args << arg->defaultValueExpression();
- }
- break;
- }
-
- if (type->isCppPrimitive() || type->isEnum() || isPointer(arg->type())) {
- QString argValue = minimalConstructor(arg->type());
- if (argValue.isEmpty()) {
- args.clear();
- break;
- }
- args << argValue;
- } else {
- args.clear();
- break;
- }
+ if (!ctor->isUserAdded() && !ctor->isPrivate()
+ && ctor->functionType() == AbstractMetaFunction::ConstructorFunction) {
+ // No arguments: Default constructible
+ const auto &arguments = ctor->arguments();
+ if (arguments.isEmpty()) {
+ return DefaultValue(DefaultValue::DefaultConstructor,
+ QLatin1String("::") + qualifiedCppName);
}
-
- if (!args.isEmpty())
- return QString::fromLatin1("::%1(%2)").arg(qualifiedCppName, args.join(QLatin1String(", ")));
-
- candidates << ctor;
+ // First argument has unmodified default: Default constructible with values
+ if (arguments.constFirst()->hasUnmodifiedDefaultValueExpression()) {
+ return DefaultValue(DefaultValue::DefaultConstructorWithDefaultValues,
+ QLatin1String("::") + qualifiedCppName);
+ }
+ // Examine arguments, exclude functions taking a self parameter
+ bool simple = true;
+ bool suitable = true;
+ for (int i = 0, size = arguments.size();
+ suitable && i < size && !arguments.at(i)->hasDefaultValueExpression(); ++i) {
+ const AbstractMetaArgument *arg = arguments.at(i);
+ const TypeEntry *aType = arg->type()->typeEntry();
+ suitable &= aType != cType;
+ simple &= aType->isCppPrimitive() || aType->isEnum() || isPointer(arg->type());
+ }
+ if (suitable)
+ candidates.insert(arguments.size() + (simple ? 0 : 100), ctor);
}
}
- // Constructors with C++ primitive types, enums, pointers, value types,
- // and user defined primitive types.
- // Builds the minimal constructor recursively.
- for (const AbstractMetaFunction *ctor : qAsConst(candidates)) {
+ for (auto it = candidates.cbegin(), end = candidates.cend(); it != end; ++it) {
+ const AbstractMetaArgumentList &arguments = it.value()->arguments();
QStringList args;
- const AbstractMetaArgumentList &arguments = ctor->arguments();
- for (const AbstractMetaArgument *arg : arguments) {
- if (arg->type()->typeEntry() == metaClass->typeEntry()) {
- args.clear();
- break;
- }
- QString argValue = minimalConstructor(arg->type());
- if (argValue.isEmpty()) {
- args.clear();
+ bool ok = true;
+ for (int i =0, size = arguments.size(); ok && i < size; ++i) {
+ const AbstractMetaArgument *arg = arguments.at(i);
+ if (arg->hasDefaultValueExpression()) {
+ if (arg->hasModifiedDefaultValueExpression())
+ args << arg->defaultValueExpression(); // Spell out modified values
break;
}
- args << argValue;
- }
- if (!args.isEmpty()) {
- return QString::fromLatin1("::%1(%2)").arg(qualifiedCppName, args.join(QLatin1String(", ")));
+ auto argValue = minimalConstructor(arg->type());
+ ok &= argValue.isValid();
+ args << argValue.constructorParameter();
}
+ if (ok)
+ return DefaultValue(DefaultValue::Custom, constructorCall(qualifiedCppName, args));
}
- return QString();
+ return DefaultValue(DefaultValue::Error);
+}
+
+// Should int be used for a (protected) enum when generating the public wrapper?
+bool Generator::useEnumAsIntForProtectedHack(const AbstractMetaType *metaType) const
+{
+ if (metaType->isFlags())
+ return true;
+ if (!metaType->isEnum())
+ return false;
+ const AbstractMetaEnum *metaEnum = findAbstractMetaEnum(metaType);
+ if (!metaEnum)
+ return true;
+ if (metaEnum->attributes() & AbstractMetaAttributes::Public) // No reason, type is public
+ return false;
+ // Only ordinary C-enums can be used as int, scoped enums fail when used
+ // as function arguments.
+ if (metaEnum->enumKind() == EnumKind::EnumClass)
+ qWarning(lcShiboken, "%s", qPrintable(msgCannotUseEnumAsInt(metaEnum->name())));
+ return true;
}
QString Generator::translateType(const AbstractMetaType *cType,
@@ -754,7 +823,7 @@ QString Generator::translateType(const AbstractMetaType *cType,
s = QLatin1String("void");
} else if (cType->isArray()) {
s = translateType(cType->arrayElementType(), context, options) + QLatin1String("[]");
- } else if (options & Generator::EnumAsInts && (cType->isEnum() || cType->isFlags())) {
+ } else if ((options & Generator::EnumAsInts) && useEnumAsIntForProtectedHack(cType)) {
s = QLatin1String("int");
} else {
if (options & Generator::OriginalName) {
diff --git a/sources/shiboken2/generator/generator.h b/sources/shiboken2/generator/generator.h
index 010ed868c..225e7aec7 100644
--- a/sources/shiboken2/generator/generator.h
+++ b/sources/shiboken2/generator/generator.h
@@ -57,7 +57,7 @@ class ContainerTypeEntry;
class Indentor;
QTextStream& formatCode(QTextStream &s, const QString& code, Indentor &indentor);
-void verifyDirectoryFor(const QFile &file);
+void verifyDirectoryFor(const QString &file);
QString getClassTargetFullName(const AbstractMetaClass* metaClass, bool includePackageName = true);
QString getClassTargetFullName(const AbstractMetaEnum* metaEnum, bool includePackageName = true);
@@ -95,6 +95,42 @@ const int alwaysGenerateDestructor = 1;
const int alwaysGenerateDestructor = 0;
#endif
+class DefaultValue
+{
+public:
+ enum Type
+ {
+ Error,
+ Boolean,
+ CppScalar, // A C++ scalar type (int,..) specified by value()
+ Custom, // A custom constructor/expression, uses value() as is
+ DefaultConstructor, // For classes named value()
+ DefaultConstructorWithDefaultValues, // as DefaultConstructor, but can't return {} though.
+ Enum, // Enum value as specified by value()
+ Pointer, // Pointer of type value()
+ Void // "", for return values only
+ };
+
+ explicit DefaultValue(Type t = Error, QString value = QString());
+ explicit DefaultValue(QString customValue);
+
+ bool isValid() const { return m_type != Error; }
+
+ QString returnValue() const;
+ QString initialization() const;
+ QString constructorParameter() const;
+
+ QString value() const { return m_value; }
+ void setValue(const QString &value) { m_value = value; }
+
+ Type type() const { return m_type; }
+ void setType(Type type) { m_type = type; }
+
+private:
+ Type m_type;
+ QString m_value;
+};
+
/**
* A GeneratorContext object contains a pointer to an AbstractMetaClass and/or a specialized
* AbstractMetaType, for which code is currently being generated.
@@ -166,13 +202,74 @@ public:
Generator();
virtual ~Generator();
- bool setup(const ApiExtractor& extractor, const QMap<QString, QString> args);
+ bool setup(const ApiExtractor& extractor);
virtual OptionDescriptions options() const;
+ virtual bool handleOption(const QString &key, const QString &value);
/// Returns the classes used to generate the binding code.
AbstractMetaClassList classes() const;
+ /// Returns the output directory
+ QString outputDirectory() const;
+
+ /// Set the output directory
+ void setOutputDirectory(const QString &outDir);
+
+ /**
+ * Start the code generation, be sure to call setClasses before callign this method.
+ * For each class it creates a QTextStream, call the write method with the current
+ * class and the associated text stream, then write the text stream contents if needed.
+ * \see #write
+ */
+ bool generate();
+
+ /// Returns the license comment to be prepended to each source file generated.
+ QString licenseComment() const;
+
+ /// Sets the license comment to be prepended to each source file generated.
+ void setLicenseComment(const QString &licenseComment);
+
+ /// Returns the generator's name. Used for cosmetic purposes.
+ virtual const char* name() const = 0;
+
+ /**
+ * Retrieves the name of the currently processed module.
+ * While package name is a complete package idetification, e.g. 'PySide.QtCore',
+ * a module name represents the last part of the package, e.g. 'QtCore'.
+ * If the target language separates the modules with characters other than
+ * dots ('.') the generator subclass must overload this method.
+ * \return a string representing the last part of a package name
+ */
+ QString moduleName() const;
+
+ /**
+ * Retrieves a list of constructors used in implicit conversions
+ * available on the given type. The TypeEntry must be a value-type
+ * or else it will return an empty list.
+ * \param type a TypeEntry that is expected to be a value-type
+ * \return a list of constructors that could be used as implicit converters
+ */
+ AbstractMetaFunctionList implicitConversions(const TypeEntry* type) const;
+
+ /// Convenience function for implicitConversions(const TypeEntry* type).
+ AbstractMetaFunctionList implicitConversions(const AbstractMetaType* metaType) const;
+
+ /// Check if type is a pointer.
+ static bool isPointer(const AbstractMetaType* type);
+
+ /// Tells if the type or class is an Object (or QObject) Type.
+ static bool isObjectType(const TypeEntry* type);
+ static bool isObjectType(const ComplexTypeEntry* type);
+ static bool isObjectType(const AbstractMetaType* metaType);
+ static bool isObjectType(const AbstractMetaClass* metaClass);
+
+ /// Returns true if the type is a C string (const char*).
+ static bool isCString(const AbstractMetaType* type);
+ /// Returns true if the type is a void pointer.
+ static bool isVoidPointer(const AbstractMetaType* type);
+
+protected:
/// Returns the classes, topologically ordered, used to generate the binding code.
///
/// The classes are ordered such that derived classes appear later in the list than
@@ -191,33 +288,12 @@ public:
/// Returns all container types found by APIExtractor
ContainerTypeEntryList containerTypes() const;
- /// Returns an AbstractMetaEnum for a given EnumTypeEntry, or NULL if not found.
- const AbstractMetaEnum* findAbstractMetaEnum(const EnumTypeEntry* typeEntry) const;
-
/// Returns an AbstractMetaEnum for a given TypeEntry that is an EnumTypeEntry, or NULL if not found.
const AbstractMetaEnum* findAbstractMetaEnum(const TypeEntry* typeEntry) const;
- /// Returns an AbstractMetaEnum for the enum related to a given FlagsTypeEntry, or NULL if not found.
- const AbstractMetaEnum* findAbstractMetaEnum(const FlagsTypeEntry* typeEntry) const;
-
/// Returns an AbstractMetaEnum for a given AbstractMetaType that holds an EnumTypeEntry, or NULL if not found.
const AbstractMetaEnum* findAbstractMetaEnum(const AbstractMetaType* metaType) const;
- /// Returns the output directory
- QString outputDirectory() const;
-
- /// Set the output directory
- void setOutputDirectory(const QString &outDir);
-
- /**
- * Start the code generation, be sure to call setClasses before callign this method.
- * For each class it creates a QTextStream, call the write method with the current
- * class and the associated text stream, then write the text stream contents if needed.
- * \see #write
- */
- bool generate();
-
-
/// Generates a file for given AbstractMetaClass or AbstractMetaType (smart pointer case).
bool generateFileForContext(GeneratorContext &context);
@@ -225,9 +301,6 @@ public:
QString getFileNameBaseForSmartPointer(const AbstractMetaType *smartPointerType,
const AbstractMetaClass *smartPointerClass) const;
- /// Returns the generator's name. Used for cosmetic purposes.
- virtual const char* name() const = 0;
-
/// Returns true if the generator should generate any code for the TypeEntry.
bool shouldGenerateTypeEntry(const TypeEntry*) const;
@@ -266,56 +339,10 @@ public:
void replaceTemplateVariables(QString &code, const AbstractMetaFunction *func);
/**
- * Returns the license comment to be prepended to each source file generated.
- */
- QString licenseComment() const;
-
- /**
- * Sets the license comment to be prepended to each source file generated.
- */
- void setLicenseComment(const QString &licenseComment);
-
- /**
* Returns the package name.
*/
QString packageName() const;
- /**
- * Retrieves the name of the currently processed module.
- * While package name is a complete package idetification, e.g. 'PySide.QtCore',
- * a module name represents the last part of the package, e.g. 'QtCore'.
- * If the target language separates the modules with characters other than
- * dots ('.') the generator subclass must overload this method.
- * \return a string representing the last part of a package name
- */
- virtual QString moduleName() const;
-
- /**
- * Retrieves a list of constructors used in implicit conversions
- * available on the given type. The TypeEntry must be a value-type
- * or else it will return an empty list.
- * \param type a TypeEntry that is expected to be a value-type
- * \return a list of constructors that could be used as implicit converters
- */
- AbstractMetaFunctionList implicitConversions(const TypeEntry* type) const;
-
- /// Convenience function for implicitConversions(const TypeEntry* type).
- AbstractMetaFunctionList implicitConversions(const AbstractMetaType* metaType) const;
-
- /// Check if type is a pointer.
- static bool isPointer(const AbstractMetaType* type);
-
- /// Tells if the type or class is an Object (or QObject) Type.
- static bool isObjectType(const TypeEntry* type);
- static bool isObjectType(const ComplexTypeEntry* type);
- static bool isObjectType(const AbstractMetaType* metaType);
- static bool isObjectType(const AbstractMetaClass* metaClass);
-
- /// Returns true if the type is a C string (const char*).
- static bool isCString(const AbstractMetaType* type);
- /// Returns true if the type is a void pointer.
- static bool isVoidPointer(const AbstractMetaType* type);
-
// Returns the full name of the type.
QString getFullTypeName(const TypeEntry* type) const;
QString getFullTypeName(const AbstractMetaType* type) const;
@@ -333,11 +360,10 @@ public:
* It will check first for a user defined default constructor.
* Returns a null string if it fails.
*/
- QString minimalConstructor(const TypeEntry* type) const;
- QString minimalConstructor(const AbstractMetaType* type) const;
- QString minimalConstructor(const AbstractMetaClass* metaClass) const;
+ DefaultValue minimalConstructor(const TypeEntry* type) const;
+ DefaultValue minimalConstructor(const AbstractMetaType* type) const;
+ DefaultValue minimalConstructor(const AbstractMetaClass* metaClass) const;
-protected:
/**
* Returns the file name used to write the binding code of an AbstractMetaClass/Type.
* \param context the GeneratorContext which contains an AbstractMetaClass or AbstractMetaType
@@ -348,7 +374,7 @@ protected:
virtual QString fileNameForContext(GeneratorContext &context) const = 0;
- virtual bool doSetup(const QMap<QString, QString>& args) = 0;
+ virtual bool doSetup() = 0;
/**
* Write the bindding code for an AbstractMetaClass.
@@ -378,6 +404,8 @@ protected:
const QString &context);
private:
+ bool useEnumAsIntForProtectedHack(const AbstractMetaType *cType) const;
+
struct GeneratorPrivate;
GeneratorPrivate* m_d;
void collectInstantiatedContainersAndSmartPointers(const AbstractMetaFunction* func);
diff --git a/sources/shiboken2/generator/main.cpp b/sources/shiboken2/generator/main.cpp
index 0b7c15244..362191fd0 100644
--- a/sources/shiboken2/generator/main.cpp
+++ b/sources/shiboken2/generator/main.cpp
@@ -34,6 +34,9 @@
#include <QtCore/QDir>
#include <iostream>
#include <apiextractor.h>
+#include <fileout.h>
+#include <typedatabase.h>
+#include <messages.h>
#include "generator.h"
#include "shibokenconfig.h"
#include "cppgenerator.h"
@@ -41,9 +44,9 @@
#include "qtdocgenerator.h"
#ifdef _WINDOWS
- #define PATH_SPLITTER ";"
+static const QChar pathSplitter = QLatin1Char(';');
#else
- #define PATH_SPLITTER ":"
+static const QChar pathSplitter = QLatin1Char(':');
#endif
static inline QString languageLevelOption() { return QStringLiteral("language-level"); }
@@ -52,95 +55,12 @@ static inline QString frameworkIncludePathOption() { return QStringLiteral("fram
static inline QString systemIncludePathOption() { return QStringLiteral("system-include-paths"); }
static inline QString typesystemPathOption() { return QStringLiteral("typesystem-paths"); }
static inline QString helpOption() { return QStringLiteral("help"); }
-static const char helpHint[] = "Note: use --help or -h for more information.\n";
-
-namespace {
-
-class ArgsHandler
-{
-public:
- explicit ArgsHandler(const QMap<QString, QString>& other);
- virtual ~ArgsHandler();
-
- inline QMap<QString, QString>& args() const
- {
- return *m_args;
- }
-
- inline bool argExists(const QString& s) const
- {
- return m_args->contains(s);
- }
-
- QString removeArg(const QString& s);
- bool argExistsRemove(const QString& s);
+static inline QString diffOption() { return QStringLiteral("diff"); }
+static inline QString dryrunOption() { return QStringLiteral("dry-run"); }
- inline QString argValue(const QString& s) const
- {
- return m_args->value(s);
- }
-
- inline bool noArgs() const
- {
- return m_args->isEmpty();
- }
-
- QString errorMessage() const;
-
-private:
- QMap<QString, QString>* m_args;
-};
-
-ArgsHandler::ArgsHandler(const QMap<QString, QString>& other)
- : m_args(new QMap<QString, QString>(other))
-{
-}
-
-ArgsHandler::~ArgsHandler()
-{
- delete m_args;
-}
-
-QString ArgsHandler::removeArg(const QString& s)
-{
- QString retval;
-
- if (argExists(s)) {
- retval = argValue(s);
- m_args->remove(s);
- }
-
- return retval;
-}
-
-bool ArgsHandler::argExistsRemove(const QString& s)
-{
- bool retval = false;
-
- if (argExists(s)) {
- retval = true;
- m_args->remove(s);
- }
+static const char helpHint[] = "Note: use --help or -h for more information.\n";
- return retval;
-}
-
-QString ArgsHandler::errorMessage() const
-{
- typedef QMap<QString, QString>::ConstIterator StringMapConstIt;
-
- QString message;
- QTextStream str(&message);
- str << "shiboken: Called with wrong arguments:";
- for (StringMapConstIt it = m_args->cbegin(), end = m_args->cend(); it != end; ++it) {
- str << ' ' << it.key();
- if (!it.value().isEmpty())
- str << ' ' << it.value();
- }
- str << "\nCommand line: " << QCoreApplication::arguments().join(QLatin1Char(' '));
- return message;
-}
-}
+typedef QMap<QString, QString> CommandArgumentMap;
typedef Generator::OptionDescriptions OptionDescriptions;
@@ -214,18 +134,18 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
}
if (!includePaths.isEmpty())
- args.insert(includePathOption(), includePaths.join(QLatin1String(PATH_SPLITTER)));
+ args.insert(includePathOption(), includePaths.join(pathSplitter));
if (!frameworkIncludePaths.isEmpty())
args.insert(frameworkIncludePathOption(),
- frameworkIncludePaths.join(QLatin1String(PATH_SPLITTER)));
+ frameworkIncludePaths.join(pathSplitter));
if (!systemIncludePaths.isEmpty()) {
args.insert(systemIncludePathOption(),
- systemIncludePaths.join(QLatin1String(PATH_SPLITTER)));
+ systemIncludePaths.join(pathSplitter));
}
if (!typesystemPaths.isEmpty())
- args.insert(typesystemPathOption(), typesystemPaths.join(QLatin1String(PATH_SPLITTER)));
+ args.insert(typesystemPathOption(), typesystemPaths.join(pathSplitter));
if (!apiVersions.isEmpty())
args.insert(QLatin1String("api-version"), apiVersions.join(QLatin1Char('|')));
if (!languageLevel.isEmpty())
@@ -233,9 +153,9 @@ static bool processProjectFile(QFile& projectFile, QMap<QString, QString>& args)
return true;
}
-static QMap<QString, QString> getInitializedArguments()
+static CommandArgumentMap getInitializedArguments()
{
- QMap<QString, QString> args;
+ CommandArgumentMap args;
QStringList arguments = QCoreApplication::arguments();
QString appName = arguments.constFirst();
arguments.removeFirst();
@@ -277,11 +197,11 @@ static QMap<QString, QString> getInitializedArguments()
// Concatenate values of path arguments that can occur multiple times on the
// command line.
static void addPathOptionValue(const QString &option, const QString &value,
- QMap<QString, QString> &args)
+ CommandArgumentMap &args)
{
- const QMap<QString, QString>::iterator it = args.find(option);
+ const CommandArgumentMap::iterator it = args.find(option);
if (it != args.end())
- it.value().append(QLatin1String(PATH_SPLITTER) + value);
+ it.value().append(pathSplitter + value);
else
args.insert(option, value);
}
@@ -369,7 +289,9 @@ void printUsage()
s << "Usage:\n "
<< "shiboken [options] header-file typesystem-file\n\n"
<< "General options:\n";
- const QString pathSyntax = QLatin1String("<path>[" PATH_SPLITTER "<path>" PATH_SPLITTER "...]");
+ QString pathSyntax;
+ QTextStream(&pathSyntax) << "<path>[" << pathSplitter << "<path>"
+ << pathSplitter << "...]";
OptionDescriptions generalOptions = OptionDescriptions()
<< qMakePair(QLatin1String("api-version=<\"package mask\">,<\"version\">"),
QLatin1String("Specify the supported api version used to generate the bindings"))
@@ -380,18 +302,22 @@ void printUsage()
<< qMakePair(QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
QLatin1String("Semicolon separated list of type system entries (classes, namespaces,\n"
"global functions and enums) to be dropped from generation."))
- << qMakePair(QLatin1String("-F") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-F<path>"), QString())
<< qMakePair(QLatin1String("framework-include-paths=") + pathSyntax,
QLatin1String("Framework include paths used by the C++ parser"))
- << qMakePair(QLatin1String("-isystem") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-isystem<path>"), QString())
<< qMakePair(QLatin1String("system-include-paths=") + pathSyntax,
QLatin1String("System include paths used by the C++ parser"))
<< qMakePair(QLatin1String("generator-set=<\"generator module\">"),
QLatin1String("generator-set to be used. e.g. qtdoc"))
+ << qMakePair(diffOption(),
+ QLatin1String("Print a diff of wrapper files"))
+ << qMakePair(dryrunOption(),
+ QLatin1String("Dry run, do not generate wrapper files"))
<< qMakePair(QLatin1String("-h"), QString())
<< qMakePair(helpOption(),
QLatin1String("Display this help and exit"))
- << qMakePair(QLatin1String("-I") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-I<path>"), QString())
<< qMakePair(QLatin1String("include-paths=") + pathSyntax,
QLatin1String("Include paths used by the C++ parser"))
<< qMakePair(languageLevelOption() + QLatin1String("=, -std=<level>"),
@@ -407,7 +333,7 @@ void printUsage()
"Replaces and overrides command line arguments"))
<< qMakePair(QLatin1String("silent"),
QLatin1String("Avoid printing any message"))
- << qMakePair(QLatin1String("-T") + pathSyntax, QString())
+ << qMakePair(QLatin1String("-T<path>"), QString())
<< qMakePair(QLatin1String("typesystem-paths=") + pathSyntax,
QLatin1String("Paths used when searching for typesystems"))
<< qMakePair(QLatin1String("version"),
@@ -438,19 +364,15 @@ static inline void errorPrint(const QString& s)
<< "\nCommand line: " << qPrintable(arguments.join(QLatin1Char(' '))) << '\n';
}
-static QString msgInvalidVersion(const QString &package, const QString &version)
-{
- return QLatin1String("Invalid version \"") + version
- + QLatin1String("\" specified for package ") + package + QLatin1Char('.');
-}
-
static void parseIncludePathOption(const QString &option, HeaderType headerType,
- ArgsHandler &args,
+ CommandArgumentMap &args,
ApiExtractor &extractor)
{
- const QString path = args.removeArg(option);
- if (!path.isEmpty()) {
- const QStringList includePathListList = path.split(QLatin1String(PATH_SPLITTER));
+ const CommandArgumentMap::iterator it = args.find(option);
+ if (it != args.end()) {
+ const QStringList includePathListList =
+ it.value().split(pathSplitter, QString::SkipEmptyParts);
+ args.erase(it);
for (const QString &s : includePathListList)
extractor.addIncludePath(HeaderPath{QFile::encodeName(s), headerType});
}
@@ -469,19 +391,24 @@ int main(int argc, char *argv[])
qCDebug(lcShiboken()).noquote().nospace() << QCoreApplication::arguments().join(QLatin1Char(' '));
// Store command arguments in a map
- QMap<QString, QString> args = getCommandLineArgs();
- ArgsHandler argsHandler(args);
+ CommandArgumentMap args = getCommandLineArgs();
Generators generators;
- if (argsHandler.argExistsRemove(QLatin1String("version"))) {
+ CommandArgumentMap::iterator ait = args.find(QLatin1String("version"));
+ if (ait != args.end()) {
+ args.erase(ait);
printVerAndBanner();
return EXIT_SUCCESS;
}
- QString generatorSet = argsHandler.removeArg(QLatin1String("generator-set"));
- // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
- if (generatorSet.isEmpty())
- generatorSet = argsHandler.removeArg(QLatin1String("generatorSet"));
+ QString generatorSet;
+ ait = args.find(QLatin1String("generator-set"));
+ if (ait == args.end()) // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
+ ait = args.find(QLatin1String("generatorSet"));
+ if (ait != args.end()) {
+ generatorSet = ait.value();
+ args.erase(ait);
+ }
// Pre-defined generator sets.
if (generatorSet == QLatin1String("qtdoc")) {
@@ -497,28 +424,45 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
- if (argsHandler.argExistsRemove(QLatin1String("help"))) {
+ ait = args.find(QLatin1String("help"));
+ if (ait != args.end()) {
+ args.erase(ait);
printUsage();
return EXIT_SUCCESS;
}
+ ait = args.find(diffOption());
+ if (ait != args.end()) {
+ args.erase(ait);
+ FileOut::diff = true;
+ }
+
+ ait = args.find(dryrunOption());
+ if (ait != args.end()) {
+ args.erase(ait);
+ FileOut::dummy = true;
+ }
+
QString licenseComment;
- QString licenseFileName = argsHandler.removeArg(QLatin1String("license-file"));
- if (!licenseFileName.isEmpty()) {
- if (QFile::exists(licenseFileName)) {
- QFile licenseFile(licenseFileName);
- if (licenseFile.open(QIODevice::ReadOnly))
- licenseComment = QString::fromUtf8(licenseFile.readAll());
+ ait = args.find(QLatin1String("license-file"));
+ if (ait != args.end()) {
+ QFile licenseFile(ait.value());
+ args.erase(ait);
+ if (licenseFile.open(QIODevice::ReadOnly)) {
+ licenseComment = QString::fromUtf8(licenseFile.readAll());
} else {
- errorPrint(QStringLiteral("Couldn't find the file containing the license heading: %1").
- arg(licenseFileName));
+ errorPrint(QStringLiteral("Could not open the file \"%1\" containing the license heading: %2").
+ arg(QDir::toNativeSeparators(licenseFile.fileName()), licenseFile.errorString()));
return EXIT_FAILURE;
}
}
- QString outputDirectory = argsHandler.removeArg(QLatin1String("output-directory"));
- if (outputDirectory.isEmpty())
- outputDirectory = QLatin1String("out");
+ QString outputDirectory = QLatin1String("out");
+ ait = args.find(QLatin1String("output-directory"));
+ if (ait != args.end()) {
+ outputDirectory = ait.value();
+ args.erase(ait);
+ }
if (!QDir(outputDirectory).exists()) {
if (!QDir().mkpath(outputDirectory)) {
@@ -532,11 +476,15 @@ int main(int argc, char *argv[])
ApiExtractor extractor;
extractor.setLogDirectory(outputDirectory);
- if (argsHandler.argExistsRemove(QLatin1String("silent"))) {
+ ait = args.find(QLatin1String("silent"));
+ if (ait != args.end()) {
extractor.setSilent(true);
+ args.erase(ait);
} else {
- QString level = argsHandler.removeArg(QLatin1String("debug-level"));
- if (!level.isEmpty()) {
+ ait = args.find(QLatin1String("debug-level"));
+ if (ait != args.end()) {
+ const QString level = ait.value();
+ args.erase(ait);
if (level == QLatin1String("sparse"))
extractor.setDebugLevel(ReportHandler::SparseDebug);
else if (level == QLatin1String("medium"))
@@ -545,11 +493,15 @@ int main(int argc, char *argv[])
extractor.setDebugLevel(ReportHandler::FullDebug);
}
}
- if (argsHandler.argExistsRemove(QLatin1String("no-suppress-warnings")))
+ ait = args.find(QLatin1String("no-suppress-warnings"));
+ if (ait != args.end()) {
+ args.erase(ait);
extractor.setSuppressWarnings(false);
-
- if (argsHandler.argExists(QLatin1String("api-version"))) {
- const QStringList &versions = argsHandler.removeArg(QLatin1String("api-version")).split(QLatin1Char('|'));
+ }
+ ait = args.find(QLatin1String("api-version"));
+ if (ait != args.end()) {
+ const QStringList &versions = ait.value().split(QLatin1Char('|'));
+ args.erase(ait);
for (const QString &fullVersion : versions) {
QStringList parts = fullVersion.split(QLatin1Char(','));
QString package;
@@ -563,54 +515,65 @@ int main(int argc, char *argv[])
}
}
- if (argsHandler.argExists(QLatin1String("drop-type-entries")))
- extractor.setDropTypeEntries(argsHandler.removeArg(QLatin1String("drop-type-entries")));
+ ait = args.find(QLatin1String("drop-type-entries"));
+ if (ait != args.end()) {
+ extractor.setDropTypeEntries(ait.value());
+ args.erase(ait);
+ }
- QString path = argsHandler.removeArg(QLatin1String("typesystem-paths"));
- if (!path.isEmpty())
- extractor.addTypesystemSearchPath(path.split(QLatin1String(PATH_SPLITTER)));
+ ait = args.find(QLatin1String("typesystem-paths"));
+ if (ait != args.end()) {
+ extractor.addTypesystemSearchPath(ait.value().split(pathSplitter));
+ args.erase(ait);
+ }
parseIncludePathOption(includePathOption(), HeaderType::Standard,
- argsHandler, extractor);
+ args, extractor);
parseIncludePathOption(frameworkIncludePathOption(), HeaderType::Framework,
- argsHandler, extractor);
+ args, extractor);
parseIncludePathOption(systemIncludePathOption(), HeaderType::System,
- argsHandler, extractor);
+ args, extractor);
- QString cppFileName = argsHandler.removeArg(QLatin1String("arg-1"));
+ ait = args.find(QLatin1String("arg-1"));
+ if (ait == args.end()) {
+ errorPrint(QLatin1String("Required argument header-file is missing."));
+ return EXIT_FAILURE;
+ }
+ const QString cppFileName = ait.value();
+ args.erase(ait);
const QFileInfo cppFileNameFi(cppFileName);
if (!cppFileNameFi.isFile() && !cppFileNameFi.isSymLink()) {
errorPrint(QLatin1Char('"') + cppFileName + QLatin1String("\" does not exist."));
return EXIT_FAILURE;
}
- QString typeSystemFileName = argsHandler.removeArg(QLatin1String("arg-2"));
+ ait = args.find(QLatin1String("arg-2"));
+ if (ait == args.end()) {
+ errorPrint(QLatin1String("Required argument typesystem-file is missing."));
+ return EXIT_FAILURE;
+ }
+ const QString typeSystemFileName = ait.value();
+ args.erase(ait);
QString messagePrefix = QFileInfo(typeSystemFileName).baseName();
if (messagePrefix.startsWith(QLatin1String("typesystem_")))
messagePrefix.remove(0, 11);
ReportHandler::setPrefix(QLatin1Char('(') + messagePrefix + QLatin1Char(')'));
- /* Make sure to remove the project file's arguments (if any) and
- * --project-file, also the arguments of each generator before
- * checking if there isn't any existing arguments in argsHandler.
- */
- argsHandler.removeArg(QLatin1String("project-file"));
- QMap<QString, QString> projectFileArgs = getInitializedArguments();
- if (!projectFileArgs.isEmpty()) {
- QMap<QString, QString>::const_iterator it =
- projectFileArgs.constBegin();
- for ( ; it != projectFileArgs.constEnd(); ++it)
- argsHandler.removeArg(it.key());
- }
- for (const GeneratorPtr &generator : qAsConst(generators)) {
- const OptionDescriptions &options = generator->options();
- for (const auto &od : options)
- argsHandler.removeArg(od.first);
- }
-
- const QString languageLevel = argsHandler.removeArg(languageLevelOption());
- if (!languageLevel.isEmpty()) {
- const QByteArray languageLevelBA = languageLevel.toLatin1();
+ // Pass option to all generators (Cpp/Header generator have the same options)
+ for (ait = args.begin(); ait != args.end(); ) {
+ bool found = false;
+ for (const GeneratorPtr &generator : qAsConst(generators))
+ found |= generator->handleOption(ait.key(), ait.value());
+ if (found)
+ ait = args.erase(ait);
+ else
+ ++ait;
+ }
+
+ ait = args.find(languageLevelOption());
+ if (ait != args.end()) {
+ const QByteArray languageLevelBA = ait.value().toLatin1();
+ args.erase(ait);
const LanguageLevel level = clang::languageLevelFromOption(languageLevelBA.constData());
if (level == LanguageLevel::Default) {
std::cout << "Invalid argument for language level: \""
@@ -620,8 +583,17 @@ int main(int argc, char *argv[])
extractor.setLanguageLevel(level);
}
- if (!argsHandler.noArgs()) {
- errorPrint(argsHandler.errorMessage());
+ /* Make sure to remove the project file's arguments (if any) and
+ * --project-file, also the arguments of each generator before
+ * checking if there isn't any existing arguments in argsHandler.
+ */
+ args.remove(QLatin1String("project-file"));
+ CommandArgumentMap projectFileArgs = getInitializedArguments();
+ for (auto it = projectFileArgs.cbegin(), end = projectFileArgs.cend(); it != end; ++it)
+ args.remove(it.key());
+
+ if (!args.isEmpty()) {
+ errorPrint(msgLeftOverArguments(args));
std::cout << helpHint;
return EXIT_FAILURE;
}
@@ -642,17 +614,16 @@ int main(int argc, char *argv[])
if (!extractor.classCount())
qCWarning(lcShiboken) << "No C++ classes found!";
- qCDebug(lcShiboken) << extractor;
+ qCDebug(lcShiboken) << extractor << '\n'
+ << *TypeDatabase::instance();
for (const GeneratorPtr &g : qAsConst(generators)) {
g->setOutputDirectory(outputDirectory);
g->setLicenseComment(licenseComment);
- if (g->setup(extractor, args)) {
- if (!g->generate()) {
- errorPrint(QLatin1String("Error running generator: ")
- + QLatin1String(g->name()) + QLatin1Char('.'));
- return EXIT_FAILURE;
- }
+ if (!g->setup(extractor) || !g->generate()) {
+ errorPrint(QLatin1String("Error running generator: ")
+ + QLatin1String(g->name()) + QLatin1Char('.'));
+ return EXIT_FAILURE;
}
}
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index d47ba8bd7..19ddd5f37 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -28,6 +28,7 @@
#include "qtdocgenerator.h"
#include <abstractmetalang.h>
+#include <messages.h>
#include <reporthandler.h>
#include <typesystem.h>
#include <qtdocparser.h>
@@ -202,34 +203,6 @@ private:
const QString &m_label;
};
-static QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
- const QString &tag, const QString &message)
-{
- QString result;
- QTextStream str(&result);
- str << "While handling <";
- const QStringRef currentTag = reader.name();
- if (currentTag.isEmpty())
- str << tag;
- else
- str << currentTag;
- str << "> in " << context << ", line "<< reader.lineNumber()
- << ": " << message;
- return result;
-}
-
-static QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context,
- const QString &tag, const QString &location, const QString &identifier,
- const QString &fallback)
-{
- QString message = QLatin1String("Falling back to \"")
- + QDir::toNativeSeparators(fallback) + QLatin1String("\" for \"") + location
- + QLatin1Char('"');
- if (!identifier.isEmpty())
- message += QLatin1String(" [") + identifier + QLatin1Char(']');
- return msgTagWarning(reader, context, tag, message);
-}
-
struct QtXmlToSphinx::LinkContext
{
enum Type
@@ -305,7 +278,7 @@ QTextStream &operator<<(QTextStream &str, const QtXmlToSphinx::LinkContext &link
}
QtXmlToSphinx::QtXmlToSphinx(QtDocGenerator* generator, const QString& doc, const QString& context)
- : m_context(context), m_generator(generator), m_insideBold(false), m_insideItalic(false)
+ : m_tableHasHeader(false), m_context(context), m_generator(generator), m_insideBold(false), m_insideItalic(false)
{
m_handlerMap.insert(QLatin1String("heading"), &QtXmlToSphinx::handleHeadingTag);
m_handlerMap.insert(QLatin1String("brief"), &QtXmlToSphinx::handleParaTag);
@@ -1302,7 +1275,7 @@ bool QtXmlToSphinx::convertToRst(QtDocGenerator *generator,
QFile sourceFile(sourceFileName);
if (!sourceFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
if (errorMessage)
- *errorMessage = FileOut::msgCannotOpenForReading(sourceFile);
+ *errorMessage = msgCannotOpenForReading(sourceFile);
return false;
}
const QString doc = QString::fromUtf8(sourceFile.readAll());
@@ -1325,7 +1298,13 @@ void QtXmlToSphinx::Table::normalize()
//QDoc3 generates tables with wrong number of columns. We have to
//check and if necessary, merge the last columns.
- int maxCols = self.at(0).count();
+ int maxCols = -1;
+ for (const auto &row : qAsConst(self)) {
+ if (row.count() > maxCols)
+ maxCols = row.count();
+ }
+ if (maxCols <= 0)
+ return;
// add col spans
for (row = 0; row < count(); ++row) {
for (col = 0; col < at(row).count(); ++col) {
@@ -1513,11 +1492,10 @@ QString QtDocGenerator::fileNameForContext(GeneratorContext &context) const
const AbstractMetaClass *metaClass = context.metaClass();
if (!context.forSmartPointer()) {
return getClassTargetFullName(metaClass, false) + fileNameSuffix();
- } else {
- const AbstractMetaType *smartPointerType = context.preciseType();
- QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass);
- return fileNameBase + fileNameSuffix();
}
+ const AbstractMetaType *smartPointerType = context.preciseType();
+ QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass);
+ return fileNameBase + fileNameSuffix();
}
void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc,
@@ -1534,7 +1512,7 @@ void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc
} else {
const QString &value = doc.value();
const QVector<QStringRef> lines = value.splitRef(QLatin1Char('\n'));
- int typesystemIndentation = std::numeric_limits<int>().max();
+ int typesystemIndentation = std::numeric_limits<int>::max();
// check how many spaces must be removed from the beginning of each line
for (const QStringRef &line : lines) {
const auto it = std::find_if(line.cbegin(), line.cend(),
@@ -1542,7 +1520,7 @@ void QtDocGenerator::writeFormattedText(QTextStream &s, const Documentation &doc
if (it != line.cend())
typesystemIndentation = qMin(typesystemIndentation, int(it - line.cbegin()));
}
- if (typesystemIndentation == std::numeric_limits<int>().max())
+ if (typesystemIndentation == std::numeric_limits<int>::max())
typesystemIndentation = 0;
for (const QStringRef &line : lines) {
s << INDENT
@@ -1677,7 +1655,7 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
functionList << str;
}
- if ((functionList.size() > 0) || (staticFunctionList.size() > 0)) {
+ if (!functionList.isEmpty() || !staticFunctionList.isEmpty()) {
QtXmlToSphinx::Table functionTable;
s << endl
@@ -1694,7 +1672,7 @@ void QtDocGenerator::writeFunctionList(QTextStream& s, const AbstractMetaClass*
void QtDocGenerator::writeFunctionBlock(QTextStream& s, const QString& title, QStringList& functions)
{
- if (functions.size() > 0) {
+ if (!functions.isEmpty()) {
s << title << endl
<< QString(title.size(), QLatin1Char('^')) << endl;
@@ -1777,7 +1755,8 @@ void QtDocGenerator::writeConstructors(QTextStream& s, const AbstractMetaClass*
writeFormattedText(s, func->documentation(), cppClass);
}
-QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* cppClass, const AbstractMetaFunction* func)
+QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */,
+ const AbstractMetaFunction* func)
{
QString ret;
int optArgs = 0;
@@ -1859,8 +1838,7 @@ void QtDocGenerator::writeDocSnips(QTextStream &s,
if (row.trimmed().size() == 0) {
if (currenRow == 0)
continue;
- else
- s << endl;
+ s << endl;
}
if (currenRow == 0) {
@@ -2124,7 +2102,7 @@ void QtDocGenerator::writeModuleDocumentation()
s << ".. module:: " << it.key() << endl << endl;
- QString title = it.key();
+ const QString &title = it.key();
s << title << endl;
s << Pad('*', title.length()) << endl << endl;
@@ -2201,7 +2179,7 @@ void QtDocGenerator::writeAdditionalDocumentation()
QFile additionalDocumentationFile(m_additionalDocumentationList);
if (!additionalDocumentationFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(lcShiboken, "%s",
- qPrintable(FileOut::msgCannotOpenForReading(additionalDocumentationFile)));
+ qPrintable(msgCannotOpenForReading(additionalDocumentationFile)));
return;
}
@@ -2261,32 +2239,28 @@ void QtDocGenerator::writeAdditionalDocumentation()
successCount, count);
}
-bool QtDocGenerator::doSetup(const QMap<QString, QString>& args)
-{
- m_libSourceDir = args.value(QLatin1String("library-source-dir"));
- m_docDataDir = args.value(QLatin1String("documentation-data-dir"));
#ifdef __WIN32__
# define PATH_SEP ';'
#else
# define PATH_SEP ':'
#endif
- m_codeSnippetDirs = args.value(QLatin1String("documentation-code-snippets-dir"), m_libSourceDir).split(QLatin1Char(PATH_SEP));
- m_extraSectionDir = args.value(QLatin1String("documentation-extra-sections-dir"));
- m_docParser = args.value(QLatin1String("doc-parser")) == QLatin1String("doxygen")
- ? static_cast<DocParser*>(new DoxygenParser)
- : static_cast<DocParser*>(new QtDocParser);
- qCDebug(lcShiboken).noquote().nospace() << "doc-parser: " << args.value(QLatin1String("doc-parser"));
+bool QtDocGenerator::doSetup()
+{
+ if (m_codeSnippetDirs.isEmpty())
+ m_codeSnippetDirs = m_libSourceDir.split(QLatin1Char(PATH_SEP));
+
+ if (!m_docParser)
+ m_docParser = new QtDocParser;
if (m_libSourceDir.isEmpty() || m_docDataDir.isEmpty()) {
qCWarning(lcShiboken) << "Documentation data dir and/or Qt source dir not informed, "
"documentation will not be extracted from Qt sources.";
return false;
- } else {
- m_docParser->setDocumentationDataDirectory(m_docDataDir);
- m_docParser->setLibrarySourceDirectory(m_libSourceDir);
}
- m_additionalDocumentationList = args.value(additionalDocumentationOption());
+
+ m_docParser->setDocumentationDataDirectory(m_docDataDir);
+ m_docParser->setLibrarySourceDirectory(m_libSourceDir);
return true;
}
@@ -2294,19 +2268,49 @@ bool QtDocGenerator::doSetup(const QMap<QString, QString>& args)
Generator::OptionDescriptions QtDocGenerator::options() const
{
return OptionDescriptions()
- << qMakePair(QLatin1String("doc-parser"),
+ << qMakePair(QLatin1String("doc-parser=<parser>"),
QLatin1String("The documentation parser used to interpret the documentation\n"
"input files (qdoc|doxygen)"))
- << qMakePair(QLatin1String("documentation-code-snippets-dir"),
+ << qMakePair(QLatin1String("documentation-code-snippets-dir=<dir>"),
QLatin1String("Directory used to search code snippets used by the documentation"))
- << qMakePair(QLatin1String("documentation-data-dir"),
+ << qMakePair(QLatin1String("documentation-data-dir=<dir>"),
QLatin1String("Directory with XML files generated by documentation tool"))
- << qMakePair(QLatin1String("documentation-extra-sections-dir"),
+ << qMakePair(QLatin1String("documentation-extra-sections-dir=<dir>"),
QLatin1String("Directory used to search for extra documentation sections"))
- << qMakePair(QLatin1String("library-source-dir"),
+ << qMakePair(QLatin1String("library-source-dir=<dir>"),
QLatin1String("Directory where library source code is located"))
- << qMakePair(additionalDocumentationOption(),
+ << qMakePair(additionalDocumentationOption() + QLatin1String("=<file>"),
QLatin1String("List of additional XML files to be converted to .rst files\n"
"(for example, tutorials)."));
}
+bool QtDocGenerator::handleOption(const QString &key, const QString &value)
+{
+ if (key == QLatin1String("library-source-dir")) {
+ m_libSourceDir = value;
+ return true;
+ }
+ if (key == QLatin1String("documentation-data-dir")) {
+ m_docDataDir = value;
+ return true;
+ }
+ if (key == QLatin1String("documentation-code-snippets-dir")) {
+ m_codeSnippetDirs = value.split(QLatin1Char(PATH_SEP));
+ return true;
+ }
+ if (key == QLatin1String("documentation-extra-sections-dir")) {
+ m_extraSectionDir = value;
+ return true;
+ }
+ if (key == QLatin1String("doc-parser")) {
+ qCDebug(lcShiboken).noquote().nospace() << "doc-parser: " << value;
+ if (value == QLatin1String("doxygen"))
+ m_docParser = new DoxygenParser;
+ return true;
+ }
+ if (key == additionalDocumentationOption()) {
+ m_additionalDocumentationList = value;
+ return true;
+ }
+ return false;
+}
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
index e467abe90..5545de9a9 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
@@ -209,7 +209,7 @@ public:
QString docDataDir() const { return m_docDataDir; }
- bool doSetup(const QMap<QString, QString>& args) override;
+ bool doSetup() override;
const char* name() const override
{
@@ -217,15 +217,15 @@ public:
}
OptionDescriptions options() const override;
+ bool handleOption(const QString &key, const QString &value) override;
QStringList codeSnippetDirs() const
{
return m_codeSnippetDirs;
}
- bool shouldGenerate(const AbstractMetaClass *) const override;
-
protected:
+ bool shouldGenerate(const AbstractMetaClass *) const override;
QString fileNameSuffix() const override;
QString fileNameForContext(GeneratorContext &context) const override;
void generateClass(QTextStream &s, GeneratorContext &classContext) override;
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 9e1d6926e..adec70dd7 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -29,8 +29,10 @@
#include <memory>
#include "cppgenerator.h"
+#include "fileout.h"
#include "overloaddata.h"
#include <abstractmetalang.h>
+#include <messages.h>
#include <reporthandler.h>
#include <typedatabase.h>
@@ -41,6 +43,8 @@
#include <QtCore/QDebug>
#include <QMetaType>
+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>();
@@ -58,6 +62,28 @@ inline AbstractMetaType* getTypeWithoutContainer(AbstractMetaType* arg)
return arg;
}
+// A helper for writing C++ return statements for either void ("return;")
+// or some return value ("return value;")
+class returnStatement
+{
+public:
+ explicit returnStatement(QString s) : m_returnValue(std::move(s)) {}
+
+ friend QTextStream &operator<<(QTextStream &s, const returnStatement &r);
+
+private:
+ const QString m_returnValue;
+};
+
+QTextStream &operator<<(QTextStream &s, const returnStatement &r)
+{
+ s << "return";
+ if (!r.m_returnValue.isEmpty())
+ s << ' ' << r.m_returnValue;
+ s << ';';
+ return s;
+}
+
CppGenerator::CppGenerator()
{
// Number protocol structure members names
@@ -87,27 +113,27 @@ CppGenerator::CppGenerator()
m_nbFuncs.insert(QLatin1String("bool"), QLatin1String("nb_nonzero"));
// sequence protocol functions
- typedef QPair<QString, QString> StrPair;
m_sequenceProtocol.insert(QLatin1String("__len__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR), QLatin1String("Py_ssize_t")));
+ {QLatin1String("PyObject* self"),
+ QLatin1String("Py_ssize_t")});
m_sequenceProtocol.insert(QLatin1String("__getitem__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", Py_ssize_t _i"),
- QLatin1String("PyObject*")));
+ {QLatin1String("PyObject* self, Py_ssize_t _i"),
+ QLatin1String("PyObject*")});
m_sequenceProtocol.insert(QLatin1String("__setitem__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", Py_ssize_t _i, PyObject* _value"),
- QLatin1String("int")));
+ {QLatin1String("PyObject* self, Py_ssize_t _i, PyObject* _value"),
+ QLatin1String("int")});
m_sequenceProtocol.insert(QLatin1String("__getslice__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", Py_ssize_t _i1, Py_ssize_t _i2"),
- QLatin1String("PyObject*")));
+ {QLatin1String("PyObject* self, Py_ssize_t _i1, Py_ssize_t _i2"),
+ QLatin1String("PyObject*")});
m_sequenceProtocol.insert(QLatin1String("__setslice__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", Py_ssize_t _i1, Py_ssize_t _i2, PyObject* _value"),
- QLatin1String("int")));
+ {QLatin1String("PyObject* self, Py_ssize_t _i1, Py_ssize_t _i2, PyObject* _value"),
+ QLatin1String("int")});
m_sequenceProtocol.insert(QLatin1String("__contains__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", PyObject* _value"),
- QLatin1String("int")));
+ {QLatin1String("PyObject* self, PyObject* _value"),
+ QLatin1String("int")});
m_sequenceProtocol.insert(QLatin1String("__concat__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", PyObject* _other"),
- QLatin1String("PyObject*")));
+ {QLatin1String("PyObject* self, PyObject* _other"),
+ QLatin1String("PyObject*")});
// Sequence protocol structure members names
m_sqFuncs.insert(QLatin1String("__concat__"), QLatin1String("sq_concat"));
@@ -120,14 +146,14 @@ CppGenerator::CppGenerator()
// mapping protocol function
m_mappingProtocol.insert(QLatin1String("__mlen__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR),
- QLatin1String("Py_ssize_t")));
+ {QLatin1String("PyObject* self"),
+ QLatin1String("Py_ssize_t")});
m_mappingProtocol.insert(QLatin1String("__mgetitem__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", PyObject* _key"),
- QLatin1String("PyObject*")));
+ {QLatin1String("PyObject* self, PyObject* _key"),
+ QLatin1String("PyObject*")});
m_mappingProtocol.insert(QLatin1String("__msetitem__"),
- StrPair(QLatin1String("PyObject* " PYTHON_SELF_VAR ", PyObject* _key, PyObject* _value"),
- QLatin1String("int")));
+ {QLatin1String("PyObject* self, PyObject* _key, PyObject* _value"),
+ QLatin1String("int")});
// Sequence protocol structure members names
m_mpFuncs.insert(QLatin1String("__mlen__"), QLatin1String("mp_length"));
@@ -186,18 +212,19 @@ QVector<AbstractMetaFunctionList> CppGenerator::filterGroupedOperatorFunctions(c
return result;
}
-bool CppGenerator::hasBoolCast(const AbstractMetaClass* metaClass) const
+const AbstractMetaFunction *CppGenerator::boolCast(const AbstractMetaClass* metaClass) const
{
if (!useIsNullAsNbNonZero())
- return false;
+ return nullptr;
// TODO: This could be configurable someday
const AbstractMetaFunction* func = metaClass->findFunction(QLatin1String("isNull"));
if (!func || !func->type() || !func->type()->typeEntry()->isPrimitive() || !func->isPublic())
- return false;
+ return nullptr;
const PrimitiveTypeEntry* pte = static_cast<const PrimitiveTypeEntry*>(func->type()->typeEntry());
while (pte->referencedTypeEntry())
pte = pte->referencedTypeEntry();
- return func && func->isConstant() && pte->name() == QLatin1String("bool") && func->arguments().isEmpty();
+ return func && func->isConstant() && pte->name() == QLatin1String("bool")
+ && func->arguments().isEmpty() ? func : nullptr;
}
typedef QMap<QString, AbstractMetaFunctionList> FunctionGroupMap;
@@ -219,6 +246,21 @@ static QString chopType(QString s)
return s;
}
+// Helper for field setters: Check for "const QWidget *" (settable field),
+// but not "int *const" (read-only field).
+static bool isPointerToConst(const AbstractMetaType *t)
+{
+ const AbstractMetaType::Indirections &indirections = t->indirectionsV();
+ return t->isConstant() && !indirections.isEmpty()
+ && indirections.constLast() != Indirection::ConstPointer;
+}
+
+static inline bool canGenerateFieldSetter(const AbstractMetaField *field)
+{
+ const AbstractMetaType *type = field->type();
+ return !type->isConstant() || isPointerToConst(type);
+}
+
/*!
Function used to write the class generated binding code on the buffer
\param s the output buffer
@@ -260,6 +302,8 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
// needs the 'set' class from C++ STL.
if (hasMultipleInheritanceInAncestry(metaClass))
s << "#include <set>" << endl;
+ if (metaClass->generateExceptionHandling())
+ s << "#include <exception>" << endl;
s << endl << "// module include" << endl << "#include \"" << getModuleHeaderFileName() << '"' << endl;
@@ -315,7 +359,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
static_cast<const SmartPointerTypeEntry *>(classContext.preciseType()
->typeEntry());
QString rawGetter = typeEntry->getter();
- s << "static const char * " SMART_POINTER_GETTER " = \"" << rawGetter << "\";";
+ s << "static const char * " << SMART_POINTER_GETTER << " = \"" << rawGetter << "\";";
}
// class inject-code native/beginning
@@ -459,7 +503,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
writeCopyFunction(s, classContext);
- signatureStream << metaClass->fullName() << ".__copy__()" << endl;
+ signatureStream << fullPythonClassName(metaClass) << ".__copy__()" << endl;
}
// Write single method definitions
@@ -490,16 +534,20 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
}
}
- if (hasBoolCast(metaClass)) {
+ if (const AbstractMetaFunction *f = boolCast(metaClass)) {
ErrorCode errorCode(-1);
- s << "static int " << cpythonBaseName(metaClass) << "___nb_bool(PyObject* " PYTHON_SELF_VAR ")" << endl;
+ s << "static int " << cpythonBaseName(metaClass) << "___nb_bool(PyObject* self)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, classContext);
- s << INDENT << "int result;" << endl;
- s << INDENT << BEGIN_ALLOW_THREADS << endl;
- s << INDENT << "result = !" CPP_SELF_VAR "->isNull();" << endl;
- s << INDENT << END_ALLOW_THREADS << endl;
- s << INDENT << "return result;" << endl;
+ if (f->allowThread()) {
+ s << INDENT << "int result;" << endl;
+ s << INDENT << BEGIN_ALLOW_THREADS << endl;
+ s << INDENT << "result = !" << CPP_SELF_VAR << "->isNull();" << endl;
+ s << INDENT << END_ALLOW_THREADS << endl;
+ s << INDENT << "return result;" << endl;
+ } else {
+ s << INDENT << "return !" << CPP_SELF_VAR << "->isNull();" << endl;
+ }
s << '}' << endl << endl;
}
@@ -546,7 +594,7 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (metaField->isStatic())
continue;
writeGetterFunction(s, metaField, classContext);
- if (!metaField->type()->isConstant())
+ if (canGenerateFieldSetter(metaField))
writeSetterFunction(s, metaField, classContext);
s << endl;
}
@@ -557,10 +605,12 @@ void CppGenerator::generateClass(QTextStream &s, GeneratorContext &classContext)
if (metaField->isStatic())
continue;
- bool hasSetter = !metaField->type()->isConstant();
s << INDENT << "{const_cast<char*>(\"" << metaField->name() << "\"), ";
- s << cpythonGetterFunctionName(metaField);
- s << ", " << (hasSetter ? cpythonSetterFunctionName(metaField) : QLatin1String("0"));
+ s << cpythonGetterFunctionName(metaField) << ", ";
+ if (canGenerateFieldSetter(metaField))
+ s << cpythonSetterFunctionName(metaField);
+ else
+ s << '0';
s << "}," << endl;
}
s << INDENT << "{0} // Sentinel" << endl;
@@ -686,7 +736,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
Indentation indentation(INDENT);
- QString defaultReturnExpr;
+ DefaultValue defaultReturnExpr;
if (retType) {
const FunctionModificationList &mods = func->modifications();
for (const FunctionModification &mod : mods) {
@@ -694,9 +744,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
if (argMod.index == 0 && !argMod.replacedDefaultExpression.isEmpty()) {
static const QRegularExpression regex(QStringLiteral("%(\\d+)"));
Q_ASSERT(regex.isValid());
- defaultReturnExpr = argMod.replacedDefaultExpression;
+ QString expr = argMod.replacedDefaultExpression;
for (int offset = 0; ; ) {
- const QRegularExpressionMatch match = regex.match(defaultReturnExpr, offset);
+ const QRegularExpressionMatch match = regex.match(expr, offset);
if (!match.hasMatch())
break;
const int argId = match.capturedRef(1).toInt() - 1;
@@ -704,23 +754,27 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
qCWarning(lcShiboken) << "The expression used in return value contains an invalid index.";
break;
}
- defaultReturnExpr.replace(match.captured(0), func->arguments().at(argId)->name());
+ expr.replace(match.captured(0), func->arguments().at(argId)->name());
offset = match.capturedStart(1);
}
+ defaultReturnExpr.setType(DefaultValue::Custom);
+ defaultReturnExpr.setValue(expr);
}
}
}
- if (defaultReturnExpr.isEmpty())
+ if (!defaultReturnExpr.isValid())
defaultReturnExpr = minimalConstructor(func->type());
- if (defaultReturnExpr.isEmpty()) {
+ if (!defaultReturnExpr.isValid()) {
QString errorMsg = QLatin1String(__FUNCTION__) + QLatin1String(": ");
if (const AbstractMetaClass *c = func->implementingClass())
errorMsg += c->qualifiedCppName() + QLatin1String("::");
errorMsg += func->signature();
- errorMsg = ShibokenGenerator::msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature());
+ errorMsg = msgCouldNotFindMinimalConstructor(errorMsg, func->type()->cppSignature());
qCWarning(lcShiboken).noquote().nospace() << errorMsg;
s << endl << INDENT << "#error " << errorMsg << endl;
}
+ } else {
+ defaultReturnExpr.setType(DefaultValue::Void);
}
if (func->isAbstract() && func->isModifiedRemoved()) {
@@ -728,7 +782,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
<< QString::fromLatin1("Pure virtual method '%1::%2' must be implement but was "\
"completely removed on type system.")
.arg(func->ownerClass()->name(), func->minimalSignature());
- s << INDENT << "return " << defaultReturnExpr << ';' << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
s << '}' << endl << endl;
return;
}
@@ -747,13 +801,13 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
s << INDENT << "if (PyErr_Occurred())" << endl;
{
Indentation indentation(INDENT);
- s << INDENT << "return " << defaultReturnExpr << ';' << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
}
- s << INDENT << "Shiboken::AutoDecRef " PYTHON_OVERRIDE_VAR "(Shiboken::BindingManager::instance().getOverride(this, \"";
+ s << INDENT << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR << "(Shiboken::BindingManager::instance().getOverride(this, \"";
s << funcName << "\"));" << endl;
- s << INDENT << "if (" PYTHON_OVERRIDE_VAR ".isNull()) {" << endl;
+ s << INDENT << "if (" << PYTHON_OVERRIDE_VAR << ".isNull()) {" << endl;
{
Indentation indentation(INDENT);
CodeSnipList snips;
@@ -768,7 +822,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '";
s << func->ownerClass()->name() << '.' << funcName;
s << "()' not implemented.\");" << endl;
- s << INDENT << "return " << (retType ? defaultReturnExpr : QString());
+ s << INDENT << "return";
+ if (retType)
+ s << ' ' << defaultReturnExpr.returnValue();
} else {
s << INDENT << "gil.release();" << endl;
s << INDENT;
@@ -785,7 +841,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
writeConversionRule(s, func, TypeSystem::TargetLangCode);
- s << INDENT << "Shiboken::AutoDecRef " PYTHON_ARGS "(";
+ s << INDENT << "Shiboken::AutoDecRef " << PYTHON_ARGS << "(";
if (func->arguments().isEmpty() || allArgumentsRemoved(func)) {
s << "PyTuple_New(0));" << endl;
@@ -844,7 +900,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
if (argMod.resetAfterUse && !invalidateArgs.contains(argMod.index)) {
invalidateArgs.insert(argMod.index);
s << INDENT << "bool invalidateArg" << argMod.index;
- s << " = PyTuple_GET_ITEM(" PYTHON_ARGS ", " << argMod.index - 1 << ")->ob_refcnt == 1;" << endl;
+ s << " = PyTuple_GET_ITEM(" << PYTHON_ARGS << ", " << argMod.index - 1 << ")->ob_refcnt == 1;" << endl;
} else if (argMod.index == 0 && argMod.ownerships[TypeSystem::TargetLangCode] == TypeSystem::CppOwnership) {
invalidateReturn = true;
}
@@ -866,36 +922,36 @@ 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 << ", NULL));" << endl;
s << INDENT << "// An error happened in python code!" << endl;
- s << INDENT << "if (" PYTHON_RETURN_VAR ".isNull()) {" << endl;
+ s << INDENT << "if (" << PYTHON_RETURN_VAR << ".isNull()) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "PyErr_Print();" << endl;
- s << INDENT << "return " << defaultReturnExpr << ';' << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
}
s << INDENT << '}' << endl;
if (retType) {
if (invalidateReturn)
- s << INDENT << "bool invalidateArg0 = " PYTHON_RETURN_VAR "->ob_refcnt == 1;" << endl;
+ s << INDENT << "bool invalidateArg0 = " << PYTHON_RETURN_VAR << "->ob_refcnt == 1;" << endl;
if (func->typeReplaced(0) != QLatin1String("PyObject")) {
s << INDENT << "// Check return type" << endl;
s << INDENT;
if (func->typeReplaced(0).isEmpty()) {
- s << "PythonToCppFunc " PYTHON_TO_CPP_VAR " = " << cpythonIsConvertibleFunction(func->type());
- s << PYTHON_RETURN_VAR ");" << endl;
- s << INDENT << "if (!" PYTHON_TO_CPP_VAR ") {" << endl;
+ s << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << " = " << cpythonIsConvertibleFunction(func->type());
+ s << PYTHON_RETURN_VAR << ");" << endl;
+ s << INDENT << "if (!" << PYTHON_TO_CPP_VAR << ") {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "Shiboken::warning(PyExc_RuntimeWarning, 2, "\
"\"Invalid return value in function %s, expected %s, got %s.\", \"";
s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func);
- s << ", Py_TYPE(" PYTHON_RETURN_VAR ")->tp_name);" << endl;
- s << INDENT << "return " << defaultReturnExpr << ';' << endl;
+ s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);" << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
}
s << INDENT << '}' << endl;
@@ -907,15 +963,16 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
isNumber(func->type()->typeEntry()), func->typeReplaced(0));
s << ';' << endl;
s << INDENT << "if (!typeIsValid";
- s << (isPointerToWrapperType(func->type()) ? " && " PYTHON_RETURN_VAR " != Py_None" : "");
+ if (isPointerToWrapperType(func->type()))
+ s << " && " << PYTHON_RETURN_VAR << " != Py_None";
s << ") {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "Shiboken::warning(PyExc_RuntimeWarning, 2, "\
"\"Invalid return value in function %s, expected %s, got %s.\", \"";
s << func->ownerClass()->name() << '.' << funcName << "\", " << getVirtualFunctionReturnTypeName(func);
- s << ", Py_TYPE(" PYTHON_RETURN_VAR ")->tp_name);" << endl;
- s << INDENT << "return " << defaultReturnExpr << ';' << endl;
+ s << ", Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);" << endl;
+ s << INDENT << returnStatement(defaultReturnExpr.returnValue()) << endl;
}
s << INDENT << '}' << endl;
@@ -935,12 +992,12 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
if (invalidateReturn) {
s << INDENT << "if (invalidateArg0)" << endl;
Indentation indentation(INDENT);
- s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR ".object());" << endl;
+ s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR << ".object());" << endl;
}
for (int argIndex : qAsConst(invalidateArgs)) {
s << INDENT << "if (invalidateArg" << argIndex << ')' << endl;
Indentation indentation(INDENT);
- s << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" PYTHON_ARGS ", ";
+ s << INDENT << "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" << PYTHON_ARGS << ", ";
s << (argIndex - 1) << "));" << endl;
}
@@ -950,9 +1007,9 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
for (const ArgumentModification &argMod : funcMod.argument_mods) {
if (argMod.ownerships.contains(TypeSystem::NativeCode)
&& argMod.index == 0 && argMod.ownerships[TypeSystem::NativeCode] == TypeSystem::CppOwnership) {
- s << INDENT << "if (Shiboken::Object::checkType(" PYTHON_RETURN_VAR "))" << endl;
+ s << INDENT << "if (Shiboken::Object::checkType(" << PYTHON_RETURN_VAR << "))" << endl;
Indentation indent(INDENT);
- s << INDENT << "Shiboken::Object::releaseOwnership(" PYTHON_RETURN_VAR ");" << endl;
+ s << INDENT << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR << ");" << endl;
}
}
}
@@ -978,7 +1035,7 @@ void CppGenerator::writeVirtualMethodNative(QTextStream&s, const AbstractMetaFun
}
if (func->type()->referenceType() == LValueReference && !isPointer(func->type()))
s << '*';
- s << CPP_RETURN_VAR ";" << endl;
+ s << CPP_RETURN_VAR << ';' << endl;
}
s << '}' << endl << endl;
@@ -995,7 +1052,7 @@ void CppGenerator::writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass
s << INDENT << "SbkObject* pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);" << endl;
s << INDENT << "if (pySelf == NULL)" << endl;
s << INDENT << INDENT << "return " << metaClass->qualifiedCppName() << "::metaObject();" << endl;
- s << INDENT << "return PySide::SignalManager::retriveMetaObject(reinterpret_cast<PyObject*>(pySelf));" << endl;
+ s << INDENT << "return PySide::SignalManager::retrieveMetaObject(reinterpret_cast<PyObject*>(pySelf));" << endl;
s << '}' << endl << endl;
// qt_metacall function
@@ -1259,7 +1316,7 @@ void CppGenerator::writeConverterFunctions(QTextStream &s, const AbstractMetaCla
toCppConv = QLatin1Char('*') + cpythonWrapperCPtr(sourceClass->typeEntry(), QLatin1String("pyIn"));
} else {
// Constructor that does implicit conversion.
- if (!conv->typeReplaced(1).isEmpty())
+ if (!conv->typeReplaced(1).isEmpty() || conv->isModifiedToArray(1))
continue;
const AbstractMetaType* sourceType = conv->arguments().constFirst()->type();
typeCheck = cpythonCheckFunction(sourceType);
@@ -1419,7 +1476,7 @@ void CppGenerator::writeConverterRegister(QTextStream &s, const AbstractMetaClas
sourceType = buildAbstractMetaTypeFromAbstractMetaClass(conv->ownerClass());
} else {
// Constructor that does implicit conversion.
- if (!conv->typeReplaced(1).isEmpty())
+ if (!conv->typeReplaced(1).isEmpty() || conv->isModifiedToArray(1))
continue;
sourceType = conv->arguments().constFirst()->type();
}
@@ -1467,7 +1524,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
// Check if the right constructor was called.
if (!ownerClass->hasPrivateDestructor()) {
s << INDENT;
- s << "if (Shiboken::Object::isUserType(" PYTHON_SELF_VAR ") && !Shiboken::ObjectType::canCallConstructor(" PYTHON_SELF_VAR "->ob_type, Shiboken::SbkType< ::";
+ s << "if (Shiboken::Object::isUserType(self) && !Shiboken::ObjectType::canCallConstructor(self->ob_type, Shiboken::SbkType< ::";
QString qualifiedCppName;
if (!context.forSmartPointer())
qualifiedCppName = ownerClass->qualifiedCppName();
@@ -1476,7 +1533,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
s << qualifiedCppName << " >()))" << endl;
Indentation indent(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
}
// Declare pointer for the underlying C++ object.
s << INDENT << "::";
@@ -1497,7 +1554,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 << " = 0;" << endl;
initPythonArguments = minArgs != maxArgs || maxArgs > 1;
usesNamedArguments = rfunc->isCallOperator() || overloadData.hasArgumentWithDefaultValue();
@@ -1505,7 +1562,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
if (maxArgs > 0) {
s << INDENT << "int overloadId = -1;" << endl;
- s << INDENT << "PythonToCppFunc " PYTHON_TO_CPP_VAR;
+ s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR;
if (pythonFunctionWrapperUsesListOfArguments(overloadData))
s << "[] = { 0" << QString::fromLatin1(", 0").repeated(maxArgs-1) << " }";
s << ';' << endl;
@@ -1518,7 +1575,7 @@ void CppGenerator::writeMethodWrapperPreamble(QTextStream &s, OverloadData &over
if (initPythonArguments) {
s << INDENT << "int numArgs = ";
if (minArgs == 0 && maxArgs == 1 && !rfunc->isConstructor() && !pythonFunctionWrapperUsesListOfArguments(overloadData))
- s << "(" PYTHON_ARG " == 0 ? 0 : 1);" << endl;
+ s << "(" << PYTHON_ARG << " == 0 ? 0 : 1);" << endl;
else
writeArgumentsInitializer(s, overloadData);
}
@@ -1534,7 +1591,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
const AbstractMetaClass* metaClass = rfunc->ownerClass();
s << "static int" << endl;
- s << cpythonFunctionName(rfunc) << "(PyObject* " PYTHON_SELF_VAR ", PyObject* args, PyObject* kwds)" << endl;
+ s << cpythonFunctionName(rfunc) << "(PyObject* self, PyObject* args, PyObject* kwds)" << endl;
s << '{' << endl;
QSet<QString> argNamesSet;
@@ -1560,10 +1617,10 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << INDENT << "const QMetaObject* metaObject;" << endl;
}
- s << INDENT << "SbkObject* sbkSelf = reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR ");" << endl;
+ s << INDENT << "SbkObject* sbkSelf = reinterpret_cast<SbkObject*>(self);" << endl;
if (metaClass->isAbstract() || metaClass->baseClassNames().size() > 1) {
- s << INDENT << "SbkObjectType* type = reinterpret_cast<SbkObjectType*>(" PYTHON_SELF_VAR "->ob_type);" << endl;
+ s << INDENT << "SbkObjectType* type = reinterpret_cast<SbkObjectType*>(self->ob_type);" << endl;
s << INDENT << "SbkObjectType* myType = reinterpret_cast<SbkObjectType*>(" << cpythonTypeNameExt(metaClass->typeEntry()) << ");" << endl;
}
@@ -1577,7 +1634,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
s << INDENT << "\"'" << metaClass->qualifiedCppName();
}
s << "' represents a C++ abstract class and cannot be instantiated\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << '}' << endl << endl;
}
@@ -1608,7 +1665,7 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
{
Indentation indent(INDENT);
s << INDENT << "delete cptr;" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << '}' << endl;
if (overloadData.maxArgs() > 0) {
@@ -1636,12 +1693,12 @@ void CppGenerator::writeConstructorWrapper(QTextStream &s, const AbstractMetaFun
// Create metaObject and register signal/slot
if (metaClass->isQObject() && usePySideExtensions()) {
s << endl << INDENT << "// QObject setup" << endl;
- s << INDENT << "PySide::Signal::updateSourceObject(" PYTHON_SELF_VAR ");" << endl;
+ s << INDENT << "PySide::Signal::updateSourceObject(self);" << endl;
s << INDENT << "metaObject = cptr->metaObject(); // <- init python qt properties" << endl;
- s << INDENT << "if (kwds && !PySide::fillQtProperties(" PYTHON_SELF_VAR ", metaObject, kwds, argNames, " << argNamesSet.count() << "))" << endl;
+ s << INDENT << "if (kwds && !PySide::fillQtProperties(self, metaObject, kwds, argNames, " << argNamesSet.count() << "))" << endl;
{
Indentation indentation(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
}
@@ -1694,7 +1751,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
int maxArgs = overloadData.maxArgs();
s << "static PyObject* ";
- s << cpythonFunctionName(rfunc) << "(PyObject* " PYTHON_SELF_VAR;
+ s << cpythonFunctionName(rfunc) << "(PyObject* self";
if (maxArgs > 0) {
s << ", PyObject* " << (pythonFunctionWrapperUsesListOfArguments(overloadData) ? "args" : PYTHON_ARG);
if (overloadData.hasArgumentWithDefaultValue() || rfunc->isCallOperator())
@@ -1707,6 +1764,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
s << endl;
/*
+ * This code is intended for shift operations only:
* Make sure reverse <</>> operators defined in other classes (specially from other modules)
* are called. A proper and generic solution would require an reengineering in the operator
* system like the extended converters.
@@ -1721,30 +1779,32 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
&& rfunc->isOperatorOverload();
if (callExtendedReverseOperator) {
QString revOpName = ShibokenGenerator::pythonOperatorFunctionName(rfunc).insert(2, QLatin1Char('r'));
- if (rfunc->isBinaryOperator()) {
+ // For custom classes, operations like __radd__ and __rmul__
+ // will enter an infinite loop.
+ if (rfunc->isBinaryOperator() && revOpName.contains(QLatin1String("shift"))) {
s << INDENT << "if (!isReverse" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "&& Shiboken::Object::checkType(" PYTHON_ARG ")" << endl;
- s << INDENT << "&& !PyObject_TypeCheck(" PYTHON_ARG ", " PYTHON_SELF_VAR "->ob_type)" << endl;
- s << INDENT << "&& PyObject_HasAttrString(" PYTHON_ARG ", const_cast<char*>(\"" << revOpName << "\"))) {" << endl;
+ s << INDENT << "&& Shiboken::Object::checkType(" << PYTHON_ARG << ")" << endl;
+ s << INDENT << "&& !PyObject_TypeCheck(" << PYTHON_ARG << ", self->ob_type)" << endl;
+ s << INDENT << "&& PyObject_HasAttrString(" << PYTHON_ARG << ", const_cast<char*>(\"" << revOpName << "\"))) {" << endl;
// This PyObject_CallMethod call will emit lots of warnings like
// "deprecated conversion from string constant to char *" during compilation
// due to the method name argument being declared as "char*" instead of "const char*"
// issue 6952 http://bugs.python.org/issue6952
- s << INDENT << "PyObject* revOpMethod = PyObject_GetAttrString(" PYTHON_ARG ", const_cast<char*>(\"" << revOpName << "\"));" << endl;
+ s << INDENT << "PyObject* revOpMethod = PyObject_GetAttrString(" << PYTHON_ARG << ", const_cast<char*>(\"" << revOpName << "\"));" << endl;
s << INDENT << "if (revOpMethod && PyCallable_Check(revOpMethod)) {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << PYTHON_RETURN_VAR " = PyObject_CallFunction(revOpMethod, const_cast<char*>(\"O\"), " PYTHON_SELF_VAR ");" << endl;
+ s << INDENT << PYTHON_RETURN_VAR << " = PyObject_CallFunction(revOpMethod, const_cast<char*>(\"O\"), self);" << endl;
s << INDENT << "if (PyErr_Occurred() && (PyErr_ExceptionMatches(PyExc_NotImplementedError)";
s << " || PyErr_ExceptionMatches(PyExc_AttributeError))) {" << endl;
{
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 << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");" << endl;
+ s << INDENT << PYTHON_RETURN_VAR << " = 0;" << endl;
}
s << INDENT << '}' << endl;
}
@@ -1754,7 +1814,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
s << INDENT << "}" << endl;
}
s << INDENT << "// Do not enter here if other object has implemented a reverse operator." << endl;
- s << INDENT << "if (!" PYTHON_RETURN_VAR ") {" << endl << endl;
+ s << INDENT << "if (!" << PYTHON_RETURN_VAR << ") {" << endl << endl;
}
if (maxArgs > 0)
@@ -1763,7 +1823,7 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
writeFunctionCalls(s, overloadData, classContext);
if (callExtendedReverseOperator)
- s << endl << INDENT << "} // End of \"if (!" PYTHON_RETURN_VAR ")\"" << endl;
+ s << endl << INDENT << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"" << endl;
s << endl;
@@ -1771,10 +1831,10 @@ void CppGenerator::writeMethodWrapper(QTextStream &s, const AbstractMetaFunction
if (hasReturnValue) {
if (rfunc->isInplaceOperator()) {
- s << INDENT << "Py_INCREF(" PYTHON_SELF_VAR ");\n";
- s << INDENT << "return " PYTHON_SELF_VAR ";\n";
+ s << INDENT << "Py_INCREF(self);\n";
+ s << INDENT << "return self;\n";
} else {
- s << INDENT << "return " PYTHON_RETURN_VAR ";\n";
+ s << INDENT << "return " << PYTHON_RETURN_VAR << ";\n";
}
} else {
s << INDENT << "Py_RETURN_NONE;" << endl;
@@ -1795,7 +1855,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl
int maxArgs = overloadData.maxArgs();
s << INDENT << "PyObject* ";
- s << PYTHON_ARGS "[] = {"
+ s << PYTHON_ARGS << "[] = {"
<< QString(maxArgs, QLatin1Char('0')).split(QLatin1String(""), QString::SkipEmptyParts).join(QLatin1String(", "))
<< "};" << endl;
s << endl;
@@ -1807,8 +1867,8 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl
s << INDENT << "PyObject* nonvarargs = PyTuple_GetSlice(args, 0, " << maxArgs << ");" << endl;
s << INDENT << "Shiboken::AutoDecRef auto_nonvarargs(nonvarargs);" << endl;
- s << INDENT << PYTHON_ARGS "[" << maxArgs << "] = PyTuple_GetSlice(args, " << maxArgs << ", numArgs);" << endl;
- s << INDENT << "Shiboken::AutoDecRef auto_varargs(" PYTHON_ARGS "[" << maxArgs << "]);" << endl;
+ s << INDENT << PYTHON_ARGS << '[' << maxArgs << "] = PyTuple_GetSlice(args, " << maxArgs << ", numArgs);" << endl;
+ s << INDENT << "Shiboken::AutoDecRef auto_varargs(" << PYTHON_ARGS << "[" << maxArgs << "]);" << endl;
s << endl;
}
@@ -1822,7 +1882,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): too many arguments\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << '}';
}
@@ -1835,7 +1895,7 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_TypeError, \"" << fullPythonFunctionName(rfunc) << "(): not enough arguments\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << '}';
}
@@ -1867,13 +1927,12 @@ void CppGenerator::writeArgumentsInitializer(QTextStream& s, OverloadData& overl
s << "PyArg_ParseTuple(" << argsVar << ", \"|" << QByteArray(maxArgs, 'O') << ':' << funcName << '"';
else
s << "PyArg_UnpackTuple(" << argsVar << ", \"" << funcName << "\", " << minArgs << ", " << maxArgs;
- QStringList palist;
for (int i = 0; i < maxArgs; i++)
- palist << QString::fromLatin1("&(" PYTHON_ARGS "[%1])").arg(i);
- s << ", " << palist.join(QLatin1String(", ")) << "))" << endl;
+ s << ", &(" << PYTHON_ARGS << '[' << i << "])";
+ s << "))" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << endl;
}
@@ -1895,7 +1954,7 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
}
QString cppSelfAttribution;
- QString pythonSelfVar = QLatin1String(PYTHON_SELF_VAR);
+ QString pythonSelfVar = QLatin1String("self");
QString cpythonWrapperCPtrResult;
if (!context.forSmartPointer())
cpythonWrapperCPtrResult = cpythonWrapperCPtr(metaClass, pythonSelfVar);
@@ -1908,7 +1967,7 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
.arg(className, QLatin1String(CPP_SELF_VAR), cast,
cpythonWrapperCPtrResult);
} else {
- s << INDENT << className << "* " CPP_SELF_VAR " = 0;" << endl;
+ s << INDENT << className << "* " << CPP_SELF_VAR << " = 0;" << endl;
writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
cppSelfAttribution = QString::fromLatin1("%1 = %2%3")
.arg(QLatin1String(CPP_SELF_VAR),
@@ -1918,17 +1977,17 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
// Checks if the underlying C++ object is valid.
if (hasStaticOverload && !cppSelfAsReference) {
- s << INDENT << "if (" PYTHON_SELF_VAR ") {" << endl;
+ s << INDENT << "if (self) {" << endl;
{
Indentation indent(INDENT);
- writeInvalidPyObjectCheck(s, QLatin1String(PYTHON_SELF_VAR));
+ writeInvalidPyObjectCheck(s, QLatin1String("self"));
s << INDENT << cppSelfAttribution << ';' << endl;
}
s << INDENT << '}' << endl;
return;
}
- writeInvalidPyObjectCheck(s, QLatin1String(PYTHON_SELF_VAR));
+ writeInvalidPyObjectCheck(s, QLatin1String("self"));
s << INDENT << cppSelfAttribution << ';' << endl;
}
@@ -1942,17 +2001,17 @@ void CppGenerator::writeCppSelfDefinition(QTextStream &s,
if (func->isOperatorOverload() && func->isBinaryOperator()) {
QString checkFunc = cpythonCheckFunction(func->ownerClass()->typeEntry());
- s << INDENT << "bool isReverse = " << checkFunc << PYTHON_ARG ")" << endl;
+ s << INDENT << "bool isReverse = " << checkFunc << PYTHON_ARG << ')' << endl;
{
Indentation indent1(INDENT);
Indentation indent2(INDENT);
Indentation indent3(INDENT);
Indentation indent4(INDENT);
- s << INDENT << "&& !" << checkFunc << PYTHON_SELF_VAR ");" << endl;
+ s << INDENT << "&& !" << checkFunc << "self);" << endl;
}
s << INDENT << "if (isReverse)" << endl;
Indentation indent(INDENT);
- s << INDENT << "std::swap(" PYTHON_SELF_VAR ", " PYTHON_ARG ");" << endl;
+ s << INDENT << "std::swap(self, " << PYTHON_ARG << ");" << endl;
}
writeCppSelfDefinition(s, context, hasStaticOverload);
@@ -2053,17 +2112,20 @@ void CppGenerator::writeErrorSection(QTextStream& s, OverloadData& overloadData)
<< ", 0};" << endl;
s << INDENT << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", \"" << funcName << "\", overloads);" << endl;
}
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
void CppGenerator::writeFunctionReturnErrorCheckSection(QTextStream& s, bool hasReturnValue)
{
- s << INDENT << "if (PyErr_Occurred()" << (hasReturnValue ? " || !" PYTHON_RETURN_VAR : "") << ") {" << endl;
+ s << INDENT << "if (PyErr_Occurred()";
+ if (hasReturnValue)
+ s << " || !" << PYTHON_RETURN_VAR;
+ s << ") {" << endl;
{
Indentation indent(INDENT);
if (hasReturnValue)
- s << INDENT << "Py_XDECREF(" PYTHON_RETURN_VAR ");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");" << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << '}' << endl;
}
@@ -2072,12 +2134,13 @@ void CppGenerator::writeInvalidPyObjectCheck(QTextStream& s, const QString& pyOb
{
s << INDENT << "if (!Shiboken::Object::isValid(" << pyObj << "))" << endl;
Indentation indent(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
static QString pythonToCppConverterForArgumentName(const QString& argumentName)
{
- static const QRegularExpression pyArgsRegex(QLatin1String(PYTHON_ARGS"(\\[\\d+[-]?\\d*\\])"));
+ static const QRegularExpression pyArgsRegex(QLatin1String(PYTHON_ARGS)
+ + QLatin1String(R"((\[\d+[-]?\d*\]))"));
Q_ASSERT(pyArgsRegex.isValid());
const QRegularExpressionMatch match = pyArgsRegex.match(argumentName);
QString result = QLatin1String(PYTHON_TO_CPP_VAR);
@@ -2379,7 +2442,7 @@ void CppGenerator::writeConversionRule(QTextStream& s, const AbstractMetaFunctio
void CppGenerator::writeNoneReturn(QTextStream& s, const AbstractMetaFunction* func, bool thereIsReturnValue)
{
if (thereIsReturnValue && (!func->type() || func->argumentRemoved(0)) && !injectedCodeHasReturnValueAttribution(func)) {
- s << INDENT << PYTHON_RETURN_VAR " = Py_None;" << endl;
+ s << INDENT << PYTHON_RETURN_VAR << " = Py_None;" << endl;
s << INDENT << "Py_INCREF(Py_None);" << endl;
}
}
@@ -2493,8 +2556,9 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
const AbstractMetaFunction* refFunc = overloadData->referenceFunction();
QStringList typeChecks;
+
QString pyArgName = (usePyArgs && maxArgs > 1)
- ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(overloadData->argPos())
+ ? pythonArgsAt(overloadData->argPos())
: QLatin1String(PYTHON_ARG);
OverloadData* od = overloadData;
int startArg = od->argPos();
@@ -2503,7 +2567,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(QTextStream& s, const Ov
bool typeReplacedByPyObject = od->argumentTypeReplaced() == QLatin1String("PyObject");
if (!typeReplacedByPyObject) {
if (usePyArgs)
- pyArgName = QString::fromLatin1(PYTHON_ARGS "[%1]").arg(od->argPos());
+ pyArgName = pythonArgsAt(od->argPos());
QString typeCheck;
QTextStream tck(&typeCheck);
const AbstractMetaFunction* func = od->referenceFunction();
@@ -2613,7 +2677,7 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
s << INDENT << "PyErr_Format(PyExc_TypeError, \"%s is a private method.\", \""
<< func->signature().replace(QLatin1String("::"), QLatin1String("."))
<< "\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
return;
}
@@ -2630,7 +2694,8 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
const AbstractMetaArgument* arg = func->arguments().at(argIdx);
if (func->argumentRemoved(argIdx + 1)) {
if (!arg->defaultValueExpression().isEmpty()) {
- QString cppArgRemoved = QString::fromLatin1(CPP_ARG_REMOVED "%1").arg(argIdx);
+ const QString cppArgRemoved = QLatin1String(CPP_ARG_REMOVED)
+ + QString::number(argIdx);
s << INDENT << getFullTypeName(arg->type()) << ' ' << cppArgRemoved;
s << " = " << guessScopeForDefaultValue(func, arg) << ';' << endl;
writeUnusedVariableCast(s, cppArgRemoved);
@@ -2649,8 +2714,8 @@ void CppGenerator::writeSingleFunctionCall(QTextStream &s,
if (!argType || (mayHaveUnunsedArguments && !injectedCodeUsesArgument(func, argIdx)))
continue;
int argPos = argIdx - removedArgs;
- QString argName = QString::fromLatin1(CPP_ARG"%1").arg(argPos);
- QString pyArgName = usePyArgs ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(argPos) : QLatin1String(PYTHON_ARG);
+ QString argName = QLatin1String(CPP_ARG) + QString::number(argPos);
+ QString pyArgName = usePyArgs ? pythonArgsAt(argPos) : QLatin1String(PYTHON_ARG);
QString defaultValue = guessScopeForDefaultValue(func, arg);
writeArgumentConversion(s, argType, argName, pyArgName, func->implementingClass(), defaultValue, func->isUserAdded());
}
@@ -2896,10 +2961,8 @@ void CppGenerator::writePythonToCppConversionFunctions(QTextStream& s, const Abs
const AbstractMetaType* type = containerType->instantiations().at(i);
QString typeName = getFullTypeName(type);
if (type->isValue() && isValueTypeWithCopyConstructorOnly(type)) {
- static const QRegularExpression regex(QLatin1String(CONVERTTOCPP_REGEX));
- Q_ASSERT(regex.isValid());
for (int pos = 0; ; ) {
- const QRegularExpressionMatch match = regex.match(code, pos);
+ const QRegularExpressionMatch match = convertToCppRegEx().match(code, pos);
if (!match.hasMatch())
break;
pos = match.capturedEnd();
@@ -2954,15 +3017,13 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream& s, const AbstractMe
s << INDENT << "PyObject* ";
for (const AbstractMetaArgument *arg : args) {
int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex());
- QString pyArgName = usePyArgs
- ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(pyArgIndex)
- : QLatin1String(PYTHON_ARG);
+ QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex) : QLatin1String(PYTHON_ARG);
s << "value = PyDict_GetItemString(kwds, \"" << arg->name() << "\");" << endl;
s << INDENT << "if (value && " << pyArgName << ") {" << endl;
{
Indentation indent(INDENT);
s << INDENT << pyErrString.arg(arg->name()) << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << "} else if (value) {" << endl;
{
@@ -2989,7 +3050,7 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
*wrappedClass = 0;
QString pyArgName;
if (argIndex == -1) {
- pyArgName = QLatin1String(PYTHON_SELF_VAR);
+ pyArgName = QLatin1String("self");
*wrappedClass = func->implementingClass();
} else if (argIndex == 0) {
AbstractMetaType *funcType = func->type();
@@ -3016,12 +3077,23 @@ QString CppGenerator::argumentNameFromIndex(const AbstractMetaFunction* func, in
&& OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass())[func->name()]))
pyArgName = QLatin1String(PYTHON_ARG);
else
- pyArgName = QString::fromLatin1(PYTHON_ARGS "[%1]").arg(argIndex - 1);
+ pyArgName = pythonArgsAt(argIndex - 1);
}
}
return pyArgName;
}
+static QStringList defaultExceptionHandling()
+{
+ static const QStringList result{
+ QLatin1String("} catch (const std::exception &e) {"),
+ QLatin1String(" PyErr_SetString(PyExc_RuntimeError, e.what());"),
+ QLatin1String("} catch (...) {"),
+ QLatin1String(" PyErr_SetString(PyExc_RuntimeError, \"An unknown exception was caught\");"),
+ QLatin1String("}")};
+ return result;
+}
+
void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *func,
GeneratorContext &context, int maxArgs)
{
@@ -3037,12 +3109,12 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
if (func->isAbstract()) {
- s << INDENT << "if (Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR "))) {\n";
+ s << INDENT << "if (Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject*>(self))) {\n";
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '";
s << func->ownerClass()->name() << '.' << func->name() << "()' not implemented.\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << "}\n";
}
@@ -3091,16 +3163,21 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
if (hasConversionRule)
userArgs << arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX);
else if (!arg->defaultValueExpression().isEmpty())
- userArgs << QString::fromLatin1(CPP_ARG_REMOVED "%1").arg(i);
+ userArgs.append(QLatin1String(CPP_ARG_REMOVED) + QString::number(i));
} else {
int idx = arg->argumentIndex() - removedArgs;
bool deRef = isValueTypeWithCopyConstructorOnly(arg->type())
|| isObjectTypeUsedAsValueType(arg->type())
|| (arg->type()->referenceType() == LValueReference && isWrapperType(arg->type()) && !isPointer(arg->type()));
- QString argName = hasConversionRule
- ? arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX)
- : QString::fromLatin1("%1" CPP_ARG "%2").arg(deRef ? QLatin1String("*") : QString()).arg(idx);
- userArgs << argName;
+ if (hasConversionRule) {
+ userArgs.append(arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX));
+ } else {
+ QString argName;
+ if (deRef)
+ argName += QLatin1Char('*');
+ argName += QLatin1String(CPP_ARG) + QString::number(idx);
+ userArgs.append(argName);
+ }
}
}
@@ -3113,17 +3190,16 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
bool argsClear = true;
for (int i = func->arguments().size() - 1; i >= maxArgs + removedArgs; i--) {
const AbstractMetaArgument* arg = func->arguments().at(i);
- bool defValModified = arg->defaultValueExpression() != arg->originalDefaultValueExpression();
+ const bool defValModified = arg->hasModifiedDefaultValueExpression();
bool hasConversionRule = !func->conversionRule(TypeSystem::NativeCode, arg->argumentIndex() + 1).isEmpty();
if (argsClear && !defValModified && !hasConversionRule)
continue;
- else
- argsClear = false;
+ argsClear = false;
otherArgsModified |= defValModified || hasConversionRule || func->argumentRemoved(i + 1);
if (hasConversionRule)
otherArgs.prepend(arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX));
else
- otherArgs.prepend(QString::fromLatin1(CPP_ARG_REMOVED "%1").arg(i));
+ otherArgs.prepend(QLatin1String(CPP_ARG_REMOVED) + QString::number(i));
}
if (otherArgsModified)
userArgs << otherArgs;
@@ -3135,10 +3211,11 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
QString useVAddr;
QTextStream uva(&useVAddr);
if (func->isOperatorOverload() && !func->isCallOperator()) {
- QString firstArg = QLatin1String("(*" CPP_SELF_VAR ")");
- if (func->isPointerOperator())
- firstArg.remove(1, 1); // remove the de-reference operator
-
+ QString firstArg(QLatin1Char('('));
+ if (!func->isPointerOperator()) // no de-reference operator
+ firstArg += QLatin1Char('*');
+ firstArg += QLatin1String(CPP_SELF_VAR);
+ firstArg += QLatin1Char(')');
QString secondArg = QLatin1String(CPP_ARG0);
if (!func->isUnaryOperator() && shouldDereferenceArgumentPointer(func->arguments().constFirst())) {
secondArg.prepend(QLatin1String("(*"));
@@ -3211,7 +3288,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
} else {
const QString selfVarCast = func->ownerClass() == func->implementingClass()
? QLatin1String(CPP_SELF_VAR)
- : QLatin1String("reinterpret_cast<") + methodCallClassName + QLatin1String(" *>(" CPP_SELF_VAR ")");
+ : QLatin1String("reinterpret_cast<") + methodCallClassName
+ + QLatin1String(" *>(") + QLatin1String(CPP_SELF_VAR) + QLatin1Char(')');
if (func->isConstant()) {
if (avoidProtectedHack()) {
mc << "const_cast<const ::";
@@ -3219,7 +3297,8 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
// PYSIDE-500: Need a special wrapper cast when inherited
const QString selfWrapCast = func->ownerClass() == func->implementingClass()
? QLatin1String(CPP_SELF_VAR)
- : QLatin1String("reinterpret_cast<") + wrapperName(func->ownerClass()) + QLatin1String(" *>(" CPP_SELF_VAR ")");
+ : QLatin1String("reinterpret_cast<") + wrapperName(func->ownerClass())
+ + QLatin1String(" *>(") + QLatin1String(CPP_SELF_VAR) + QLatin1Char(')');
mc << wrapperName(func->ownerClass());
mc << "*>(" << selfWrapCast << ")->";
}
@@ -3263,7 +3342,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
methodCallClassName);
normalCall.remove(QLatin1String("::%CLASS_NAME::"));
methodCall.clear();
- mc << "Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR ")) ? ";
+ mc << "Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject*>(self)) ? ";
mc << virtualCall << " : " << normalCall;
}
}
@@ -3271,7 +3350,19 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
if (!injectedCodeCallsCppFunction(func)) {
- s << INDENT << BEGIN_ALLOW_THREADS << endl << INDENT;
+ const bool allowThread = func->allowThread();
+ const bool generateExceptionHandling = func->generateExceptionHandling();
+ if (generateExceptionHandling) {
+ s << INDENT << "try {\n";
+ ++INDENT.indent;
+ if (allowThread) {
+ s << INDENT << "Shiboken::ThreadStateSaver threadSaver;\n"
+ << INDENT << "threadSaver.save();\n";
+ }
+ } else if (allowThread) {
+ s << INDENT << BEGIN_ALLOW_THREADS << endl;
+ }
+ s << INDENT;
if (isCtor) {
s << (useVAddr.isEmpty() ?
QString::fromLatin1("cptr = %1;").arg(methodCall) : useVAddr) << endl;
@@ -3299,18 +3390,23 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
methodCall.append(QLatin1Char(')'));
}
}
- s << " " CPP_RETURN_VAR " = ";
+ s << " " << CPP_RETURN_VAR << " = ";
s << methodCall << ';' << endl;
} else {
s << methodCall << ';' << endl;
}
- s << INDENT << END_ALLOW_THREADS << endl;
+ if (allowThread) {
+ s << INDENT << (generateExceptionHandling
+ ? "threadSaver.restore();" : END_ALLOW_THREADS) << '\n';
+ }
+
+ // Convert result
if (!func->conversionRule(TypeSystem::TargetLangCode, 0).isEmpty()) {
writeConversionRule(s, func, TypeSystem::TargetLangCode, QLatin1String(PYTHON_RETURN_VAR));
} else if (!isCtor && !func->isInplaceOperator() && func->type()
&& !injectedCodeHasReturnValueAttribution(func, TypeSystem::TargetLangCode)) {
- s << INDENT << PYTHON_RETURN_VAR " = ";
+ s << INDENT << PYTHON_RETURN_VAR << " = ";
if (isObjectTypeUsedAsValueType(func->type())) {
s << "Shiboken::Object::newObject(reinterpret_cast<SbkObjectType *>(" << cpythonTypeNameExt(func->type()->typeEntry())
<< "), " << CPP_RETURN_VAR << ", true, true)";
@@ -3319,6 +3415,13 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
}
s << ';' << endl;
}
+
+ if (generateExceptionHandling) { // "catch" code
+ --INDENT.indent;
+ const QStringList handlingCode = defaultExceptionHandling();
+ for (const auto &line : handlingCode)
+ s << INDENT << line << '\n';
+ }
}
}
@@ -3370,7 +3473,7 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
s << "getOwnership(" << pyArgName << ");";
} else if (wrappedClass->hasVirtualDestructor()) {
if (arg_mod.index == 0)
- s << "releaseOwnership(" PYTHON_RETURN_VAR ");";
+ s << "releaseOwnership(" << PYTHON_RETURN_VAR << ");";
else
s << "releaseOwnership(" << pyArgName << ");";
} else {
@@ -3406,10 +3509,10 @@ void CppGenerator::writeMethodCall(QTextStream &s, const AbstractMetaFunction *f
else
s << INDENT << "Shiboken::Object::removeReference(";
- s << "reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR "), \"";
+ s << "reinterpret_cast<SbkObject*>(self), \"";
QString varName = arg_mod.referenceCounts.constFirst().varName;
if (varName.isEmpty())
- varName = func->minimalSignature() + QString().number(arg_mod.index);
+ varName = func->minimalSignature() + QString::number(arg_mod.index);
s << varName << "\", " << pyArgName
<< (refCount.action == ReferenceCount::Add ? ", true" : "")
@@ -3531,7 +3634,7 @@ void CppGenerator::writeEnumConverterInitialization(QTextStream& s, const TypeEn
const FlagsTypeEntry* flags = 0;
if (enumType->isFlags())
- flags = reinterpret_cast<const FlagsTypeEntry*>(enumType);
+ flags = static_cast<const FlagsTypeEntry*>(enumType);
s << INDENT << "// Register converter for " << enumFlagName << " '" << enumType->qualifiedCppName() << "'." << endl;
s << INDENT << '{' << endl;
@@ -3575,7 +3678,7 @@ void CppGenerator::writeEnumConverterInitialization(QTextStream& s, const TypeEn
s << INDENT << '}' << endl;
if (!flags)
- writeEnumConverterInitialization(s, reinterpret_cast<const EnumTypeEntry*>(enumType)->flags());
+ writeEnumConverterInitialization(s, static_cast<const EnumTypeEntry*>(enumType)->flags());
}
void CppGenerator::writeContainerConverterInitialization(QTextStream& s, const AbstractMetaType* type)
@@ -3656,10 +3759,7 @@ bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass* metaClass)
}
const ComplexTypeEntry* baseType = metaClass->typeEntry()->baseContainerType();
- if (baseType && baseType->isContainer())
- return true;
-
- return false;
+ return baseType && baseType->isContainer();
}
bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass* metaClass)
@@ -3872,7 +3972,7 @@ void CppGenerator::writeMappingMethods(QTextStream &s,
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
s << funcRetVal << ' ' << funcName << '(' << funcArgs << ')' << endl << '{' << endl;
- writeInvalidPyObjectCheck(s, QLatin1String(PYTHON_SELF_VAR));
+ writeInvalidPyObjectCheck(s, QLatin1String("self"));
writeCppSelfDefinition(s, func, context);
@@ -3899,7 +3999,7 @@ void CppGenerator::writeSequenceMethods(QTextStream &s,
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
s << funcRetVal << ' ' << funcName << '(' << funcArgs << ')' << endl << '{' << endl;
- writeInvalidPyObjectCheck(s, QLatin1String(PYTHON_SELF_VAR));
+ writeInvalidPyObjectCheck(s, QLatin1String("self"));
writeCppSelfDefinition(s, func, context);
@@ -3964,7 +4064,6 @@ void CppGenerator::writeTypeAsMappingDefinition(QTextStream& s, const AbstractMe
funcs.insert(QLatin1String("__msetitem__"), QString());
}
- QString baseName = cpythonBaseName(metaClass);
for (auto it = m_mpFuncs.cbegin(), end = m_mpFuncs.cend(); it != end; ++it) {
const QString &mpName = it.key();
if (funcs[mpName].isEmpty())
@@ -4015,7 +4114,8 @@ void CppGenerator::writeTypeAsNumberDefinition(QTextStream& s, const AbstractMet
QString baseName = cpythonBaseName(metaClass);
- nb[QLatin1String("bool")] = hasBoolCast(metaClass) ? baseName + QLatin1String("___nb_bool") : QString();
+ if (hasBoolCast(metaClass))
+ nb.insert(QLatin1String("bool"), baseName + QLatin1String("___nb_bool"));
for (QHash<QString, QString>::const_iterator it = m_nbFuncs.cbegin(), end = m_nbFuncs.cend(); it != end; ++it) {
const QString &nbName = it.key();
@@ -4054,9 +4154,9 @@ void CppGenerator::writeTpTraverseFunction(QTextStream& s, const AbstractMetaCla
{
QString baseName = cpythonBaseName(metaClass);
s << "static int ";
- s << baseName << "_traverse(PyObject* " PYTHON_SELF_VAR ", visitproc visit, void* arg)" << endl;
+ s << baseName << "_traverse(PyObject* self, visitproc visit, void* arg)" << endl;
s << '{' << endl;
- s << INDENT << "return reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())->tp_traverse(" PYTHON_SELF_VAR ", visit, arg);" << endl;
+ s << INDENT << "return reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())->tp_traverse(self, visit, arg);" << endl;
s << '}' << endl;
}
@@ -4064,9 +4164,9 @@ void CppGenerator::writeTpClearFunction(QTextStream& s, const AbstractMetaClass*
{
QString baseName = cpythonBaseName(metaClass);
s << "static int ";
- s << baseName << "_clear(PyObject* " PYTHON_SELF_VAR ")" << endl;
+ s << baseName << "_clear(PyObject* self)" << endl;
s << '{' << endl;
- s << INDENT << "return reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())->tp_clear(" PYTHON_SELF_VAR ");" << endl;
+ s << INDENT << "return reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())->tp_clear(self);" << endl;
s << '}' << endl;
}
@@ -4074,7 +4174,7 @@ void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context)
{
const AbstractMetaClass *metaClass = context.metaClass();
const QString className = chopType(cpythonTypeName(metaClass));
- s << "static PyObject* " << className << "___copy__(PyObject* " PYTHON_SELF_VAR ")" << endl;
+ s << "static PyObject* " << className << "___copy__(PyObject* self)" << endl;
s << "{" << endl;
writeCppSelfDefinition(s, context, false, true);
QString conversionCode;
@@ -4084,9 +4184,9 @@ void CppGenerator::writeCopyFunction(QTextStream &s, GeneratorContext &context)
conversionCode = cpythonToPythonConversionFunction(context.preciseType());
s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << " = " << conversionCode;
- s << CPP_SELF_VAR ");" << endl;
+ s << CPP_SELF_VAR << ");" << endl;
writeFunctionReturnErrorCheckSection(s);
- s << INDENT << "return " PYTHON_RETURN_VAR ";" << endl;
+ s << INDENT << "return " << PYTHON_RETURN_VAR << ";" << endl;
s << "}" << endl;
s << endl;
}
@@ -4096,7 +4196,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
GeneratorContext &context)
{
ErrorCode errorCode(0);
- s << "static PyObject* " << cpythonGetterFunctionName(metaField) << "(PyObject* " PYTHON_SELF_VAR ", void*)" << endl;
+ s << "static PyObject* " << cpythonGetterFunctionName(metaField) << "(PyObject* self, void*)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, context);
@@ -4161,7 +4261,7 @@ void CppGenerator::writeGetterFunction(QTextStream &s,
s << INDENT << "pyOut = ";
s << "Shiboken::Object::newObject(reinterpret_cast<SbkObjectType *>(" << cpythonTypeNameExt(fieldType)
<< "), " << cppField << ", false, true);" << endl;
- s << INDENT << "Shiboken::Object::setParent(" PYTHON_SELF_VAR ", pyOut)";
+ s << INDENT << "Shiboken::Object::setParent(self, pyOut)";
} else {
s << INDENT << "pyOut = ";
writeToPythonConversion(s, fieldType, metaField->enclosingClass(), cppField);
@@ -4177,7 +4277,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
GeneratorContext &context)
{
ErrorCode errorCode(0);
- s << "static int " << cpythonSetterFunctionName(metaField) << "(PyObject* " PYTHON_SELF_VAR ", PyObject* pyIn, void*)" << endl;
+ s << "static int " << cpythonSetterFunctionName(metaField) << "(PyObject* self, PyObject* pyIn, void*)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, context);
@@ -4193,7 +4293,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
AbstractMetaType* fieldType = metaField->type();
- s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ';' << endl;
+ s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << "{nullptr};" << endl;
s << INDENT << "if (!";
writeTypeCheck(s, fieldType, QLatin1String("pyIn"), isNumber(fieldType->typeEntry()));
s << ") {" << endl;
@@ -4219,6 +4319,8 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << INDENT << PYTHON_TO_CPP_VAR << "(pyIn, &cppOut_local);" << endl;
s << INDENT << cppField << " = cppOut_local";
} else {
+ if (isPointerToConst(fieldType))
+ s << "const ";
s << getFullTypeNameWithoutModifiers(fieldType);
s << QString::fromLatin1("*").repeated(fieldType->indirections()) << "& cppOut_ptr = ";
s << cppField << ';' << endl;
@@ -4227,7 +4329,7 @@ void CppGenerator::writeSetterFunction(QTextStream &s,
s << ';' << endl << endl;
if (isPointerToWrapperType(fieldType)) {
- s << INDENT << "Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR "), \"";
+ s << INDENT << "Shiboken::Object::keepReference(reinterpret_cast<SbkObject*>(self), \"";
s << metaField->name() << "\", pyIn);" << endl;
}
@@ -4240,12 +4342,12 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
const AbstractMetaClass *metaClass = context.metaClass();
QString baseName = cpythonBaseName(metaClass);
s << "static PyObject* ";
- s << baseName << "_richcompare(PyObject* " PYTHON_SELF_VAR ", PyObject* " PYTHON_ARG ", int op)" << endl;
+ s << baseName << "_richcompare(PyObject* self, PyObject* " << PYTHON_ARG << ", int op)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, context, false, true);
writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
- s << INDENT << "PyObject* " PYTHON_RETURN_VAR " = 0;" << endl;
- s << INDENT << "PythonToCppFunc " PYTHON_TO_CPP_VAR << ';' << endl;
+ s << INDENT << "PyObject* " << PYTHON_RETURN_VAR << " = 0;" << endl;
+ s << INDENT << "PythonToCppFunc " << PYTHON_TO_CPP_VAR << ';' << endl;
writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
s << endl;
@@ -4302,15 +4404,17 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
CodeSnipList snips = func->injectedCodeSnips();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode, func, func->arguments().constLast());
} else {
- QString expression = QString::fromLatin1("%1%2 %3 (%4" CPP_ARG0 ")")
- .arg(func->isPointerOperator() ? QLatin1String("&") : QString(),
- QLatin1String(CPP_SELF_VAR), op,
- shouldDereferenceAbstractMetaTypePointer(argType) ? QLatin1String("*") : QString());
s << INDENT;
if (func->type())
- s << func->type()->cppSignature() << " " CPP_RETURN_VAR " = ";
- s << expression << ';' << endl;
- s << INDENT << PYTHON_RETURN_VAR " = ";
+ s << func->type()->cppSignature() << " " << CPP_RETURN_VAR << " = ";
+ // expression
+ if (func->isPointerOperator())
+ s << '&';
+ s << CPP_SELF_VAR << ' ' << op << '(';
+ if (shouldDereferenceAbstractMetaTypePointer(argType))
+ s << '*';
+ s << CPP_ARG0 << ");" << endl;
+ s << INDENT << PYTHON_RETURN_VAR << " = ";
if (func->type())
writeToPythonConversion(s, func->type(), metaClass, QLatin1String(CPP_RETURN_VAR));
else
@@ -4324,9 +4428,9 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
s << " else {" << endl;
if (operatorId == QLatin1String("Py_EQ") || operatorId == QLatin1String("Py_NE")) {
Indentation indent(INDENT);
- s << INDENT << PYTHON_RETURN_VAR " = "
+ s << INDENT << PYTHON_RETURN_VAR << " = "
<< (operatorId == QLatin1String("Py_EQ") ? "Py_False" : "Py_True") << ';' << endl;
- s << INDENT << "Py_INCREF(" PYTHON_RETURN_VAR ");" << endl;
+ s << INDENT << "Py_INCREF(" << PYTHON_RETURN_VAR << ");" << endl;
} else {
Indentation indent(INDENT);
s << INDENT << "goto " << baseName << "_RichComparison_TypeError;" << endl;
@@ -4343,18 +4447,18 @@ void CppGenerator::writeRichCompareFunction(QTextStream &s, GeneratorContext &co
}
s << INDENT << '}' << endl << endl;
- s << INDENT << "if (" PYTHON_RETURN_VAR " && !PyErr_Occurred())" << endl;
+ s << INDENT << "if (" << PYTHON_RETURN_VAR << " && !PyErr_Occurred())" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return " PYTHON_RETURN_VAR ";" << endl;
+ s << INDENT << "return " << PYTHON_RETURN_VAR << ";" << endl;
}
s << INDENT << baseName << "_RichComparison_TypeError:" << endl;
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"operator not implemented.\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
s << '}' << endl << endl;
}
-void CppGenerator::writeMethodDefinitionEntry(QTextStream& s, const AbstractMetaFunctionList overloads)
+void CppGenerator::writeMethodDefinitionEntry(QTextStream& s, const AbstractMetaFunctionList &overloads)
{
Q_ASSERT(!overloads.isEmpty());
OverloadData overloadData(overloads, this);
@@ -4378,7 +4482,7 @@ void CppGenerator::writeMethodDefinitionEntry(QTextStream& s, const AbstractMeta
s << "|METH_STATIC";
}
-void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList overloads)
+void CppGenerator::writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList &overloads)
{
Q_ASSERT(!overloads.isEmpty());
const AbstractMetaFunction* func = overloads.constFirst();
@@ -4510,7 +4614,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
s << INDENT << "if (!" << cpythonTypeNameExt(cppEnum->typeEntry()) << ')' << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl << endl;
}
}
@@ -4543,7 +4647,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
<< "))->tp_dict, \"" << enumValue->name() << "\", anonEnumItem) < 0)" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << "Py_DECREF(anonEnumItem);" << endl;
}
@@ -4553,7 +4657,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
s << enumValueText << ") < 0)" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
}
break;
@@ -4564,7 +4668,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
Indentation indent(INDENT);
s << INDENT << enclosingObjectVariable << ", \"" << enumValue->name() << "\", ";
s << enumValueText << "))" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
break;
case EnumClass: {
@@ -4573,7 +4677,7 @@ void CppGenerator::writeEnumInitialization(QTextStream& s, const AbstractMetaEnu
Indentation indent(INDENT);
s << INDENT << enumVarTypeObj<< ", \"" << enumValue->name() << "\", "
<< enumValueText << "))" << endl
- << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ << INDENT << returnStatement(m_currentErrorCode) << endl;
}
break;
}
@@ -4618,11 +4722,11 @@ void CppGenerator::writeFlagsToLong(QTextStream& s, const AbstractMetaEnum* cppE
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
if (!flagsEntry)
return;
- s << "static PyObject* " << cpythonEnumName(cppEnum) << "_long(PyObject* " PYTHON_SELF_VAR ")" << endl;
+ s << "static PyObject* " << cpythonEnumName(cppEnum) << "_long(PyObject* self)" << endl;
s << "{" << endl;
s << INDENT << "int val;" << endl;
AbstractMetaType* flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry);
- s << INDENT << cpythonToCppConversionFunction(flagsType) << PYTHON_SELF_VAR << ", &val);" << endl;
+ s << INDENT << cpythonToCppConversionFunction(flagsType) << "self, &val);" << endl;
s << INDENT << "return Shiboken::Conversions::copyToPython(Shiboken::Conversions::PrimitiveTypeConverter<int>(), &val);" << endl;
s << "}" << endl;
}
@@ -4632,12 +4736,12 @@ void CppGenerator::writeFlagsNonZero(QTextStream& s, const AbstractMetaEnum* cpp
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
if (!flagsEntry)
return;
- s << "static int " << cpythonEnumName(cppEnum) << "__nonzero(PyObject* " PYTHON_SELF_VAR ")" << endl;
+ s << "static int " << cpythonEnumName(cppEnum) << "__nonzero(PyObject* self)" << endl;
s << "{" << endl;
s << INDENT << "int val;" << endl;
AbstractMetaType* flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry);
- s << INDENT << cpythonToCppConversionFunction(flagsType) << PYTHON_SELF_VAR << ", &val);" << endl;
+ s << INDENT << cpythonToCppConversionFunction(flagsType) << "self, &val);" << endl;
s << INDENT << "return val != 0;" << endl;
s << "}" << endl;
}
@@ -4679,24 +4783,24 @@ void CppGenerator::writeFlagsNumberMethodsDefinition(QTextStream& s, const Abstr
}
void CppGenerator::writeFlagsBinaryOperator(QTextStream& s, const AbstractMetaEnum* cppEnum,
- QString pyOpName, QString cppOpName)
+ const QString &pyOpName, const QString &cppOpName)
{
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
Q_ASSERT(flagsEntry);
- s << "PyObject* " << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* " PYTHON_SELF_VAR ", PyObject* " PYTHON_ARG ")" << endl;
+ s << "PyObject* " << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* self, PyObject* " << PYTHON_ARG << ")" << endl;
s << '{' << endl;
AbstractMetaType* flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry);
- s << INDENT << "::" << flagsEntry->originalName() << " cppResult, " CPP_SELF_VAR ", cppArg;" << endl;
+ 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(" PYTHON_SELF_VAR ");" << endl;
- s << INDENT << "cppArg = (" << flagsEntry->originalName() << ")(int)PyLong_AsLong(" PYTHON_ARG ");" << 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 << "#else" << endl;
- s << INDENT << CPP_SELF_VAR " = (::" << flagsEntry->originalName() << ")(int)PyInt_AsLong(" PYTHON_SELF_VAR ");" << endl;
- s << INDENT << "cppArg = (" << flagsEntry->originalName() << ")(int)PyInt_AsLong(" PYTHON_ARG ");" << 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 << "#endif" << endl << endl;
- s << INDENT << "cppResult = " CPP_SELF_VAR " " << cppOpName << " cppArg;" << endl;
+ s << INDENT << "cppResult = " << CPP_SELF_VAR << " " << cppOpName << " cppArg;" << endl;
s << INDENT << "return ";
writeToPythonConversion(s, flagsType, 0, QLatin1String("cppResult"));
s << ';' << endl;
@@ -4704,23 +4808,24 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream& s, const AbstractMetaEn
}
void CppGenerator::writeFlagsUnaryOperator(QTextStream& s, const AbstractMetaEnum* cppEnum,
- QString pyOpName, QString cppOpName, bool boolResult)
+ const QString &pyOpName,
+ const QString &cppOpName, bool boolResult)
{
FlagsTypeEntry* flagsEntry = cppEnum->typeEntry()->flags();
Q_ASSERT(flagsEntry);
- s << "PyObject* " << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* " PYTHON_SELF_VAR ", PyObject* " PYTHON_ARG ")" << endl;
+ s << "PyObject* " << cpythonEnumName(cppEnum) << "___" << pyOpName << "__(PyObject* self, PyObject* " << PYTHON_ARG << ")" << endl;
s << '{' << endl;
AbstractMetaType* flagsType = buildAbstractMetaTypeFromTypeEntry(flagsEntry);
- s << INDENT << "::" << flagsEntry->originalName() << " " CPP_SELF_VAR ";" << endl;
- s << INDENT << cpythonToCppConversionFunction(flagsType) << PYTHON_SELF_VAR << ", &" CPP_SELF_VAR ");" << endl;
+ s << INDENT << "::" << flagsEntry->originalName() << " " << CPP_SELF_VAR << ";" << endl;
+ s << INDENT << cpythonToCppConversionFunction(flagsType) << "self, &" << CPP_SELF_VAR << ");" << endl;
s << INDENT;
if (boolResult)
s << "bool";
else
s << "::" << flagsEntry->originalName();
- s << " cppResult = " << cppOpName << CPP_SELF_VAR ";" << endl;
+ s << " cppResult = " << cppOpName << CPP_SELF_VAR << ';' << endl;
s << INDENT << "return ";
if (boolResult)
s << "PyBool_FromLong(cppResult)";
@@ -4846,8 +4951,16 @@ void CppGenerator::writeClassRegister(QTextStream &s,
else
s << INDENT << "0," << endl;
- // 9:isInnerClass
- s << INDENT << (hasEnclosingClass ? "true" : "false") << endl;
+ // 9:wrapperflags
+ QByteArrayList wrapperFlags;
+ if (hasEnclosingClass)
+ wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::InnerClass"));
+ if (metaClass->deleteInMainThread())
+ wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::DeleteInMainThread"));
+ if (wrapperFlags.isEmpty())
+ s << INDENT << '0';
+ else
+ s << INDENT << wrapperFlags.join(" | ");
}
s << INDENT << ");" << endl;
s << INDENT << endl;
@@ -5042,25 +5155,27 @@ void CppGenerator::writeTypeDiscoveryFunction(QTextStream& s, const AbstractMeta
s << "}\n\n";
}
-QString CppGenerator::writeSmartPointerGetterCast() {
- return QLatin1String("const_cast<char *>(" SMART_POINTER_GETTER ")");
+QString CppGenerator::writeSmartPointerGetterCast()
+{
+ return QLatin1String("const_cast<char *>(")
+ + QLatin1String(SMART_POINTER_GETTER) + QLatin1Char(')');
}
void CppGenerator::writeSetattroFunction(QTextStream &s, GeneratorContext &context)
{
const AbstractMetaClass* metaClass = context.metaClass();
- s << "static int " << cpythonSetattroFunctionName(metaClass) << "(PyObject* " PYTHON_SELF_VAR ", PyObject* name, PyObject* value)" << endl;
+ s << "static int " << cpythonSetattroFunctionName(metaClass) << "(PyObject* self, PyObject* name, PyObject* value)" << endl;
s << '{' << endl;
if (usePySideExtensions()) {
- s << INDENT << "Shiboken::AutoDecRef pp(reinterpret_cast<PyObject*>(PySide::Property::getObject(" PYTHON_SELF_VAR ", name)));" << endl;
+ s << INDENT << "Shiboken::AutoDecRef pp(reinterpret_cast<PyObject*>(PySide::Property::getObject(self, name)));" << endl;
s << INDENT << "if (!pp.isNull())" << endl;
Indentation indent(INDENT);
- s << INDENT << "return PySide::Property::setValue(reinterpret_cast<PySideProperty*>(pp.object()), " PYTHON_SELF_VAR ", value);" << endl;
+ s << INDENT << "return PySide::Property::setValue(reinterpret_cast<PySideProperty*>(pp.object()), self, value);" << endl;
}
if (context.forSmartPointer()) {
s << INDENT << "// Try to find the 'name' attribute, by retrieving the PyObject for the corresponding C++ object held by the smart pointer." << endl;
- s << INDENT << "PyObject *rawObj = PyObject_CallMethod(" PYTHON_SELF_VAR ", "
+ s << INDENT << "PyObject *rawObj = PyObject_CallMethod(self, "
<< writeSmartPointerGetterCast() << ", 0);" << endl;
s << INDENT << "if (rawObj) {" << endl;
{
@@ -5078,7 +5193,7 @@ void CppGenerator::writeSetattroFunction(QTextStream &s, GeneratorContext &conte
}
- s << INDENT << "return PyObject_GenericSetAttr(" PYTHON_SELF_VAR ", name, value);" << endl;
+ s << INDENT << "return PyObject_GenericSetAttr(self, name, value);" << endl;
s << '}' << endl;
}
@@ -5088,27 +5203,29 @@ static inline QString qMetaObjectClassName() { return QStringLiteral("QMetaObjec
void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &context)
{
const AbstractMetaClass* metaClass = context.metaClass();
- s << "static PyObject* " << cpythonGetattroFunctionName(metaClass) << "(PyObject* " PYTHON_SELF_VAR ", PyObject* name)" << endl;
+ s << "static PyObject* " << cpythonGetattroFunctionName(metaClass) << "(PyObject* self, PyObject* name)" << endl;
s << '{' << endl;
QString getattrFunc;
if (usePySideExtensions() && metaClass->isQObject()) {
AbstractMetaClass *qobjectClass = AbstractMetaClass::findClass(classes(), qObjectClassName());
- getattrFunc = QString::fromLatin1("PySide::getMetaDataFromQObject(%1, " PYTHON_SELF_VAR ", name)")
- .arg(cpythonWrapperCPtr(qobjectClass, QLatin1String(PYTHON_SELF_VAR)));
+ QTextStream(&getattrFunc) << "PySide::getMetaDataFromQObject("
+ << cpythonWrapperCPtr(qobjectClass, QLatin1String("self"))
+ << ", self, name)";
} else {
- getattrFunc = QLatin1String("PyObject_GenericGetAttr(" PYTHON_SELF_VAR ", name)");
+ getattrFunc = QLatin1String("PyObject_GenericGetAttr(") + QLatin1String("self")
+ + QLatin1String(", name)");
}
if (classNeedsGetattroFunction(metaClass)) {
- s << INDENT << "if (" PYTHON_SELF_VAR ") {" << endl;
+ s << INDENT << "if (self) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "// Search the method in the instance dict" << endl;
- s << INDENT << "if (reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR ")->ob_dict) {" << endl;
+ s << INDENT << "if (reinterpret_cast<SbkObject*>(self)->ob_dict) {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "PyObject* meth = PyDict_GetItem(reinterpret_cast<SbkObject*>(" PYTHON_SELF_VAR ")->ob_dict, name);" << endl;
+ s << INDENT << "PyObject* meth = PyDict_GetItem(reinterpret_cast<SbkObject*>(self)->ob_dict, name);" << endl;
s << INDENT << "if (meth) {" << endl;
{
Indentation indent(INDENT);
@@ -5119,16 +5236,16 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte
}
s << INDENT << '}' << endl;
s << INDENT << "// Search the method in the type dict" << endl;
- s << INDENT << "if (Shiboken::Object::isUserType(" PYTHON_SELF_VAR ")) {" << endl;
+ s << INDENT << "if (Shiboken::Object::isUserType(self)) {" << endl;
{
Indentation indent(INDENT);
// PYSIDE-772: Perform optimized name mangling.
- s << INDENT << "Shiboken::AutoDecRef tmp(_Pep_PrivateMangle(" PYTHON_SELF_VAR ", name));" << endl;
- s << INDENT << "PyObject *meth = PyDict_GetItem(Py_TYPE(" PYTHON_SELF_VAR ")->tp_dict, tmp);" << endl;
+ s << INDENT << "Shiboken::AutoDecRef tmp(_Pep_PrivateMangle(self, name));" << endl;
+ s << INDENT << "PyObject *meth = PyDict_GetItem(Py_TYPE(self)->tp_dict, tmp);" << endl;
s << INDENT << "if (meth)" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "return PyFunction_Check(meth) ? SBK_PyMethod_New(meth, " PYTHON_SELF_VAR ") : " << getattrFunc << ';' << endl;
+ s << INDENT << "return PyFunction_Check(meth) ? SBK_PyMethod_New(meth, self) : " << getattrFunc << ';' << endl;
}
}
s << INDENT << '}' << endl;
@@ -5147,7 +5264,7 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte
s << INDENT << "};" << endl;
s << INDENT << "if (Shiboken::String::compare(name, \"" << func->name() << "\") == 0)" << endl;
Indentation indent(INDENT);
- s << INDENT << "return PyCFunction_NewEx(&non_static_" << defName << ", " PYTHON_SELF_VAR ", 0);" << endl;
+ s << INDENT << "return PyCFunction_NewEx(&non_static_" << defName << ", self, 0);" << endl;
}
}
s << INDENT << '}' << endl;
@@ -5168,7 +5285,7 @@ void CppGenerator::writeGetattroFunction(QTextStream& s, GeneratorContext &conte
s << INDENT << "// Try to find the 'name' attribute, by retrieving the PyObject for "
"the corresponding C++ object held by the smart pointer." << endl;
- s << INDENT << "PyObject *rawObj = PyObject_CallMethod(" PYTHON_SELF_VAR ", "
+ s << INDENT << "PyObject *rawObj = PyObject_CallMethod(self, "
<< writeSmartPointerGetterCast() << ", 0);" << endl;
s << INDENT << "if (rawObj) {" << endl;
{
@@ -5289,15 +5406,11 @@ bool CppGenerator::finishGeneration()
QString moduleFileName(outputDirectory() + QLatin1Char('/') + subDirectoryForPackage(packageName()));
moduleFileName += QLatin1Char('/') + moduleName().toLower() + QLatin1String("_module_wrapper.cpp");
- QFile file(moduleFileName);
- verifyDirectoryFor(file);
- if (!file.open(QFile::WriteOnly)) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Error writing file: " << QDir::toNativeSeparators(moduleFileName);
- return false;
- }
- QTextStream s(&file);
+ verifyDirectoryFor(moduleFileName);
+ FileOut file(moduleFileName);
+
+ QTextStream &s = file.stream;
// write license comment
s << licenseComment() << endl;
@@ -5305,10 +5418,10 @@ bool CppGenerator::finishGeneration()
s << "#include <sbkpython.h>" << endl;
s << "#include <shiboken.h>" << endl;
s << "#include <algorithm>" << endl;
+ s << "#include <signature.h>" << endl;
if (usePySideExtensions()) {
s << includeQDebug;
s << "#include <pyside.h>" << endl;
- s << "#include <signature.h>" << endl;
s << "#include <qapp_macro.h>" << endl;
}
@@ -5328,13 +5441,12 @@ bool CppGenerator::finishGeneration()
}
TypeDatabase* typeDb = TypeDatabase::instance();
- TypeSystemTypeEntry* moduleEntry = reinterpret_cast<TypeSystemTypeEntry*>(typeDb->findType(packageName()));
+ const TypeSystemTypeEntry *moduleEntry = typeDb->findTypeSystemType(packageName());
+ Q_ASSERT(moduleEntry);
//Extra includes
s << endl << "// Extra includes" << endl;
- QVector<Include> extraIncludes;
- if (moduleEntry)
- extraIncludes = moduleEntry->extraIncludes();
+ QVector<Include> extraIncludes = moduleEntry->extraIncludes();
for (AbstractMetaEnum *cppEnum : qAsConst(globalEnums))
extraIncludes.append(cppEnum->typeEntry()->extraIncludes());
qSort(extraIncludes.begin(), extraIncludes.end());
@@ -5343,14 +5455,15 @@ bool CppGenerator::finishGeneration()
s << endl;
s << "// Current module's type array." << endl;
- s << "PyTypeObject** " << cppApiVariableName() << ';' << endl;
+ s << "PyTypeObject** " << cppApiVariableName() << " = nullptr;" << endl;
+
+ s << "// Current module's PyObject pointer." << endl;
+ s << "PyObject* " << pythonModuleObjectName() << " = nullptr;" << endl;
s << "// Current module's converter array." << endl;
- s << "SbkConverter** " << convertersVariableName() << ';' << endl;
+ s << "SbkConverter** " << convertersVariableName() << " = nullptr;" << endl;
- CodeSnipList snips;
- if (moduleEntry)
- snips = moduleEntry->codeSnips();
+ const CodeSnipList snips = moduleEntry->codeSnips();
// module inject-code native/beginning
if (!snips.isEmpty()) {
@@ -5519,6 +5632,9 @@ bool CppGenerator::finishGeneration()
s << moduleName() << "_methods);" << endl;
s << "#endif" << endl << endl;
+ s << INDENT << "// Make module available from global scope" << endl;
+ s << INDENT << pythonModuleObjectName() << " = module;" << endl << endl;
+
//s << INDENT << "// Initialize converters for primitive types." << endl;
//s << INDENT << "initConverters();" << endl << endl;
@@ -5601,25 +5717,28 @@ bool CppGenerator::finishGeneration()
// cleanup staticMetaObject attribute
s << INDENT << "PySide::registerCleanupFunction(cleanTypesAttributes);" << endl << endl;
+ }
- // PYSIDE-510: Create a signatures string for the introspection feature.
- s << "// The signatures string for the global functions." << endl;
- s << "// Multiple signatures have their index \"n:\" in front." << endl;
- s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl;
- QString line;
- while (signatureStream.readLineInto(&line))
- s << INDENT << '"' << line << "\\n\"" << endl;
- s << ';' << endl;
- // finish the rest of __signature__ initialization.
- s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
- << "_SignaturesString);" << endl;
+ // PYSIDE-510: Create a signatures string for the introspection feature.
+ s << "// The signatures string for the global functions." << endl;
+ s << "// Multiple signatures have their index \"n:\" in front." << endl;
+ s << "const char " << moduleName() << "_SignaturesString[] = \"\"" << endl;
+ QString line;
+ while (signatureStream.readLineInto(&line))
+ s << INDENT << '"' << line << "\\n\"" << endl;
+ s << ';' << endl;
+ // finish the rest of __signature__ initialization.
+ s << INDENT << "FinishSignatureInitialization(module, " << moduleName()
+ << "_SignaturesString);" << endl;
+
+ if (usePySideExtensions()) {
// initialize the qApp module.
- s << INDENT << "NotifyModuleForQApp(module);" << endl << endl;
+ s << INDENT << "NotifyModuleForQApp(module);" << endl;
}
-
+ s << endl;
s << "SBK_MODULE_INIT_FUNCTION_END" << endl;
- return true;
+ return file.done() != FileOut::Failure;
}
static ArgumentOwner getArgumentOwner(const AbstractMetaFunction* func, int argIndex)
@@ -5663,22 +5782,20 @@ bool CppGenerator::writeParentChildManagement(QTextStream& s, const AbstractMeta
if (parentIndex == 0) {
parentVariable = QLatin1String(PYTHON_RETURN_VAR);
} else if (parentIndex == -1) {
- parentVariable = QLatin1String(PYTHON_SELF_VAR);
+ parentVariable = QLatin1String("self");
} else {
parentVariable = usePyArgs
- ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(parentIndex - 1)
- : QLatin1String(PYTHON_ARG);
+ ? pythonArgsAt(parentIndex - 1) : QLatin1String(PYTHON_ARG);
}
}
if (childIndex == 0) {
childVariable = QLatin1String(PYTHON_RETURN_VAR);
} else if (childIndex == -1) {
- childVariable = QLatin1String(PYTHON_SELF_VAR);
+ childVariable = QLatin1String("self");
} else {
childVariable = usePyArgs
- ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(childIndex - 1)
- : QLatin1String(PYTHON_ARG);
+ ? pythonArgsAt(childIndex - 1) : QLatin1String(PYTHON_ARG);
}
s << INDENT << "Shiboken::Object::setParent(" << parentVariable << ", " << childVariable << ");\n";
@@ -5717,7 +5834,7 @@ void CppGenerator::writeReturnValueHeuristics(QTextStream& s, const AbstractMeta
ArgumentOwner argOwner = getArgumentOwner(func, ArgumentOwner::ReturnIndex);
if (argOwner.action == ArgumentOwner::Invalid || argOwner.index != ArgumentOwner::ThisIndex) {
if (isPointerToWrapperType(type))
- s << INDENT << "Shiboken::Object::setParent(" << self << ", " PYTHON_RETURN_VAR ");" << endl;
+ s << INDENT << "Shiboken::Object::setParent(self, " << PYTHON_RETURN_VAR << ");" << endl;
}
}
@@ -5737,19 +5854,19 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
ErrorCode errorCode(0);
// __len__
- s << "Py_ssize_t " << cpythonBaseName(metaClass->typeEntry()) << "__len__(PyObject* " PYTHON_SELF_VAR ")" << endl;
+ s << "Py_ssize_t " << cpythonBaseName(metaClass->typeEntry()) << "__len__(PyObject* self)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, context);
- s << INDENT << "return " CPP_SELF_VAR "->size();" << endl;
+ s << INDENT << "return " << CPP_SELF_VAR << "->size();" << endl;
s << '}' << endl;
// __getitem__
- s << "PyObject* " << cpythonBaseName(metaClass->typeEntry()) << "__getitem__(PyObject* " PYTHON_SELF_VAR ", Py_ssize_t _i)" << endl;
+ s << "PyObject* " << cpythonBaseName(metaClass->typeEntry()) << "__getitem__(PyObject* self, Py_ssize_t _i)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, context);
writeIndexError(s, QLatin1String("index out of bounds"));
- s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " CPP_SELF_VAR "->begin();" << endl;
+ s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " << CPP_SELF_VAR << "->begin();" << endl;
s << INDENT << "for (Py_ssize_t pos = 0; pos < _i; pos++) _item++;" << endl;
const AbstractMetaType* itemType = metaClass->templateBaseClassInstantiations().constFirst();
@@ -5761,7 +5878,7 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
// __setitem__
ErrorCode errorCode2(-1);
- s << "int " << cpythonBaseName(metaClass->typeEntry()) << "__setitem__(PyObject* " PYTHON_SELF_VAR ", Py_ssize_t _i, PyObject* pyArg)" << endl;
+ s << "int " << cpythonBaseName(metaClass->typeEntry()) << "__setitem__(PyObject* self, Py_ssize_t _i, PyObject* pyArg)" << endl;
s << '{' << endl;
writeCppSelfDefinition(s, context);
writeIndexError(s, QLatin1String("list assignment index out of range"));
@@ -5779,7 +5896,7 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
s << INDENT << '}' << endl;
writeArgumentConversion(s, itemType, QLatin1String("cppValue"), QLatin1String("pyArg"), metaClass);
- s << INDENT << metaClass->qualifiedCppName() << "::iterator _item = " CPP_SELF_VAR "->begin();" << endl;
+ 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;
@@ -5787,11 +5904,11 @@ void CppGenerator::writeStdListWrapperMethods(QTextStream &s, GeneratorContext &
}
void CppGenerator::writeIndexError(QTextStream& s, const QString& errorMsg)
{
- s << INDENT << "if (_i < 0 || _i >= (Py_ssize_t) " CPP_SELF_VAR "->size()) {" << endl;
+ s << INDENT << "if (_i < 0 || _i >= (Py_ssize_t) " << CPP_SELF_VAR << "->size()) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_IndexError, \"" << errorMsg << "\");" << endl;
- s << INDENT << "return " << m_currentErrorCode << ';' << endl;
+ s << INDENT << returnStatement(m_currentErrorCode) << endl;
}
s << INDENT << '}' << endl;
}
@@ -5808,7 +5925,10 @@ QString CppGenerator::writeReprFunction(QTextStream &s, GeneratorContext &contex
s << INDENT << "QBuffer buffer;" << endl;
s << INDENT << "buffer.open(QBuffer::ReadWrite);" << endl;
s << INDENT << "QDebug dbg(&buffer);" << endl;
- s << INDENT << "dbg << " << (metaClass->typeEntry()->isValue() ? "*" : "") << CPP_SELF_VAR ";" << endl;
+ s << INDENT << "dbg << ";
+ if (metaClass->typeEntry()->isValue())
+ s << '*';
+ s << CPP_SELF_VAR << ';' << endl;
s << INDENT << "buffer.close();" << endl;
s << INDENT << "QByteArray str = buffer.data();" << endl;
s << INDENT << "int idx = str.indexOf('(');" << endl;
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.h b/sources/shiboken2/generator/shiboken2/cppgenerator.h
index 1b59bcda7..55a1c265d 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.h
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.h
@@ -234,8 +234,8 @@ private:
void writeClassDefinition(QTextStream &s,
const AbstractMetaClass *metaClass,
GeneratorContext &classContext);
- void writeMethodDefinitionEntry(QTextStream& s, const AbstractMetaFunctionList overloads);
- void writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList overloads);
+ void writeMethodDefinitionEntry(QTextStream& s, const AbstractMetaFunctionList &overloads);
+ void writeMethodDefinition(QTextStream& s, const AbstractMetaFunctionList &overloads);
void writeSignatureInfo(QTextStream &s, const AbstractMetaFunctionList &overloads);
/// Writes the implementation of all methods part of python sequence protocol
void writeSequenceMethods(QTextStream &s,
@@ -275,9 +275,10 @@ private:
void writeFlagsNonZero(QTextStream& s, const AbstractMetaEnum* cppEnum);
void writeFlagsNumberMethodsDefinition(QTextStream& s, const AbstractMetaEnum* cppEnum);
void writeFlagsBinaryOperator(QTextStream& s, const AbstractMetaEnum* cppEnum,
- QString pyOpName, QString cppOpName);
+ const QString &pyOpName, const QString &cppOpName);
void writeFlagsUnaryOperator(QTextStream& s, const AbstractMetaEnum* cppEnum,
- QString pyOpName, QString cppOpName, bool boolResult = false);
+ const QString &pyOpName, const QString &cppOpName,
+ bool boolResult = false);
/// Writes the function that registers the multiple inheritance information for the classes that need it.
void writeMultipleInheritanceInitializerFunction(QTextStream& s, const AbstractMetaClass* metaClass);
@@ -292,7 +293,7 @@ private:
void writeParentChildManagement(QTextStream& s, const AbstractMetaFunction* func, bool userHeuristicForReturn);
bool writeParentChildManagement(QTextStream& s, const AbstractMetaFunction* func, int argIndex, bool userHeuristicPolicy);
- void writeReturnValueHeuristics(QTextStream& s, const AbstractMetaFunction* func, const QString& self = QLatin1String(PYTHON_SELF_VAR));
+ void writeReturnValueHeuristics(QTextStream& s, const AbstractMetaFunction* func, const QString& self = QLatin1String("self"));
void writeInitQtMetaTypeFunctionBody(QTextStream &s, GeneratorContext &context) const;
/**
@@ -327,7 +328,9 @@ private:
QString writeReprFunction(QTextStream &s, GeneratorContext &context);
- bool hasBoolCast(const AbstractMetaClass* metaClass) const;
+ const AbstractMetaFunction *boolCast(const AbstractMetaClass* metaClass) const;
+ bool hasBoolCast(const AbstractMetaClass* metaClass) const
+ { return boolCast(metaClass) != nullptr; }
// Number protocol structure members names.
static QHash<QString, QString> m_nbFuncs;
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.cpp b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
index 8fde3cd31..8881d71f4 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.cpp
@@ -32,6 +32,8 @@
#include <reporthandler.h>
#include <fileout.h>
+#include <algorithm>
+
#include <QtCore/QDir>
#include <QtCore/QTextStream>
#include <QtCore/QVariant>
@@ -49,11 +51,10 @@ QString HeaderGenerator::fileNameForContext(GeneratorContext &context) const
QString fileNameBase = metaClass->qualifiedCppName().toLower();
fileNameBase.replace(QLatin1String("::"), QLatin1String("_"));
return fileNameBase + fileNameSuffix();
- } else {
- const AbstractMetaType *smartPointerType = context.preciseType();
- QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass);
- return fileNameBase + fileNameSuffix();
}
+ const AbstractMetaType *smartPointerType = context.preciseType();
+ QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass);
+ return fileNameBase + fileNameSuffix();
}
void HeaderGenerator::writeCopyCtor(QTextStream& s, const AbstractMetaClass* metaClass) const
@@ -116,8 +117,6 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
if (!avoidProtectedHack())
s << "#define protected public" << endl << endl;
- s << "#include <shiboken.h>" << endl << endl;
-
//Includes
s << metaClass->typeEntry()->include() << endl;
@@ -173,7 +172,7 @@ void HeaderGenerator::generateClass(QTextStream &s, GeneratorContext &classConte
s << INDENT << "void* qt_metacast(const char* _clname) override;" << endl;
}
- if (m_inheritedOverloads.size()) {
+ if (!m_inheritedOverloads.isEmpty()) {
s << INDENT << "// Inherited overloads, because the using keyword sux" << endl;
writeInheritedOverloads(s);
m_inheritedOverloads.clear();
@@ -230,7 +229,7 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
QString argName = arg->name();
const TypeEntry* enumTypeEntry = 0;
if (arg->type()->isFlags())
- enumTypeEntry = reinterpret_cast<const FlagsTypeEntry*>(arg->type()->typeEntry())->originator();
+ enumTypeEntry = static_cast<const FlagsTypeEntry*>(arg->type()->typeEntry())->originator();
else if (arg->type()->isEnum())
enumTypeEntry = arg->type()->typeEntry();
if (enumTypeEntry)
@@ -284,49 +283,86 @@ void HeaderGenerator::writeFunction(QTextStream& s, const AbstractMetaFunction*
}
}
-static void _writeTypeIndexDefineLine(QTextStream& s, const QString& variableName, int typeIndex)
+static void _writeTypeIndexValue(QTextStream& s, const QString& variableName,
+ int typeIndex)
{
- s << "#define ";
- s.setFieldWidth(60);
+ s << " ";
+ s.setFieldWidth(56);
s << variableName;
s.setFieldWidth(0);
- s << ' ' << typeIndex << endl;
+ s << " = " << typeIndex;
+}
+
+static inline void _writeTypeIndexValueLine(QTextStream& s,
+ const QString& variableName,
+ int typeIndex)
+{
+ _writeTypeIndexValue(s, variableName, typeIndex);
+ s << ",\n";
}
-void HeaderGenerator::writeTypeIndexDefineLine(QTextStream& s, const TypeEntry* typeEntry)
+
+void HeaderGenerator::writeTypeIndexValueLine(QTextStream& s, const TypeEntry* typeEntry)
{
if (!typeEntry || !typeEntry->generateCode())
return;
s.setFieldAlignment(QTextStream::AlignLeft);
- int typeIndex = getTypeIndex(typeEntry);
- _writeTypeIndexDefineLine(s, getTypeIndexVariableName(typeEntry), typeIndex);
+ const int typeIndex = typeEntry->sbkIndex();
+ _writeTypeIndexValueLine(s, getTypeIndexVariableName(typeEntry), typeIndex);
if (typeEntry->isComplex()) {
- const ComplexTypeEntry* cType = reinterpret_cast<const ComplexTypeEntry*>(typeEntry);
+ const ComplexTypeEntry* cType = static_cast<const ComplexTypeEntry*>(typeEntry);
if (cType->baseContainerType()) {
const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes(), cType);
if (metaClass->templateBaseClass())
- _writeTypeIndexDefineLine(s, getTypeIndexVariableName(metaClass, true), typeIndex);
+ _writeTypeIndexValueLine(s, getTypeIndexVariableName(metaClass, true), typeIndex);
}
}
if (typeEntry->isEnum()) {
- const EnumTypeEntry* ete = reinterpret_cast<const EnumTypeEntry*>(typeEntry);
+ const EnumTypeEntry* ete = static_cast<const EnumTypeEntry*>(typeEntry);
if (ete->flags())
- writeTypeIndexDefineLine(s, ete->flags());
+ writeTypeIndexValueLine(s, ete->flags());
}
}
-void HeaderGenerator::writeTypeIndexDefine(QTextStream& s, const AbstractMetaClass* metaClass)
+void HeaderGenerator::writeTypeIndexValueLines(QTextStream& s, const AbstractMetaClass* metaClass)
{
if (!metaClass->typeEntry()->generateCode())
return;
- writeTypeIndexDefineLine(s, metaClass->typeEntry());
+ writeTypeIndexValueLine(s, metaClass->typeEntry());
const AbstractMetaEnumList &enums = metaClass->enums();
for (const AbstractMetaEnum *metaEnum : enums) {
if (metaEnum->isPrivate())
continue;
- writeTypeIndexDefineLine(s, metaEnum->typeEntry());
+ writeTypeIndexValueLine(s, metaEnum->typeEntry());
}
}
+// Format the typedefs for the typedef entries to be generated
+static void formatTypeDefEntries(QTextStream &s)
+{
+ QVector<const TypedefEntry *> entries;
+ const auto typeDbEntries = TypeDatabase::instance()->typedefEntries();
+ for (auto it = typeDbEntries.cbegin(), end = typeDbEntries.cend(); it != end; ++it) {
+ if (it.value()->generateCode() != 0)
+ entries.append(it.value());
+ }
+ if (entries.isEmpty())
+ return;
+ s << "\n// typedef entries\n";
+ for (const auto e : entries) {
+ const QString name = e->qualifiedCppName();
+ // Fixme: simplify by using nested namespaces in C++ 17.
+ const auto components = name.splitRef(QLatin1String("::"));
+ const int nameSpaceCount = components.size() - 1;
+ for (int n = 0; n < nameSpaceCount; ++n)
+ s << "namespace " << components.at(n) << " {\n";
+ s << "using " << components.constLast() << " = " << e->sourceType() << ";\n";
+ for (int n = 0; n < nameSpaceCount; ++n)
+ s << "}\n";
+ }
+ s << '\n';
+}
+
+
bool HeaderGenerator::finishGeneration()
{
// Generate the main header for this module.
@@ -342,47 +378,49 @@ bool HeaderGenerator::finishGeneration()
Indentation indent(INDENT);
- macrosStream << "// Type indices" << endl;
+ macrosStream << "// Type indices\nenum : int {\n";
AbstractMetaEnumList globalEnums = this->globalEnums();
- const AbstractMetaClassList &classList = classes();
+ AbstractMetaClassList classList = classes();
+
+ std::sort(classList.begin(), classList.end(), [](AbstractMetaClass *a, AbstractMetaClass* b) {
+ return a->typeEntry()->sbkIndex() < b->typeEntry()->sbkIndex();
+ });
+
for (const AbstractMetaClass *metaClass : classList) {
- writeTypeIndexDefine(macrosStream, metaClass);
+ writeTypeIndexValueLines(macrosStream, metaClass);
lookForEnumsInClassesNotToBeGenerated(globalEnums, metaClass);
}
for (const AbstractMetaEnum *metaEnum : qAsConst(globalEnums))
- writeTypeIndexDefineLine(macrosStream, metaEnum->typeEntry());
+ writeTypeIndexValueLine(macrosStream, metaEnum->typeEntry());
// Write the smart pointer define indexes.
int smartPointerCountIndex = getMaxTypeIndex();
int smartPointerCount = 0;
const QVector<const AbstractMetaType *> &instantiatedSmartPtrs = instantiatedSmartPointers();
for (const AbstractMetaType *metaType : instantiatedSmartPtrs) {
- QString variableName = getTypeIndexVariableName(metaType);
- macrosStream << "#define ";
- macrosStream.setFieldWidth(60);
- macrosStream << variableName;
- macrosStream.setFieldWidth(0);
- macrosStream << ' ' << smartPointerCountIndex << " // " << metaType->cppSignature()
- << endl;
+ _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(metaType),
+ smartPointerCountIndex);
+ macrosStream << ", // " << metaType->cppSignature() << endl;
++smartPointerCountIndex;
++smartPointerCount;
}
+ _writeTypeIndexValue(macrosStream,
+ QLatin1String("SBK_") + moduleName() + QLatin1String("_IDX_COUNT"),
+ getMaxTypeIndex() + smartPointerCount);
+ macrosStream << "\n};\n";
- macrosStream << "#define ";
- macrosStream.setFieldWidth(60);
- macrosStream << QLatin1String("SBK_") + moduleName() + QLatin1String("_IDX_COUNT");
- macrosStream.setFieldWidth(0);
- macrosStream << ' ' << getMaxTypeIndex() + smartPointerCount << endl << endl;
macrosStream << "// This variable stores all Python types exported by this module." << endl;
macrosStream << "extern PyTypeObject** " << cppApiVariableName() << ';' << endl << endl;
+ macrosStream << "// This variable stores the Python module object exported by this module." << endl;
+ macrosStream << "extern PyObject* " << pythonModuleObjectName() << ';' << endl << endl;
macrosStream << "// This variable stores all type converters exported by this module." << endl;
macrosStream << "extern SbkConverter** " << convertersVariableName() << ';' << endl << endl;
// TODO-CONVERTER ------------------------------------------------------------------------------
// Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex().
- macrosStream << "// Converter indices" << endl;
+ macrosStream << "// Converter indices\nenum : int {\n";
const PrimitiveTypeEntryList &primitives = primitiveTypes();
int pCount = 0;
for (const PrimitiveTypeEntry *ptype : primitives) {
@@ -393,28 +431,25 @@ bool HeaderGenerator::finishGeneration()
if (!ptype->generateCode() || !ptype->customConversion())
continue;
- _writeTypeIndexDefineLine(macrosStream, getTypeIndexVariableName(ptype), pCount++);
+ _writeTypeIndexValueLine(macrosStream, getTypeIndexVariableName(ptype), pCount++);
}
const QVector<const AbstractMetaType *> &containers = instantiatedContainers();
for (const AbstractMetaType *container : containers) {
- //_writeTypeIndexDefineLine(macrosStream, getTypeIndexVariableName(container), pCount);
- // DEBUG
- QString variableName = getTypeIndexVariableName(container);
- macrosStream << "#define ";
- macrosStream.setFieldWidth(60);
- macrosStream << variableName;
- macrosStream.setFieldWidth(0);
- macrosStream << ' ' << pCount << " // " << container->cppSignature() << endl;
- // DEBUG
+ _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount);
+ macrosStream << ", // " << container->cppSignature() << endl;
pCount++;
}
// Because on win32 the compiler will not accept a zero length array.
if (pCount == 0)
pCount++;
- _writeTypeIndexDefineLine(macrosStream, QStringLiteral("SBK_%1_CONVERTERS_IDX_COUNT").arg(moduleName()), pCount);
- macrosStream << endl;
+ _writeTypeIndexValue(macrosStream, QStringLiteral("SBK_%1_CONVERTERS_IDX_COUNT")
+ .arg(moduleName()), pCount);
+ macrosStream << "\n};\n";
+
+ formatTypeDefEntries(macrosStream);
+
// TODO-CONVERTER ------------------------------------------------------------------------------
macrosStream << "// Macros for type check" << endl;
@@ -474,12 +509,6 @@ bool HeaderGenerator::finishGeneration()
s << "#include <sbkpython.h>" << endl;
s << "#include <sbkconverter.h>" << endl;
- s << "#include <sbkenum.h>" << endl;
- s << "#include <basewrapper.h>" << endl;
- s << "#include <bindingmanager.h>" << endl;
- s << "#include <memory>" << endl << endl;
- if (usePySideExtensions())
- s << "#include <pysidesignal.h>" << endl;
QStringList requiredTargetImports = TypeDatabase::instance()->requiredTargetImports();
if (!requiredTargetImports.isEmpty()) {
@@ -580,7 +609,7 @@ void HeaderGenerator::writeInheritedOverloads(QTextStream& s)
QString argName = arg->name();
const TypeEntry* enumTypeEntry = 0;
if (arg->type()->isFlags())
- enumTypeEntry = reinterpret_cast<const FlagsTypeEntry*>(arg->type()->typeEntry())->originator();
+ enumTypeEntry = static_cast<const FlagsTypeEntry*>(arg->type()->typeEntry())->originator();
else if (arg->type()->isEnum())
enumTypeEntry = arg->type()->typeEntry();
if (enumTypeEntry)
diff --git a/sources/shiboken2/generator/shiboken2/headergenerator.h b/sources/shiboken2/generator/shiboken2/headergenerator.h
index acf0448a7..821531aab 100644
--- a/sources/shiboken2/generator/shiboken2/headergenerator.h
+++ b/sources/shiboken2/generator/shiboken2/headergenerator.h
@@ -55,8 +55,8 @@ private:
void writeSbkTypeFunction(QTextStream& s, const AbstractMetaEnum* cppEnum);
void writeSbkTypeFunction(QTextStream& s, const AbstractMetaClass* cppClass);
void writeSbkTypeFunction(QTextStream &s, const AbstractMetaType *metaType);
- void writeTypeIndexDefineLine(QTextStream& s, const TypeEntry* typeEntry);
- void writeTypeIndexDefine(QTextStream& s, const AbstractMetaClass* metaClass);
+ void writeTypeIndexValueLine(QTextStream& s, const TypeEntry* typeEntry);
+ void writeTypeIndexValueLines(QTextStream& s, const AbstractMetaClass* metaClass);
void writeProtectedEnumSurrogate(QTextStream& s, const AbstractMetaEnum* cppEnum);
void writeInheritedOverloads(QTextStream& s);
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
index 73198ba12..a95603754 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp
@@ -94,8 +94,6 @@ static bool typesAreEqual(const AbstractMetaType* typeA, const AbstractMetaType*
*/
struct OverloadSortData
{
- OverloadSortData() : counter(0) {}
-
/**
* Adds a typeName into the type map without associating it with
* a OverloadData. This is done to express type dependencies that could
@@ -121,7 +119,7 @@ struct OverloadSortData
int lastProcessedItemId() { return counter - 1; }
- int counter;
+ int counter = 0;
QHash<QString, int> map; // typeName -> id
QHash<int, OverloadData*> reverseMap; // id -> OverloadData;
};
@@ -149,11 +147,11 @@ static QString getImplicitConversionTypeName(const AbstractMetaType* containerTy
for (const AbstractMetaType *otherType : instantiations)
types << (otherType == instantiation ? impConv : getTypeName(otherType));
- const ContainerTypeEntry* containerTypeEntry = dynamic_cast<const ContainerTypeEntry*>(containerType->typeEntry());
- return containerTypeEntry->qualifiedCppName() + QLatin1Char('<')
+ return containerType->typeEntry()->qualifiedCppName() + QLatin1Char('<')
+ types.join(QLatin1String(", ")) + QLatin1String(" >");
}
+// overloaddata.cpp
static QString msgCyclicDependency(const QString &funcName, const QString &graphName,
const OverloadData::MetaFunctionList &involvedConversions)
{
@@ -499,7 +497,8 @@ OverloadData::OverloadData(const AbstractMetaFunctionList& overloads, const Shib
OverloadData::OverloadData(OverloadData* headOverloadData, const AbstractMetaFunction* func,
const AbstractMetaType* argType, int argPos)
: m_minArgs(256), m_maxArgs(0), m_argPos(argPos), m_argType(argType),
- m_headOverloadData(headOverloadData), m_previousOverloadData(0)
+ m_headOverloadData(headOverloadData), m_previousOverloadData(nullptr),
+ m_generator(nullptr)
{
if (func)
this->addOverload(func);
@@ -808,8 +807,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList&
{
int minArgs = 10000;
int maxArgs = 0;
- for (int i = 0; i < overloads.size(); i++) {
- const AbstractMetaFunction* func = overloads[i];
+ for (const AbstractMetaFunction *func : overloads) {
int origNumArgs = func->arguments().size();
int removed = numberOfRemovedArguments(func);
int numArgs = origNumArgs - removed;
@@ -825,7 +823,7 @@ QPair<int, int> OverloadData::getMinMaxArguments(const AbstractMetaFunctionList&
minArgs = fixedArgIndex;
}
}
- return QPair<int, int>(minArgs, maxArgs);
+ return {minArgs, maxArgs};
}
bool OverloadData::isSingleArgument(const AbstractMetaFunctionList& overloads)
@@ -840,7 +838,7 @@ bool OverloadData::isSingleArgument(const AbstractMetaFunctionList& overloads)
return singleArgument;
}
-void OverloadData::dumpGraph(QString filename) const
+void OverloadData::dumpGraph(const QString &filename) const
{
QFile file(filename);
if (file.open(QFile::WriteOnly)) {
diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.h b/sources/shiboken2/generator/shiboken2/overloaddata.h
index 435c19aa2..4759ca9c3 100644
--- a/sources/shiboken2/generator/shiboken2/overloaddata.h
+++ b/sources/shiboken2/generator/shiboken2/overloaddata.h
@@ -114,7 +114,7 @@ public:
/// Returns true if all overloads have no more than one argument.
static bool isSingleArgument(const AbstractMetaFunctionList& overloads);
- void dumpGraph(QString filename) const;
+ void dumpGraph(const QString &filename) const;
QString dumpGraph() const;
bool hasArgumentTypeReplace() const;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 80096cbf2..b9eea7529 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -28,9 +28,11 @@
#include "shibokengenerator.h"
#include <abstractmetalang.h>
+#include <messages.h>
#include "overloaddata.h"
#include <reporthandler.h>
#include <typedatabase.h>
+#include <abstractmetabuilder.h>
#include <iostream>
#include <QtCore/QDir>
@@ -39,13 +41,29 @@
#include <limits>
#include <memory>
-#define NULL_VALUE "NULL"
-#define AVOID_PROTECTED_HACK "avoid-protected-hack"
-#define PARENT_CTOR_HEURISTIC "enable-parent-ctor-heuristic"
-#define RETURN_VALUE_HEURISTIC "enable-return-value-heuristic"
-#define ENABLE_PYSIDE_EXTENSIONS "enable-pyside-extensions"
-#define DISABLE_VERBOSE_ERROR_MESSAGES "disable-verbose-error-messages"
-#define USE_ISNULL_AS_NB_NONZERO "use-isnull-as-nb_nonzero"
+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";
+static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
+static const char DISABLE_VERBOSE_ERROR_MESSAGES[] = "disable-verbose-error-messages";
+static const char USE_ISNULL_AS_NB_NONZERO[] = "use-isnull-as-nb_nonzero";
+
+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 *PYTHON_ARG = "pyArg";
+const char *PYTHON_ARGS = "pyArgs";
+const char *PYTHON_OVERRIDE_VAR = "pyOverride";
+const char *PYTHON_RETURN_VAR = "pyResult";
+const char *PYTHON_TO_CPP_VAR = "pythonToCpp";
+const char *SMART_POINTER_GETTER = "kSmartPointerGetter";
+
+const char *CONV_RULE_OUT_VAR_SUFFIX = "_out";
+const char *BEGIN_ALLOW_THREADS =
+ "PyThreadState* _save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS";
+const char *END_ALLOW_THREADS = "PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS";
//static void dumpFunction(AbstractMetaFunctionList lst);
@@ -100,7 +118,7 @@ static QString resolveScopePrefix(const AbstractMetaEnum *metaEnum,
return resolveScopePrefix(parts, value);
}
-ShibokenGenerator::ShibokenGenerator() : Generator()
+ShibokenGenerator::ShibokenGenerator()
{
if (m_pythonPrimitiveTypeName.isEmpty())
ShibokenGenerator::initPrimitiveTypesCorrespondences();
@@ -117,17 +135,19 @@ ShibokenGenerator::ShibokenGenerator() : Generator()
m_typeSystemConvName[TypeSystemIsConvertibleFunction] = QLatin1String("isConvertible");
m_typeSystemConvName[TypeSystemToCppFunction] = QLatin1String("toCpp");
m_typeSystemConvName[TypeSystemToPythonFunction] = QLatin1String("toPython");
+
+ const char CHECKTYPE_REGEX[] = R"(%CHECKTYPE\[([^\[]*)\]\()";
+ const char ISCONVERTIBLE_REGEX[] = R"(%ISCONVERTIBLE\[([^\[]*)\]\()";
+ const char CONVERTTOPYTHON_REGEX[] = R"(%CONVERTTOPYTHON\[([^\[]*)\]\()";
+ const char CONVERTTOCPP_REGEX[] =
+ R"((\*?%?[a-zA-Z_][\w\.]*(?:\[[^\[^<^>]+\])*)(?:\s+)=(?:\s+)%CONVERTTOCPP\[([^\[]*)\]\()";
m_typeSystemConvRegEx[TypeSystemCheckFunction] = QRegularExpression(QLatin1String(CHECKTYPE_REGEX));
m_typeSystemConvRegEx[TypeSystemIsConvertibleFunction] = QRegularExpression(QLatin1String(ISCONVERTIBLE_REGEX));
m_typeSystemConvRegEx[TypeSystemToPythonFunction] = QRegularExpression(QLatin1String(CONVERTTOPYTHON_REGEX));
m_typeSystemConvRegEx[TypeSystemToCppFunction] = QRegularExpression(QLatin1String(CONVERTTOCPP_REGEX));
}
-ShibokenGenerator::~ShibokenGenerator()
-{
- // TODO-CONVERTER: it must be caching types that were not created here.
- //qDeleteAll(m_metaTypeFromStringCache.values());
-}
+ShibokenGenerator::~ShibokenGenerator() = default;
void ShibokenGenerator::clearTpFuncs()
{
@@ -277,7 +297,7 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass* metaCl
for (const AbstractMetaFunction *func : funcs) {
if (!func->isProtected() || func->isSignal() || func->isModifiedRemoved())
continue;
- else if (func->isOperatorOverload())
+ if (func->isOperatorOverload())
protectedOperators++;
else
protectedFunctions++;
@@ -332,9 +352,8 @@ QString ShibokenGenerator::wrapperName(const AbstractMetaClass* metaClass) const
result += QLatin1String("Wrapper");
return result;
- } else {
- return metaClass->qualifiedCppName();
}
+ return metaClass->qualifiedCppName();
}
QString ShibokenGenerator::wrapperName(const AbstractMetaType *metaType) const
@@ -342,7 +361,19 @@ QString ShibokenGenerator::wrapperName(const AbstractMetaType *metaType) const
return metaType->cppSignature();
}
-QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction* func)
+QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClass)
+{
+ QString fullClassName = metaClass->name();
+ const AbstractMetaClass *enclosing = metaClass->enclosingClass();
+ while (enclosing) {
+ fullClassName.prepend(enclosing->name() + QLatin1Char('.'));
+ enclosing = enclosing->enclosingClass();
+ }
+ fullClassName.prepend(packageName() + QLatin1Char('.'));
+ return fullClassName;
+}
+
+QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction *func) //WS
{
QString funcName;
if (func->isOperatorOverload())
@@ -350,11 +381,11 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunction* fu
else
funcName = func->name();
if (func->ownerClass()) {
- QString fullName = func->ownerClass()->fullName();
+ QString fullClassName = fullPythonClassName(func->ownerClass());
if (func->isConstructor())
- funcName = fullName;
+ funcName = fullClassName;
else
- funcName.prepend(fullName + QLatin1Char('.'));
+ funcName.prepend(fullClassName + QLatin1Char('.'));
}
else {
funcName = packageName() + QLatin1Char('.') + func->name();
@@ -434,7 +465,8 @@ QString ShibokenGenerator::cpythonSetterFunctionName(const AbstractMetaField* me
return QStringLiteral("%1_set_%2").arg(cpythonBaseName(metaField->enclosingClass()), metaField->name());
}
-static QString cpythonEnumFlagsName(QString moduleName, QString qualifiedCppName)
+static QString cpythonEnumFlagsName(const QString &moduleName,
+ const QString &qualifiedCppName)
{
QString result = QStringLiteral("Sbk%1_%2").arg(moduleName, qualifiedCppName);
result.replace(QLatin1String("::"), QLatin1String("_"));
@@ -570,7 +602,7 @@ QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunction
fieldName.prepend(prefix);
prefix.clear();
} else {
- fieldName.prepend(QLatin1String(CPP_SELF_VAR "->"));
+ fieldName.prepend(QLatin1String(CPP_SELF_VAR) + QLatin1String("->"));
}
value.replace(match.captured(1), fieldName);
break;
@@ -616,12 +648,14 @@ QString ShibokenGenerator::cpythonSpecialCastFunctionName(const AbstractMetaClas
return cpythonBaseName(metaClass->typeEntry()) + QLatin1String("SpecialCastFunction");
}
-QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaClass* metaClass, QString argName)
+QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaClass* metaClass,
+ const QString &argName)
{
return cpythonWrapperCPtr(metaClass->typeEntry(), argName);
}
-QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType *metaType, QString argName)
+QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType *metaType,
+ const QString &argName)
{
if (!ShibokenGenerator::isWrapperType(metaType->typeEntry()))
return QString();
@@ -630,7 +664,8 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType *metaType,
+ QLatin1String(", reinterpret_cast<SbkObject *>(") + argName + QLatin1String(")))");
}
-QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntry* type, QString argName)
+QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntry* type,
+ const QString &argName)
{
if (!ShibokenGenerator::isWrapperType(type))
return QString();
@@ -706,7 +741,8 @@ QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunction* func,
|| arg->type()->referenceType() == LValueReference) {
result += QLatin1Char(objType);
} else if (arg->type()->isPrimitive()) {
- const PrimitiveTypeEntry* ptype = (const PrimitiveTypeEntry*) arg->type()->typeEntry();
+ const PrimitiveTypeEntry *ptype =
+ static_cast<const PrimitiveTypeEntry *>(arg->type()->typeEntry());
if (ptype->basicReferencedTypeEntry())
ptype = ptype->basicReferencedTypeEntry();
if (m_formatUnits.contains(ptype->name()))
@@ -745,7 +781,7 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntry* type)
if (ShibokenGenerator::isWrapperType(type) || type->isNamespace()) { // && type->referenceType() == NoReference) {
baseName = QLatin1String("Sbk_") + type->name();
} else if (type->isPrimitive()) {
- const PrimitiveTypeEntry* ptype = (const PrimitiveTypeEntry*) type;
+ const PrimitiveTypeEntry *ptype = static_cast<const PrimitiveTypeEntry *>(type);
while (ptype->basicReferencedTypeEntry())
ptype = ptype->basicReferencedTypeEntry();
if (ptype->targetLangApiName() == ptype->name())
@@ -753,11 +789,11 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntry* type)
else
baseName = ptype->targetLangApiName();
} else if (type->isEnum()) {
- baseName = cpythonEnumName((const EnumTypeEntry*) type);
+ baseName = cpythonEnumName(static_cast<const EnumTypeEntry *>(type));
} else if (type->isFlags()) {
- baseName = cpythonFlagsName((const FlagsTypeEntry*) type);
+ baseName = cpythonFlagsName(static_cast<const FlagsTypeEntry *>(type));
} else if (type->isContainer()) {
- const ContainerTypeEntry* ctype = (const ContainerTypeEntry*) type;
+ const ContainerTypeEntry *ctype = static_cast<const ContainerTypeEntry *>(type);
switch (ctype->type()) {
case ContainerTypeEntry::ListContainer:
case ContainerTypeEntry::StringListContainer:
@@ -858,14 +894,6 @@ QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType* type)
+ getTypeIndexVariableName(type) + QLatin1Char(']');
}
-static QString msgUnknownOperator(const AbstractMetaFunction* func)
-{
- QString result = QLatin1String("Unknown operator: \"") + func->originalName() + QLatin1Char('"');
- if (const AbstractMetaClass *c = func->implementingClass())
- result += QLatin1String(" in class: ") + c->name();
- return result;
-}
-
static inline QString unknownOperator() { return QStringLiteral("__UNKNOWN_OPERATOR__"); }
QString ShibokenGenerator::fixedCppTypeName(const CustomConversion::TargetToNativeConversion* toNative)
@@ -925,7 +953,7 @@ QString ShibokenGenerator::pythonPrimitiveTypeName(const PrimitiveTypeEntry* typ
return pythonPrimitiveTypeName(type->name());
}
-QString ShibokenGenerator::pythonOperatorFunctionName(QString cppOpFuncName)
+QString ShibokenGenerator::pythonOperatorFunctionName(const QString &cppOpFuncName)
{
QString value = m_pythonOperators.value(cppOpFuncName);
if (value.isEmpty())
@@ -953,7 +981,7 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction
return op;
}
-QString ShibokenGenerator::pythonRichCompareOperatorId(QString cppOpFuncName)
+QString ShibokenGenerator::pythonRichCompareOperatorId(const QString &cppOpFuncName)
{
return QLatin1String("Py_") + m_pythonOperators.value(cppOpFuncName).toUpper();
}
@@ -963,7 +991,7 @@ QString ShibokenGenerator::pythonRichCompareOperatorId(const AbstractMetaFunctio
return pythonRichCompareOperatorId(func->originalName());
}
-bool ShibokenGenerator::isNumber(QString cpythonApiName)
+bool ShibokenGenerator::isNumber(const QString &cpythonApiName)
{
return cpythonApiName == QLatin1String("PyInt")
|| cpythonApiName == QLatin1String("PyFloat")
@@ -975,7 +1003,7 @@ bool ShibokenGenerator::isNumber(const TypeEntry* type)
{
if (!type->isPrimitive())
return false;
- return isNumber(pythonPrimitiveTypeName((const PrimitiveTypeEntry*) type));
+ return isNumber(pythonPrimitiveTypeName(static_cast<const PrimitiveTypeEntry *>(type)));
}
bool ShibokenGenerator::isNumber(const AbstractMetaType* type)
@@ -987,7 +1015,8 @@ bool ShibokenGenerator::isPyInt(const TypeEntry* type)
{
if (!type->isPrimitive())
return false;
- return pythonPrimitiveTypeName((const PrimitiveTypeEntry*) type) == QLatin1String("PyInt");
+ return pythonPrimitiveTypeName(static_cast<const PrimitiveTypeEntry *>(type))
+ == QLatin1String("PyInt");
}
bool ShibokenGenerator::isPyInt(const AbstractMetaType* type)
@@ -998,7 +1027,7 @@ bool ShibokenGenerator::isPyInt(const AbstractMetaType* type)
bool ShibokenGenerator::isWrapperType(const TypeEntry* type)
{
if (type->isComplex())
- return ShibokenGenerator::isWrapperType((const ComplexTypeEntry*)type);
+ return ShibokenGenerator::isWrapperType(static_cast<const ComplexTypeEntry *>(type));
return type->isObject() || type->isValue() || type->isSmartPointer();
}
bool ShibokenGenerator::isWrapperType(const ComplexTypeEntry* type)
@@ -1052,7 +1081,7 @@ bool ShibokenGenerator::isUserPrimitive(const TypeEntry* type)
{
if (!type->isPrimitive())
return false;
- const PrimitiveTypeEntry* trueType = (const PrimitiveTypeEntry*) type;
+ const PrimitiveTypeEntry *trueType = static_cast<const PrimitiveTypeEntry *>(type);
if (trueType->basicReferencedTypeEntry())
trueType = trueType->basicReferencedTypeEntry();
return trueType->isPrimitive() && !trueType->isCppPrimitive()
@@ -1072,7 +1101,7 @@ bool ShibokenGenerator::isCppPrimitive(const TypeEntry* type)
return true;
if (!type->isPrimitive())
return false;
- const PrimitiveTypeEntry* trueType = (const PrimitiveTypeEntry*) type;
+ const PrimitiveTypeEntry *trueType = static_cast<const PrimitiveTypeEntry *>(type);
if (trueType->basicReferencedTypeEntry())
trueType = trueType->basicReferencedTypeEntry();
return trueType->qualifiedCppName() == QLatin1String("std::string");
@@ -1125,9 +1154,11 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType
if (isVoidPointer(metaType))
return QLatin1String("PyObject_Check");
return cpythonCheckFunction(metaType->typeEntry(), genericNumberType);
- } else if (metaType->typeEntry()->isContainer()) {
+ }
+ if (metaType->typeEntry()->isContainer()) {
QString typeCheck = QLatin1String("Shiboken::Conversions::");
- ContainerTypeEntry::Type type = ((const ContainerTypeEntry*)metaType->typeEntry())->type();
+ ContainerTypeEntry::Type type =
+ static_cast<const ContainerTypeEntry *>(metaType->typeEntry())->type();
if (type == ContainerTypeEntry::ListContainer
|| type == ContainerTypeEntry::StringListContainer
|| type == ContainerTypeEntry::LinkedListContainer
@@ -1154,8 +1185,8 @@ QString ShibokenGenerator::cpythonCheckFunction(const AbstractMetaType* metaType
const AbstractMetaType* firstType = metaType->instantiations().constFirst();
const AbstractMetaType* secondType = metaType->instantiations().constLast();
if (isPointerToWrapperType(firstType) && isPointerToWrapperType(secondType)) {
- typeCheck += QString::fromLatin1("check%1Types(%2, %3, ").arg(pyType)
- .arg(cpythonTypeNameExt(firstType), cpythonTypeNameExt(secondType));
+ typeCheck += QString::fromLatin1("check%1Types(%2, %3, ")
+ .arg(pyType, cpythonTypeNameExt(firstType), cpythonTypeNameExt(secondType));
} else {
typeCheck += QString::fromLatin1("convertible%1Types(%2, %3, %4, %5, ")
.arg(pyType, converterObject(firstType),
@@ -1182,8 +1213,10 @@ QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry* type, bool gene
if (type->isEnum() || type->isFlags() || isWrapperType(type))
return QString::fromLatin1("SbkObject_TypeCheck(%1, ").arg(cpythonTypeNameExt(type));
- else if (isCppPrimitive(type))
- return pythonPrimitiveTypeName((const PrimitiveTypeEntry*)type) + QLatin1String("_Check");
+ if (isCppPrimitive(type)) {
+ return pythonPrimitiveTypeName(static_cast<const PrimitiveTypeEntry *>(type))
+ + QLatin1String("_Check");
+ }
QString typeCheck;
if (type->targetLangApiName() == type->name())
typeCheck = cpythonIsConvertibleFunction(type);
@@ -1392,7 +1425,7 @@ void ShibokenGenerator::writeFunctionArguments(QTextStream &s,
if (options & Generator::WriteSelf) {
s << func->implementingClass()->name() << '&';
if (!(options & SkipName))
- s << " " PYTHON_SELF_VAR;
+ s << " self";
}
int argUsed = 0;
@@ -1412,13 +1445,12 @@ QString ShibokenGenerator::functionReturnType(const AbstractMetaFunction* func,
QString modifiedReturnType = QString(func->typeReplaced(0));
if (!modifiedReturnType.isNull() && !(options & OriginalTypeDescription))
return modifiedReturnType;
- else
- return translateType(func->type(), func->implementingClass(), options);
+ return translateType(func->type(), func->implementingClass(), options);
}
QString ShibokenGenerator::functionSignature(const AbstractMetaFunction *func,
- QString prepend,
- QString append,
+ const QString &prepend,
+ const QString &append,
Options options,
int /* argCount */) const
{
@@ -1619,8 +1651,9 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl
QString argValue;
if (language == TypeSystem::TargetLangCode) {
bool hasConversionRule = !func->conversionRule(convLang, i+1).isEmpty();
- bool argRemoved = func->argumentRemoved(i+1);
- removed = removed + (int) argRemoved;
+ const bool argRemoved = func->argumentRemoved(i+1);
+ if (argRemoved)
+ ++removed;
if (argRemoved && hasConversionRule)
argValue = arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX);
else if (argRemoved || (lastArg && arg->argumentIndex() > lastArg->argumentIndex()))
@@ -1636,8 +1669,7 @@ ShibokenGenerator::ArgumentVarReplacementList ShibokenGenerator::getArgumentRepl
}
if (type->typeEntry()->isCustom()) {
argValue = usePyArgs
- ? QString::fromLatin1(PYTHON_ARGS "[%1]").arg(argPos)
- : QLatin1String(PYTHON_ARG);
+ ? pythonArgsAt(argPos) : QLatin1String(PYTHON_ARG);
} else {
argValue = hasConversionRule
? arg->name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX)
@@ -1673,17 +1705,6 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
s << INDENT << "// End of code injection" << endl;
}
-static QString msgWrongIndex(const char *varName, const QString &capture, const AbstractMetaFunction *func)
-{
- QString result;
- QTextStream str(&result);
- str << "Wrong index for " << varName << " variable (" << capture << ") on ";
- if (const AbstractMetaClass *c = func->implementingClass())
- str << c->name() << "::";
- str << func->signature();
- return result;
-}
-
void ShibokenGenerator::writeCodeSnips(QTextStream& s,
const CodeSnipList& codeSnips,
TypeSystem::CodeSnipPosition position,
@@ -1712,7 +1733,7 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
Q_ASSERT(pyArgsRegex.isValid());
if (language == TypeSystem::TargetLangCode) {
if (usePyArgs) {
- code.replace(pyArgsRegex, QLatin1String(PYTHON_ARGS"[\\1-1]"));
+ code.replace(pyArgsRegex, QLatin1String(PYTHON_ARGS) + QLatin1String("[\\1-1]"));
} else {
static const QRegularExpression pyArgsRegexCheck(QStringLiteral("%PYARG_([2-9]+)"));
Q_ASSERT(pyArgsRegexCheck.isValid());
@@ -1729,8 +1750,10 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
// Python argument on the binding virtual method.
static const QRegularExpression pyArgsAttributionRegex(QStringLiteral("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"));
Q_ASSERT(pyArgsAttributionRegex.isValid());
- code.replace(pyArgsAttributionRegex, QLatin1String("PyTuple_SET_ITEM(" PYTHON_ARGS ", \\1-1, \\2)"));
- code.replace(pyArgsRegex, QLatin1String("PyTuple_GET_ITEM(" PYTHON_ARGS ", \\1-1)"));
+ code.replace(pyArgsAttributionRegex, QLatin1String("PyTuple_SET_ITEM(")
+ + QLatin1String(PYTHON_ARGS) + QLatin1String(", \\1-1, \\2)"));
+ code.replace(pyArgsRegex, QLatin1String("PyTuple_GET_ITEM(")
+ + QLatin1String(PYTHON_ARGS) + QLatin1String(", \\1-1)"));
}
// Replace %ARG#_TYPE variables.
@@ -1763,7 +1786,8 @@ void ShibokenGenerator::writeCodeSnips(QTextStream& s,
}
// Replace template variable for self Python object.
- QString pySelf = (language == TypeSystem::NativeCode) ? QLatin1String("pySelf") : QLatin1String(PYTHON_SELF_VAR);
+ QString pySelf = language == TypeSystem::NativeCode
+ ? QLatin1String("pySelf") : QLatin1String("self");
code.replace(QLatin1String("%PYSELF"), pySelf);
// Replace template variable for a pointer to C++ of this object.
@@ -1960,16 +1984,6 @@ static QString getConverterTypeSystemVariableArgument(const QString& code, int p
}
typedef QPair<QString, QString> StringPair;
-static QString msgCannotFindType(const QString &type, const QString &variable,
- const QString &why)
-{
- QString result;
- QTextStream(&result) << "Could not find type '"
- << type << "' for use in '" << variable << "' conversion: " << why
- << "\nMake sure to use the full C++ name, e.g. 'Namespace::Class'.";
- return result;
-}
-
void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, QString& code)
{
QVector<StringPair> replacements;
@@ -1978,7 +1992,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
const QRegularExpressionMatch match = rit.next();
const QStringList list = match.capturedTexts();
QString conversionString = list.constFirst();
- QString conversionTypeName = list.constLast();
+ const QString &conversionTypeName = list.constLast();
QString message;
const AbstractMetaType *conversionType = buildAbstractMetaTypeFromString(conversionTypeName, &message);
if (!conversionType) {
@@ -2002,8 +2016,8 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
if (varType != conversionType->cppSignature()) {
- qFatal(qPrintable(QString::fromLatin1("Types of receiver variable ('%1') and %CONVERTTOCPP type system variable ('%2') differ.")
- .arg(varType, conversionType->cppSignature())), NULL);
+ qFatal("Types of receiver variable ('%s') and %%CONVERTTOCPP type system variable ('%s') differ.",
+ qPrintable(varType), qPrintable(conversionType->cppSignature()));
}
c << getFullTypeName(conversionType) << ' ' << varName;
writeMinimalConstructorExpression(c, conversionType);
@@ -2032,18 +2046,21 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
c << '(';
break;
}
+ Q_FALLTHROUGH();
case TypeSystemIsConvertibleFunction:
if (conversion.isEmpty())
conversion = cpythonIsConvertibleFunction(conversionType);
+ Q_FALLTHROUGH();
case TypeSystemToPythonFunction:
if (conversion.isEmpty())
conversion = cpythonToPythonConversionFunction(conversionType);
+ Q_FALLTHROUGH();
default: {
QString arg = getConverterTypeSystemVariableArgument(code, match.capturedEnd());
conversionString += arg;
if (converterVariable == TypeSystemToPythonFunction && !isVariable(arg)) {
- qFatal(qPrintable(QString::fromLatin1("Only variables are acceptable as argument to %%CONVERTTOPYTHON type system variable on code snippet: '%1'")
- .arg(code)), NULL);
+ qFatal("Only variables are acceptable as argument to %%CONVERTTOPYTHON type system variable on code snippet: '%s'",
+ qPrintable(code));
}
if (conversion.contains(QLatin1String("%in"))) {
conversion.prepend(QLatin1Char('('));
@@ -2172,9 +2189,7 @@ bool ShibokenGenerator::classNeedsSetattroFunction(const AbstractMetaClass *meta
{
if (!metaClass)
return false;
- if (metaClass->typeEntry()->isSmartPointer())
- return true;
- return false;
+ return metaClass->typeEntry()->isSmartPointer();
}
AbstractMetaFunctionList ShibokenGenerator::getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass* metaClass)
@@ -2244,9 +2259,7 @@ AbstractMetaClassList ShibokenGenerator::getAllAncestors(const AbstractMetaClass
QString ShibokenGenerator::getModuleHeaderFileName(const QString& moduleName) const
{
- QString result = moduleName.isEmpty() ? packageName() : moduleName;
- result.replace(QLatin1Char('.'), QLatin1Char('_'));
- return result.toLower() + QLatin1String("_python.h");
+ return moduleCppPrefix(moduleName).toLower() + QLatin1String("_python.h");
}
bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass)
@@ -2254,12 +2267,10 @@ bool ShibokenGenerator::isCopyable(const AbstractMetaClass *metaClass)
{
if (metaClass->isNamespace() || isObjectType(metaClass))
return false;
- else if (metaClass->typeEntry()->copyable() == ComplexTypeEntry::Unknown)
+ if (metaClass->typeEntry()->copyable() == ComplexTypeEntry::Unknown)
return metaClass->hasCloneOperator();
- else
- return (metaClass->typeEntry()->copyable() == ComplexTypeEntry::CopyableSet);
- return false;
+ return metaClass->typeEntry()->copyable() == ComplexTypeEntry::CopyableSet;
}
AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typeSignature,
@@ -2269,110 +2280,18 @@ AbstractMetaType *ShibokenGenerator::buildAbstractMetaTypeFromString(QString typ
if (typeSignature.startsWith(QLatin1String("::")))
typeSignature.remove(0, 2);
- if (m_metaTypeFromStringCache.contains(typeSignature))
- return m_metaTypeFromStringCache.value(typeSignature);
-
- QString typeString = typeSignature;
- bool isConst = typeString.startsWith(QLatin1String("const "));
- if (isConst)
- typeString.remove(0, sizeof("const ") / sizeof(char) - 1);
-
- ReferenceType refType = NoReference;
- if (typeString.endsWith(QLatin1String("&&"))) {
- refType = RValueReference;
- typeString.chop(2);
- typeString = typeString.trimmed();
- } else if (typeString.endsWith(QLatin1Char('&'))) {
- refType = LValueReference;
- typeString.chop(1);
- typeString = typeString.trimmed();
- }
-
- int indirections = 0;
- while (typeString.endsWith(QLatin1Char('*'))) {
- ++indirections;
- typeString.chop(1);
- typeString = typeString.trimmed();
- }
-
- if (typeString.startsWith(QLatin1String("::")))
- typeString.remove(0, 2);
-
- QString adjustedTypeName = typeString;
- AbstractMetaTypeList instantiations;
- int lpos = typeString.indexOf(QLatin1Char('<'));
- if (lpos > -1) {
- QStringList instantiatedTypes;
- int rpos = typeString.lastIndexOf(QLatin1Char('>'));
- if ((lpos != -1) && (rpos != -1)) {
- QString type = typeString.mid(lpos + 1, rpos - lpos - 1);
- int depth = 0;
- int start = 0;
- for (int i = 0; i < type.count(); ++i) {
- if (type.at(i) == QLatin1Char('<')) {
- ++depth;
- } else if (type.at(i) == QLatin1Char('>')) {
- --depth;
- } else if (type.at(i) == QLatin1Char(',') && depth == 0) {
- instantiatedTypes << type.mid(start, i - start).trimmed();
- start = i + 1;
- }
- }
- instantiatedTypes << type.mid(start).trimmed();
- adjustedTypeName.truncate(lpos);
- }
- for (const QString &instantiatedType : qAsConst(instantiatedTypes)) {
- AbstractMetaType *tmplArgType = buildAbstractMetaTypeFromString(instantiatedType);
- if (!tmplArgType) {
- if (errorMessage) {
- QTextStream(errorMessage) << "Cannot find template type \""
- << instantiatedType << "\" for \"" << typeSignature << "\".";
- }
- return nullptr;
- }
- instantiations.append(tmplArgType);
- }
- }
-
- TypeEntry *typeEntry = nullptr;
- AbstractMetaType::TypeUsagePattern pattern = AbstractMetaType::InvalidPattern;
-
- if (instantiations.size() == 1
- && instantiations.at(0)->typeUsagePattern() == AbstractMetaType::EnumPattern
- && adjustedTypeName == QLatin1String("QFlags")) {
- pattern = AbstractMetaType::FlagsPattern;
- typeEntry = TypeDatabase::instance()->findType(typeSignature);
- } else {
- typeEntry = TypeDatabase::instance()->findType(adjustedTypeName);
- }
-
- if (!typeEntry) {
- if (errorMessage) {
- QTextStream(errorMessage) << "Cannot find type \"" << adjustedTypeName
- << "\" for \"" << typeSignature << "\".";
+ auto it = m_metaTypeFromStringCache.find(typeSignature);
+ if (it == m_metaTypeFromStringCache.end()) {
+ AbstractMetaType *metaType =
+ AbstractMetaBuilder::translateType(typeSignature, nullptr, true, errorMessage);
+ if (Q_UNLIKELY(!metaType)) {
+ if (errorMessage)
+ errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
+ return nullptr;
}
- return nullptr;
+ it = m_metaTypeFromStringCache.insert(typeSignature, metaType);
}
-
- AbstractMetaType *metaType = new AbstractMetaType();
- metaType->setTypeEntry(typeEntry);
- metaType->setIndirections(indirections);
- metaType->setReferenceType(refType);
- metaType->setConstant(isConst);
- metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
- switch (pattern) {
- case AbstractMetaType::FlagsPattern:
- metaType->setTypeUsagePattern(pattern);
- break;
- default:
- metaType->setInstantiations(instantiations);
- metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
- metaType->decideUsagePattern();
- break;
- }
-
- m_metaTypeFromStringCache.insert(typeSignature, metaType);
- return metaType;
+ return it.value();
}
AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const TypeEntry* typeEntry)
@@ -2384,7 +2303,7 @@ AbstractMetaType* ShibokenGenerator::buildAbstractMetaTypeFromTypeEntry(const Ty
return m_metaTypeFromStringCache.value(typeName);
AbstractMetaType* metaType = new AbstractMetaType;
metaType->setTypeEntry(typeEntry);
- metaType->setIndirections(0);
+ metaType->clearIndirections();
metaType->setReferenceType(NoReference);
metaType->setConstant(false);
metaType->decideUsagePattern();
@@ -2449,7 +2368,7 @@ AbstractMetaFunctionList ShibokenGenerator::getInheritedOverloads(const Abstract
{
AbstractMetaFunctionList results;
AbstractMetaClass* basis;
- if (func->ownerClass() && (basis = func->ownerClass()->baseClass(), basis)) {
+ if (func->ownerClass() && (basis = func->ownerClass()->baseClass())) {
for (; basis; basis = basis->baseClass()) {
const AbstractMetaFunction* inFunc = basis->findFunction(func->name());
if (inFunc && !seen->contains(inFunc->minimalSignature())) {
@@ -2509,6 +2428,23 @@ Generator::OptionDescriptions ShibokenGenerator::options() const
"the value of boolean casts"));
}
+bool ShibokenGenerator::handleOption(const QString &key, const QString & /* value */)
+{
+ if (key == QLatin1String(PARENT_CTOR_HEURISTIC))
+ return (m_useCtorHeuristic = true);
+ if (key == QLatin1String(ENABLE_PYSIDE_EXTENSIONS))
+ return (m_usePySideExtensions = true);
+ if (key == QLatin1String(RETURN_VALUE_HEURISTIC))
+ return (m_userReturnValueHeuristic = true);
+ if (key == QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES))
+ return (m_verboseErrorMessagesDisabled = true);
+ if (key == QLatin1String(USE_ISNULL_AS_NB_NONZERO))
+ return (m_useIsNullAsNbNonZero = true);
+ if (key == QLatin1String(AVOID_PROTECTED_HACK))
+ return (m_avoidProtectedHack = true);
+ return false;
+}
+
static void getCode(QStringList& code, const CodeSnipList& codeSnips)
{
for (const CodeSnip &snip : qAsConst(codeSnips))
@@ -2534,15 +2470,8 @@ static void getCode(QStringList& code, const TypeEntry* type)
code.append(toNative->conversion());
}
-bool ShibokenGenerator::doSetup(const QMap<QString, QString>& args)
+bool ShibokenGenerator::doSetup()
{
- m_useCtorHeuristic = args.contains(QLatin1String(PARENT_CTOR_HEURISTIC));
- m_usePySideExtensions = args.contains(QLatin1String(ENABLE_PYSIDE_EXTENSIONS));
- m_userReturnValueHeuristic = args.contains(QLatin1String(RETURN_VALUE_HEURISTIC));
- m_verboseErrorMessagesDisabled = args.contains(QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES));
- m_useIsNullAsNbNonZero = args.contains(QLatin1String(USE_ISNULL_AS_NB_NONZERO));
- m_avoidProtectedHack = args.contains(QLatin1String(AVOID_PROTECTED_HACK));
-
TypeDatabase* td = TypeDatabase::instance();
QStringList snips;
const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
@@ -2554,7 +2483,11 @@ bool ShibokenGenerator::doSetup(const QMap<QString, QString>& args)
const AbstractMetaClassList &classList = classes();
for (const AbstractMetaClass *metaClass : classList)
getCode(snips, metaClass->typeEntry());
- getCode(snips, td->findType(packageName()));
+
+ const TypeSystemTypeEntry *moduleEntry = td->findTypeSystemType(packageName());
+ Q_ASSERT(moduleEntry);
+ getCode(snips, moduleEntry);
+
const FunctionGroupMap &functionGroups = getFunctionGroups();
for (FunctionGroupMapIt it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
for (AbstractMetaFunction *func : it.value())
@@ -2611,15 +2544,25 @@ bool ShibokenGenerator::avoidProtectedHack() const
return m_avoidProtectedHack;
}
-QString ShibokenGenerator::cppApiVariableName(const QString& moduleName) const
-{
- QString result = moduleName.isEmpty() ? ShibokenGenerator::packageName() : moduleName;
+QString ShibokenGenerator::moduleCppPrefix(const QString& moduleName) const
+ {
+ QString result = moduleName.isEmpty() ? packageName() : moduleName;
result.replace(QLatin1Char('.'), QLatin1Char('_'));
- result.prepend(QLatin1String("Sbk"));
- result.append(QLatin1String("Types"));
return result;
}
+QString ShibokenGenerator::cppApiVariableName(const QString& moduleName) const
+{
+ return QLatin1String("Sbk") + moduleCppPrefix(moduleName)
+ + QLatin1String("Types");
+}
+
+QString ShibokenGenerator::pythonModuleObjectName(const QString& moduleName) const
+{
+ return QLatin1String("Sbk") + moduleCppPrefix(moduleName)
+ + QLatin1String("ModuleObject");
+}
+
QString ShibokenGenerator::convertersVariableName(const QString& moduleName) const
{
QString result = cppApiVariableName(moduleName);
@@ -2639,35 +2582,50 @@ static QString processInstantiationsVariableName(const AbstractMetaType* type)
}
return res;
}
+
+static void appendIndexSuffix(QString *s)
+{
+ if (!s->endsWith(QLatin1Char('_')))
+ s->append(QLatin1Char('_'));
+ s->append(QStringLiteral("IDX"));
+}
+
QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass* metaClass, bool alternativeTemplateName)
{
if (alternativeTemplateName) {
const AbstractMetaClass* templateBaseClass = metaClass->templateBaseClass();
if (!templateBaseClass)
return QString();
- QString base = _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
- QString instantiations;
+ QString result = QLatin1String("SBK_")
+ + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
const AbstractMetaTypeList &templateBaseClassInstantiations = metaClass->templateBaseClassInstantiations();
for (const AbstractMetaType *instantiation : templateBaseClassInstantiations)
- instantiations += processInstantiationsVariableName(instantiation);
- return QString::fromLatin1("SBK_%1%2_IDX").arg(base, instantiations);
+ result += processInstantiationsVariableName(instantiation);
+ appendIndexSuffix(&result);
+ return result;
}
return getTypeIndexVariableName(metaClass->typeEntry());
}
QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry* type)
{
if (type->isCppPrimitive()) {
- const PrimitiveTypeEntry* trueType = (const PrimitiveTypeEntry*) type;
+ const PrimitiveTypeEntry *trueType = static_cast<const PrimitiveTypeEntry*>(type);
if (trueType->basicReferencedTypeEntry())
type = trueType->basicReferencedTypeEntry();
}
- return QString::fromLatin1("SBK_%1_IDX").arg(_fixedCppTypeName(type->qualifiedCppName()).toUpper());
+ QString result = QLatin1String("SBK_")
+ + _fixedCppTypeName(type->qualifiedCppName()).toUpper();
+ appendIndexSuffix(&result);
+ return result;
}
QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType* type)
{
- return QString::fromLatin1("SBK%1%2_IDX")
- .arg(type->typeEntry()->isContainer() ? QLatin1Char('_') + moduleName().toUpper() : QString(),
- processInstantiationsVariableName(type));
+ QString result = QLatin1String("SBK");
+ if (type->typeEntry()->isContainer())
+ result += QLatin1Char('_') + moduleName().toUpper();
+ result += processInstantiationsVariableName(type);
+ appendIndexSuffix(&result);
+ return result;
}
bool ShibokenGenerator::verboseErrorMessagesDisabled() const
@@ -2707,30 +2665,37 @@ QString ShibokenGenerator::getDefaultValue(const AbstractMetaFunction* func, co
void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream& s, const AbstractMetaType* type, const QString& defaultCtor)
{
- if (defaultCtor.isEmpty() && isCppPrimitive(type))
+ if (!defaultCtor.isEmpty()) {
+ s << " = " << defaultCtor;
+ return;
+ }
+ if (isCppPrimitive(type))
return;
- QString ctor = defaultCtor.isEmpty() ? minimalConstructor(type) : defaultCtor;
- if (ctor.isEmpty()) {
+ const auto ctor = minimalConstructor(type);
+ if (ctor.isValid()) {
+ s << ctor.initialization();
+ } else {
const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type->cppSignature());
qCWarning(lcShiboken()).noquote() << message;
s << ";\n#error " << message << '\n';
- } else {
- s << " = " << ctor;
}
}
void ShibokenGenerator::writeMinimalConstructorExpression(QTextStream& s, const TypeEntry* type, const QString& defaultCtor)
{
- if (defaultCtor.isEmpty() && isCppPrimitive(type))
+ if (!defaultCtor.isEmpty()) {
+ s << " = " << defaultCtor;
+ return;
+ }
+ if (isCppPrimitive(type))
return;
- QString ctor = defaultCtor.isEmpty() ? minimalConstructor(type) : defaultCtor;
-
- if (ctor.isEmpty()) {
+ const auto ctor = minimalConstructor(type);
+ if (ctor.isValid()) {
+ s << ctor.initialization();
+ } else {
const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__), type->qualifiedCppName());
qCWarning(lcShiboken()).noquote() << message;
s << ";\n#error " << message << endl;
- } else {
- s << " = " << ctor;
}
}
@@ -2738,7 +2703,7 @@ bool ShibokenGenerator::isCppIntegralPrimitive(const TypeEntry* type)
{
if (!type->isCppPrimitive())
return false;
- const PrimitiveTypeEntry* trueType = (const PrimitiveTypeEntry*) type;
+ const PrimitiveTypeEntry *trueType = static_cast<const PrimitiveTypeEntry *>(type);
if (trueType->basicReferencedTypeEntry())
trueType = trueType->basicReferencedTypeEntry();
QString typeName = trueType->qualifiedCppName();
@@ -2751,8 +2716,8 @@ bool ShibokenGenerator::isCppIntegralPrimitive(const AbstractMetaType* type)
return isCppIntegralPrimitive(type->typeEntry());
}
-QString ShibokenGenerator::msgCouldNotFindMinimalConstructor(const QString &where, const QString &type)
+QString ShibokenGenerator::pythonArgsAt(int i)
{
- return where + QLatin1String(": Could not find a minimal constructor for type '") + type
- + QLatin1String("'. This will result in a compilation error.");
+ return QLatin1String(PYTHON_ARGS) + QLatin1Char('[')
+ + QString::number(i) + QLatin1Char(']');
}
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.h b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
index cb1bdd11f..60e31a99b 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.h
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.h
@@ -29,28 +29,20 @@
#ifndef SHIBOKENGENERATOR_H
#define SHIBOKENGENERATOR_H
-#define CONV_RULE_OUT_VAR_SUFFIX "_out"
-#define CPP_ARG "cppArg"
-#define CPP_ARG0 CPP_ARG"0"
-#define CPP_ARG_REMOVED "removed_" CPP_ARG
-#define CPP_RETURN_VAR "cppResult"
-#define CPP_SELF_VAR "cppSelf"
-#define PYTHON_ARG "pyArg"
-#define PYTHON_ARGS PYTHON_ARG "s"
-#define PYTHON_OVERRIDE_VAR "pyOverride"
-#define PYTHON_RETURN_VAR "pyResult"
-#define PYTHON_SELF_VAR "self"
-#define THREAD_STATE_SAVER_VAR "threadStateSaver"
-#define BEGIN_ALLOW_THREADS "PyThreadState* _save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS"
-#define END_ALLOW_THREADS "PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS"
-#define PYTHON_TO_CPP_VAR "pythonToCpp"
-#define SMART_POINTER_GETTER "kSmartPointerGetter"
-
-#define CHECKTYPE_REGEX "%CHECKTYPE\\[([^\\[]*)\\]\\("
-#define ISCONVERTIBLE_REGEX "%ISCONVERTIBLE\\[([^\\[]*)\\]\\("
-#define CONVERTTOPYTHON_REGEX "%CONVERTTOPYTHON\\[([^\\[]*)\\]\\("
-#define CONVERTTOCPP_REGEX "(\\*?%?[a-zA-Z_][\\w\\.]*(?:\\[[^\\[^<^>]+\\])*)"\
- "(?:\\s+)=(?:\\s+)%CONVERTTOCPP\\[([^\\[]*)\\]\\("
+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 *PYTHON_ARG;
+extern const char *PYTHON_ARGS;
+extern const char *PYTHON_OVERRIDE_VAR;
+extern const char *PYTHON_RETURN_VAR;
+extern const char *PYTHON_TO_CPP_VAR;
+extern const char *SMART_POINTER_GETTER;
+
+extern const char *CONV_RULE_OUT_VAR_SUFFIX;
+extern const char *BEGIN_ALLOW_THREADS;
+extern const char *END_ALLOW_THREADS;
#include <generator.h>
@@ -71,61 +63,20 @@ class ShibokenGenerator : public Generator
{
public:
ShibokenGenerator();
- virtual ~ShibokenGenerator();
+ ~ShibokenGenerator() override;
- QString translateTypeForWrapperMethod(const AbstractMetaType* cType,
- const AbstractMetaClass* context, Options opt = NoOption) const;
+ const char *name() const override { return "Shiboken"; }
/**
- * Returns a map with all functions grouped, the function name is used as key.
- * Example of return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"}
- * \param scope Where to search for functions, null means all global functions.
- */
- QMap<QString, AbstractMetaFunctionList> getFunctionGroups(const AbstractMetaClass* scope = 0);
-
- /**
- * Returns all different inherited overloads of func.
- * The function can be called multiple times without duplication.
- * \param func the metafunction to be searched in subclasses.
- * \param seen the function's minimal signatures already seen.
- */
- AbstractMetaFunctionList getInheritedOverloads(const AbstractMetaFunction *func, QSet<QString> *seen);
+ * Helper function to find for argument default value
+ */
+ static QString getDefaultValue(const AbstractMetaFunction* func, const AbstractMetaArgument* arg);
- /**
- * Returns all different inherited overloads of func, and includes func as well.
- * The function can be called multiple times without duplication.
- * \param func the metafunction to be searched in subclasses.
- * \param seen the function's minimal signatures already seen.
- */
- AbstractMetaFunctionList getFunctionAndInheritedOverloads(const AbstractMetaFunction *func, QSet<QString> *seen);
+ /// Returns a list of all ancestor classes for the given class.
+ AbstractMetaClassList getAllAncestors(const AbstractMetaClass* metaClass) const;
- /**
- * Returns all overloads for a function named \p functionName.
- * \param scope scope used to search for overloads.
- * \param functionName the function name.
- */
- AbstractMetaFunctionList getFunctionOverloads(const AbstractMetaClass* scope, const QString& functionName);
- /**
- * Write a function argument in the C++ in the text stream \p s.
- * This function just call \code s << argumentString(); \endcode
- * \param s text stream used to write the output.
- * \param func the current metafunction.
- * \param argument metaargument information to be parsed.
- * \param options some extra options.
- */
- void writeArgument(QTextStream &s,
- const AbstractMetaFunction* func,
- const AbstractMetaArgument* argument,
- Options options = NoOption) const;
- /**
- * Create a QString in the C++ format to an function argument.
- * \param func the current metafunction.
- * \param argument metaargument information to be parsed.
- * \param options some extra options.
- */
- QString argumentString(const AbstractMetaFunction* func,
- const AbstractMetaArgument* argument,
- Options options = NoOption) const;
+protected:
+ bool doSetup() override;
void writeArgumentNames(QTextStream &s,
const AbstractMetaFunction* func,
@@ -141,14 +92,21 @@ public:
void writeFunctionArguments(QTextStream &s,
const AbstractMetaFunction* func,
Options options = NoOption) const override;
- QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const;
- /// Utility function for writeCodeSnips.
- typedef QPair<const AbstractMetaArgument*, QString> ArgumentVarReplacementPair;
- typedef QVector<ArgumentVarReplacementPair> ArgumentVarReplacementList;
- ArgumentVarReplacementList getArgumentReplacement(const AbstractMetaFunction* func,
- bool usePyArgs, TypeSystem::Language language,
- const AbstractMetaArgument* lastArg);
+ /**
+ * Returns a map with all functions grouped, the function name is used as key.
+ * Example of return value: { "foo" -> ["foo(int)", "foo(int, long)], "bar" -> "bar(double)"}
+ * \param scope Where to search for functions, null means all global functions.
+ */
+ QMap<QString, AbstractMetaFunctionList> getFunctionGroups(const AbstractMetaClass* scope = 0);
+
+ /**
+ * Returns all different inherited overloads of func, and includes func as well.
+ * The function can be called multiple times without duplication.
+ * \param func the metafunction to be searched in subclasses.
+ * \param seen the function's minimal signatures already seen.
+ */
+ AbstractMetaFunctionList getFunctionAndInheritedOverloads(const AbstractMetaFunction *func, QSet<QString> *seen);
/// Write user's custom code snippets at class or module level.
void writeCodeSnips(QTextStream& s,
@@ -164,33 +122,9 @@ public:
const AbstractMetaFunction* func,
const AbstractMetaArgument* lastArg = 0);
- /// Returns a string with the user's custom code snippets that comply with \p position and \p language.
- QString getCodeSnippets(const QVector<CodeSnip> & codeSnips, TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
-
/// Replaces variables for the user's custom code at global or class level.
void processCodeSnip(QString& code, const AbstractMetaClass* context = 0);
- /// Replaces the %CONVERTTOPYTHON type system variable.
- inline void replaceConvertToPythonTypeSystemVariable(QString& code)
- {
- replaceConverterTypeSystemVariable(TypeSystemToPythonFunction, code);
- }
- /// Replaces the %CONVERTTOCPP type system variable.
- inline void replaceConvertToCppTypeSystemVariable(QString& code)
- {
- replaceConverterTypeSystemVariable(TypeSystemToCppFunction, code);
- }
- /// Replaces the %ISCONVERTIBLE type system variable.
- inline void replaceIsConvertibleToCppTypeSystemVariable(QString& code)
- {
- replaceConverterTypeSystemVariable(TypeSystemIsConvertibleFunction, code);
- }
- /// Replaces the %CHECKTYPE type system variable.
- inline void replaceTypeCheckTypeSystemVariable(QString& code)
- {
- replaceConverterTypeSystemVariable(TypeSystemCheckFunction, code);
- }
-
/**
* Verifies if any of the function's code injections of the "native"
* type needs the type system variable "%PYSELF".
@@ -239,8 +173,8 @@ public:
* \param arg_count the number of function arguments
*/
QString functionSignature(const AbstractMetaFunction* func,
- QString prepend = QString(),
- QString append = QString(),
+ const QString &prepend = QString(),
+ const QString &append = QString(),
Options options = NoOption,
int arg_count = -1) const;
@@ -259,9 +193,6 @@ public:
/// Returns a list of parent classes for a given class.
AbstractMetaClassList getBaseClasses(const AbstractMetaClass* metaClass) const;
- /// Returns a list of all ancestor classes for the given class.
- AbstractMetaClassList getAllAncestors(const AbstractMetaClass* metaClass) const;
-
const AbstractMetaClass* getMultipleInheritingClass(const AbstractMetaClass* metaClass);
void writeToPythonConversion(QTextStream& s, const AbstractMetaType* type,
@@ -283,7 +214,8 @@ public:
QString wrapperName(const AbstractMetaClass* metaClass) const;
QString wrapperName(const AbstractMetaType *metaType) const;
- QString fullPythonFunctionName(const AbstractMetaFunction* func);
+ QString fullPythonClassName(const AbstractMetaClass *metaClass);
+ QString fullPythonFunctionName(const AbstractMetaFunction *func); //WS
static QString protectedEnumSurrogateName(const AbstractMetaEnum* metaEnum);
static QString protectedFieldGetterName(const AbstractMetaField* field);
@@ -292,16 +224,16 @@ public:
static QString pythonPrimitiveTypeName(const QString& cppTypeName);
static QString pythonPrimitiveTypeName(const PrimitiveTypeEntry* type);
- static QString pythonOperatorFunctionName(QString cppOpFuncName);
+ static QString pythonOperatorFunctionName(const QString &cppOpFuncName);
static QString pythonOperatorFunctionName(const AbstractMetaFunction* func);
- static QString pythonRichCompareOperatorId(QString cppOpFuncName);
+ static QString pythonRichCompareOperatorId(const QString &cppOpFuncName);
static QString pythonRichCompareOperatorId(const AbstractMetaFunction* func);
static QString fixedCppTypeName(const CustomConversion::TargetToNativeConversion* toNative);
static QString fixedCppTypeName(const AbstractMetaType* type);
static QString fixedCppTypeName(const TypeEntry* type, QString typeName = QString());
- static bool isNumber(QString cpythonApiName);
+ static bool isNumber(const QString &cpythonApiName);
static bool isNumber(const TypeEntry* type);
static bool isNumber(const AbstractMetaType* type);
static bool isPyInt(const TypeEntry* type);
@@ -389,9 +321,10 @@ public:
QString cpythonSetattroFunctionName(const AbstractMetaClass* metaClass);
QString cpythonGetterFunctionName(const AbstractMetaField* metaField);
QString cpythonSetterFunctionName(const AbstractMetaField* metaField);
- QString cpythonWrapperCPtr(const AbstractMetaClass* metaClass, QString argName = QLatin1String(PYTHON_SELF_VAR));
- QString cpythonWrapperCPtr(const AbstractMetaType *metaType, QString argName);
- QString cpythonWrapperCPtr(const TypeEntry* type, QString argName);
+ QString cpythonWrapperCPtr(const AbstractMetaClass* metaClass,
+ const QString &argName = QLatin1String("self"));
+ QString cpythonWrapperCPtr(const AbstractMetaType *metaType, const QString &argName);
+ QString cpythonWrapperCPtr(const TypeEntry* type, const QString &argName);
/// Guesses the scope to where belongs an argument's default value.
QString guessScopeForDefaultValue(const AbstractMetaFunction *func,
@@ -414,6 +347,7 @@ public:
QString getModuleHeaderFileName(const QString& moduleName = QString()) const;
OptionDescriptions options() const override;
+ bool handleOption(const QString &key, const QString &value) override;
/// Returns true if the user enabled the so called "parent constructor heuristic".
bool useCtorHeuristic() const;
@@ -426,6 +360,7 @@ public:
/// Returns true if the generated code should use the "#define protected public" hack.
bool avoidProtectedHack() const;
QString cppApiVariableName(const QString& moduleName = QString()) const;
+ QString pythonModuleObjectName(const QString& moduleName = QString()) const;
QString convertersVariableName(const QString& moduleName = QString()) const;
/**
* Returns the type index variable name for a given class. If \p alternativeTemplateName is true
@@ -457,26 +392,12 @@ public:
void writeMinimalConstructorExpression(QTextStream& s, const AbstractMetaType* type, const QString& defaultCtor = QString());
void writeMinimalConstructorExpression(QTextStream& s, const TypeEntry* type, const QString& defaultCtor = QString());
- /**
- * Helper function to find for argument default value
- */
- static QString getDefaultValue(const AbstractMetaFunction* func, const AbstractMetaArgument* arg);
-protected:
- bool doSetup(const QMap<QString, QString>& args);
void collectContainerTypesFromConverterMacros(const QString& code, bool toPythonMacro);
// verify whether the class is copyable
bool isCopyable(const AbstractMetaClass* metaClass);
- bool m_native_jump_table;
- static QHash<QString, QString> m_pythonPrimitiveTypeName;
- static QHash<QString, QString> m_pythonOperators;
- static QHash<QString, QString> m_formatUnits;
- static QHash<QString, QString> m_tpFuncs;
- static QStringList m_knownPythonTypes;
-
void clearTpFuncs();
- const char* name() const { return "Shiboken"; }
/// Initializes correspondences between primitive and Python types.
static void initPrimitiveTypesCorrespondences();
@@ -505,6 +426,74 @@ protected:
Indentor INDENT;
+ const QRegularExpression &convertToCppRegEx() const
+ { return m_typeSystemConvRegEx[TypeSystemToCppFunction]; }
+
+ static QString pythonArgsAt(int i);
+
+ static QHash<QString, QString> m_pythonPrimitiveTypeName;
+ static QHash<QString, QString> m_pythonOperators;
+ static QHash<QString, QString> m_formatUnits;
+ static QHash<QString, QString> m_tpFuncs;
+ static QStringList m_knownPythonTypes;
+
+private:
+ QString translateTypeForWrapperMethod(const AbstractMetaType* cType,
+ const AbstractMetaClass* context,
+ Options opt = NoOption) const;
+
+ /**
+ * Returns all different inherited overloads of func.
+ * The function can be called multiple times without duplication.
+ * \param func the metafunction to be searched in subclasses.
+ * \param seen the function's minimal signatures already seen.
+ */
+ AbstractMetaFunctionList getInheritedOverloads(const AbstractMetaFunction *func,
+ QSet<QString> *seen);
+
+ /**
+ * Returns all overloads for a function named \p functionName.
+ * \param scope scope used to search for overloads.
+ * \param functionName the function name.
+ */
+ AbstractMetaFunctionList getFunctionOverloads(const AbstractMetaClass* scope,
+ const QString& functionName);
+ /**
+ * Write a function argument in the C++ in the text stream \p s.
+ * This function just call \code s << argumentString(); \endcode
+ * \param s text stream used to write the output.
+ * \param func the current metafunction.
+ * \param argument metaargument information to be parsed.
+ * \param options some extra options.
+ */
+ void writeArgument(QTextStream &s,
+ const AbstractMetaFunction* func,
+ const AbstractMetaArgument* argument,
+ Options options = NoOption) const;
+ /**
+ * Create a QString in the C++ format to an function argument.
+ * \param func the current metafunction.
+ * \param argument metaargument information to be parsed.
+ * \param options some extra options.
+ */
+ QString argumentString(const AbstractMetaFunction* func,
+ const AbstractMetaArgument* argument,
+ Options options = NoOption) const;
+
+ QString functionReturnType(const AbstractMetaFunction* func, Options options = NoOption) const;
+
+ /// Utility function for writeCodeSnips.
+ typedef QPair<const AbstractMetaArgument*, QString> ArgumentVarReplacementPair;
+ typedef QVector<ArgumentVarReplacementPair> ArgumentVarReplacementList;
+ ArgumentVarReplacementList getArgumentReplacement(const AbstractMetaFunction* func,
+ bool usePyArgs, TypeSystem::Language language,
+ const AbstractMetaArgument* lastArg);
+
+ /// Returns a string with the user's custom code snippets that comply with \p position and \p language.
+ QString getCodeSnippets(const QVector<CodeSnip> & codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language);
+
enum TypeSystemConverterVariable {
TypeSystemCheckFunction = 0,
TypeSystemIsConvertibleFunction,
@@ -514,15 +503,36 @@ protected:
};
void replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable, QString& code);
- static QString msgCouldNotFindMinimalConstructor(const QString &where, const QString &type);
+ /// Replaces the %CONVERTTOPYTHON type system variable.
+ inline void replaceConvertToPythonTypeSystemVariable(QString& code)
+ {
+ replaceConverterTypeSystemVariable(TypeSystemToPythonFunction, code);
+ }
+ /// Replaces the %CONVERTTOCPP type system variable.
+ inline void replaceConvertToCppTypeSystemVariable(QString& code)
+ {
+ replaceConverterTypeSystemVariable(TypeSystemToCppFunction, code);
+ }
+ /// Replaces the %ISCONVERTIBLE type system variable.
+ inline void replaceIsConvertibleToCppTypeSystemVariable(QString& code)
+ {
+ replaceConverterTypeSystemVariable(TypeSystemIsConvertibleFunction, code);
+ }
+ /// Replaces the %CHECKTYPE type system variable.
+ inline void replaceTypeCheckTypeSystemVariable(QString& code)
+ {
+ replaceConverterTypeSystemVariable(TypeSystemCheckFunction, code);
+ }
-private:
- bool m_useCtorHeuristic;
- bool m_userReturnValueHeuristic;
- bool m_usePySideExtensions;
- bool m_verboseErrorMessagesDisabled;
- bool m_useIsNullAsNbNonZero;
- bool m_avoidProtectedHack;
+ /// Return a prefix with '_' suitable for names in C++
+ QString moduleCppPrefix(const QString& moduleName = QString()) const;
+
+ bool m_useCtorHeuristic = false;
+ bool m_userReturnValueHeuristic = false;
+ bool m_usePySideExtensions = false;
+ bool m_verboseErrorMessagesDisabled = false;
+ bool m_useIsNullAsNbNonZero = false;
+ bool m_avoidProtectedHack = false;
typedef QHash<QString, AbstractMetaType*> AbstractMetaTypeCache;
AbstractMetaTypeCache m_metaTypeFromStringCache;
diff --git a/sources/shiboken2/libshiboken/autodecref.h b/sources/shiboken2/libshiboken/autodecref.h
index 7b6aa47da..72fd236de 100644
--- a/sources/shiboken2/libshiboken/autodecref.h
+++ b/sources/shiboken2/libshiboken/autodecref.h
@@ -43,11 +43,6 @@
#include "sbkpython.h"
#include "basewrapper.h"
-#ifdef _MSC_VER
-__pragma(warning(push))
-__pragma(warning(disable:4522)) // warning: C4522: 'Shiboken::AutoDecRef': multiple assignment operators specified
-#endif
-
struct SbkObject;
namespace Shiboken
{
@@ -58,6 +53,11 @@ namespace Shiboken
struct LIBSHIBOKEN_API AutoDecRef
{
public:
+ AutoDecRef(const AutoDecRef&) = delete;
+ AutoDecRef(AutoDecRef&&) = delete;
+ AutoDecRef& operator=(const AutoDecRef&) = delete;
+ AutoDecRef& operator=(AutoDecRef&&) = delete;
+
/**
* AutoDecRef constructor.
* \param pyobj A borrowed reference to a Python object
@@ -92,35 +92,18 @@ public:
}
/**
- * Decref the current borrowed python reference and take the reference
- * borrowed by \p other, so other.isNull() will return true.
- */
- void operator=(AutoDecRef& other)
- {
- Py_XDECREF(m_pyObj);
- m_pyObj = other.m_pyObj;
- other.m_pyObj = 0;
- }
-
- /**
* Decref the current borrowed python reference and borrow \p other.
*/
- void operator=(PyObject* other)
+ void reset(PyObject* other)
{
Py_XDECREF(m_pyObj);
m_pyObj = other;
}
private:
PyObject* m_pyObj;
- AutoDecRef(const AutoDecRef&);
- AutoDecRef& operator=(const AutoDecRef&);
};
} // namespace Shiboken
-#ifdef _MSC_VER
-__pragma(warning(pop))
-#endif
-
#endif // AUTODECREF_H
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 5ca4172c8..c9e3b9d1b 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -40,6 +40,7 @@
#include "basewrapper.h"
#include "basewrapper_p.h"
#include "bindingmanager.h"
+#include "helper.h"
#include "sbkconverter.h"
#include "sbkenum.h"
#include "sbkstring.h"
@@ -60,6 +61,15 @@ namespace {
void _destroyParentInfo(SbkObject* obj, bool keepReference);
}
+static void callDestructor(const Shiboken::DtorAccumulatorVisitor::DestructorEntries &dts)
+{
+ for (const auto &e : dts) {
+ Shiboken::ThreadStateSaver threadSaver;
+ threadSaver.save();
+ e.destructor(e.cppInstance);
+ }
+}
+
extern "C"
{
@@ -118,20 +128,15 @@ static int SbkObject_traverse(PyObject* self, visitproc visit, void* arg)
//Visit children
Shiboken::ParentInfo* pInfo = sbkSelf->d->parentInfo;
if (pInfo) {
- std::set<SbkObject*>::const_iterator it = pInfo->children.begin();
- for(; it != pInfo->children.end(); ++it)
- Py_VISIT(*it);
+ for (SbkObject *c : pInfo->children)
+ Py_VISIT(c);
}
//Visit refs
Shiboken::RefCountMap* rInfo = sbkSelf->d->referredObjects;
if (rInfo) {
- Shiboken::RefCountMap::const_iterator it = rInfo->begin();
- for (; it != rInfo->end(); ++it) {
- std::list<PyObject*>::const_iterator ref = it->second.begin();
- for(; ref != it->second.end(); ++ref)
- Py_VISIT(*ref);
- }
+ for (auto it = rInfo->begin(), end = rInfo->end(); it != end; ++it)
+ Py_VISIT(it->second);
}
if (sbkSelf->ob_dict)
@@ -186,6 +191,12 @@ SbkObjectType *SbkObject_TypeF(void)
return reinterpret_cast<SbkObjectType *>(type);
}
+static int mainThreadDeletionHandler(void *)
+{
+ if (Py_IsInitialized())
+ Shiboken::BindingManager::instance().runDeletionInMainThread();
+ return 0;
+}
static void SbkDeallocWrapperCommon(PyObject* pyObj, bool canDelete)
{
@@ -214,11 +225,32 @@ static void SbkDeallocWrapperCommon(PyObject* pyObj, bool canDelete)
PyObject_ClearWeakRefs(pyObj);
// If I have ownership and is valid delete C++ pointer
- if (canDelete && sbkObj->d->hasOwnership && sbkObj->d->validCppObject) {
- SbkObjectTypePrivate *sotp = PepType_SOTP(pyType);
+ SbkObjectTypePrivate *sotp{nullptr};
+ canDelete &= sbkObj->d->hasOwnership && sbkObj->d->validCppObject;
+ if (canDelete) {
+ sotp = PepType_SOTP(pyType);
+ if (sotp->delete_in_main_thread && Shiboken::currentThreadId() != Shiboken::mainThreadId()) {
+ auto &bindingManager = Shiboken::BindingManager::instance();
+ if (sotp->is_multicpp) {
+ Shiboken::DtorAccumulatorVisitor visitor(sbkObj);
+ Shiboken::walkThroughClassHierarchy(Py_TYPE(pyObj), &visitor);
+ for (const auto &e : visitor.entries())
+ bindingManager.addToDeletionInMainThread(e);
+ } else {
+ Shiboken::DestructorEntry e{sotp->cpp_dtor, sbkObj->d->cptr[0]};
+ bindingManager.addToDeletionInMainThread(e);
+ }
+ Py_AddPendingCall(mainThreadDeletionHandler, nullptr);
+ canDelete = false;
+ }
+ }
+
+ if (canDelete) {
if (sotp->is_multicpp) {
- Shiboken::DeallocVisitor visitor(sbkObj);
+ Shiboken::DtorAccumulatorVisitor visitor(sbkObj);
Shiboken::walkThroughClassHierarchy(Py_TYPE(pyObj), &visitor);
+ Shiboken::Object::deallocData(sbkObj, true);
+ callDestructor(visitor.entries());
} else {
void* cptr = sbkObj->d->cptr[0];
Shiboken::Object::deallocData(sbkObj, true);
@@ -325,7 +357,7 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k
Shiboken::ObjectType::initPrivateData(newType);
SbkObjectTypePrivate *sotp = PepType_SOTP(newType);
- std::list<SbkObjectType*> bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType));
+ const auto bases = Shiboken::getCppBaseClasses(reinterpret_cast<PyTypeObject*>(newType));
if (bases.size() == 1) {
SbkObjectTypePrivate *parentType = PepType_SOTP(bases.front());
sotp->mi_offsets = parentType->mi_offsets;
@@ -352,10 +384,9 @@ PyObject* SbkObjectTypeTpNew(PyTypeObject* metatype, PyObject* args, PyObject* k
sotp->d_func = nullptr;
sotp->is_user_type = 1;
- std::list<SbkObjectType*>::const_iterator it = bases.begin();
- for (; it != bases.end(); ++it) {
- if (PepType_SOTP(*it)->subtype_init)
- PepType_SOTP(*it)->subtype_init(newType, args, kwds);
+ for (SbkObjectType *base : bases) {
+ if (PepType_SOTP(base)->subtype_init)
+ PepType_SOTP(base)->subtype_init(newType, args, kwds);
}
return reinterpret_cast<PyObject*>(newType);
@@ -455,37 +486,22 @@ void _destroyParentInfo(SbkObject* obj, bool keepReference)
namespace Shiboken
{
-
-static void decRefPyObjectList(const std::list<PyObject*> &pyObj, PyObject* skip = 0);
-
-static void _walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor)
+bool walkThroughClassHierarchy(PyTypeObject *currentType, HierarchyVisitor *visitor)
{
PyObject* bases = currentType->tp_bases;
Py_ssize_t numBases = PyTuple_GET_SIZE(bases);
- for (int i = 0; i < numBases; ++i) {
+ bool result = false;
+ for (int i = 0; !result && i < numBases; ++i) {
PyTypeObject* type = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i));
-
- if (!PyType_IsSubtype(type, reinterpret_cast<PyTypeObject*>(SbkObject_TypeF()))) {
- continue;
- } else {
+ if (PyType_IsSubtype(type, reinterpret_cast<PyTypeObject*>(SbkObject_TypeF()))) {
SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(type);
- if (PepType_SOTP(sbkType)->is_user_type)
- _walkThroughClassHierarchy(type, visitor);
- else
- visitor->visit(sbkType);
+ result = PepType_SOTP(sbkType)->is_user_type
+ ? walkThroughClassHierarchy(type, visitor) : visitor->visit(sbkType);
}
- if (visitor->wasFinished())
- break;
}
+ return result;
}
-void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor)
-{
- _walkThroughClassHierarchy(currentType, visitor);
- visitor->done();
-}
-
-
bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr)
{
PyObject* sysModules = PyImport_GetModuleDict();
@@ -517,27 +533,36 @@ bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr)
// Wrapper metatype and base type ----------------------------------------------------------
-void DtorCallerVisitor::visit(SbkObjectType* node)
+HierarchyVisitor::HierarchyVisitor() = default;
+HierarchyVisitor::~HierarchyVisitor() = default;
+
+bool BaseCountVisitor::visit(SbkObjectType *)
{
- m_ptrs.push_back(std::make_pair(m_pyObj->d->cptr[m_ptrs.size()], node));
+ m_count++;
+ return false;
}
-void DtorCallerVisitor::done()
+bool BaseAccumulatorVisitor::visit(SbkObjectType *node)
{
- std::list<std::pair<void*, SbkObjectType*> >::const_iterator it = m_ptrs.begin();
- for (; it != m_ptrs.end(); ++it) {
- Shiboken::ThreadStateSaver threadSaver;
- threadSaver.save();
- PepType_SOTP(it->second)->cpp_dtor(it->first);
- }
+ m_bases.push_back(node);
+ return false;
}
-void DeallocVisitor::done()
+bool GetIndexVisitor::visit(SbkObjectType *node)
{
- Shiboken::Object::deallocData(m_pyObj, true);
- DtorCallerVisitor::done();
+ m_index++;
+ return PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(node), m_desiredType);
}
+bool DtorAccumulatorVisitor::visit(SbkObjectType *node)
+{
+ m_entries.push_back(DestructorEntry{PepType_SOTP(node)->cpp_dtor,
+ m_pyObject->d->cptr[m_entries.size()]});
+ return false;
+}
+
+void _initMainThreadId(); // helper.cpp
+
namespace Conversions { void init(); }
void init()
@@ -546,6 +571,8 @@ void init()
if (shibokenAlreadInitialised)
return;
+ _initMainThreadId();
+
Conversions::init();
PyEval_InitThreads();
@@ -609,25 +636,21 @@ void setErrorAboutWrongArguments(PyObject* args, const char* funcName, const cha
class FindBaseTypeVisitor : public HierarchyVisitor
{
- public:
- FindBaseTypeVisitor(PyTypeObject* typeToFind) : m_found(false), m_typeToFind(typeToFind) {}
- virtual void visit(SbkObjectType* node)
- {
- if (reinterpret_cast<PyTypeObject*>(node) == m_typeToFind) {
- m_found = true;
- finish();
- }
- }
- bool found() const { return m_found; }
+public:
+ explicit FindBaseTypeVisitor(PyTypeObject *typeToFind) : m_typeToFind(typeToFind) {}
+
+ bool visit(SbkObjectType *node) override
+ {
+ return reinterpret_cast<PyTypeObject*>(node) == m_typeToFind;
+ }
- private:
- bool m_found;
- PyTypeObject* m_typeToFind;
+private:
+ PyTypeObject *m_typeToFind;
};
-std::list<SbkObject*> splitPyObject(PyObject* pyObj)
+std::vector<SbkObject *> splitPyObject(PyObject* pyObj)
{
- std::list<SbkObject*> result;
+ std::vector<SbkObject *> result;
if (PySequence_Check(pyObj)) {
AutoDecRef lst(PySequence_Fast(pyObj, "Invalid keep reference object."));
if (!lst.isNull()) {
@@ -643,14 +666,11 @@ std::list<SbkObject*> splitPyObject(PyObject* pyObj)
return result;
}
-static void decRefPyObjectList(const std::list<PyObject*>& lst, PyObject *skip)
+template <class Iterator>
+inline void decRefPyObjectList(Iterator i1, Iterator i2)
{
- std::list<PyObject*>::const_iterator iter = lst.begin();
- while(iter != lst.end()) {
- if (*iter != skip)
- Py_DECREF(*iter);
- ++iter;
- }
+ for (; i1 != i2; ++i1)
+ Py_DECREF(i1->second);
}
namespace ObjectType
@@ -669,8 +689,7 @@ bool isUserType(PyTypeObject* type)
bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctorType)
{
FindBaseTypeVisitor visitor(ctorType);
- walkThroughClassHierarchy(myType, &visitor);
- if (!visitor.found()) {
+ if (!walkThroughClassHierarchy(myType, &visitor)) {
PyErr_Format(PyExc_TypeError, "%s isn't a direct base class of %s", ctorType->tp_name, myType->tp_name);
return false;
}
@@ -748,7 +767,7 @@ introduceWrapperType(PyObject *enclosingObject,
ObjectDestructor cppObjDtor,
SbkObjectType *baseType,
PyObject *baseTypes,
- bool isInnerClass)
+ unsigned wrapperFlags)
{
if (baseType) {
typeSpec->slots[0].pfunc = reinterpret_cast<void *>(baseType);
@@ -773,10 +792,14 @@ introduceWrapperType(PyObject *enclosingObject,
return nullptr;
initPrivateData(type);
+ auto sotp = PepType_SOTP(type);
+ if (wrapperFlags & DeleteInMainThread)
+ sotp->delete_in_main_thread = 1;
+
setOriginalName(type, originalName);
setDestructorFunction(type, cppObjDtor);
- if (isInnerClass) {
+ if (wrapperFlags & InnerClass) {
if (PyDict_SetItemString(enclosingObject, typeName, reinterpret_cast<PyObject *>(type)) == 0)
return type;
else
@@ -844,12 +867,13 @@ static void setSequenceOwnership(PyObject* pyObj, bool owner)
if (PySequence_Check(pyObj) && has_length) {
Py_ssize_t size = PySequence_Size(pyObj);
if (size > 0) {
- std::list<SbkObject*> objs = splitPyObject(pyObj);
- for (auto it = objs.begin(), end = objs.end(); it != end; ++it) {
- if (owner)
- getOwnership(*it);
- else
- releaseOwnership(*it);
+ const auto objs = splitPyObject(pyObj);
+ if (owner) {
+ for (SbkObject *o : objs)
+ getOwnership(o);
+ } else {
+ for (SbkObject *o : objs)
+ releaseOwnership(o);
}
}
} else if (Object::checkType(pyObj)) {
@@ -885,8 +909,9 @@ void callCppDestructors(SbkObject* pyObj)
PyTypeObject *type = Py_TYPE(pyObj);
SbkObjectTypePrivate * sotp = PepType_SOTP(type);
if (sotp->is_multicpp) {
- Shiboken::DtorCallerVisitor visitor(pyObj);
+ Shiboken::DtorAccumulatorVisitor visitor(pyObj);
Shiboken::walkThroughClassHierarchy(type, &visitor);
+ callDestructor(visitor.entries());
} else {
Shiboken::ThreadStateSaver threadSaver;
threadSaver.save();
@@ -977,10 +1002,9 @@ void invalidate(SbkObject* self)
static void recursive_invalidate(PyObject* pyobj, std::set<SbkObject*>& seen)
{
- std::list<SbkObject*> objs = splitPyObject(pyobj);
- std::list<SbkObject*>::const_iterator it = objs.begin();
- for (; it != objs.end(); it++)
- recursive_invalidate(*it, seen);
+ const auto objs = splitPyObject(pyobj);
+ for (SbkObject *o : objs)
+ recursive_invalidate(o, seen);
}
static void recursive_invalidate(SbkObject* self, std::set<SbkObject*>& seen)
@@ -999,30 +1023,22 @@ static void recursive_invalidate(SbkObject* self, std::set<SbkObject*>& seen)
if (self->d->parentInfo) {
// Create a copy because this list can be changed during the process
ChildrenList copy = self->d->parentInfo->children;
- ChildrenList::iterator it = copy.begin();
- for (; it != copy.end(); ++it) {
+ for (SbkObject *child : copy) {
// invalidate the child
- recursive_invalidate(*it, seen);
+ recursive_invalidate(child, seen);
// if the parent not is a wrapper class, then remove children from him, because We do not know when this object will be destroyed
if (!self->d->validCppObject)
- removeParent(*it, true, true);
+ removeParent(child, true, true);
}
}
// If has ref to other objects invalidate all
if (self->d->referredObjects) {
RefCountMap& refCountMap = *(self->d->referredObjects);
- RefCountMap::iterator iter;
- for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) {
- const std::list<PyObject*> lst = iter->second;
- std::list<PyObject*>::const_iterator it = lst.begin();
- while(it != lst.end()) {
- recursive_invalidate(*it, seen);
- ++it;
- }
- }
+ for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it)
+ recursive_invalidate(it->second, seen);
}
}
@@ -1037,23 +1053,17 @@ void makeValid(SbkObject* self)
// If it is a parent make all children valid
if (self->d->parentInfo) {
- ChildrenList::iterator it = self->d->parentInfo->children.begin();
- for (; it != self->d->parentInfo->children.end(); ++it)
- makeValid(*it);
+ for (SbkObject *child : self->d->parentInfo->children)
+ makeValid(child);
}
// If has ref to other objects make all valid again
if (self->d->referredObjects) {
RefCountMap& refCountMap = *(self->d->referredObjects);
RefCountMap::iterator iter;
- for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter) {
- const std::list<PyObject*> lst = iter->second;
- std::list<PyObject*>::const_iterator it = lst.begin();
- while(it != lst.end()) {
- if (Shiboken::Object::checkType(*it))
- makeValid(reinterpret_cast<SbkObject*>(*it));
- ++it;
- }
+ for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it) {
+ if (Shiboken::Object::checkType(it->second))
+ makeValid(reinterpret_cast<SbkObject *>(it->second));
}
}
}
@@ -1168,15 +1178,14 @@ SbkObject *findColocatedChild(SbkObject *wrapper,
ChildrenList& children = pInfo->children;
- ChildrenList::iterator childrenEnd = children.end();
- for (ChildrenList::iterator iChild = children.begin(); iChild != childrenEnd; ++iChild) {
- if (!((*iChild)->d && (*iChild)->d->cptr))
+ for (SbkObject *child : children) {
+ if (!(child->d && child->d->cptr))
continue;
- if ((*iChild)->d->cptr[0] == wrapper->d->cptr[0]) {
- if (reinterpret_cast<const void *>(Py_TYPE(*iChild)) == reinterpret_cast<const void *>(instanceType))
- return const_cast<SbkObject *>((*iChild));
+ if (child->d->cptr[0] == wrapper->d->cptr[0]) {
+ if (reinterpret_cast<const void *>(Py_TYPE(child)) == reinterpret_cast<const void *>(instanceType))
+ return child;
else
- return findColocatedChild(const_cast<SbkObject *>(*iChild), instanceType);
+ return findColocatedChild(child, instanceType);
}
}
return 0;
@@ -1435,57 +1444,56 @@ void* getTypeUserData(SbkObject* wrapper)
return PepType_SOTP(Py_TYPE(wrapper))->user_data;
}
-void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append)
+static inline bool isNone(const PyObject *o)
{
- bool isNone = (!referredObject || (referredObject == Py_None));
-
- if (!self->d->referredObjects)
- self->d->referredObjects = new Shiboken::RefCountMap;
-
- RefCountMap& refCountMap = *(self->d->referredObjects);
- RefCountMap::iterator iter = refCountMap.find(key);
- std::list<PyObject*> objects;
- if (iter != refCountMap.end()) {
- objects = (*iter).second;
- std::list<PyObject*>::const_iterator found = std::find(objects.begin(), objects.end(), referredObject);
-
- // skip if objects already exists
- if (found != objects.end())
- return;
- }
+ return o == nullptr || o == Py_None;
+}
- if (append && !isNone) {
- refCountMap[key].push_back(referredObject);
- Py_INCREF(referredObject);
- } else if (!append) {
- if (objects.size() > 0)
- decRefPyObjectList(objects, isNone ? 0 : referredObject);
- if (isNone) {
- if (iter != refCountMap.end())
- refCountMap.erase(iter);
- } else {
- objects.clear();
- objects.push_back(referredObject);
- refCountMap[key] = objects;
- Py_INCREF(referredObject);
+static void removeRefCountKey(SbkObject* self, const char *key)
+{
+ if (self->d->referredObjects) {
+ const auto iterPair = self->d->referredObjects->equal_range(key);
+ if (iterPair.first != iterPair.second) {
+ decRefPyObjectList(iterPair.first, iterPair.second);
+ self->d->referredObjects->erase(iterPair.first, iterPair.second);
}
}
}
-void removeReference(SbkObject* self, const char* key, PyObject* referredObject)
+void keepReference(SbkObject* self, const char* key, PyObject* referredObject, bool append)
{
- if (!referredObject || (referredObject == Py_None))
+ if (isNone(referredObject)) {
+ removeRefCountKey(self, key);
return;
+ }
- if (!self->d->referredObjects)
+ if (!self->d->referredObjects) {
+ self->d->referredObjects =
+ new Shiboken::RefCountMap{RefCountMap::value_type{key, referredObject}};
+ Py_INCREF(referredObject);
return;
+ }
RefCountMap& refCountMap = *(self->d->referredObjects);
- RefCountMap::iterator iter = refCountMap.find(key);
- if (iter != refCountMap.end()) {
- decRefPyObjectList(iter->second);
- refCountMap.erase(iter);
+ const auto iterPair = refCountMap.equal_range(key);
+ if (std::any_of(iterPair.first, iterPair.second,
+ [referredObject](const RefCountMap::value_type &v) { return v.second == referredObject; })) {
+ return;
+ }
+
+ if (!append && iterPair.first != iterPair.second) {
+ decRefPyObjectList(iterPair.first, iterPair.second);
+ refCountMap.erase(iterPair.first, iterPair.second);
}
+
+ refCountMap.insert(RefCountMap::value_type{key, referredObject});
+ Py_INCREF(referredObject);
+}
+
+void removeReference(SbkObject* self, const char* key, PyObject* referredObject)
+{
+ if (!isNone(referredObject))
+ removeRefCountKey(self, key);
}
void clearReferences(SbkObject* self)
@@ -1494,27 +1502,27 @@ void clearReferences(SbkObject* self)
return;
RefCountMap& refCountMap = *(self->d->referredObjects);
- RefCountMap::iterator iter;
- for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter)
- decRefPyObjectList(iter->second);
+ for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it)
+ Py_DECREF(it->second);
self->d->referredObjects->clear();
}
std::string info(SbkObject* self)
{
std::ostringstream s;
- std::list<SbkObjectType*> bases;
if (self->d && self->d->cptr) {
+ std::vector<SbkObjectType *> bases;
if (ObjectType::isUserType(Py_TYPE(self)))
bases = getCppBaseClasses(Py_TYPE(self));
else
bases.push_back(reinterpret_cast<SbkObjectType*>(Py_TYPE(self)));
s << "C++ address....... ";
- std::list<SbkObjectType*>::const_iterator it = bases.begin();
- for (int i = 0; it != bases.end(); ++it, ++i)
- s << reinterpret_cast<PyTypeObject *>(*it)->tp_name << '/' << self->d->cptr[i] << ' ';
+ for (size_t i = 0, size = bases.size(); i < size; ++i) {
+ auto base = reinterpret_cast<PyTypeObject *>(bases[i]);
+ s << base->tp_name << '/' << self->d->cptr[i] << ' ';
+ }
s << "\n";
}
else {
@@ -1535,9 +1543,8 @@ std::string info(SbkObject* self)
if (self->d->parentInfo && !self->d->parentInfo->children.empty()) {
s << "children.......... ";
- ChildrenList& children = self->d->parentInfo->children;
- for (ChildrenList::const_iterator it = children.begin(); it != children.end(); ++it) {
- Shiboken::AutoDecRef child(PyObject_Str(reinterpret_cast<PyObject *>(*it)));
+ for (SbkObject *sbkChild : self->d->parentInfo->children) {
+ Shiboken::AutoDecRef child(PyObject_Str(reinterpret_cast<PyObject *>(sbkChild)));
s << String::toCString(child) << ' ';
}
s << '\n';
@@ -1546,17 +1553,16 @@ std::string info(SbkObject* self)
if (self->d->referredObjects && !self->d->referredObjects->empty()) {
Shiboken::RefCountMap& map = *self->d->referredObjects;
s << "referred objects.. ";
- Shiboken::RefCountMap::const_iterator it = map.begin();
- for (; it != map.end(); ++it) {
- if (it != map.begin())
- s << " ";
- s << '"' << it->first << "\" => ";
- std::list<PyObject*>::const_iterator j = it->second.begin();
- for (; j != it->second.end(); ++j) {
- Shiboken::AutoDecRef obj(PyObject_Str(*j));
- s << String::toCString(obj) << ' ';
+ std::string lastKey;
+ for (auto it = map.begin(), end = map.end(); it != end; ++it) {
+ if (it->first != lastKey) {
+ if (!lastKey.empty())
+ s << " ";
+ s << '"' << it->first << "\" => ";
+ lastKey = it->first;
}
- s << ' ';
+ Shiboken::AutoDecRef obj(PyObject_Str(it->second));
+ s << String::toCString(obj) << ' ';
}
s << '\n';
}
diff --git a/sources/shiboken2/libshiboken/basewrapper.h b/sources/shiboken2/libshiboken/basewrapper.h
index 134a3bc51..65849d783 100644
--- a/sources/shiboken2/libshiboken/basewrapper.h
+++ b/sources/shiboken2/libshiboken/basewrapper.h
@@ -190,6 +190,12 @@ LIBSHIBOKEN_API void setDestructorFunction(SbkObjectType* self, ObjectDes
LIBSHIBOKEN_API void initPrivateData(SbkObjectType* self);
+enum WrapperFlags
+{
+ InnerClass = 0x1,
+ DeleteInMainThread = 0x2
+};
+
/**
* Initializes a Shiboken wrapper type and adds it to the module,
* or to the enclosing class if the type is an inner class.
@@ -215,7 +221,7 @@ LIBSHIBOKEN_API SbkObjectType *introduceWrapperType(PyObject *enclosingObject,
ObjectDestructor cppObjDtor,
SbkObjectType *baseType,
PyObject *baseTypes,
- bool isInnerClass);
+ unsigned wrapperFlags = 0);
/**
* Set the subtype init hook for a type.
diff --git a/sources/shiboken2/libshiboken/basewrapper_p.h b/sources/shiboken2/libshiboken/basewrapper_p.h
index ebd2648e7..f8a381078 100644
--- a/sources/shiboken2/libshiboken/basewrapper_p.h
+++ b/sources/shiboken2/libshiboken/basewrapper_p.h
@@ -43,10 +43,10 @@
#include "sbkpython.h"
#include "basewrapper.h"
-#include <list>
-#include <map>
+#include <unordered_map>
#include <set>
#include <string>
+#include <vector>
struct SbkObject;
struct SbkObjectType;
@@ -58,7 +58,7 @@ namespace Shiboken
* This mapping associates a method and argument of an wrapper object with the wrapper of
* said argument when it needs the binding to help manage its reference count.
*/
-typedef std::map<std::string, std::list<PyObject*> > RefCountMap;
+typedef std::unordered_multimap<std::string, PyObject *> RefCountMap;
/// Linked list of SbkBaseWrapper pointers
typedef std::set<SbkObject*> ChildrenList;
@@ -137,6 +137,7 @@ struct SbkObjectTypePrivate
/// Tells is the type is a value type or an object-type, see BEHAVIOUR_* constants.
// TODO-CONVERTERS: to be deprecated/removed
int type_behaviour : 2;
+ int delete_in_main_thread : 1;
/// C++ name
char* original_name;
/// Type user data
@@ -150,10 +151,21 @@ struct SbkObjectTypePrivate
namespace Shiboken
{
+
+/**
+ * \internal
+ * Data required to invoke a C++ destructor
+ */
+struct DestructorEntry
+{
+ ObjectDestructor destructor;
+ void *cppInstance;
+};
+
/**
* Utility function used to transform a PyObject that implements sequence protocol into a std::list.
**/
-std::list<SbkObject*> splitPyObject(PyObject* pyObj);
+std::vector<SbkObject *> splitPyObject(PyObject* pyObj);
/**
* Visitor class used by walkOnClassHierarchy function.
@@ -161,81 +173,71 @@ std::list<SbkObject*> splitPyObject(PyObject* pyObj);
class HierarchyVisitor
{
public:
- HierarchyVisitor() : m_wasFinished(false) {}
- virtual ~HierarchyVisitor() {}
- virtual void visit(SbkObjectType* node) = 0;
- virtual void done() {}
- void finish() { m_wasFinished = true; };
- bool wasFinished() const { return m_wasFinished; }
-private:
- bool m_wasFinished;
+ HierarchyVisitor(const HierarchyVisitor &) = delete;
+ HierarchyVisitor(HierarchyVisitor &&) = delete;
+ HierarchyVisitor &operator=(const HierarchyVisitor &) = delete;
+ HierarchyVisitor &operator=(HierarchyVisitor &&) = delete;
+
+ HierarchyVisitor();
+ virtual ~HierarchyVisitor();
+
+ virtual bool visit(SbkObjectType *node) = 0; // return true to terminate
};
class BaseCountVisitor : public HierarchyVisitor
{
public:
- BaseCountVisitor() : m_count(0) {}
-
- void visit(SbkObjectType*)
- {
- m_count++;
- }
+ bool visit(SbkObjectType *) override;
int count() const { return m_count; }
+
private:
- int m_count;
+ int m_count = 0;
};
class BaseAccumulatorVisitor : public HierarchyVisitor
{
public:
- BaseAccumulatorVisitor() {}
+ typedef std::vector<SbkObjectType *> Result;
- void visit(SbkObjectType* node)
- {
- m_bases.push_back(node);
- }
+ bool visit(SbkObjectType *node) override;
+
+ Result bases() const { return m_bases; }
- std::list<SbkObjectType*> bases() const { return m_bases; }
private:
- std::list<SbkObjectType*> m_bases;
+ Result m_bases;
};
class GetIndexVisitor : public HierarchyVisitor
{
public:
- GetIndexVisitor(PyTypeObject* desiredType) : m_index(-1), m_desiredType(desiredType) {}
- virtual void visit(SbkObjectType* node)
- {
- m_index++;
- if (PyType_IsSubtype(reinterpret_cast<PyTypeObject*>(node), m_desiredType))
- finish();
- }
+ explicit GetIndexVisitor(PyTypeObject* desiredType) : m_desiredType(desiredType) {}
+
+ bool visit(SbkObjectType *node) override;
+
int index() const { return m_index; }
private:
- int m_index;
- PyTypeObject* m_desiredType;
+ int m_index = -1;
+ PyTypeObject *m_desiredType;
};
-/// Call the destructor of each C++ object held by a Python object
-class DtorCallerVisitor : public HierarchyVisitor
+/// Collect destructors and C++ instances of each C++ object held by a Python
+/// object
+class DtorAccumulatorVisitor : public HierarchyVisitor
{
public:
- DtorCallerVisitor(SbkObject* pyObj) : m_pyObj(pyObj) {}
- void visit(SbkObjectType* node);
- void done();
-protected:
- std::list<std::pair<void*, SbkObjectType*> > m_ptrs;
- SbkObject* m_pyObj;
-};
+ explicit DtorAccumulatorVisitor(SbkObject *pyObj) : m_pyObject(pyObj) {}
-/// Dealloc of each C++ object held by a Python object, this implies a call to the C++ object destructor
-class DeallocVisitor : public DtorCallerVisitor
-{
-public:
- DeallocVisitor(SbkObject* pyObj) : DtorCallerVisitor(pyObj) {}
- void done();
+ bool visit(SbkObjectType *node) override;
+
+ using DestructorEntries = std::vector<DestructorEntry>;
+
+ const DestructorEntries &entries() const { return m_entries; }
+
+private:
+ DestructorEntries m_entries;
+ SbkObject *m_pyObject;
};
/// \internal Internal function used to walk on classes inheritance trees.
@@ -244,7 +246,7 @@ public:
* For each pure Shiboken type found, HiearchyVisitor::visit is called and the algorithm consider
* all children of this type as visited.
*/
-void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor);
+bool walkThroughClassHierarchy(PyTypeObject *currentType, HierarchyVisitor *visitor);
inline int getTypeIndexOnHierarchy(PyTypeObject* baseType, PyTypeObject* desiredType)
{
@@ -260,7 +262,7 @@ inline int getNumberOfCppBaseClasses(PyTypeObject* baseType)
return visitor.count();
}
-inline std::list<SbkObjectType*> getCppBaseClasses(PyTypeObject* baseType)
+inline std::vector<SbkObjectType *> getCppBaseClasses(PyTypeObject* baseType)
{
BaseAccumulatorVisitor visitor;
walkThroughClassHierarchy(baseType, &visitor);
diff --git a/sources/shiboken2/libshiboken/bindingmanager.cpp b/sources/shiboken2/libshiboken/bindingmanager.cpp
index 0aa520b38..8a9e912fd 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken2/libshiboken/bindingmanager.cpp
@@ -57,14 +57,12 @@ typedef std::unordered_map<const void *, SbkObject *> WrapperMap;
class Graph
{
public:
- typedef std::list<SbkObjectType*> NodeList;
+ typedef std::vector<SbkObjectType *> NodeList;
typedef std::unordered_map<SbkObjectType *, NodeList> Edges;
Edges m_edges;
- Graph()
- {
- }
+ Graph() = default;
void addEdge(SbkObjectType* from, SbkObjectType* to)
{
@@ -78,14 +76,13 @@ public:
file << "digraph D {\n";
- Edges::const_iterator i = m_edges.begin();
- for (; i != m_edges.end(); ++i) {
- SbkObjectType* node1 = i->first;
+ for (auto i = m_edges.begin(), end = m_edges.end(); i != end; ++i) {
+ auto node1 = reinterpret_cast<const PyTypeObject *>(i->first);
const NodeList& nodeList = i->second;
- NodeList::const_iterator j = nodeList.begin();
- for (; j != nodeList.end(); ++j) {
- file << '"' << reinterpret_cast<PyTypeObject *>(*j)->tp_name << "\" -> \""
- << reinterpret_cast<PyTypeObject *>(node1)->tp_name << "\"\n";
+ for (const SbkObjectType *o : nodeList) {
+ auto node2 = reinterpret_cast<const PyTypeObject *>(o);
+ file << '"' << node2->tp_name << "\" -> \""
+ << node1->tp_name << "\"\n";
}
}
file << "}\n";
@@ -97,9 +94,8 @@ public:
Edges::const_iterator edgesIt = m_edges.find(type);
if (edgesIt != m_edges.end()) {
const NodeList& adjNodes = m_edges.find(type)->second;
- NodeList::const_iterator i = adjNodes.begin();
- for (; i != adjNodes.end(); ++i) {
- SbkObjectType* newType = identifyType(cptr, *i, baseType);
+ for (SbkObjectType *node : adjNodes) {
+ SbkObjectType* newType = identifyType(cptr, node, baseType);
if (newType)
return newType;
}
@@ -115,9 +111,8 @@ public:
if (typeFound != type)
*cptr = typeFound;
return type;
- } else {
- return nullptr;
}
+ return nullptr;
}
};
@@ -128,10 +123,9 @@ static void showWrapperMap(const WrapperMap& wrapperMap)
if (Py_VerboseFlag > 0) {
fprintf(stderr, "-------------------------------\n");
fprintf(stderr, "WrapperMap: %p (size: %d)\n", &wrapperMap, (int) wrapperMap.size());
- WrapperMap::const_iterator iter;
- for (iter = wrapperMap.begin(); iter != wrapperMap.end(); ++iter) {
- const SbkObject *sbkObj = iter->second;
- fprintf(stderr, "key: %p, value: %p (%s, refcnt: %d)\n", iter->first,
+ for (auto it = wrapperMap.begin(), end = wrapperMap.end(); it != end; ++it) {
+ const SbkObject *sbkObj = it->second;
+ fprintf(stderr, "key: %p, value: %p (%s, refcnt: %d)\n", it->first,
static_cast<const void *>(sbkObj),
(Py_TYPE(sbkObj))->tp_name,
int(reinterpret_cast<const PyObject *>(sbkObj)->ob_refcnt));
@@ -142,8 +136,11 @@ static void showWrapperMap(const WrapperMap& wrapperMap)
#endif
struct BindingManager::BindingManagerPrivate {
+ using DestructorEntries = std::vector<DestructorEntry>;
+
WrapperMap wrapperMapper;
Graph classHierarchy;
+ DestructorEntries deleteInMainThread;
bool destroying;
BindingManagerPrivate() : destroying(false) {}
@@ -255,6 +252,18 @@ void BindingManager::releaseWrapper(SbkObject* sbkObj)
sbkObj->d->validCppObject = false;
}
+void BindingManager::runDeletionInMainThread()
+{
+ for (const DestructorEntry &e : m_d->deleteInMainThread)
+ e.destructor(e.cppInstance);
+ m_d->deleteInMainThread.clear();
+}
+
+void BindingManager::addToDeletionInMainThread(const DestructorEntry &e)
+{
+ m_d->deleteInMainThread.push_back(e);
+}
+
SbkObject* BindingManager::retrieveWrapper(const void* cptr)
{
WrapperMap::iterator iter = m_d->wrapperMapper.find(cptr);
diff --git a/sources/shiboken2/libshiboken/bindingmanager.h b/sources/shiboken2/libshiboken/bindingmanager.h
index 13a4d3a2e..d03aa999a 100644
--- a/sources/shiboken2/libshiboken/bindingmanager.h
+++ b/sources/shiboken2/libshiboken/bindingmanager.h
@@ -50,11 +50,18 @@ struct SbkObjectType;
namespace Shiboken
{
+struct DestructorEntry;
+
typedef void (*ObjectVisitor)(SbkObject*, void*);
class LIBSHIBOKEN_API BindingManager
{
public:
+ BindingManager(const BindingManager&) = delete;
+ BindingManager(BindingManager&&) = delete;
+ BindingManager& operator=(const BindingManager&) = delete;
+ BindingManager& operator=(BindingManager&&) = delete;
+
static BindingManager& instance();
bool hasWrapper(const void *cptr);
@@ -62,6 +69,9 @@ public:
void registerWrapper(SbkObject* pyObj, void* cptr);
void releaseWrapper(SbkObject* wrapper);
+ void runDeletionInMainThread();
+ void addToDeletionInMainThread(const DestructorEntry &);
+
SbkObject* retrieveWrapper(const void* cptr);
PyObject* getOverride(const void* cptr, const char* methodName);
@@ -94,10 +104,7 @@ public:
private:
~BindingManager();
- // disable copy
BindingManager();
- BindingManager(const BindingManager&);
- BindingManager& operator=(const BindingManager&);
struct BindingManagerPrivate;
BindingManagerPrivate* m_d;
diff --git a/sources/shiboken2/libshiboken/gilstate.h b/sources/shiboken2/libshiboken/gilstate.h
index 00b049802..9da4871d1 100644
--- a/sources/shiboken2/libshiboken/gilstate.h
+++ b/sources/shiboken2/libshiboken/gilstate.h
@@ -49,6 +49,11 @@ namespace Shiboken
class LIBSHIBOKEN_API GilState
{
public:
+ GilState(const GilState&) = delete;
+ GilState(GilState&&) = delete;
+ GilState& operator=(const GilState&) = delete;
+ GilState& operator=(GilState&&) = delete;
+
GilState();
~GilState();
void release();
diff --git a/sources/shiboken2/libshiboken/helper.cpp b/sources/shiboken2/libshiboken/helper.cpp
index 472924723..e42daff07 100644
--- a/sources/shiboken2/libshiboken/helper.cpp
+++ b/sources/shiboken2/libshiboken/helper.cpp
@@ -41,6 +41,12 @@
#include "sbkstring.h"
#include <stdarg.h>
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <pthread.h>
+#endif
+
namespace Shiboken
{
@@ -141,4 +147,24 @@ int warning(PyObject* category, int stacklevel, const char* format, ...)
return result;
}
+ThreadId currentThreadId()
+{
+#if defined(_WIN32)
+ return GetCurrentThreadId();
+#elif defined(__APPLE_CC__)
+ return reinterpret_cast<ThreadId>(pthread_self());
+#else
+ return pthread_self();
+#endif
+}
+
+// Internal, used by init() from main thread
+static ThreadId _mainThreadId{0};
+void _initMainThreadId() { _mainThreadId = currentThreadId(); }
+
+ThreadId mainThreadId()
+{
+ return _mainThreadId;
+}
+
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/helper.h b/sources/shiboken2/libshiboken/helper.h
index b215142c7..9b6d8903f 100644
--- a/sources/shiboken2/libshiboken/helper.h
+++ b/sources/shiboken2/libshiboken/helper.h
@@ -77,7 +77,12 @@ template<class T>
class AutoArrayPointer
{
public:
- AutoArrayPointer(int size) { data = new T[size]; }
+ AutoArrayPointer(const AutoArrayPointer&) = delete;
+ AutoArrayPointer(AutoArrayPointer&&) = delete;
+ AutoArrayPointer& operator=(const AutoArrayPointer&) = delete;
+ AutoArrayPointer& operator=(AutoArrayPointer&&) = delete;
+
+ explicit AutoArrayPointer(int size) { data = new T[size]; }
T& operator[](int pos) { return data[pos]; }
operator T*() const { return data; }
~AutoArrayPointer() { delete[] data; }
@@ -85,6 +90,10 @@ class AutoArrayPointer
T* data;
};
+typedef unsigned long long ThreadId;
+LIBSHIBOKEN_API ThreadId currentThreadId();
+LIBSHIBOKEN_API ThreadId mainThreadId();
+
/**
* An utility function used to call PyErr_WarnEx with a formatted message.
*/
diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp
index 0baf6ed42..7cca03c84 100644
--- a/sources/shiboken2/libshiboken/pep384impl.cpp
+++ b/sources/shiboken2/libshiboken/pep384impl.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "pep384impl.h"
-#include <autodecref.h>
+#include "autodecref.h"
extern "C"
{
@@ -398,7 +398,10 @@ PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
return ret;
}
+#endif // Py_LIMITED_API
+
// This is only a simple local helper that returns a computed variable.
+// Used also in Python 2.
static PyObject *
PepRun_GetResult(const char *command, const char *resvar)
{
@@ -415,6 +418,8 @@ PepRun_GetResult(const char *command, const char *resvar)
return res;
}
+#ifdef Py_LIMITED_API
+
/*****************************************************************************
*
* Support for classobject.h
@@ -497,15 +502,48 @@ static PyTypeObject *getFunctionType(void)
PyTypeObject *PepStaticMethod_TypePtr = NULL;
-static PyTypeObject *getStaticMethodType(void)
+static PyTypeObject *
+getStaticMethodType(void)
{
+ // this works for Python 3, only
+ // "StaticMethodType = type(str.__dict__['maketrans'])\n";
static const char prog[] =
- "StaticMethodType = type(str.__dict__['maketrans'])\n";
- return (PyTypeObject *) PepRun_GetResult(prog, "StaticMethodType");
+ "from xxsubtype import spamlist\n"
+ "StaticMethod_Type = type(spamlist.__dict__['staticmeth'])\n";
+ return (PyTypeObject *) PepRun_GetResult(prog, "StaticMethod_Type");
}
+typedef struct {
+ PyObject_HEAD
+ PyObject *sm_callable;
+ PyObject *sm_dict;
+} staticmethod;
+
+PyObject *
+PyStaticMethod_New(PyObject *callable)
+{
+ staticmethod *sm = (staticmethod *)
+ PyType_GenericAlloc(PepStaticMethod_TypePtr, 0);
+ if (sm != NULL) {
+ Py_INCREF(callable);
+ sm->sm_callable = callable;
+ }
+ return (PyObject *)sm;
+}
#endif // Py_LIMITED_API
+#if PY_VERSION_HEX < 0x03000000
+PyTypeObject *PepMethodDescr_TypePtr = NULL;
+
+static PyTypeObject *
+getMethodDescrType(void)
+{
+ static const char prog[] =
+ "MethodDescr_Type = type(str.split)\n";
+ return (PyTypeObject *) PepRun_GetResult(prog, "MethodDescr_Type");
+}
+#endif
+
/*****************************************************************************
*
* Common newly needed functions
@@ -630,6 +668,9 @@ Pep384_Init()
PepFunction_TypePtr = getFunctionType();
PepStaticMethod_TypePtr = getStaticMethodType();
#endif
+#if PY_VERSION_HEX < 0x03000000
+ PepMethodDescr_TypePtr = getMethodDescrType();
+#endif
}
} // extern "C"
diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h
index b566a6218..bfa8f38a7 100644
--- a/sources/shiboken2/libshiboken/pep384impl.h
+++ b/sources/shiboken2/libshiboken/pep384impl.h
@@ -63,6 +63,7 @@ extern "C"
*/
#ifdef Py_LIMITED_API
// Why the hell is this useful debugging function not allowed?
+// BTW: When used, it breaks on Windows, intentionally!
LIBSHIBOKEN_API void _PyObject_Dump(PyObject *);
#endif
@@ -286,7 +287,7 @@ LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject *
// But this is no problem as we check it's validity for every version.
#define PYTHON_BUFFER_VERSION_COMPATIBLE (PY_VERSION_HEX >= 0x03030000 && \
- PY_VERSION_HEX < 0X0307FFFF)
+ PY_VERSION_HEX < 0x0307FFFF)
#if !PYTHON_BUFFER_VERSION_COMPATIBLE
# error Please check the buffer compatibility for this python version!
#endif
@@ -332,10 +333,11 @@ LIBSHIBOKEN_API PyObject *PepFunction_Get(PyObject *, const char *);
#define PyFunction_Check(op) (Py_TYPE(op) == PepFunction_TypePtr)
#define PyFunction_GET_CODE(func) PyFunction_GetCode(func)
-#define PyFunction_GetCode(func) PepFunction_Get((PyObject *)func, "__code__")
-#define PepFunction_GetName(func) PepFunction_Get((PyObject *)func, "__name__")
+#define PyFunction_GetCode(func) PepFunction_Get((PyObject *)func, "__code__")
+#define PepFunction_GetName(func) PepFunction_Get((PyObject *)func, "__name__")
#else
-#define PepFunction_GetName(func) (((PyFunctionObject *)func)->func_name)
+#define PepFunction_TypePtr (&PyFunction_Type)
+#define PepFunction_GetName(func) (((PyFunctionObject *)func)->func_name)
#endif
/*****************************************************************************
@@ -467,9 +469,16 @@ LIBSHIBOKEN_API PyObject *_Pep_PrivateMangle(PyObject *self, PyObject *name);
#ifdef Py_LIMITED_API
extern LIBSHIBOKEN_API PyTypeObject *PepStaticMethod_TypePtr;
+LIBSHIBOKEN_API PyObject *PyStaticMethod_New(PyObject *callable);
#else
#define PepStaticMethod_TypePtr &PyStaticMethod_Type
#endif
+// Although not PEP specific, we resolve this similar issue, here:
+#if PY_VERSION_HEX < 0x03000000
+extern LIBSHIBOKEN_API PyTypeObject *PepMethodDescr_TypePtr;
+#else
+#define PepMethodDescr_TypePtr &PyMethodDescr_Type
+#endif
/*****************************************************************************
*
diff --git a/sources/shiboken2/libshiboken/pep384impl_doc.rst b/sources/shiboken2/libshiboken/pep384impl_doc.rst
index 2844249ad..ab286dd3e 100644
--- a/sources/shiboken2/libshiboken/pep384impl_doc.rst
+++ b/sources/shiboken2/libshiboken/pep384impl_doc.rst
@@ -283,7 +283,9 @@ written that skips over dotted name parts.
Finally, the function ``_PyObject_Dump`` was excluded from the limited API.
This is a useful debugging aid that we always want to have available,
-so it is added back, again.
+so it is added back, again. Anyway, we did not reimplement it, and so
+Windows is not supported.
+Therefore, a forgotten debugging call of this functions will break COIN. :-)
Using The New Type API
diff --git a/sources/shiboken2/libshiboken/qt_attribution.json b/sources/shiboken2/libshiboken/qt_attribution.json
index 12a0952df..071870780 100644
--- a/sources/shiboken2/libshiboken/qt_attribution.json
+++ b/sources/shiboken2/libshiboken/qt_attribution.json
@@ -7,6 +7,6 @@
"Homepage": "http://www.python.org/",
"Version": "3.7.0",
"License": "PSF LICENSE AGREEMENT FOR PYTHON 3.7.0",
- "LicenseFile": "bufferprocs27.h",
+ "LicenseFile": "bufferprocs_py37.h",
"Copyright": "© Copyright 2001-2018, Python Software Foundation."
}
diff --git a/sources/shiboken2/libshiboken/sbkconverter.cpp b/sources/shiboken2/libshiboken/sbkconverter.cpp
index a13222de6..4f6ebf65f 100644
--- a/sources/shiboken2/libshiboken/sbkconverter.cpp
+++ b/sources/shiboken2/libshiboken/sbkconverter.cpp
@@ -78,7 +78,8 @@ void init()
Primitive<unsigned int>::createConverter(),
Primitive<unsigned long>::createConverter(),
Primitive<unsigned short>::createConverter(),
- VoidPtr::createConverter()
+ VoidPtr::createConverter(),
+ Primitive<std::nullptr_t>::createConverter()
};
PrimitiveTypeConverters = primitiveTypeConverters;
@@ -100,6 +101,7 @@ void init()
converters["unsigned long"] = primitiveTypeConverters[SBK_UNSIGNEDLONG_IDX];
converters["unsigned short"] = primitiveTypeConverters[SBK_UNSIGNEDSHORT_IDX];
converters["void*"] = primitiveTypeConverters[SBK_VOIDPTR_IDX];
+ converters["std::nullptr_t"] = primitiveTypeConverters[SBK_NULLPTR_T_IDX];
initArrayConverters();
}
@@ -246,10 +248,8 @@ PythonToCppFunc isPythonToCppPointerConvertible(SbkObjectType *type, PyObject *p
static inline PythonToCppFunc IsPythonToCppConvertible(const SbkConverter *converter, PyObject *pyIn)
{
assert(pyIn);
- const ToCppConversionList& convs = converter->toCppConversions;
- for (ToCppConversionList::const_iterator conv = convs.begin(), end = convs.end(); conv != end; ++conv) {
- PythonToCppFunc toCppFunc = 0;
- if ((toCppFunc = (*conv).first(pyIn)))
+ for (const ToCppConversion &c : converter->toCppConversions) {
+ if (PythonToCppFunc toCppFunc = c.first(pyIn))
return toCppFunc;
}
return 0;
@@ -361,7 +361,7 @@ bool isImplicitConversion(SbkObjectType *type, PythonToCppFunc toCppFunc)
// Note that we don't check if the Python to C++ conversion is in
// the list of the type's conversions, for it is expected that the
// caller knows what he's doing.
- ToCppConversionList::iterator conv = PepType_SOTP(type)->converter->toCppConversions.begin();
+ const auto conv = PepType_SOTP(type)->converter->toCppConversions.cbegin();
return toCppFunc != (*conv).second;
}
diff --git a/sources/shiboken2/libshiboken/sbkconverter.h b/sources/shiboken2/libshiboken/sbkconverter.h
index 0effebf57..33c33025b 100644
--- a/sources/shiboken2/libshiboken/sbkconverter.h
+++ b/sources/shiboken2/libshiboken/sbkconverter.h
@@ -341,6 +341,7 @@ LIBSHIBOKEN_API bool pythonTypeIsWrapperType(const SbkConverter *converter);
#define SBK_UNSIGNEDLONG_IDX 14
#define SBK_UNSIGNEDSHORT_IDX 15
#define SBK_VOIDPTR_IDX 16
+#define SBK_NULLPTR_T_IDX 17
template<typename T> SbkConverter* PrimitiveTypeConverter() { return 0; }
template<> inline SbkConverter* PrimitiveTypeConverter<PY_LONG_LONG>() { return primitiveTypeConverter(SBK_PY_LONG_LONG_IDX); }
@@ -360,6 +361,7 @@ template<> inline SbkConverter* PrimitiveTypeConverter<unsigned int>() { return
template<> inline SbkConverter* PrimitiveTypeConverter<unsigned long>() { return primitiveTypeConverter(SBK_UNSIGNEDLONG_IDX); }
template<> inline SbkConverter* PrimitiveTypeConverter<unsigned short>() { return primitiveTypeConverter(SBK_UNSIGNEDSHORT_IDX); }
template<> inline SbkConverter* PrimitiveTypeConverter<void*>() { return primitiveTypeConverter(SBK_VOIDPTR_IDX); }
+template<> inline SbkConverter* PrimitiveTypeConverter<std::nullptr_t>() { return primitiveTypeConverter(SBK_NULLPTR_T_IDX); }
} // namespace Shiboken::Conversions
@@ -386,6 +388,7 @@ template<> inline PyTypeObject* SbkType<unsigned char>() { return &PyInt_Type; }
template<> inline PyTypeObject* SbkType<unsigned int>() { return &PyLong_Type; }
template<> inline PyTypeObject* SbkType<unsigned long>() { return &PyLong_Type; }
template<> inline PyTypeObject* SbkType<unsigned short>() { return &PyInt_Type; }
+template<> inline PyTypeObject* SbkType<std::nullptr_t>() { return Py_TYPE(&_Py_NoneStruct); }
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/sbkconverter_p.h b/sources/shiboken2/libshiboken/sbkconverter_p.h
index f39608663..cb968ed89 100644
--- a/sources/shiboken2/libshiboken/sbkconverter_p.h
+++ b/sources/shiboken2/libshiboken/sbkconverter_p.h
@@ -43,11 +43,11 @@
#include "sbkpython.h"
#include "sbkconverter.h"
#include "sbkstring.h"
-#include <list>
#include <limits>
#include <typeinfo>
#include <sstream>
#include <iostream>
+#include <vector>
#include "sbkdbg.h"
@@ -55,7 +55,7 @@ extern "C"
{
typedef std::pair<IsConvertibleToCppFunc, PythonToCppFunc> ToCppConversion;
-typedef std::list<ToCppConversion> ToCppConversionList;
+typedef std::vector<ToCppConversion> ToCppConversionVector;
/**
* \internal
@@ -104,7 +104,7 @@ struct SbkConverter
* For Object Types, that never have implicit conversions, this
* list is always empty.
*/
- ToCppConversionList toCppConversions;
+ ToCppConversionVector toCppConversions;
};
} // extern "C"
@@ -533,6 +533,36 @@ struct Primitive<std::string> : TwoPrimitive<std::string>
}
};
+// nullptr_t
+template <>
+struct Primitive<std::nullptr_t> : TwoPrimitive<std::nullptr_t>
+{
+ static PyObject* toPython(const void* cppIn)
+ {
+ return Py_None;
+ }
+ static void toCpp(PyObject *, void *cppOut)
+ {
+ *reinterpret_cast<std::nullptr_t*>(cppOut) = nullptr;
+ }
+ static PythonToCppFunc isConvertible(PyObject* pyIn)
+ {
+ if (pyIn == Py_None)
+ return toCpp;
+ return nullptr;
+ }
+ static void otherToCpp(PyObject* pyIn, void* cppOut)
+ {
+ *reinterpret_cast<std::nullptr_t*>(cppOut) = nullptr;
+ }
+ static PythonToCppFunc isOtherConvertible(PyObject* pyIn)
+ {
+ if (pyIn == nullptr)
+ return otherToCpp;
+ return nullptr;
+ }
+};
+
namespace Shiboken {
namespace Conversions {
SbkConverter *createConverterObject(PyTypeObject *type,
diff --git a/sources/shiboken2/libshiboken/sbkdbg.h b/sources/shiboken2/libshiboken/sbkdbg.h
index c26816bbd..fdaf2a27a 100644
--- a/sources/shiboken2/libshiboken/sbkdbg.h
+++ b/sources/shiboken2/libshiboken/sbkdbg.h
@@ -63,6 +63,11 @@
class BaseLogger
{
public:
+ BaseLogger(const BaseLogger&) = delete;
+ BaseLogger(BaseLogger&&) = delete;
+ BaseLogger& operator=(const BaseLogger&) = delete;
+ BaseLogger& operator=(BaseLogger&&) = delete;
+
BaseLogger(std::ostream& output, const char* function, const char* context)
: m_stream(output), m_function(function), m_context(context) {}
~BaseLogger()
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index d129e6380..26b40c3cb 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -47,9 +47,11 @@
#include <string.h>
#include <cstring>
-#include <list>
+#include <vector>
#define SBK_ENUM(ENUM) reinterpret_cast<SbkEnumObject*>(ENUM)
+#define SBK_TYPE_CHECK(o) (strcmp(Py_TYPE(Py_TYPE(o))->tp_name, "Shiboken.EnumType") == 0)
+typedef PyObject* (*enum_func)(PyObject*, PyObject*);
extern "C"
{
@@ -75,7 +77,7 @@ struct SbkEnumObject
static PyObject* SbkEnumObject_repr(PyObject* self)
{
- const SbkEnumObject *enumObj = reinterpret_cast<SbkEnumObject *>(self);
+ const SbkEnumObject *enumObj = SBK_ENUM(self);
if (enumObj->ob_name)
return Shiboken::String::fromFormat("%s.%s", (Py_TYPE(self))->tp_name, PyBytes_AS_STRING(enumObj->ob_name));
else
@@ -84,7 +86,7 @@ static PyObject* SbkEnumObject_repr(PyObject* self)
static PyObject* SbkEnumObject_name(PyObject* self, void*)
{
- SbkEnumObject *enum_self = reinterpret_cast<SbkEnumObject *>(self);
+ SbkEnumObject *enum_self = SBK_ENUM(self);
if (enum_self->ob_name == NULL)
Py_RETURN_NONE;
@@ -113,6 +115,43 @@ static PyObject* SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
return reinterpret_cast<PyObject*>(self);
}
+static PyObject* enum_op(enum_func f, PyObject *a, PyObject *b) {
+ PyObject *valA = a;
+ PyObject *valB = b;
+ PyObject *result = nullptr;
+ bool enumA = false;
+ bool enumB = false;
+
+ // We are not allowing floats
+ if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
+ // Check if both variables are SbkEnumObject
+ if (SBK_TYPE_CHECK(valA)) {
+ valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+ enumA = true;
+ }
+ if (SBK_TYPE_CHECK(valB)) {
+ valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+ enumB = true;
+ }
+ }
+
+ // Without an enum we are not supporting the operation
+ if (!(enumA || enumB)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ } else {
+ result = f(valA, valB);
+ }
+
+ // Decreasing the reference of the used variables a and b.
+ if (enumA)
+ Py_DECREF(valA);
+ if (enumB)
+ Py_DECREF(valB);
+
+ return result;
+}
+
/* Notes:
* On Py3k land we use long type when using integer numbers. However, on older
* versions of Python (version 2) we need to convert it to int type,
@@ -126,48 +165,19 @@ static PyObject* enum_int(PyObject* v)
return PyInt_FromLong(SBK_ENUM(v)->ob_value);
}
-static long getNumberValue(PyObject* v)
-{
- PyObject* number = PyNumber_Long(v);
- long result = PyLong_AsLong(number);
- Py_XDECREF(number);
- return result;
-}
-
static PyObject* enum_and(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA & valB);
+ return enum_op(PyNumber_And, self, b);
}
static PyObject* enum_or(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA | valB);
+return enum_op(PyNumber_Or, self, b);
}
static PyObject* enum_xor(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA ^ valB);
+ return enum_op(PyNumber_Xor, self, b);
}
static int enum_bool(PyObject* v)
@@ -177,72 +187,63 @@ static int enum_bool(PyObject* v)
static PyObject* enum_add(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA + valB);
+ return enum_op(PyNumber_Add, self, v);
}
static PyObject* enum_subtract(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA - valB);
+ return enum_op(PyNumber_Subtract, self, v);
}
static PyObject* enum_multiply(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA * valB);
+return enum_op(PyNumber_Multiply, self, v);
}
#ifndef IS_PY3K
static PyObject* enum_divide(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyLong_FromLong(valA / valB);
+ return enum_op(PyNumber_Divide, self, v);
}
#endif
static PyObject* enum_richcompare(PyObject* self, PyObject* other, int op)
{
- int result = 0;
- if (!PyNumber_Check(other)) {
+ PyObject *valA = self;
+ PyObject *valB = other;
+ PyObject *result = nullptr;
+ bool enumA = false;
+ bool enumB = false;
+
+ // We are not allowing floats
+ if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
+
+ // Check if both variables are SbkEnumObject
+ if (SBK_TYPE_CHECK(valA)) {
+ valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+ enumA = true;
+ }
+ if (SBK_TYPE_CHECK(valB)) {
+ valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+ enumB =true;
+ }
+ }
+
+ // Without an enum we are not supporting the operation
+ if (!(enumA || enumB)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
+ } else {
+ result = PyObject_RichCompare(valA, valB, op);
}
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(other);
-
- switch (op) {
- case Py_EQ:
- result = (valA == valB);
- break;
- case Py_NE:
- result = (valA != valB);
- break;
- case Py_LE:
- result = (valA <= valB);
- break;
- case Py_GE:
- result = (valA >= valB);
- break;
- case Py_LT:
- result = (valA < valB);
- break;
- case Py_GT:
- result = (valA > valB);
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
- if (result)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ // Decreasing the reference of the used variables a and b.
+ if (enumA)
+ Py_DECREF(valA);
+ if (enumB)
+ Py_DECREF(valB);
+
+ return result;
}
static Py_hash_t enum_hash(PyObject* pyObj)
@@ -339,15 +340,18 @@ namespace Shiboken {
class DeclaredEnumTypes
{
public:
+ DeclaredEnumTypes(const DeclaredEnumTypes&) = delete;
+ DeclaredEnumTypes(DeclaredEnumTypes&&) = delete;
+ DeclaredEnumTypes& operator=(const DeclaredEnumTypes&) = delete;
+ DeclaredEnumTypes& operator=(DeclaredEnumTypes&&) = delete;
+
DeclaredEnumTypes();
~DeclaredEnumTypes();
static DeclaredEnumTypes& instance();
void addEnumType(PyTypeObject* type);
private:
- DeclaredEnumTypes(const DeclaredEnumTypes&);
- DeclaredEnumTypes& operator=(const DeclaredEnumTypes&);
- std::list<PyTypeObject*> m_enumTypes;
+ std::vector<PyTypeObject *> m_enumTypes;
};
namespace Enum {
@@ -373,7 +377,9 @@ PyObject* getEnumItemFromValue(PyTypeObject* enumType, long itemValue)
return 0;
}
-static PyTypeObject* createEnum(const char* fullName, const char* cppName, const char* shortName, PyTypeObject* flagsType)
+static PyTypeObject* createEnum(const char* fullName, const char* cppName,
+ const char* /* shortName */,
+ PyTypeObject* flagsType)
{
PyTypeObject* enumType = newTypeWithName(fullName, cppName, flagsType);
if (PyType_Ready(enumType) < 0)
@@ -524,13 +530,8 @@ copyNumberMethods(PyTypeObject *flagsType,
int *pidx)
{
int idx = *pidx;
-#ifdef IS_PY3K
-# define SLOT slot
-#else
-# define SLOT slot_
-#endif
#define PUT_SLOT(name) \
- number_slots[idx].SLOT = (name); \
+ number_slots[idx].slot = (name); \
number_slots[idx].pfunc = PyType_GetSlot(flagsType, (name)); \
++idx;
@@ -593,8 +594,8 @@ newTypeWithName(const char* name,
newspec->flags = SbkNewType_spec.flags;
// we must append all the number methods, so rebuild everything:
int idx = 0;
- while (SbkNewType_slots[idx].SLOT) {
- newslots[idx].SLOT = SbkNewType_slots[idx].SLOT;
+ while (SbkNewType_slots[idx].slot) {
+ newslots[idx].slot = SbkNewType_slots[idx].slot;
newslots[idx].pfunc = SbkNewType_slots[idx].pfunc;
++idx;
}
@@ -644,14 +645,10 @@ DeclaredEnumTypes& DeclaredEnumTypes::instance()
return me;
}
-DeclaredEnumTypes::DeclaredEnumTypes()
-{
-}
+DeclaredEnumTypes::DeclaredEnumTypes() = default;
DeclaredEnumTypes::~DeclaredEnumTypes()
{
- std::list<PyTypeObject*>::const_iterator it = m_enumTypes.begin();
- for (; it != m_enumTypes.end(); ++it) {
/*
* PYSIDE-595: This was "delete *it;" before introducing 'PyType_FromSpec'.
* XXX what should I do now?
@@ -660,8 +657,8 @@ DeclaredEnumTypes::~DeclaredEnumTypes()
* So right now I am doing nothing. Surely wrong but no crash.
* See also the comment in function 'createGlobalEnumItem'.
*/
- //fprintf(stderr, "ttt %d %s\n", Py_REFCNT(*it), *it->tp_name);
- }
+ // for (PyTypeObject *o : m_enumTypes)
+ // fprintf(stderr, "ttt %d %s\n", Py_REFCNT(o), o->tp_name);
m_enumTypes.clear();
}
diff --git a/sources/shiboken2/libshiboken/sbkpython.h b/sources/shiboken2/libshiboken/sbkpython.h
index 29e25605a..f06b0b19e 100644
--- a/sources/shiboken2/libshiboken/sbkpython.h
+++ b/sources/shiboken2/libshiboken/sbkpython.h
@@ -42,19 +42,65 @@
#include "sbkversion.h"
+// Qt's "slots" macro collides with the "slots" member variables
+// used in some Python structs. For compilers that support push_macro,
+// temporarily undefine it.
+#if defined(slots) && (defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__))
+# pragma push_macro("slots")
+# undef slots
/*
* Python 2 has function _Py_Mangle directly in Python.h .
* This creates wrong language binding unless we define 'extern "C"' here.
*/
extern "C" {
-#include <Python.h>
+/*
+ * Python 2 uses the "register" keyword, which is deprecated in C++ 11
+ * and forbidden in C++17.
+ */
+# if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-register"
+# endif
+
+# include <Python.h>
+
+# if defined(__clang__)
+# pragma clang diagnostic pop
+# endif
}
-#include <structmember.h>
+# include <structmember.h>
// Now we have the usual variables from Python.h .
-#include "python25compat.h"
-#include "shibokenmacros.h"
-#include "pep384impl.h"
-#include "typespec.h"
+# include "python25compat.h"
+# include "shibokenmacros.h"
+# include "pep384impl.h"
+# include "typespec.h"
+# pragma pop_macro("slots")
+
+#else
+
+extern "C" {
+/*
+ * Python 2 uses the "register" keyword, which is deprecated in C++ 11
+ * and forbidden in C++17.
+ */
+# if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wdeprecated-register"
+# endif
+
+# include <Python.h>
+
+# if defined(__clang__)
+# pragma clang diagnostic pop
+# endif
+}
+# include <structmember.h>
+// Now we have the usual variables from Python.h .
+# include "python25compat.h"
+# include "shibokenmacros.h"
+# include "pep384impl.h"
+# include "typespec.h"
+#endif
#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
diff --git a/sources/shiboken2/libshiboken/sbkstring.cpp b/sources/shiboken2/libshiboken/sbkstring.cpp
index 6ca35f12e..a3ffcdabb 100644
--- a/sources/shiboken2/libshiboken/sbkstring.cpp
+++ b/sources/shiboken2/libshiboken/sbkstring.cpp
@@ -66,10 +66,7 @@ bool check(PyObject* obj)
bool checkChar(PyObject* pyobj)
{
- if (check(pyobj) && (len(pyobj) == 1))
- return true;
-
- return false;
+ return check(pyobj) && (len(pyobj) == 1);
}
bool isConvertible(PyObject* obj)
diff --git a/sources/shiboken2/libshiboken/shibokenbuffer.cpp b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
index dc29b40a7..a691a31ee 100644
--- a/sources/shiboken2/libshiboken/shibokenbuffer.cpp
+++ b/sources/shiboken2/libshiboken/shibokenbuffer.cpp
@@ -58,6 +58,7 @@ void* Shiboken::Buffer::getPointer(PyObject* pyObj, Py_ssize_t* size)
PyBuffer_Release(&view);
return view.buf;
}
+ return nullptr;
#else
Py_ssize_t bufferSize = 0;
@@ -85,7 +86,8 @@ PyObject* Shiboken::Buffer::newObject(void* memory, Py_ssize_t size, Type type)
view.shape = shape;
// Pep384: This is way too complicated and impossible with the limited api:
//return PyMemoryView_FromBuffer(&view);
- return PyMemoryView_FromMemory((char *)view.buf, size, type == ReadOnly ? PyBUF_READ : PyBUF_WRITE);
+ return PyMemoryView_FromMemory(reinterpret_cast<char *>(view.buf),
+ size, type == ReadOnly ? PyBUF_READ : PyBUF_WRITE);
#else
return type == ReadOnly ? PyBuffer_FromMemory(memory, size) : PyBuffer_FromReadWriteMemory(memory, size);
#endif
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index f0bb8e609..922f85906 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -38,6 +38,7 @@
****************************************************************************/
#include "basewrapper.h"
+#include "autodecref.h"
extern "C"
{
@@ -77,18 +78,25 @@ typedef struct safe_globals_struc {
static safe_globals pyside_globals = 0;
-static PyObject *GetSignature_Function(PyCFunctionObject *);
-static PyObject *GetSignature_TypeMod(PyObject *);
+static PyObject *GetClassKey(PyObject *ob);
+
+static PyObject *GetSignature_Function(PyObject *, const char *);
+static PyObject *GetSignature_TypeMod(PyObject *, const char *);
+static PyObject *GetSignature_Wrapper(PyObject *, const char *);
+static PyObject *get_signature(PyObject *self, PyObject *args);
static PyObject *PySide_BuildSignatureProps(PyObject *class_mod);
+static void init_module_1(void);
+static void init_module_2(void);
+
const char helper_module_name[] = "signature_loader";
const char bootstrap_name[] = "bootstrap";
const char arg_name[] = "pyside_arg_dict";
const char func_name[] = "pyside_type_init";
static PyObject *
-CreateSignature(PyObject *props, const char *sig_kind)
+CreateSignature(PyObject *props, PyObject *key)
{
/*
* Here is the new function to create all signatures. It simply calls
@@ -97,30 +105,95 @@ CreateSignature(PyObject *props, const char *sig_kind)
* to support '_signature_is_functionlike()'.
*/
return PyObject_CallFunction(pyside_globals->createsig_func,
- (char *)"(Os)", props, sig_kind);
+ (char *)"(OO)", props, key);
}
static PyObject *
-pyside_cf_get___signature__(PyObject *func)
+pyside_cf_get___signature__(PyObject *func, const char *modifier)
{
- return GetSignature_Function((PyCFunctionObject *)func);
+ init_module_2();
+ return GetSignature_Function(func, modifier);
}
static PyObject *
-pyside_sm_get___signature__(PyObject *sm)
+pyside_sm_get___signature__(PyObject *sm, const char *modifier)
{
- PyObject *func, *ret;
+ init_module_2();
+ Shiboken::AutoDecRef func(PyObject_GetAttrString(sm, "__func__"));
+ if (Py_TYPE(func) == PepFunction_TypePtr)
+ Py_RETURN_NONE;
+ return GetSignature_Function(func, modifier);
+}
- func = PyObject_GetAttrString(sm, "__func__");
- ret = GetSignature_Function((PyCFunctionObject *)func);
- Py_XDECREF(func);
- return ret;
+static PyObject *
+_get_class_of_cf(PyObject *ob_cf)
+{
+ PyObject *selftype = PyCFunction_GET_SELF(ob_cf);
+ if (selftype == NULL)
+ selftype = PyDict_GetItem(pyside_globals->map_dict, (PyObject *)ob_cf);
+ if (selftype == NULL) {
+ if (!PyErr_Occurred())
+ Py_RETURN_NONE;
+ return NULL;
+ }
+ PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype))
+ ? selftype : (PyObject *)Py_TYPE(selftype);
+ // do we support module functions?
+ Py_INCREF(typemod);
+ return typemod;
+}
+
+static PyObject *
+_get_class_of_sm(PyObject *ob_sm)
+{
+ Shiboken::AutoDecRef func(PyObject_GetAttrString(ob_sm, "__func__"));
+ return _get_class_of_cf(func);
}
-#ifdef Py_LIMITED_API
+static PyObject *
+_get_class_of_descr(PyObject *ob)
+{
+ Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
+ return PyObject_GetAttrString(ob, "__objclass__");
+}
+
+static PyObject *
+GetClassOfFunc(PyObject *ob)
+{
+ if (PyType_Check(ob))
+ return ob;
+ if (Py_TYPE(ob) == &PyCFunction_Type)
+ return _get_class_of_cf(ob);
+ if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
+ return _get_class_of_sm(ob);
+ if (Py_TYPE(ob) == PepMethodDescr_TypePtr)
+ return _get_class_of_descr(ob);
+ if (Py_TYPE(ob) == &PyWrapperDescr_Type)
+ return _get_class_of_descr(ob);
+ Py_FatalError("unexpected type in GetClassOfFunc");
+ return nullptr;
+}
+
+static PyObject *
+compute_name_key(PyObject *ob)
+{
+ if (PyType_Check(ob))
+ return GetClassKey(GetClassOfFunc(ob));
+ PyObject *func = ob;
+ if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
+ func = PyObject_GetAttrString(ob, "__func__");
+ else
+ Py_INCREF(func);
+ Shiboken::AutoDecRef func_name(PyObject_GetAttrString(func, "__name__"));
+ Py_DECREF(func);
+ if (func_name.isNull())
+ Py_FatalError("unexpected name problem in compute_name_key");
+ Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
+ return Py_BuildValue("(OO)", type_key.object(), func_name.object());
+}
static int
-build_qualname_to_func(PyObject *obtype)
+build_name_key_to_func(PyObject *obtype)
{
PyTypeObject *type = (PyTypeObject *)obtype;
PyMethodDef *meth = type->tp_methods;
@@ -129,230 +202,245 @@ build_qualname_to_func(PyObject *obtype)
return 0;
for (; meth->ml_name != NULL; meth++) {
- PyObject *func = PyCFunction_NewEx(meth, obtype, NULL);
- PyObject *qualname = PyObject_GetAttrString(func, "__qualname__");
- if (func == NULL || qualname == NULL) {
- return -1;
- }
- if (PyDict_SetItem(pyside_globals->map_dict, qualname, func) < 0) {
+ Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, NULL));
+ Shiboken::AutoDecRef name_key(compute_name_key(func));
+ if (func.isNull() || name_key.isNull()
+ || PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0)
return -1;
- }
- Py_DECREF(func);
- Py_DECREF(qualname);
}
return 0;
}
static PyObject *
-qualname_to_typename(PyObject *qualname)
-{
- PyObject *func = PyObject_GetAttrString(qualname, "split");
- PyObject *list = func ? PyObject_CallFunction(func, (char *)"(s)", ".")
- : NULL;
- PyObject *res = list ? PyList_GetItem(list, 0) : NULL;
- Py_XINCREF(res);
- Py_XDECREF(func);
- Py_XDECREF(list);
- return res;
-}
-
-static PyObject *
-qualname_to_func(PyObject *ob)
+name_key_to_func(PyObject *ob)
{
/*
- * If we have __qualname__, then we can easily build a mapping
- * from __qualname__ to PyCFunction. This is necessary when
- * the limited API does not let us go easily from descriptor
- * to PyMethodDef.
+ * We build a mapping from name_key to function.
+ * This could also be computed directly, but the Limited API
+ * makes this impossible. So we always build our own mapping.
*/
- PyObject *ret;
- PyObject *qualname = PyObject_GetAttrString((PyObject *)ob,
- "__qualname__");
- if (qualname != NULL) {
- ret = PyDict_GetItem(pyside_globals->map_dict, qualname);
- if (ret == NULL) {
- // do a lazy initialization
- PyObject *type_name = qualname_to_typename(qualname);
- PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
- type_name);
- Py_XDECREF(type_name);
- if (type == NULL)
- Py_RETURN_NONE;
- if (build_qualname_to_func(type) < 0)
- return NULL;
- ret = PyDict_GetItem(pyside_globals->map_dict, qualname);
- }
- Py_XINCREF(ret);
- Py_DECREF(qualname);
- }
- else
+ Shiboken::AutoDecRef name_key(compute_name_key(ob));
+ if (name_key.isNull())
Py_RETURN_NONE;
+
+ PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
+ if (ret == NULL) {
+ // do a lazy initialization
+ Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
+ PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
+ type_key);
+ if (type == nullptr)
+ Py_RETURN_NONE;
+ assert(PyType_Check(type));
+ if (build_name_key_to_func(type) < 0)
+ return NULL;
+ ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
+ }
+ Py_XINCREF(ret);
return ret;
}
-#endif
static PyObject *
-pyside_md_get___signature__(PyObject *ob)
-{
- PyObject *func;
- PyObject *result;
-#ifndef Py_LIMITED_API
- PyMethodDescrObject *descr = (PyMethodDescrObject *)ob;
-
-# if PYTHON_USES_D_COMMON
- func = PyCFunction_NewEx(descr->d_method,
- (PyObject *)descr->d_common.d_type, NULL);
-# else
- func = PyCFunction_NewEx(descr->d_method,
- (PyObject *)descr->d_type, NULL);
-# endif
-#else
- /*
- * With limited access, we cannot use the fields of a method descriptor,
- * but in Python 3 we have the __qualname__ field which allows us to
- * grab the method object from our registry.
- */
- func = qualname_to_func(ob);
-#endif
- if (func == Py_None)
+pyside_md_get___signature__(PyObject *ob_md, const char *modifier)
+{
+ init_module_2();
+ Shiboken::AutoDecRef func(name_key_to_func(ob_md));
+ if (func.object() == Py_None)
return Py_None;
- if (func == NULL)
+ if (func.isNull())
Py_FatalError("missing mapping in MethodDescriptor");
- result = pyside_cf_get___signature__(func);
- Py_DECREF(func);
- return result;
+ return pyside_cf_get___signature__(func, modifier);
}
static PyObject *
-pyside_tp_get___signature__(PyObject *typemod)
+pyside_wd_get___signature__(PyObject *ob, const char *modifier)
{
- return GetSignature_TypeMod(typemod);
+ init_module_2();
+ return GetSignature_Wrapper(ob, modifier);
}
static PyObject *
-GetSignature_Function(PyCFunctionObject *func)
+pyside_tp_get___signature__(PyObject *typemod, const char *modifier)
{
- PyObject *typemod, *type_name, *dict, *props, *value, *selftype;
- PyObject *func_name = PyObject_GetAttrString((PyObject *)func, "__name__");
- const char *sig_kind;
- int flags;
+ init_module_2();
+ return GetSignature_TypeMod(typemod, modifier);
+}
- selftype = PyCFunction_GET_SELF((PyObject *)func);
- if (selftype == NULL)
- selftype = PyDict_GetItem(pyside_globals->map_dict, (PyObject *)func);
- if (selftype == NULL) {
- if (!PyErr_Occurred()) {
- PyErr_Format(PyExc_SystemError,
- "the signature for \"%s\" should exist",
- PepCFunction_GET_NAMESTR(func)
- );
- }
- return NULL;
+// forward
+static PyObject *
+GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier);
+
+static PyObject *
+GetClassKey(PyObject *ob)
+{
+ assert(PyType_Check(ob) || PyModule_Check(ob));
+ /*
+ * We obtain a unique key using the module name and the class name.
+ *
+ * The class name is a bit funny when modules are nested.
+ * Example:
+ *
+ * "sample.Photon.ValueIdentity" is a class.
+ * name: "ValueIdentity"
+ * module: "sample.Photon"
+ *
+ * This is the PyCFunction behavior, as opposed to Python functions.
+ */
+ Shiboken::AutoDecRef class_name(PyObject_GetAttrString(ob, "__name__"));
+ Shiboken::AutoDecRef module_name(PyObject_GetAttrString(ob, "__module__"));
+
+ if (module_name.isNull())
+ PyErr_Clear();
+
+ // Note: if we have a module, then __module__ is null, and we get
+ // the module name through __name__ .
+ if (class_name.isNull())
+ return nullptr;
+ if (module_name.object())
+ return Py_BuildValue("(OO)", module_name.object(), class_name.object());
+ return Py_BuildValue("O", class_name.object());
+}
+
+static PyObject *empty_dict = nullptr;
+
+static PyObject *
+TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
+{
+ PyObject *dict = PyDict_GetItem(pyside_globals->arg_dict, type_key);
+ if (dict == nullptr) {
+ if (empty_dict == nullptr)
+ empty_dict = PyDict_New();
+ dict = empty_dict;
}
- if ((PyType_Check(selftype) || PyModule_Check(selftype)))
- typemod = selftype;
- else
- typemod = (PyObject *)Py_TYPE(selftype);
- type_name = PyObject_GetAttrString(typemod, "__name__");
- if (type_name == NULL)
+ if (PyTuple_Check(dict))
+ dict = PySide_BuildSignatureProps(obtype);
+ return dict;
+}
+
+static PyObject *
+GetSignature_Function(PyObject *ob_func, const char *modifier)
+{
+ // make sure that we look into PyCFunction, only...
+ if (Py_TYPE(ob_func) == PepFunction_TypePtr)
Py_RETURN_NONE;
- dict = PyDict_GetItem(pyside_globals->arg_dict, type_name);
- Py_DECREF(type_name);
- if (dict == NULL)
+ Shiboken::AutoDecRef typemod(GetClassOfFunc(ob_func));
+ Shiboken::AutoDecRef type_key(GetClassKey(typemod));
+ if (type_key.isNull())
Py_RETURN_NONE;
- if (PyTuple_Check(dict)) {
- /*
- * We do the initialization lazily.
- * This has also the advantage that we can freely import PySide.
- */
- dict = PySide_BuildSignatureProps(typemod);
- if (dict == NULL)
- Py_RETURN_NONE;
- }
- props = PyDict_GetItem(dict, func_name);
- if (props == NULL)
+ PyObject *dict = TypeKey_to_PropsDict(type_key, typemod);
+ if (dict == nullptr)
+ return nullptr;
+ Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob_func, "__name__"));
+ PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
+ if (props == nullptr)
Py_RETURN_NONE;
- flags = PyCFunction_GET_FLAGS((PyObject *)func);
- if (flags & METH_CLASS)
+
+ int flags = PyCFunction_GET_FLAGS(ob_func);
+ const char *sig_kind;
+ if (PyModule_Check(typemod))
+ sig_kind = "function";
+ else if (flags & METH_CLASS)
sig_kind = "classmethod";
else if (flags & METH_STATIC)
sig_kind = "staticmethod";
else
sig_kind = "method";
- value = PyDict_GetItemString(props, sig_kind);
- if (value == NULL) {
- // we need to compute a signature object
- value = CreateSignature(props, sig_kind);
- if (value != NULL) {
- if (PyDict_SetItemString(props, sig_kind, value) < 0)
- return NULL;
- }
- else
- Py_RETURN_NONE;
- }
- return Py_INCREF(value), value;
+ return GetSignature_Cached(props, sig_kind, modifier);
}
static PyObject *
-GetSignature_TypeMod(PyObject *ob)
+GetSignature_Wrapper(PyObject *ob, const char *modifier)
{
- PyObject *ob_name, *dict, *props, *value;
- const char *sig_kind;
-
- ob_name = PyObject_GetAttrString(ob, "__name__");
- dict = PyDict_GetItem(pyside_globals->arg_dict, ob_name);
- if (dict == NULL)
+ Shiboken::AutoDecRef func_name(PyObject_GetAttrString(ob, "__name__"));
+ Shiboken::AutoDecRef objclass(PyObject_GetAttrString(ob, "__objclass__"));
+ Shiboken::AutoDecRef class_key(GetClassKey(objclass));
+
+ if (func_name.isNull() || objclass.isNull() || class_key.isNull())
+ return nullptr;
+ PyObject *dict = TypeKey_to_PropsDict(class_key, objclass);
+ if (dict == nullptr)
+ return nullptr;
+ PyObject *props = PyDict_GetItem(dict, func_name);
+ if (props == nullptr)
Py_RETURN_NONE;
- if (PyTuple_Check(dict)) {
- dict = PySide_BuildSignatureProps(ob);
- if (dict == NULL) {
- Py_RETURN_NONE;
- }
- }
- props = PyDict_GetItem(dict, ob_name);
- Py_DECREF(ob_name);
- if (props == NULL)
+ return GetSignature_Cached(props, "method", modifier);
+}
+
+static PyObject *
+GetSignature_TypeMod(PyObject *ob, const char *modifier)
+{
+ Shiboken::AutoDecRef ob_name(PyObject_GetAttrString(ob, "__name__"));
+ Shiboken::AutoDecRef ob_key(GetClassKey(ob));
+
+ PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
+ if (dict == nullptr)
+ return nullptr;
+ PyObject *props = PyDict_GetItem(dict, ob_name);
+ if (props == nullptr)
Py_RETURN_NONE;
- sig_kind = "method";
- value = PyDict_GetItemString(props, sig_kind);
- if (value == NULL) {
+ return GetSignature_Cached(props, "method", modifier);
+}
+
+static PyObject *
+GetSignature_Cached(PyObject *props, const char *sig_kind, const char *modifier)
+{
+ Shiboken::AutoDecRef key(modifier == nullptr
+ ? Py_BuildValue("s", sig_kind)
+ : Py_BuildValue("(ss)", sig_kind, modifier));
+ PyObject *value = PyDict_GetItem(props, key);
+ if (value == nullptr) {
// we need to compute a signature object
- value = CreateSignature(props, sig_kind);
- if (value != NULL) {
- if (PyDict_SetItemString(props, sig_kind, value) < 0)
- return NULL;
+ value = CreateSignature(props, key);
+ if (value != nullptr) {
+ if (PyDict_SetItem(props, key, value) < 0)
+ // this is an error
+ return nullptr;
}
- else
+ else {
+ // key not found
Py_RETURN_NONE;
+ }
}
return Py_INCREF(value), value;
}
-
static const char PySide_PythonCode[] =
- "from __future__ import print_function, absolute_import\n"
- "import sys, os, traceback\n"
-
- "pyside_package_dir = os.environ.get('PYSIDE_PACKAGE_DIR', '.')\n"
- "__file__ = os.path.join(pyside_package_dir, 'support', 'signature', 'loader.py')\n"
-
- "def bootstrap():\n"
- " try:\n"
- " with open(__file__) as _f:\n"
- " exec(compile(_f.read(), __file__, 'exec'))\n"
- " except Exception as e:\n"
- " print('Exception:', e)\n"
- " traceback.print_exc(file=sys.stdout)\n"
- " globals().update(locals())\n"
- ;
+ "from __future__ import print_function, absolute_import\n" R"~(if True:
+
+ # This is becoming the 'signature_loader' module.
+
+ import sys, os, traceback
+ # We avoid imports in phase 1 that could fail. "import shiboken" of the
+ # binary would even crash in FinishSignatureInitialization.
+
+ def bootstrap():
+ global __file__
+ try:
+ import shiboken2 as root
+ except ImportError:
+ # uninstalled case without ctest, try only this one which has __init__:
+ from shibokenmodule import shiboken2 as root
+ rp = os.path.realpath(os.path.dirname(root.__file__))
+ # This can be the shiboken2 directory or the binary module, so search.
+ while len(rp) > 3 and not os.path.exists(os.path.join(rp, 'support')):
+ rp = os.path.abspath(os.path.join(rp, '..'))
+ __file__ = os.path.join(rp, 'support', 'signature', 'loader.py')
+ try:
+ with open(__file__) as _f:
+ exec(compile(_f.read(), __file__, 'exec'))
+ except Exception as e:
+ print('Exception:', e)
+ traceback.print_exc(file=sys.stdout)
+ globals().update(locals())
+
+ )~";
static safe_globals_struc *
init_phase_1(void)
{
- safe_globals_struc *p;
PyObject *d, *v;
-
- p = (safe_globals_struc *)malloc(sizeof(safe_globals_struc));
+ safe_globals_struc *p = (safe_globals_struc *)
+ malloc(sizeof(safe_globals_struc));
if (p == NULL)
goto error;
p->helper_module = PyImport_AddModule((char *) helper_module_name);
@@ -373,11 +461,10 @@ init_phase_1(void)
if (p->map_dict == NULL)
goto error;
- // Build a dict for the prepared arguments
+ // build a dict for the prepared arguments
p->arg_dict = PyDict_New();
- if (p->arg_dict == NULL)
- goto error;
- if (PyObject_SetAttrString(p->helper_module, arg_name, p->arg_dict) < 0)
+ if (p->arg_dict == NULL
+ || PyObject_SetAttrString(p->helper_module, arg_name, p->arg_dict) < 0)
goto error;
return p;
@@ -387,16 +474,24 @@ error:
}
static int
-init_phase_2(safe_globals_struc *p)
+init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
{
- PyObject *bootstrap_func;
-
+ PyObject *bootstrap_func, *v = nullptr;
+ PyMethodDef *ml;
+
+ // The single function to be called, but maybe more to come.
+ for (ml = methods; ml->ml_name != NULL; ml++) {
+ v = PyCFunction_NewEx(ml, nullptr, nullptr);
+ if (v == nullptr
+ || PyObject_SetAttrString(p->helper_module, ml->ml_name, v) != 0)
+ goto error;
+ Py_DECREF(v);
+ }
bootstrap_func = PyObject_GetAttrString(p->helper_module, bootstrap_name);
- if (bootstrap_func == NULL)
+ if (bootstrap_func == NULL
+ || PyObject_CallFunction(bootstrap_func, (char *)"()") == NULL)
goto error;
- if (PyObject_CallFunction(bootstrap_func, (char *)"()") == NULL)
- goto error;
- // now the loader is initialized
+ // now the loader should be initialized
p->sigparse_func = PyObject_GetAttrString(p->helper_module, func_name);
if (p->sigparse_func == NULL)
goto error;
@@ -406,6 +501,8 @@ init_phase_2(safe_globals_struc *p)
return 0;
error:
+ Py_XDECREF(v);
+ PyErr_Print();
PyErr_SetString(PyExc_SystemError, "could not initialize part 2");
return -1;
}
@@ -413,20 +510,17 @@ error:
static int
add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp)
{
+ assert(PyType_Check(type));
+ PyType_Ready(type);
PyObject *dict = type->tp_dict;
-
for (; gsp->name != NULL; gsp++) {
- PyObject *descr;
if (PyDict_GetItemString(dict, gsp->name))
continue;
- descr = PyDescr_NewGetSet(type, gsp);
- if (descr == NULL)
+ Shiboken::AutoDecRef descr(PyDescr_NewGetSet(type, gsp));
+ if (descr.isNull())
return -1;
- if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
- Py_DECREF(descr);
+ if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
return -1;
- }
- Py_DECREF(descr);
}
return 0;
}
@@ -463,6 +557,47 @@ static PyGetSetDef new_PyType_getsets[] = {
{0}
};
+static PyGetSetDef new_PyWrapperDescr_getsets[] = {
+ {(char *) "__signature__", (getter)pyside_wd_get___signature__},
+ {0}
+};
+
+////////////////////////////////////////////////////////////////////////////
+//
+// get_signature -- providing a superior interface
+//
+// Additionally to the interface via __signature__, we also provide
+// a general function, which allows for different signature layouts.
+// The "modifier" argument is a string that is passed in from loader.py .
+// Configuration what the modifiers mean is completely in Python.
+//
+
+static PyObject *
+get_signature(PyObject *self, PyObject *args)
+{
+ PyObject *ob;
+ const char *modifier = nullptr;
+
+ init_module_1();
+
+ if (!PyArg_ParseTuple(args, "O|s", &ob, &modifier))
+ return NULL;
+ if (Py_TYPE(ob) == PepFunction_TypePtr)
+ Py_RETURN_NONE;
+
+ if (Py_TYPE(ob) == &PyCFunction_Type)
+ return pyside_cf_get___signature__(ob, modifier);
+ if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
+ return pyside_sm_get___signature__(ob, modifier);
+ if (Py_TYPE(ob) == PepMethodDescr_TypePtr)
+ return pyside_md_get___signature__(ob, modifier);
+ if (PyType_Check(ob))
+ return pyside_tp_get___signature__(ob, modifier);
+ if (Py_TYPE(ob) == &PyWrapperDescr_Type)
+ return pyside_wd_get___signature__(ob, modifier);
+ Py_RETURN_NONE;
+}
+
////////////////////////////////////////////////////////////////////////////
//
// This special Type_Ready does certain initializations earlier with
@@ -495,25 +630,22 @@ void handler(int sig) {
#endif // _WIN32
static int
-PySideType_Ready(PyTypeObject *type)
+PySide_PatchTypes(void)
{
- PyObject *md;
static int init_done = 0;
if (!init_done) {
- // Python2 does not expose certain types. We look them up:
- // PyMethodDescr_Type 'type(str.__dict__["split"])'
- // PyClassMethodDescr_Type. 'type(dict.__dict__["fromkeys"])'
- // The latter is not needed until we use class methods in PySide.
- md = PyObject_GetAttrString((PyObject *)&PyString_Type, "split");
- if (md == NULL
+ Shiboken::AutoDecRef md(PyObject_GetAttrString((PyObject *)&PyString_Type, "split")); // method-descriptor
+ Shiboken::AutoDecRef wd(PyObject_GetAttrString((PyObject *)Py_TYPE(Py_True), "__add__")); // wrapper-descriptor
+ if (md.isNull() || wd.isNull()
|| PyType_Ready(Py_TYPE(md)) < 0
- || add_more_getsets(Py_TYPE(md), new_PyMethodDescr_getsets) < 0
+ || add_more_getsets(PepMethodDescr_TypePtr, new_PyMethodDescr_getsets) < 0
|| add_more_getsets(&PyCFunction_Type, new_PyCFunction_getsets) < 0
|| add_more_getsets(PepStaticMethod_TypePtr, new_PyStaticMethod_getsets) < 0
- || add_more_getsets(&PyType_Type, new_PyType_getsets) < 0)
+ || add_more_getsets(&PyType_Type, new_PyType_getsets) < 0
+ || add_more_getsets(Py_TYPE(wd), new_PyWrapperDescr_getsets) < 0
+ )
return -1;
- Py_DECREF(md);
#ifndef _WIN32
// We enable the stack trace in CI, only.
const char *testEnv = getenv("QTEST_ENVIRONMENT");
@@ -522,58 +654,38 @@ PySideType_Ready(PyTypeObject *type)
#endif // _WIN32
init_done = 1;
}
- return PyType_Ready(type);
+ return 0;
}
-static int
-build_func_to_type(PyObject *obtype)
+static void
+init_module_1(void)
{
- PyTypeObject *type = (PyTypeObject *)obtype;
- PyObject *dict = type->tp_dict;
- PyMethodDef *meth = type->tp_methods;
-
- if (meth == 0)
- return 0;
+ static int init_done = 0;
- for (; meth->ml_name != NULL; meth++) {
- if (meth->ml_flags & METH_STATIC) {
- PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
- if (descr == NULL)
- return -1;
- PyObject *func = PyObject_GetAttrString(descr, "__func__");
- if (func == NULL ||
- PyDict_SetItem(pyside_globals->map_dict, func, obtype) < 0)
- return -1;
- Py_DECREF(func);
- }
+ if (!init_done) {
+ pyside_globals = init_phase_1();
+ if (pyside_globals != nullptr)
+ init_done = 1;
}
- return 0;
}
static int
PySide_BuildSignatureArgs(PyObject *module, PyObject *type,
const char *signatures)
{
- PyObject *type_name, *arg_tup;
- const char *name = NULL;
- static int init_done = 0;
+ PyObject *type_key, *arg_tup;
- if (!init_done) {
- pyside_globals = init_phase_1();
- if (pyside_globals == NULL)
- return -1;
- init_done = 1;
- }
+ init_module_1();
arg_tup = Py_BuildValue("(Os)", type, signatures);
if (arg_tup == NULL)
return -1;
+ /*
+ * We either get a module name or the dict of an EnclosingObject.
+ * We can ignore the EnclosingObject since we get full name info
+ * from the type.
+ */
if (!PyModule_Check(module))
- return 0;
- name = PyModule_GetName(module);
- if (name == NULL)
- return -1;
- if (strncmp(name, "PySide2.Qt", 10) != 0)
- return 0;
+ assert(PyDict_Check(module));
/*
* Normally, we would now just call the Python function with the
* arguments and then continue processing.
@@ -585,51 +697,69 @@ PySide_BuildSignatureArgs(PyObject *module, PyObject *type,
* - by calling the python function late, we can freely import PySide
* without recursion problems.
*/
- type_name = PyObject_GetAttrString(type, "__name__");
- if (type_name == NULL)
+ type_key = GetClassKey(type);
+ if (type_key == nullptr)
return -1;
- if (PyDict_SetItem(pyside_globals->arg_dict, type_name, arg_tup) < 0)
+ if (PyDict_SetItem(pyside_globals->arg_dict, type_key, arg_tup) < 0)
return -1;
/*
- * We record also a mapping from type name to type. This helps to lazily
- * initialize the Py_LIMITED_API in qualname_to_func().
+ * We record also a mapping from type key to type. This helps to lazily
+ * initialize the Py_LIMITED_API in name_key_to_func().
*/
- if (PyDict_SetItem(pyside_globals->map_dict, type_name, type) < 0)
+
+ if (PyDict_SetItem(pyside_globals->map_dict, type_key, type) < 0)
return -1;
return 0;
}
-static PyObject *
-PySide_BuildSignatureProps(PyObject *classmod)
+static PyMethodDef signature_methods[] = {
+ {"get_signature", (PyCFunction)get_signature, METH_VARARGS,
+ "get the __signature__, but pass an optional string parameter"},
+ {NULL, NULL}
+};
+
+static void
+init_module_2(void)
{
- PyObject *arg_tup, *dict, *type_name;
static int init_done = 0;
if (!init_done) {
- if (init_phase_2(pyside_globals) < 0)
- return NULL;
+ // Phase 2 will call __init__.py which touches a signature, itself.
+ // Therefore we set init_done prior to init_phase_2().
init_done = 1;
+ init_phase_2(pyside_globals, signature_methods);
}
+}
+
+static PyObject *
+PySide_BuildSignatureProps(PyObject *classmod)
+{
/*
* Here is the second part of the function.
* This part will be called on-demand when needed by some attribute.
* We simply pick up the arguments that we stored here and replace
* them by the function result.
*/
- type_name = PyObject_GetAttrString(classmod, "__name__");
- if (type_name == NULL)
- return NULL;
- arg_tup = PyDict_GetItem(pyside_globals->arg_dict, type_name);
- if (arg_tup == NULL)
- return NULL;
- dict = PyObject_CallObject(pyside_globals->sigparse_func, arg_tup);
- if (dict == NULL)
- return NULL;
+ init_module_2();
+ Shiboken::AutoDecRef type_key(GetClassKey(classmod));
+ if (type_key.isNull())
+ return nullptr;
+ PyObject *arg_tup = PyDict_GetItem(pyside_globals->arg_dict, type_key);
+ if (arg_tup == nullptr)
+ return nullptr;
+ PyObject *dict = PyObject_CallObject(pyside_globals->sigparse_func, arg_tup);
+ if (dict == nullptr) {
+ if (PyErr_Occurred())
+ return nullptr;
+ // No error: return an empty dict.
+ if (empty_dict == nullptr)
+ empty_dict = PyDict_New();
+ return empty_dict;
+ }
// We replace the arguments by the result dict.
- if (PyDict_SetItem(pyside_globals->arg_dict, type_name, dict) < 0)
- return NULL;
- Py_DECREF(type_name);
+ if (PyDict_SetItem(pyside_globals->arg_dict, type_key, dict) < 0)
+ return nullptr;
return dict;
}
@@ -638,7 +768,7 @@ SbkSpecial_Type_Ready(PyObject *module, PyTypeObject *type,
const char *signatures)
{
int ret;
- if (PySideType_Ready(type) < 0)
+ if (PyType_Ready(type) < 0)
return -1;
ret = PySide_BuildSignatureArgs(module, (PyObject *)type, signatures);
if (ret < 0) {
@@ -648,27 +778,25 @@ SbkSpecial_Type_Ready(PyObject *module, PyTypeObject *type,
return ret;
}
+static int _finish_nested_classes(PyObject *dict);
+static int _build_func_to_type(PyObject *obtype);
+
static int
PySide_FinishSignatures(PyObject *module, const char *signatures)
{
- const char *name = NULL;
+ /*
+ * Initialization of module functions and resolving of static methods.
+ */
- // CRUCIAL: Do not call this on "testbinding":
- // The module is different and should not get signatures, anyway.
- name = PyModule_GetName(module);
+ const char *name = PyModule_GetName(module);
if (name == NULL)
return -1;
- if (strncmp(name, "PySide2.Qt", 10) != 0)
- return 0;
// we abuse the call for types, since they both have a __name__ attribute.
if (PySide_BuildSignatureArgs(module, module, signatures) < 0)
return -1;
/*
- * Python2 does not abuse the 'm_self' field for the type. So we need to
- * supply this for all static methods.
- *
* Note: This function crashed when called from PySide_BuildSignatureArgs.
* Probably this was too early.
*
@@ -676,20 +804,111 @@ PySide_FinishSignatures(PyObject *module, const char *signatures)
* to the PyCFunction attributes. Therefore I simplified things
* and always use our own mapping.
*/
- {
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- PyObject *dict = PyModule_GetDict(module);
+ PyObject *key, *func, *obdict = PyModule_GetDict(module);
+ Py_ssize_t pos = 0;
+
+ while (PyDict_Next(obdict, &pos, &key, &func))
+ if (PyCFunction_Check(func))
+ if (PyDict_SetItem(pyside_globals->map_dict, func, module) < 0)
+ return -1;
+ if (_finish_nested_classes(obdict) < 0)
+ return -1;
+ return 0;
+}
+
+static int
+_finish_nested_classes(PyObject *obdict)
+{
+ PyObject *key, *value, *obtype;
+ PyTypeObject *subtype;
+ Py_ssize_t pos = 0;
+
+ if (obdict == NULL)
+ return -1;
+ while (PyDict_Next(obdict, &pos, &key, &value)) {
+ if (PyType_Check(value)) {
+ obtype = value;
+ if (_build_func_to_type(obtype) < 0)
+ return -1;
+ // now continue with nested cases
+ subtype = reinterpret_cast<PyTypeObject *>(obtype);
+ if (_finish_nested_classes(subtype->tp_dict) < 0)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+_build_func_to_type(PyObject *obtype)
+{
+ /*
+ * There is no general way to directly get the type of a static method.
+ * On Python 3, the type is hidden in an unused pointer in the
+ * PyCFunction structure, but the Limited API does not allow to access
+ * this, either.
+ *
+ * In the end, it was easier to avoid such tricks and build an explicit
+ * mapping from function to type.
+ *
+ * We walk through the method list of the type
+ * and record the mapping from static method to this type in a dict.
+ * We also check for hidden methods, see below.
+ */
+ PyTypeObject *type = reinterpret_cast<PyTypeObject *>(obtype);
+ PyObject *dict = type->tp_dict;
+ PyMethodDef *meth = type->tp_methods;
- if (dict == NULL)
+ if (meth == 0)
+ return 0;
+
+ for (; meth->ml_name != NULL; meth++) {
+ /*
+ * It is possible that a method is overwritten by another
+ * attribute with the same name. This case was obviously provoked
+ * explicitly in "testbinding.TestObject.staticMethodDouble",
+ * where instead of the method a "PySide2.QtCore.Signal" object
+ * was in the dict.
+ * This overlap is also found in regular PySide under
+ * "PySide2.QtCore.QProcess.error" where again a signal object is
+ * returned. These hidden methods will be opened for the
+ * signature module by adding them under the name
+ * "{name}.overload".
+ */
+ PyObject *descr = PyDict_GetItemString(dict, meth->ml_name);
+ const char *look_attr = meth->ml_flags & METH_STATIC ? "__func__" : "__name__";
+ int check_name = meth->ml_flags & METH_STATIC ? 0 : 1;
+ if (descr == NULL)
return -1;
- while (PyDict_Next(dict, &pos, &key, &value)) {
- if (PyType_Check(value)) {
- PyObject *type = value;
- if (build_func_to_type(type) < 0)
- return -1;
- }
+ // We first check all methods if one is hidden by something else.
+ Shiboken::AutoDecRef look(PyObject_GetAttrString(descr, look_attr));
+ Shiboken::AutoDecRef given(Py_BuildValue("s", meth->ml_name));
+ if (look.isNull()
+ || (check_name && PyObject_RichCompareBool(look, given, Py_EQ) != 1)) {
+ PyErr_Clear();
+ Shiboken::AutoDecRef cfunc(PyCFunction_NewEx(meth, (PyObject*)type, NULL));
+ if (cfunc.isNull())
+ return -1;
+ if (meth->ml_flags & METH_STATIC)
+ descr = PyStaticMethod_New(cfunc);
+ else
+ descr = PyDescr_NewMethod(type, meth);
+ if (descr == nullptr)
+ return -1;
+ char mangled_name[200];
+ strcpy(mangled_name, meth->ml_name);
+ strcat(mangled_name, ".overload");
+ if (PyDict_SetItemString(dict, mangled_name, descr) < 0)
+ return -1;
+ if (PyDict_SetItemString(pyside_globals->map_dict, mangled_name, obtype) < 0)
+ return -1;
+ continue;
+ }
+ // Then we insert the mapping for static methods.
+ if (meth->ml_flags & METH_STATIC) {
+ if (PyDict_SetItem(pyside_globals->map_dict, look, obtype) < 0)
+ return -1;
}
}
return 0;
@@ -698,6 +917,15 @@ PySide_FinishSignatures(PyObject *module, const char *signatures)
void
FinishSignatureInitialization(PyObject *module, const char *signatures)
{
+ /*
+ * This function is called at the very end of a module initialization.
+ * We now patch certain types to support the __signature__ attribute,
+ * initialize module functions and resolve static methods.
+ *
+ * Still, it is not possible to call init phase 2 from here,
+ * because the import is still running. Do it from Python!
+ */
+ PySide_PatchTypes();
if (PySide_FinishSignatures(module, signatures) < 0) {
PyErr_Print();
PyErr_SetNone(PyExc_ImportError);
diff --git a/sources/shiboken2/libshiboken/signature.h b/sources/shiboken2/libshiboken/signature.h
index 3a229cb5c..b65317662 100644
--- a/sources/shiboken2/libshiboken/signature.h
+++ b/sources/shiboken2/libshiboken/signature.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt for Python.
@@ -45,8 +45,8 @@
extern "C"
{
-LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char*);
-LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char*);
+LIBSHIBOKEN_API int SbkSpecial_Type_Ready(PyObject *, PyTypeObject *, const char *); //WS
+LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *);
} // extern "C"
diff --git a/sources/shiboken2/libshiboken/threadstatesaver.h b/sources/shiboken2/libshiboken/threadstatesaver.h
index e9f97f300..ddad9b67f 100644
--- a/sources/shiboken2/libshiboken/threadstatesaver.h
+++ b/sources/shiboken2/libshiboken/threadstatesaver.h
@@ -49,15 +49,17 @@ namespace Shiboken
class LIBSHIBOKEN_API ThreadStateSaver
{
public:
+ ThreadStateSaver(const ThreadStateSaver&) = delete;
+ ThreadStateSaver(ThreadStateSaver&&) = delete;
+ ThreadStateSaver &operator=(const ThreadStateSaver&) = delete;
+ ThreadStateSaver &operator=(ThreadStateSaver&&) = delete;
+
ThreadStateSaver();
~ThreadStateSaver();
void save();
void restore();
private:
PyThreadState* m_threadState;
-
- ThreadStateSaver(const ThreadStateSaver&);
- ThreadStateSaver& operator=(const ThreadStateSaver&);
};
} // namespace Shiboken
diff --git a/sources/shiboken2/libshiboken/typespec.cpp b/sources/shiboken2/libshiboken/typespec.cpp
index d532c97ed..a67daf12d 100644
--- a/sources/shiboken2/libshiboken/typespec.cpp
+++ b/sources/shiboken2/libshiboken/typespec.cpp
@@ -37,6 +37,7 @@
**
****************************************************************************/
+#include "sbkpython.h"
#include "typespec.h"
#include <structmember.h>
@@ -514,7 +515,7 @@ best_base(PyObject *bases)
}
static const short slotoffsets[] = {
- -1, /* invalid slot_ */
+ -1, /* invalid slot */
/* Generated by typeslots.py */
0,
0,
@@ -603,7 +604,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
PyObject *modname;
char *s;
char *res_start = (char*)res;
- PyType_Slot *slot_;
+ PyType_Slot *slot;
/* Set the type name and qualname */
s = (char *)strrchr(spec->name, '.'); // C++11
@@ -632,11 +633,11 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
if (!bases) {
base = &PyBaseObject_Type;
/* See whether Py_tp_base(s) was specified */
- for (slot_ = spec->slots; slot_->slot_; slot_++) {
- if (slot_->slot_ == Py_tp_base)
- base = (PyTypeObject *)slot_->pfunc; // C++11
- else if (slot_->slot_ == Py_tp_bases) {
- bases = (PyObject *)slot_->pfunc; // C++11
+ for (slot = spec->slots; slot->slot; slot++) {
+ if (slot->slot == Py_tp_base)
+ base = (PyTypeObject *)slot->pfunc; // C++11
+ else if (slot->slot == Py_tp_bases) {
+ bases = (PyObject *)slot->pfunc; // C++11
Py_INCREF(bases);
}
}
@@ -676,23 +677,23 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
type->tp_basicsize = spec->basicsize;
type->tp_itemsize = spec->itemsize;
- for (slot_ = spec->slots; slot_->slot_; slot_++) {
- if (slot_->slot_ < 0
- || (size_t)slot_->slot_ >= Py_ARRAY_LENGTH(slotoffsets)) {
- PyErr_SetString(PyExc_RuntimeError, "invalid slot_ offset");
+ for (slot = spec->slots; slot->slot; slot++) {
+ if (slot->slot < 0
+ || (size_t)slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) {
+ PyErr_SetString(PyExc_RuntimeError, "invalid slot offset");
goto fail;
}
- if (slot_->slot_ == Py_tp_base || slot_->slot_ == Py_tp_bases)
+ if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases)
/* Processed above */
continue;
- *(void**)(res_start + slotoffsets[slot_->slot_]) = slot_->pfunc;
+ *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc;
- /* need to make a copy of the docstring slot_, which usually
+ /* need to make a copy of the docstring slot, which usually
points to a static string literal */
- if (slot_->slot_ == Py_tp_doc) {
+ if (slot->slot == Py_tp_doc) {
// No signature in Python 2
- // const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot_->pfunc);
- const char *old_doc = (const char *)slot_->pfunc;
+ // const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc);
+ const char *old_doc = (const char *)slot->pfunc;
size_t len = strlen(old_doc)+1;
char *tp_doc = (char *)PyObject_MALLOC(len); // C++11
if (tp_doc == NULL) {
@@ -759,17 +760,17 @@ PyType_FromSpec(PyType_Spec *spec)
}
void *
-PyType_GetSlot(PyTypeObject *type, int slot_)
+PyType_GetSlot(PyTypeObject *type, int slot)
{
- if (!PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot_ < 0) {
+ if (!PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE) || slot < 0) {
PyErr_BadInternalCall();
return NULL;
}
- if ((size_t)slot_ >= Py_ARRAY_LENGTH(slotoffsets)) {
- /* Extension module requesting slot_ from a future version */
+ if ((size_t)slot >= Py_ARRAY_LENGTH(slotoffsets)) {
+ /* Extension module requesting slot from a future version */
return NULL;
}
- return *(void**)(((char*)type) + slotoffsets[slot_]);
+ return *(void**)(((char*)type) + slotoffsets[slot]);
}
} // extern "C"
diff --git a/sources/shiboken2/libshiboken/typespec.h b/sources/shiboken2/libshiboken/typespec.h
index 799fcb1b8..81227acac 100644
--- a/sources/shiboken2/libshiboken/typespec.h
+++ b/sources/shiboken2/libshiboken/typespec.h
@@ -40,7 +40,7 @@
#ifndef TYPESPEC_H
#define TYPESPEC_H
-#include <Python.h>
+#include "sbkpython.h"
#include "shibokenmacros.h"
#if PY_MAJOR_VERSION < 3
@@ -48,7 +48,7 @@ extern "C"
{
typedef struct{
- int slot_; // slot is somehow reserved in Qt /* slot id, see below */
+ int slot; // slot is somehow reserved in Qt /* slot id, see below */
void *pfunc; /* function pointer */
} PyType_Slot;
diff --git a/sources/shiboken2/libshiboken/voidptr.cpp b/sources/shiboken2/libshiboken/voidptr.cpp
index 0d7b6b9cd..a306f7a9d 100644
--- a/sources/shiboken2/libshiboken/voidptr.cpp
+++ b/sources/shiboken2/libshiboken/voidptr.cpp
@@ -193,7 +193,11 @@ PyObject *SbkVoidPtrObject_repr(PyObject *v)
SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(v);
+ #ifdef IS_PY3K
+ PyObject *s = PyUnicode_FromFormat("%s(%p, %zd, %s)",
+ #else
PyObject *s = PyBytes_FromFormat("%s(%p, %zd, %s)",
+ #endif
Py_TYPE(sbkObject)->tp_name,
sbkObject->cptr,
sbkObject->size,
@@ -205,7 +209,11 @@ PyObject *SbkVoidPtrObject_repr(PyObject *v)
PyObject *SbkVoidPtrObject_str(PyObject *v)
{
SbkVoidPtrObject *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(v);
+ #ifdef IS_PY3K
+ PyObject *s = PyUnicode_FromFormat("%s(Address %p, Size %zd, isWritable %s)",
+ #else
PyObject *s = PyBytes_FromFormat("%s(Address %p, Size %zd, isWritable %s)",
+ #endif
Py_TYPE(sbkObject)->tp_name,
sbkObject->cptr,
sbkObject->size,
diff --git a/sources/shiboken2/shiboken_tool.py b/sources/shiboken2/shiboken_tool.py
new file mode 100755
index 000000000..8494c5d57
--- /dev/null
+++ b/sources/shiboken2/shiboken_tool.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#############################################################################
+##
+## Copyright (C) 2018 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$
+##
+#############################################################################
+import sys
+import os
+import subprocess
+
+def main():
+ # The tools listed as entrypoints in setup.py are copied to 'scripts/..'
+ cmd = os.path.join("..", os.path.basename(sys.argv[0]))
+ command = [os.path.join(os.path.dirname(os.path.realpath(__file__)), cmd)]
+ command.extend(sys.argv[1:])
+ sys.exit(subprocess.call(command))
+
+if __name__ == "__main__":
+ main()
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index 709dd8714..8df1c2992 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -38,8 +38,10 @@
#############################################################################
major_version = "5"
-minor_version = "11"
-patch_version = "4"
+minor_version = "12"
+patch_version = "0"
+pre_release_version_type = "a" # e.g. "a", "b", "rc".
+pre_release_version = "1" # e.g "1", "2", (which means "beta1", "beta2", if type is "b")
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index f2d7b30f2..0eba3eaff 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -12,7 +12,9 @@ set(shibokenmodule_TYPESYSTEM
${CMAKE_CURRENT_SOURCE_DIR}/typesystem_shiboken.xml
)
-add_custom_command(OUTPUT ${sample_SRC}
+add_custom_command(
+OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+BYPRODUCTS ${sample_SRC}
# Note: shiboken2 is an executable target. By not specifying its explicit
# path, CMAKE figures it out, itself!
# This fixes an issue with Visual Studio, see https://github.com/PySide/shiboken2/pull/11
@@ -39,5 +41,53 @@ target_link_libraries(shibokenmodule
libshiboken)
add_dependencies(shibokenmodule shiboken2)
+create_generator_target(shibokenmodule)
-install(TARGETS shibokenmodule DESTINATION ${PYTHON_SITE_PACKAGES})
+install(TARGETS shibokenmodule DESTINATION ${PYTHON_SITE_PACKAGES}/shiboken2)
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY)
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken2")
+
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY)
+
+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/layout.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/layout.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/loader.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/loader.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/mapping.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/mapping.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/parser.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/parser.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/lib/__init__.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/lib/__init__.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/lib/enum_sig.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/lib/enum_sig.py" COPYONLY)
+if (PYTHON_VERSION_MAJOR EQUAL 3)
+else()
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/backport_inspect.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/backport_inspect.py" COPYONLY)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/signature/typing27.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/support/signature/typing27.py" COPYONLY)
+endif()
+install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/support"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken2")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/__init__.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken2")
+
+# Use absolute path instead of relative path, to avoid ninja build errors due to
+# duplicate file dependency inconsistency.
+set(shiboken_version_relative_path "${CMAKE_CURRENT_SOURCE_DIR}/../shiboken_version.py")
+get_filename_component(shiboken_version_path ${shiboken_version_relative_path} ABSOLUTE)
+configure_file("${shiboken_version_path}"
+ "${CMAKE_CURRENT_BINARY_DIR}/_git_shiboken_module_version.py" @ONLY)
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_git_shiboken_module_version.py"
+ DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken2")
diff --git a/sources/shiboken2/shibokenmodule/__init__.py.in b/sources/shiboken2/shibokenmodule/__init__.py.in
new file mode 100644
index 000000000..81ab0063a
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/__init__.py.in
@@ -0,0 +1,4 @@
+__version__ = "@FINAL_PACKAGE_VERSION@"
+__version_info__ = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MICRO_VERSION@, "@shiboken_PRE_RELEASE_VERSION_TYPE@", "@shiboken_PRE_RELEASE_VERSION@")
+
+from .shiboken2 import *
diff --git a/sources/shiboken2/shibokenmodule/_config.py.in b/sources/shiboken2/shibokenmodule/_config.py.in
new file mode 100644
index 000000000..9607e5ca7
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/_config.py.in
@@ -0,0 +1,11 @@
+shiboken_library_soversion = str(@shiboken2_library_so_version@)
+
+version = "@FINAL_PACKAGE_VERSION@"
+version_info = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MICRO_VERSION@, "@shiboken_PRE_RELEASE_VERSION_TYPE@", "@shiboken_PRE_RELEASE_VERSION@")
+
+@PACKAGE_BUILD_DATE@
+@PACKAGE_BUILD_COMMIT_DATE@
+@PACKAGE_BUILD_COMMIT_HASH@
+@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@
+@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
+@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@
diff --git a/sources/shiboken2/shibokenmodule/support/__init__.py b/sources/shiboken2/shibokenmodule/support/__init__.py
new file mode 100644
index 000000000..760d89571
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/__init__.py
@@ -0,0 +1,40 @@
+#############################################################################
+##
+## Copyright (C) 2017 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$
+##
+#############################################################################
+
+# this file intentionally left blank
diff --git a/sources/pyside2/PySide2/support/signature/PSF-3.7.0.txt b/sources/shiboken2/shibokenmodule/support/signature/PSF-3.7.0.txt
index be42010dd..be42010dd 100644
--- a/sources/pyside2/PySide2/support/signature/PSF-3.7.0.txt
+++ b/sources/shiboken2/shibokenmodule/support/signature/PSF-3.7.0.txt
diff --git a/sources/shiboken2/shibokenmodule/support/signature/__init__.py b/sources/shiboken2/shibokenmodule/support/signature/__init__.py
new file mode 100644
index 000000000..d0791df04
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/__init__.py
@@ -0,0 +1,47 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+# Trigger initialization phase 2.
+_ = type.__signature__
+
+## from signature_loader import get_signature, inspect, typing
+# This causes a recursion in Python 2!
+# We do everything from signature_loader, instead.
diff --git a/sources/pyside2/PySide2/support/signature/backport_inspect.py b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py
index 0eafe9caa..6b97470e2 100644
--- a/sources/pyside2/PySide2/support/signature/backport_inspect.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py
@@ -113,8 +113,8 @@ CO_NOFREE = 0x0040
# We use '__builtin__' and '__name__' instead.
# It is further changed because we use a local copy of typing
def formatannotation(annotation, base_module=None):
- if getattr(annotation, '__module__', None) == 'PySide2.support.signature.typing':
- return repr(annotation).replace('PySide2.support.signature.typing.', '')
+ if getattr(annotation, '__module__', None) == 'support.signature.typing':
+ return repr(annotation).replace('support.signature.typing', 'typing')
if isinstance(annotation, type):
if annotation.__module__ in ('__builtin__', base_module):
return annotation.__name__
diff --git a/sources/pyside2/PySide2/support/signature/fix-complaints.py b/sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py
index fa2b44420..e078ef1ab 100644
--- a/sources/pyside2/PySide2/support/signature/fix-complaints.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/fix-complaints.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
diff --git a/sources/shiboken2/shibokenmodule/support/signature/layout.py b/sources/shiboken2/shibokenmodule/support/signature/layout.py
new file mode 100644
index 000000000..cd3a5dc8f
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/layout.py
@@ -0,0 +1,246 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+"""
+layout.py
+
+The signature module now has the capability to configure
+differently formatted versions of signatures. The default
+layout is known from the "__signature__" attribute.
+
+The function "get_signature(ob, modifier=None)" produces the same
+signatures by default. By passing different modifiers, you
+can select different layouts.
+
+This module configures the different layouts which can be used.
+It also implements them in this file. The configurations are
+used literally as strings like "signature", "existence", etc.
+"""
+
+from textwrap import dedent
+from signature_loader import inspect
+from signature_loader.mapping import ellipsis
+
+
+class SimpleNamespace(object):
+ # From types.rst, because the builtin is implemented in Python 3, only.
+ def __init__(self, **kwargs):
+ self.__dict__.update(kwargs)
+
+ def __repr__(self):
+ keys = sorted(self.__dict__)
+ items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
+ return "{}({})".format(type(self).__name__, ", ".join(items))
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+
+class SignatureLayout(SimpleNamespace):
+ """
+ Configure a signature.
+
+ The layout of signatures can have different layouts which are
+ controlled by keyword arguments:
+
+ definition=True Determines if self will generated.
+ defaults=True
+ ellipsis=False Replaces defaults by "...".
+ return_annotation=True
+ parameter_names=True False removes names before ":".
+ """
+ allowed_keys = SimpleNamespace(definition=True,
+ defaults=True,
+ ellipsis=False,
+ return_annotation=True,
+ parameter_names=True)
+ allowed_values = True, False
+
+ def __init__(self, **kwds):
+ args = SimpleNamespace(**self.allowed_keys.__dict__)
+ args.__dict__.update(kwds)
+ self.__dict__.update(args.__dict__)
+ err_keys = list(set(self.__dict__) - set(self.allowed_keys.__dict__))
+ if err_keys:
+ self._attributeerror(err_keys)
+ err_values = list(set(self.__dict__.values()) - set(self.allowed_values))
+ if err_values:
+ self._valueerror(err_values)
+
+ def __setattr__(self, key, value):
+ if key not in self.allowed_keys.__dict__:
+ self._attributeerror([key])
+ if value not in self.allowed_values:
+ self._valueerror([value])
+ self.__dict__[key] = value
+
+ def _attributeerror(self, err_keys):
+ err_keys = ", ".join(err_keys)
+ allowed_keys = ", ".join(self.allowed_keys.__dict__.keys())
+ raise AttributeError(dedent("""\
+ Not allowed: '{err_keys}'.
+ The only allowed keywords are '{allowed_keys}'.
+ """.format(**locals())))
+
+ def _valueerror(self, err_values):
+ err_values = ", ".join(map(str, err_values))
+ allowed_values = ", ".join(map(str, self.allowed_values))
+ raise ValueError(dedent("""\
+ Not allowed: '{err_values}'.
+ The only allowed values are '{allowed_values}'.
+ """.format(**locals())))
+
+# The following names are used literally in this module.
+# This way, we avoid the dict hashing problem.
+signature = SignatureLayout()
+
+existence = SignatureLayout(definition=False,
+ defaults=False,
+ return_annotation=False,
+ parameter_names=False)
+
+hintingstub = SignatureLayout(ellipsis=True)
+
+typeerror = SignatureLayout(definition=False,
+ return_annotation=False,
+ parameter_names=False)
+
+
+def define_nameless_parameter():
+ """
+ Create Nameless Parameters
+
+ A nameless parameter has a reduced string representation.
+ This is done by cloning the parameter type and overwriting its
+ __str__ method. The inner structure is still a valid parameter.
+ """
+ def __str__(self):
+ # for Python 2, we must change self to be an instance of P
+ klass = self.__class__
+ self.__class__ = P
+ txt = P.__str__(self)
+ self.__class__ = klass
+ txt = txt[txt.index(":") + 1:].strip() if ":" in txt else txt
+ return txt
+
+ P = inspect.Parameter
+ newname = "NamelessParameter"
+ bases = P.__bases__
+ body = dict(P.__dict__) # get rid of mappingproxy
+ if "__slots__" in body:
+ # __slots__ would create duplicates
+ for name in body["__slots__"]:
+ del body[name]
+ body["__str__"] = __str__
+ return type(newname, bases, body)
+
+
+NamelessParameter = define_nameless_parameter()
+
+
+def make_signature_nameless(signature):
+ """
+ Make a Signature Nameless
+
+ We use an existing signature and change the type of its parameters.
+ The signature looks different, but is totally intact.
+ """
+ for key in signature.parameters.keys():
+ signature.parameters[key].__class__ = NamelessParameter
+
+
+def create_signature(props, key):
+ if not props:
+ # empty signatures string
+ return
+ if isinstance(props["multi"], list):
+ # multi sig: call recursively
+ return list(create_signature(elem, key)
+ for elem in props["multi"])
+ if type(key) is tuple:
+ sig_kind, modifier = key
+ else:
+ sig_kind, modifier = key, "signature"
+
+ layout = globals()[modifier] # lookup of the modifier in this module
+ if not isinstance(layout, SignatureLayout):
+ raise SystemError("Modifiers must be names of a SignatureLayout "
+ "instance")
+
+ # this is the basic layout of a signature
+ varnames = props["varnames"]
+ if layout.definition:
+ if sig_kind == "function":
+ pass
+ elif sig_kind == "method":
+ varnames = ("self",) + varnames
+ elif sig_kind == "staticmethod":
+ pass
+ elif sig_kind == "classmethod":
+ varnames = ("klass",) + varnames
+ else:
+ raise SystemError("Methods must be function, method, staticmethod or "
+ "classmethod")
+ # calculate the modifications
+ defaults = props["defaults"][:]
+ if not layout.defaults:
+ defaults = ()
+ if layout.ellipsis:
+ defaults = (ellipsis,) * len(defaults)
+ annotations = props["annotations"].copy()
+ if not layout.return_annotation and "return" in annotations:
+ del annotations["return"]
+
+ # attach parameters to a fake function and build a signature
+ argstr = ", ".join(varnames)
+ fakefunc = eval("lambda {}: None".format(argstr))
+ fakefunc.__name__ = props["name"]
+ fakefunc.__defaults__ = defaults
+ fakefunc.__kwdefaults__ = props["kwdefaults"]
+ fakefunc.__annotations__ = annotations
+ sig = inspect._signature_from_function(inspect.Signature, fakefunc)
+
+ # the special case of nameless parameters
+ if not layout.parameter_names:
+ make_signature_nameless(sig)
+ return sig
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/support/signature/lib/__init__.py b/sources/shiboken2/shibokenmodule/support/signature/lib/__init__.py
new file mode 100644
index 000000000..2d640cb89
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/lib/__init__.py
@@ -0,0 +1,40 @@
+#############################################################################
+##
+## Copyright (C) 2018 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$
+##
+#############################################################################
+
+# this file intentionally left blank
diff --git a/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py
new file mode 100644
index 000000000..013ec36cc
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/lib/enum_sig.py
@@ -0,0 +1,168 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+"""
+enum_sig.py
+
+Enumerate all signatures of a class.
+
+This module separates the enumeration process from the formatting.
+It is not easy to adhere to this protocol, but in the end, it paid off
+by producing a lot of clarity.
+"""
+
+import sys
+from signature_loader import get_signature, inspect
+
+
+class ExactEnumerator(object):
+ """
+ ExactEnumerator enumerates all signatures in a module as they are.
+
+ This class is used for generating complete listings of all signatures.
+ An appropriate formatter should be supplied, if printable output
+ is desired.
+ """
+
+ def __init__(self, formatter, result_type=dict):
+ self.fmt = formatter
+ self.result_type = result_type
+
+ def module(self, mod_name):
+ __import__(mod_name)
+ with self.fmt.module(mod_name):
+ module = sys.modules[mod_name]
+ members = inspect.getmembers(module, inspect.isclass)
+ functions = inspect.getmembers(module, inspect.isroutine)
+ ret = self.result_type()
+ self.fmt.class_name = None
+ for func_name, func in functions:
+ ret.update(self.function(func_name, func))
+ for class_name, klass in members:
+ ret.update(self.klass(class_name, klass))
+ return ret
+
+ def klass(self, class_name, klass):
+ if not "Shiboken" in repr(klass.mro()):
+ # don't look into any foreign classes!
+ ret = self.result_type()
+ return ret
+ bases_list = []
+ for base in klass.__bases__:
+ name = base.__name__
+ if name == "object":
+ pass
+ else:
+ modname = base.__module__
+ name = modname + "." + base.__name__
+ bases_list.append(name)
+ class_str = "{}({})".format(class_name, ", ".join(bases_list))
+ with self.fmt.klass(class_name, class_str):
+ ret = self.function("__init__", klass)
+ # class_members = inspect.getmembers(klass)
+ # gives us also the inherited things.
+ class_members = sorted(list(klass.__dict__.items()))
+ subclasses = []
+ for thing_name, thing in class_members:
+ if inspect.isclass(thing):
+ subclass_name = ".".join((class_name, thing_name))
+ subclasses.append((subclass_name, thing))
+ else:
+ func_name = thing_name.split(".")[0] # remove ".overload"
+ ret.update(self.function(func_name, thing))
+ for subclass_name, subclass in subclasses:
+ ret.update(self.klass(subclass_name, subclass))
+ return ret
+
+ def function(self, func_name, func):
+ ret = self.result_type()
+ signature = getattr(func, '__signature__', None)
+ if signature is not None:
+ with self.fmt.function(func_name, signature) as key:
+ ret[key] = signature
+ return ret
+
+
+def stringify(signature):
+ if isinstance(signature, list):
+ # remove duplicates which still sometimes occour:
+ ret = set(stringify(sig) for sig in signature)
+ return sorted(ret) if len(ret) > 1 else list(ret)[0]
+ return tuple(str(pv) for pv in signature.parameters.values())
+
+
+class SimplifyingEnumerator(ExactEnumerator):
+ """
+ SimplifyingEnumerator enumerates all signatures in a module filtered.
+
+ There are no default values, no variable
+ names and no self parameter. Only types are present after simplification.
+ The functions 'next' resp. '__next__' are removed
+ to make the output identical for Python 2 and 3.
+ An appropriate formatter should be supplied, if printable output
+ is desired.
+ """
+
+ def function(self, func_name, func):
+ ret = self.result_type()
+ signature = get_signature(func, 'existence')
+ sig = stringify(signature) if signature is not None else None
+ if sig is not None and func_name not in ("next", "__next__", "__div__"):
+ with self.fmt.function(func_name, sig) as key:
+ ret[key] = sig
+ return ret
+
+class HintingEnumerator(ExactEnumerator):
+ """
+ HintingEnumerator enumerates all signatures in a module slightly changed.
+
+ This class is used for generating complete listings of all signatures for
+ hinting stubs. Only default values are replaced by "...".
+ """
+
+ def function(self, func_name, func):
+ ret = self.result_type()
+ signature = get_signature(func, 'hintingstub')
+ if signature is not None:
+ with self.fmt.function(func_name, signature) as key:
+ ret[key] = signature
+ return ret
+
diff --git a/sources/shiboken2/shibokenmodule/support/signature/loader.py b/sources/shiboken2/shibokenmodule/support/signature/loader.py
new file mode 100644
index 000000000..de27d441c
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/loader.py
@@ -0,0 +1,202 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+"""
+loader.py
+
+The loader has to lazy-load the signature module and also provides a few
+Python modules to support Python 2.7 .
+
+This file was originally directly embedded into the C source.
+After it grew more and more, I now prefer to have it as Python file.
+The remaining stub loader in the C source is now only a short string.
+
+This version does no longer use an embedded .zip file but is a package.
+The old code without a package but with zip compression can still be found
+at https://codereview.qt-project.org/#/c/203533/ for reference.
+"""
+
+import sys
+import os
+import traceback
+import types
+from contextlib import contextmanager
+
+"""
+A note on the import problem (solved):
+
+During the tests, the shiboken build structure has the layout
+
+ shiboken2/shibokenmodule/shiboken2.abi3.so
+
+and the name "shiboken2" in sys.modules points directly to the binary
+file, hiding the outer shiboken2 module.
+
+To fix that, we temporarily remove the binary from sys.path,
+do the needed imports and then restore the binary.
+This action was put into a context manager for readability.
+"""
+
+# On Python 2, we only have ImportError, which is way too coarse.
+# When problems occour, please use Python 3, because it has the finer
+# ModuleNotFoundError.
+
+try:
+ ModuleNotFoundError
+except NameError:
+ ModuleNotFoundError = ImportError
+
+@contextmanager
+def ensure_import_support():
+ # Make sure that we always have the shiboken containing package first.
+ # This is sometimes hidden by the ctest paths.
+ # We adjust the path in a way that the support folder comes first.
+ # This can be in "shiboken2/support" or in "shibokenmodule/support",
+ # so we use the "support" folder as toplevel.
+ sbk_support_dir = os.path.abspath(os.path.join(__file__, "..", "..", ".."))
+ sys.path.insert(0, sbk_support_dir)
+ sbk = "shiboken2"
+ save_sbk = sys.modules.pop(sbk) if sbk in sys.modules else None
+ # make sure that we get at the support folder
+ try:
+ import support
+ yield
+ except Exception as e:
+ print("Problem importing support:")
+ print(e)
+ traceback.print_exc()
+ sys.stdout.flush()
+ sys.exit(-1)
+ if save_sbk:
+ sys.modules[sbk] = save_sbk
+ sys.path.pop(0)
+
+
+# patching inspect's formatting to keep the word "typing":
+def formatannotation(annotation, base_module=None):
+ # if getattr(annotation, '__module__', None) == 'typing':
+ # return repr(annotation).replace('typing.', '')
+ if isinstance(annotation, type):
+ if annotation.__module__ in ('builtins', base_module):
+ return annotation.__qualname__
+ return annotation.__module__+'.'+annotation.__qualname__
+ return repr(annotation)
+
+# patching __repr__ to disable the __repr__ of typing.TypeVar:
+"""
+ def __repr__(self):
+ if self.__covariant__:
+ prefix = '+'
+ elif self.__contravariant__:
+ prefix = '-'
+ else:
+ prefix = '~'
+ return prefix + self.__name__
+"""
+def _typevar__repr__(self):
+ return "typing." + self.__name__
+
+with ensure_import_support():
+ # We store all needed modules in signature_loader.
+ # This way, they are always accessible.
+ import signature_loader
+
+ if sys.version_info >= (3,):
+ import typing
+ import inspect
+ inspect.formatannotation = formatannotation
+ else:
+ import inspect
+ namespace = inspect.__dict__
+ from support.signature import typing27 as typing
+ typing.__name__ = "typing"
+ from support.signature import backport_inspect as inspect
+ _doc = inspect.__doc__
+ inspect.__dict__.update(namespace)
+ inspect.__doc__ += _doc
+ # force inspect to find all attributes. See "heuristic" in pydoc.py!
+ inspect.__all__ = list(x for x in dir(inspect) if not x.startswith("_"))
+ typing.TypeVar.__repr__ = _typevar__repr__
+
+ def put_into_loader_package(module, loader=signature_loader):
+ # Note: the "with" statement hides that we are no longer in a
+ # global context, but inside ensure_import_support. Therefore,
+ # we need to explicitly pass the signature_loader in.
+
+ # take the last component of the module name
+ name = module.__name__.rsplit(".", 1)[-1]
+ # allow access as signature_loader.typing
+ setattr(loader, name, module)
+ # put into sys.modules as a package to allow all import options
+ fullname = "{}.{}".format(loader.__name__, name)
+ sys.modules[fullname] = module
+
+ put_into_loader_package(typing)
+ put_into_loader_package(inspect)
+ from support.signature import mapping as sbk_mapping
+ sbk_mapping.__name__ = "sbk_mapping"
+ put_into_loader_package(sbk_mapping)
+ # We may or may not use PySide.
+ try:
+ from PySide2.support.signature import mapping
+ except ModuleNotFoundError:
+ mapping = sbk_mapping
+ mapping.__name__ = "mapping"
+ put_into_loader_package(mapping)
+ from support.signature import layout
+ put_into_loader_package(layout)
+ from support.signature.lib import enum_sig
+ put_into_loader_package(enum_sig)
+ from support.signature.parser import pyside_type_init
+
+
+# Note also that during the tests we have a different encoding that would
+# break the Python license decorated files without an encoding line.
+
+# name used in signature.cpp
+def create_signature(props, key):
+ return layout.create_signature(props, key)
+
+# name used in signature.cpp
+def seterror_argument(args, func_name):
+ return errorhandler.seterror_argument(args, func_name)
+
+# end of file
diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
new file mode 100644
index 000000000..3e76cd94a
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
@@ -0,0 +1,210 @@
+#############################################################################
+##
+## Copyright (C) 2018 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
+
+"""
+mapping.py
+
+This module has the mapping from the pyside C-modules view of signatures
+to the Python representation.
+
+The PySide modules are not loaded in advance, but only after they appear
+in sys.modules. This minimizes the loading overhead.
+"""
+
+import sys
+import struct
+import os
+import pkgutil
+
+from signature_loader import typing
+
+class ellipsis(object):
+ def __repr__(self):
+ return "..."
+ellipsis = ellipsis()
+Char = typing.Union[str, int] # how do I model the limitation to 1 char?
+StringList = typing.List[str]
+IntList = typing.List[int]
+Point = typing.Tuple[float, float]
+PointList = typing.List[Point]
+IntMatrix = typing.List[IntList]
+Variant = typing.Any
+ModelIndexList = typing.List[int]
+QImageCleanupFunction = typing.Callable
+FloatList = typing.List[float]
+FloatMatrix = typing.List[FloatList]
+# Pair could be more specific, but we loose the info in the generator.
+Pair = typing.Tuple[typing.Any, typing.Any]
+MultiMap = typing.DefaultDict[str, typing.List[str]]
+
+# ulong_max is only 32 bit on windows.
+ulong_max = 2*sys.maxsize+1 if len(struct.pack("L", 1)) != 4 else 0xffffffff
+ushort_max = 0xffff
+
+GL_COLOR_BUFFER_BIT = 0x00004000
+GL_NEAREST = 0x2600
+
+WId = int
+
+# from 5.9
+GL_TEXTURE_2D = 0x0DE1
+GL_RGBA = 0x1908
+
+class _NotCalled(str):
+ """
+ Wrap some text with semantics
+
+ This class is wrapped around text in order to avoid calling it.
+ There are three reasons for this:
+
+ - some instances cannot be created since they are abstract,
+ - some can only be created after qApp was created,
+ - some have an ugly __repr__ with angle brackets in it.
+
+ By using derived classes, good looking instances can be created
+ which can be used to generate source code or .pyi files. When the
+ real object is needed, the wrapper can simply be called.
+ """
+ def __repr__(self):
+ suppress = "support.signature.typing."
+ text = self[len(suppress):] if self.startswith(suppress) else self
+ return "{}({})".format(type(self).__name__, text)
+
+ def __call__(self):
+ from signature_loader.mapping import __dict__ as namespace
+ text = self if self.endswith(")") else self + "()"
+ return eval(text, namespace)
+
+# Some types are abstract. They just show their name.
+class Virtual(_NotCalled):
+ pass
+
+# Other types I simply could not find.
+class Missing(_NotCalled):
+ def __repr__(self):
+ return '{}("{}")'.format(type(self).__name__, self)
+
+class Invalid(_NotCalled):
+ pass
+
+# Helper types
+class Default(_NotCalled):
+ pass
+
+class Instance(_NotCalled):
+ pass
+
+
+class Reloader(object):
+ _uninitialized = ["sample"]
+ _prefixes = [""]
+
+ def __init__(self):
+ self.sys_module_count = 0
+ self.uninitialized = self._uninitialized
+
+ def update(self, g=None):
+ if self.sys_module_count == len(sys.modules):
+ return
+ self.sys_module_count = len(sys.modules)
+ if g is None:
+ g = globals()
+ for mod_name in self.uninitialized[:]:
+ for prefix in self._prefixes:
+ import_name = prefix + mod_name
+ if import_name in sys.modules:
+ # check if this is a real module
+ obj = sys.modules[import_name]
+ if not getattr(obj, "__file__", None) or os.path.isdir(obj.__file__):
+ raise ImportError("Module '{mod_name}' is at most a "
+ "namespace!".format(**locals()))
+ # module is real
+ self.uninitialized.remove(mod_name)
+ proc_name = "init_" + mod_name
+ if proc_name in g:
+ g.update(g[proc_name]())
+
+
+update_mapping = Reloader().update
+type_map = {}
+
+
+def init_sample():
+ import sample
+ import datetime
+ type_map.update({
+ "sample.int": int,
+ "Complex": complex,
+ "sample.OddBool": bool,
+ "sample.bool": bool,
+ "sample.PStr": str,
+ "double[]": FloatList,
+ "OddBool": bool,
+ "PStr": str,
+ "sample.char": Char,
+ "double[][]": FloatMatrix,
+ "int[]": IntList,
+ "int[][]": IntMatrix,
+ "sample.Point": Point,
+ "sample.ObjectType": object,
+ "std.string": str,
+ "HANDLE": int,
+ "Foo.HANDLE": int,
+ "sample.Photon.TemplateBase": Missing("sample.Photon.TemplateBase"),
+ "ObjectType.Identifier": Missing("sample.ObjectType.Identifier"),
+ "zero(HANDLE)": 0,
+ "Null": None,
+ "zero(sample.ObjectType)": None,
+ "std.size_t": int,
+ 'Str("<unknown>")': "<unknown>",
+ 'Str("<unk")': "<unk",
+ 'Str("nown>")': "nown>",
+ "zero(sample.ObjectModel)": None,
+ "sample.unsigned char": Char,
+ "sample.double": float,
+ "zero(sample.bool)": False,
+ "PyDate": datetime.date,
+ "ZeroIn": 0,
+ "Point[]": PointList,
+ })
+ return locals()
+
+# end of file
diff --git a/sources/pyside2/PySide2/support/signature/parser.py b/sources/shiboken2/shibokenmodule/support/signature/parser.py
index 9313fb540..5178d9ef9 100644
--- a/sources/pyside2/PySide2/support/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/parser.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2017 The Qt Company Ltd.
+## Copyright (C) 2018 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of Qt for Python.
@@ -45,9 +45,11 @@ import warnings
import types
import keyword
import functools
-from .mapping import type_map, update_mapping, __dict__ as namespace
+from signature_loader.mapping import (
+ type_map, update_mapping, __dict__ as namespace)
_DEBUG = False
+LIST_KEYWORDS = False
"""
parser.py
@@ -74,6 +76,7 @@ def dprint(*args, **kw):
import pprint
for arg in args:
pprint.pprint(arg)
+ sys.stdout.flush()
def _parse_line(line):
line_re = r"""
@@ -119,6 +122,8 @@ def _parse_line(line):
for arg in arglist:
name, ann = arg.split(":")
if name in keyword.kwlist:
+ if LIST_KEYWORDS:
+ print("KEYWORD", ret)
name = name + "_"
if "=" in ann:
ann, default = ann.split("=")
@@ -130,6 +135,10 @@ def _parse_line(line):
multi = ret["multi"]
if multi is not None:
ret["multi"] = int(multi)
+ funcname = ret["funcname"]
+ parts = funcname.split(".")
+ if parts[-1] in keyword.kwlist:
+ ret["funcname"] = funcname + "_"
return ret
def make_good_value(thing, valtype):
@@ -192,8 +201,14 @@ def calculate_props(line):
arglist = res["arglist"]
annotations = {}
_defaults = []
- for tup in arglist:
+ for idx, tup in enumerate(arglist):
name, ann = tup[:2]
+ if ann == "...":
+ name = "*args"
+ # copy the fields back :()
+ ann = 'NULL' # maps to None
+ tup = name, ann
+ arglist[idx] = tup
annotations[name] = _resolve_type(ann, line)
if len(tup) == 3:
default = _resolve_value(tup[2], ann, line)
@@ -214,6 +229,31 @@ def calculate_props(line):
props["multi"] = res["multi"]
return props
+def fixup_multilines(sig_str):
+ lines = list(line.strip() for line in sig_str.strip().splitlines())
+ res = []
+ multi_lines = []
+ for line in lines:
+ multi = re.match(r"([0-9]+):", line)
+ if multi:
+ idx, rest = int(multi.group(1)), line[multi.end():]
+ multi_lines.append(rest)
+ if idx > 0:
+ continue
+ # remove duplicates
+ multi_lines = sorted(set(multi_lines))
+ # renumber or return a single line
+ nmulti = len(multi_lines)
+ if nmulti > 1:
+ for idx, line in enumerate(multi_lines):
+ res.append("{}:{}".format(nmulti-idx-1, line))
+ else:
+ res.append(multi_lines[0])
+ multi_lines = []
+ else:
+ res.append(line)
+ return res
+
def pyside_type_init(typemod, sig_str):
dprint()
if type(typemod) is types.ModuleType:
@@ -222,9 +262,10 @@ def pyside_type_init(typemod, sig_str):
dprint("Initialization of type '{}.{}'".format(typemod.__module__,
typemod.__name__))
update_mapping()
+ lines = fixup_multilines(sig_str)
ret = {}
multi_props = []
- for line in sig_str.strip().splitlines():
+ for line in lines:
props = calculate_props(line)
shortname = props["name"]
multi = props["multi"]
@@ -232,10 +273,10 @@ def pyside_type_init(typemod, sig_str):
ret[shortname] = props
dprint(props)
else:
- fullname = props.pop("fullname")
multi_props.append(props)
if multi > 0:
continue
+ fullname = props.pop("fullname")
multi_props = {"multi": multi_props, "fullname": fullname}
ret[shortname] = multi_props
dprint(multi_props)
diff --git a/sources/pyside2/PySide2/support/signature/qt_attribution.json b/sources/shiboken2/shibokenmodule/support/signature/qt_attribution.json
index 491ae8054..491ae8054 100644
--- a/sources/pyside2/PySide2/support/signature/qt_attribution.json
+++ b/sources/shiboken2/shibokenmodule/support/signature/qt_attribution.json
diff --git a/sources/pyside2/PySide2/support/signature/typing27.py b/sources/shiboken2/shibokenmodule/support/signature/typing27.py
index ae1d6ba27..5d1c6058b 100644
--- a/sources/pyside2/PySide2/support/signature/typing27.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/typing27.py
@@ -95,6 +95,7 @@ import functools
import re as stdlib_re # Avoid confusion with the re we export.
import sys
import types
+import copy
try:
import collections.abc as collections_abc
except ImportError:
@@ -160,6 +161,7 @@ __all__ = [
'NewType',
'no_type_check',
'no_type_check_decorator',
+ 'NoReturn',
'overload',
'Text',
'TYPE_CHECKING',
@@ -445,7 +447,7 @@ def _type_check(arg, msg):
if (
type(arg).__name__ in ('_Union', '_Optional') and
not getattr(arg, '__origin__', None) or
- isinstance(arg, TypingMeta) and _gorg(arg) in (Generic, _Protocol)
+ isinstance(arg, TypingMeta) and arg._gorg in (Generic, _Protocol)
):
raise TypeError("Plain %s is not valid as type argument" % arg)
return arg
@@ -1033,29 +1035,6 @@ class _Optional(_FinalTypingBase):
Optional = _Optional(_root=True)
-def _gorg(a):
- """Return the farthest origin of a generic class (internal helper)."""
- assert isinstance(a, GenericMeta)
- while a.__origin__ is not None:
- a = a.__origin__
- return a
-
-
-def _geqv(a, b):
- """Return whether two generic classes are equivalent (internal helper).
-
- The intention is to consider generic class X and any of its
- parameterized forms (X[T], X[int], etc.) as equivalent.
-
- However, X is not equivalent to a subclass of X.
-
- The relation is reflexive, symmetric and transitive.
- """
- assert isinstance(a, GenericMeta) and isinstance(b, GenericMeta)
- # Reduce each to its origin.
- return _gorg(a) is _gorg(b)
-
-
def _next_in_mro(cls):
"""Helper for Generic.__new__.
@@ -1065,7 +1044,7 @@ def _next_in_mro(cls):
next_in_mro = object
# Look for the last occurrence of Generic or Generic[...].
for i, c in enumerate(cls.__mro__[:-1]):
- if isinstance(c, GenericMeta) and _gorg(c) is Generic:
+ if isinstance(c, GenericMeta) and c._gorg is Generic:
next_in_mro = cls.__mro__[i + 1]
return next_in_mro
@@ -1166,13 +1145,15 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
extra = namespace.get('__extra__')
if extra is not None and type(extra) is abc.ABCMeta and extra not in bases:
bases = (extra,) + bases
- bases = tuple(_gorg(b) if isinstance(b, GenericMeta) else b for b in bases)
+ bases = tuple(b._gorg if isinstance(b, GenericMeta) else b for b in bases)
# remove bare Generic from bases if there are other generic bases
if any(isinstance(b, GenericMeta) and b is not Generic for b in bases):
bases = tuple(b for b in bases if b is not Generic)
namespace.update({'__origin__': origin, '__extra__': extra})
self = super(GenericMeta, cls).__new__(cls, name, bases, namespace)
+ super(GenericMeta, self).__setattr__('_gorg',
+ self if not origin else origin._gorg)
self.__parameters__ = tvars
# Be prepared that GenericMeta will be subclassed by TupleMeta
@@ -1219,7 +1200,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
def _abc_negative_cache(self):
if isinstance(self.__extra__, abc.ABCMeta):
return self.__extra__._abc_negative_cache
- return _gorg(self)._abc_generic_negative_cache
+ return self._gorg._abc_generic_negative_cache
@_abc_negative_cache.setter
def _abc_negative_cache(self, value):
@@ -1233,7 +1214,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
def _abc_negative_cache_version(self):
if isinstance(self.__extra__, abc.ABCMeta):
return self.__extra__._abc_negative_cache_version
- return _gorg(self)._abc_generic_negative_cache_version
+ return self._gorg._abc_generic_negative_cache_version
@_abc_negative_cache_version.setter
def _abc_negative_cache_version(self, value):
@@ -1283,7 +1264,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
if self.__origin__ is None:
return self
tree_args = _subs_tree(self, tvars, args)
- return (_gorg(self),) + tuple(tree_args)
+ return (self._gorg,) + tuple(tree_args)
def __eq__(self, other):
if not isinstance(other, GenericMeta):
@@ -1299,7 +1280,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
def __getitem__(self, params):
if not isinstance(params, tuple):
params = (params,)
- if not params and not _gorg(self) is Tuple:
+ if not params and self._gorg is not Tuple:
raise TypeError(
"Parameter list to %s[...] cannot be empty" % _qualname(self))
msg = "Parameters to generic types must be types."
@@ -1343,7 +1324,11 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
def __subclasscheck__(self, cls):
if self.__origin__ is not None:
- if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']:
+ # This should only be modules within the standard
+ # library. singledispatch is the only exception, because
+ # it's a Python 2 backport of functools.singledispatch.
+ if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools',
+ 'singledispatch']:
raise TypeError("Parameterized generics cannot be used with class "
"or instance checks")
return False
@@ -1362,11 +1347,6 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
return issubclass(instance.__class__, self)
return False
- def __copy__(self):
- return self.__class__(self.__name__, self.__bases__, dict(self.__dict__),
- self.__parameters__, self.__args__, self.__origin__,
- self.__extra__, self.__orig_bases__)
-
def __setattr__(self, attr, value):
# We consider all the subscripted genrics as proxies for original class
if (
@@ -1375,7 +1355,17 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
):
super(GenericMeta, self).__setattr__(attr, value)
else:
- super(GenericMeta, _gorg(self)).__setattr__(attr, value)
+ super(GenericMeta, self._gorg).__setattr__(attr, value)
+
+
+def _copy_generic(self):
+ """Hack to work around https://bugs.python.org/issue11480 on Python 2"""
+ return self.__class__(self.__name__, self.__bases__, dict(self.__dict__),
+ self.__parameters__, self.__args__, self.__origin__,
+ self.__extra__, self.__orig_bases__)
+
+
+copy._copy_dispatch[GenericMeta] = _copy_generic
# Prevent checks for Generic to crash when defining Generic.
@@ -1386,10 +1376,18 @@ def _generic_new(base_cls, cls, *args, **kwds):
# Assure type is erased on instantiation,
# but attempt to store it in __orig_class__
if cls.__origin__ is None:
- return base_cls.__new__(cls)
+ if (base_cls.__new__ is object.__new__ and
+ cls.__init__ is not object.__init__):
+ return base_cls.__new__(cls)
+ else:
+ return base_cls.__new__(cls, *args, **kwds)
else:
- origin = _gorg(cls)
- obj = base_cls.__new__(origin)
+ origin = cls._gorg
+ if (base_cls.__new__ is object.__new__ and
+ cls.__init__ is not object.__init__):
+ obj = base_cls.__new__(origin)
+ else:
+ obj = base_cls.__new__(origin, *args, **kwds)
try:
obj.__orig_class__ = cls
except AttributeError:
@@ -1423,7 +1421,7 @@ class Generic(object):
__slots__ = ()
def __new__(cls, *args, **kwds):
- if _geqv(cls, Generic):
+ if cls._gorg is Generic:
raise TypeError("Type Generic cannot be instantiated; "
"it can be used only as a base class")
return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
@@ -1445,7 +1443,7 @@ class TupleMeta(GenericMeta):
@_tp_cache
def __getitem__(self, parameters):
- if self.__origin__ is not None or not _geqv(self, Tuple):
+ if self.__origin__ is not None or self._gorg is not Tuple:
# Normal generic rules apply if this is not the first subscription
# or a subscription of a subclass.
return super(TupleMeta, self).__getitem__(parameters)
@@ -1474,6 +1472,9 @@ class TupleMeta(GenericMeta):
"with issubclass().")
+copy._copy_dispatch[TupleMeta] = _copy_generic
+
+
class Tuple(tuple):
"""Tuple type; Tuple[X, Y] is the cross-product type of X and Y.
@@ -1489,7 +1490,7 @@ class Tuple(tuple):
__slots__ = ()
def __new__(cls, *args, **kwds):
- if _geqv(cls, Tuple):
+ if cls._gorg is Tuple:
raise TypeError("Type Tuple cannot be instantiated; "
"use tuple() instead")
return _generic_new(tuple, cls, *args, **kwds)
@@ -1504,7 +1505,7 @@ class CallableMeta(GenericMeta):
return self._tree_repr(self._subs_tree())
def _tree_repr(self, tree):
- if _gorg(self) is not Callable:
+ if self._gorg is not Callable:
return super(CallableMeta, self)._tree_repr(tree)
# For actual Callable (not its subclass) we override
# super(CallableMeta, self)._tree_repr() for nice formatting.
@@ -1524,7 +1525,7 @@ class CallableMeta(GenericMeta):
with hashable arguments to improve speed.
"""
- if self.__origin__ is not None or not _geqv(self, Callable):
+ if self.__origin__ is not None or self._gorg is not Callable:
return super(CallableMeta, self).__getitem__(parameters)
if not isinstance(parameters, tuple) or len(parameters) != 2:
raise TypeError("Callable must be used as "
@@ -1552,6 +1553,9 @@ class CallableMeta(GenericMeta):
return super(CallableMeta, self).__getitem__(parameters)
+copy._copy_dispatch[CallableMeta] = _copy_generic
+
+
class Callable(object):
"""Callable type; Callable[[int], str] is a function of (int) -> str.
@@ -1568,7 +1572,7 @@ class Callable(object):
__slots__ = ()
def __new__(cls, *args, **kwds):
- if _geqv(cls, Callable):
+ if cls._gorg is Callable:
raise TypeError("Type Callable cannot be instantiated; "
"use a non-abstract subclass instead")
return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
@@ -1618,7 +1622,7 @@ def no_type_check(arg):
if isinstance(arg, type):
arg_attrs = arg.__dict__.copy()
for attr, val in arg.__dict__.items():
- if val in arg.__bases__:
+ if val in arg.__bases__ + (arg,):
arg_attrs.pop(attr)
for obj in arg_attrs.values():
if isinstance(obj, types.FunctionType):
@@ -1735,6 +1739,7 @@ class _ProtocolMeta(GenericMeta):
if (not attr.startswith('_abc_') and
attr != '__abstractmethods__' and
attr != '_is_protocol' and
+ attr != '_gorg' and
attr != '__dict__' and
attr != '__args__' and
attr != '__slots__' and
@@ -1886,7 +1891,7 @@ class List(list, MutableSequence[T]):
__extra__ = list
def __new__(cls, *args, **kwds):
- if _geqv(cls, List):
+ if cls._gorg is List:
raise TypeError("Type List cannot be instantiated; "
"use list() instead")
return _generic_new(list, cls, *args, **kwds)
@@ -1897,7 +1902,7 @@ class Deque(collections.deque, MutableSequence[T]):
__extra__ = collections.deque
def __new__(cls, *args, **kwds):
- if _geqv(cls, Deque):
+ if cls._gorg is Deque:
return collections.deque(*args, **kwds)
return _generic_new(collections.deque, cls, *args, **kwds)
@@ -1907,7 +1912,7 @@ class Set(set, MutableSet[T]):
__extra__ = set
def __new__(cls, *args, **kwds):
- if _geqv(cls, Set):
+ if cls._gorg is Set:
raise TypeError("Type Set cannot be instantiated; "
"use set() instead")
return _generic_new(set, cls, *args, **kwds)
@@ -1918,7 +1923,7 @@ class FrozenSet(frozenset, AbstractSet[T_co]):
__extra__ = frozenset
def __new__(cls, *args, **kwds):
- if _geqv(cls, FrozenSet):
+ if cls._gorg is FrozenSet:
raise TypeError("Type FrozenSet cannot be instantiated; "
"use frozenset() instead")
return _generic_new(frozenset, cls, *args, **kwds)
@@ -1975,7 +1980,7 @@ class Dict(dict, MutableMapping[KT, VT]):
__extra__ = dict
def __new__(cls, *args, **kwds):
- if _geqv(cls, Dict):
+ if cls._gorg is Dict:
raise TypeError("Type Dict cannot be instantiated; "
"use dict() instead")
return _generic_new(dict, cls, *args, **kwds)
@@ -1986,7 +1991,7 @@ class DefaultDict(collections.defaultdict, MutableMapping[KT, VT]):
__extra__ = collections.defaultdict
def __new__(cls, *args, **kwds):
- if _geqv(cls, DefaultDict):
+ if cls._gorg is DefaultDict:
return collections.defaultdict(*args, **kwds)
return _generic_new(collections.defaultdict, cls, *args, **kwds)
@@ -1996,7 +2001,7 @@ class Counter(collections.Counter, Dict[T, int]):
__extra__ = collections.Counter
def __new__(cls, *args, **kwds):
- if _geqv(cls, Counter):
+ if cls._gorg is Counter:
return collections.Counter(*args, **kwds)
return _generic_new(collections.Counter, cls, *args, **kwds)
@@ -2015,7 +2020,7 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]):
__extra__ = _G_base
def __new__(cls, *args, **kwds):
- if _geqv(cls, Generator):
+ if cls._gorg is Generator:
raise TypeError("Type Generator cannot be instantiated; "
"create a subclass instead")
return _generic_new(_G_base, cls, *args, **kwds)
@@ -2144,7 +2149,7 @@ class IO(Generic[AnyStr]):
def close(self):
pass
- @abstractmethod
+ @abstractproperty
def closed(self):
pass
diff --git a/sources/shiboken2/tests/libsample/CMakeLists.txt b/sources/shiboken2/tests/libsample/CMakeLists.txt
index 7bbc0c3dd..ae3d40312 100644
--- a/sources/shiboken2/tests/libsample/CMakeLists.txt
+++ b/sources/shiboken2/tests/libsample/CMakeLists.txt
@@ -10,6 +10,7 @@ complex.cpp
onlycopy.cpp
derived.cpp
echo.cpp
+exceptiontest.cpp
functions.cpp
handle.cpp
implicitconv.cpp
diff --git a/sources/shiboken2/tests/libsample/exceptiontest.cpp b/sources/shiboken2/tests/libsample/exceptiontest.cpp
new file mode 100644
index 000000000..1302a8e43
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/exceptiontest.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "exceptiontest.h"
+
+class TestException : public std::exception
+{
+public:
+ const char *what() const noexcept override
+ { return "TestException"; }
+};
+
+ExceptionTest::ExceptionTest() = default;
+
+int ExceptionTest::intThrowStdException(bool doThrow)
+{
+ if (doThrow)
+ throw TestException();
+ return 1;
+}
+
+void ExceptionTest::voidThrowStdException(bool doThrow)
+{
+ if (doThrow)
+ throw TestException();
+}
+
+int ExceptionTest::intThrowInt(bool doThrow)
+{
+ if (doThrow)
+ throw 42;
+ return 1;
+}
+
+void ExceptionTest::voidThrowInt(bool doThrow)
+{
+ if (doThrow)
+ throw 42;
+}
diff --git a/sources/shiboken2/tests/libsample/exceptiontest.h b/sources/shiboken2/tests/libsample/exceptiontest.h
new file mode 100644
index 000000000..8ab3e2b67
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/exceptiontest.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EXCEPTIONTEST_H
+#define EXCEPTIONTEST_H
+
+#include "libsamplemacros.h"
+
+#include <exception>
+
+class LIBSAMPLE_API ExceptionTest
+{
+ public:
+ ExceptionTest();
+
+ int intThrowStdException(bool doThrow);
+ void voidThrowStdException(bool doThrow);
+
+ int intThrowInt(bool doThrow);
+ void voidThrowInt(bool doThrow);
+};
+
+#endif // EXCEPTIONTEST_H
diff --git a/sources/shiboken2/tests/libsample/mapuser.cpp b/sources/shiboken2/tests/libsample/mapuser.cpp
index 1dbd02d26..89a835af8 100644
--- a/sources/shiboken2/tests/libsample/mapuser.cpp
+++ b/sources/shiboken2/tests/libsample/mapuser.cpp
@@ -67,3 +67,8 @@ MapUser::showMap(std::map<std::string, int> mapping)
cout << (*it).first << " => " << (*it).second << endl;
}
+std::map<int, std::list<std::list<double> > > MapUser::foo() const
+{
+ std::map<int, std::list<std::list<double> > > result;
+ return result;
+}
diff --git a/sources/shiboken2/tests/libsample/mapuser.h b/sources/shiboken2/tests/libsample/mapuser.h
index 9677d2df2..ad434b957 100644
--- a/sources/shiboken2/tests/libsample/mapuser.h
+++ b/sources/shiboken2/tests/libsample/mapuser.h
@@ -58,6 +58,8 @@ public:
inline const std::map<int, ByteArray>& passMapIntValueType(const std::map<int, ByteArray>& arg) { return arg; }
+ std::map<int, std::list<std::list<double> > > foo() const;
+
private:
std::map<std::string, std::list<int> > m_map;
};
diff --git a/sources/shiboken2/tests/libsample/nontypetemplate.h b/sources/shiboken2/tests/libsample/nontypetemplate.h
new file mode 100644
index 000000000..4e2100626
--- /dev/null
+++ b/sources/shiboken2/tests/libsample/nontypetemplate.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of Qt for Python.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NONTYPETEMPLATE_H
+#define NONTYPETEMPLATE_H
+
+#include "libsamplemacros.h"
+
+#include <algorithm>
+#include <numeric>
+
+template <int Size> class IntArray
+{
+public:
+ explicit IntArray(int v) { std::fill(m_array, m_array + Size, v); }
+
+ int sum() const { return std::accumulate(m_array, m_array + Size, int(0)); }
+
+private:
+ int m_array[Size];
+};
+
+typedef IntArray<2> IntArray2;
+typedef IntArray<3> IntArray3;
+
+#endif // NONTYPETEMPLATE_H
diff --git a/sources/shiboken2/tests/libsample/objecttype.cpp b/sources/shiboken2/tests/libsample/objecttype.cpp
index e09a92f47..f82b7cf0d 100644
--- a/sources/shiboken2/tests/libsample/objecttype.cpp
+++ b/sources/shiboken2/tests/libsample/objecttype.cpp
@@ -282,6 +282,7 @@ void ObjectType::callVirtualCreateChild()
ObjectType* fake_parent = new ObjectType();
ObjectType* fake_child = createChild(fake_parent);
assert(fake_child->isPython());
+ (void)fake_child;
delete fake_parent;
}
diff --git a/sources/shiboken2/tests/libsample/objecttype.h b/sources/shiboken2/tests/libsample/objecttype.h
index bcb4f3332..ecd67b684 100644
--- a/sources/shiboken2/tests/libsample/objecttype.h
+++ b/sources/shiboken2/tests/libsample/objecttype.h
@@ -63,7 +63,7 @@ private:
class ObjectTypeLayout;
class ObjectType;
-typedef std::list<ObjectType*> ObjectTypeList;
+using ObjectTypeList = std::list<ObjectType*>;
class LIBSAMPLE_API ObjectType
{
diff --git a/sources/shiboken2/tests/libsample/samplenamespace.cpp b/sources/shiboken2/tests/libsample/samplenamespace.cpp
index ec3da3dbf..e066869d2 100644
--- a/sources/shiboken2/tests/libsample/samplenamespace.cpp
+++ b/sources/shiboken2/tests/libsample/samplenamespace.cpp
@@ -36,6 +36,13 @@ using namespace std;
namespace SampleNamespace
{
+// PYSIDE-817, scoped enums must not be converted to int in the wrappers generated
+// for the protected hacks
+SomeClass::PublicScopedEnum SomeClass::protectedMethodReturningPublicScopedEnum() const
+{
+ return PublicScopedEnum::v1;
+}
+
OutValue
enumInEnumOut(InValue in)
{
diff --git a/sources/shiboken2/tests/libsample/samplenamespace.h b/sources/shiboken2/tests/libsample/samplenamespace.h
index 37a445e51..27fa11290 100644
--- a/sources/shiboken2/tests/libsample/samplenamespace.h
+++ b/sources/shiboken2/tests/libsample/samplenamespace.h
@@ -96,9 +96,11 @@ LIBSAMPLE_API void doSomethingWithArray(const unsigned char* data, unsigned int
LIBSAMPLE_API int enumItemAsDefaultValueToIntArgument(int value = ZeroIn);
-class SomeClass
+class LIBSAMPLE_API SomeClass
{
public:
+ enum class PublicScopedEnum { v1, v2 };
+
class SomeInnerClass
{
public:
@@ -131,6 +133,8 @@ protected:
ProtectedItem0,
ProtectedItem1
};
+
+ PublicScopedEnum protectedMethodReturningPublicScopedEnum() const;
};
class DerivedFromNamespace : public SomeClass::SomeInnerClass::OkThisIsRecursiveEnough
diff --git a/sources/shiboken2/tests/minimalbinding/CMakeLists.txt b/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
index b8b6417d1..ec674b56b 100644
--- a/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/minimalbinding/CMakeLists.txt
@@ -15,7 +15,9 @@ ${CMAKE_CURRENT_BINARY_DIR}/minimal/minbooluser_wrapper.cpp
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/minimal-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt" @ONLY)
-add_custom_command(OUTPUT ${minimal_SRC}
+add_custom_command(
+OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+BYPRODUCTS ${minimal_SRC}
COMMAND shiboken2 --project-file=${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt ${GENERATOR_EXTRA_FLAGS}
DEPENDS ${minimal_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken2
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -38,3 +40,4 @@ target_link_libraries(minimal
libminimal
${SBK_PYTHON_LIBRARIES}
libshiboken)
+create_generator_target(minimal)
diff --git a/sources/shiboken2/tests/otherbinding/CMakeLists.txt b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
index 186766b41..0be66f797 100644
--- a/sources/shiboken2/tests/otherbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/otherbinding/CMakeLists.txt
@@ -17,7 +17,9 @@ ${CMAKE_CURRENT_BINARY_DIR}/other/other_module_wrapper.cpp
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/other-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt" @ONLY)
-add_custom_command(OUTPUT ${other_SRC}
+add_custom_command(
+OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+BYPRODUCTS ${other_SRC}
COMMAND shiboken2 --project-file=${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt ${GENERATOR_EXTRA_FLAGS}
DEPENDS ${other_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken2
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -48,4 +50,5 @@ target_link_libraries(other
libshiboken)
add_dependencies(other sample)
+create_generator_target(other)
diff --git a/sources/shiboken2/tests/otherbinding/extended_multiply_operator_test.py b/sources/shiboken2/tests/otherbinding/extended_multiply_operator_test.py
index 08541a1f4..0c58fbf5b 100755
--- a/sources/shiboken2/tests/otherbinding/extended_multiply_operator_test.py
+++ b/sources/shiboken2/tests/otherbinding/extended_multiply_operator_test.py
@@ -57,7 +57,7 @@ class PointOperationsWithNumber(unittest.TestCase):
'''sample.Point * other.Number'''
pt = Point(2, 7)
num = Number(11)
- self.assertEqual(pt * num, pt * 11)
+ self.assertEqual(pt * num.value(), pt * 11)
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/CMakeLists.txt b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
index 32117e44a..7f4bec5f4 100644
--- a/sources/shiboken2/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/samplebinding/CMakeLists.txt
@@ -29,11 +29,14 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/derived_someinnerclass_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/echo_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/event_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/expression_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/exceptiontest_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/friendofonlycopy_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/handleholder_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/implicitconv_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/implicitbase_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/implicittarget_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intarray2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/intarray3_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/intlist_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sortedoverload_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/intwrapper_wrapper.cpp
@@ -125,7 +128,9 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/union_wrapper.cpp
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt" @ONLY)
-add_custom_command(OUTPUT ${sample_SRC}
+add_custom_command(
+OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+BYPRODUCTS ${sample_SRC}
COMMAND shiboken2 --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt ${GENERATOR_EXTRA_FLAGS}
DEPENDS ${sample_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken2
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -149,3 +154,4 @@ target_link_libraries(sample
libsample
${SBK_PYTHON_LIBRARIES}
libshiboken)
+create_generator_target(sample)
diff --git a/sources/shiboken2/tests/samplebinding/exception_test.py b/sources/shiboken2/tests/samplebinding/exception_test.py
new file mode 100644
index 000000000..d6c02433a
--- /dev/null
+++ b/sources/shiboken2/tests/samplebinding/exception_test.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+#
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## 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 General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## 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-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import unittest
+
+from sample import ExceptionTest
+
+class CppExceptionTest(unittest.TestCase):
+
+ def testVoid(self):
+ exceptionCount = 0
+ et = ExceptionTest()
+
+ et.voidThrowStdException(False)
+
+ try:
+ et.voidThrowStdException(True)
+ except:
+ exceptionCount += 1
+
+ et.voidThrowInt(False)
+
+ try:
+ et.voidThrowInt(True)
+ except:
+ exceptionCount += 1
+
+ self.assertEqual(exceptionCount, 2)
+
+ def testReturnValue(self):
+ exceptionCount = 0
+ et = ExceptionTest()
+
+ result = et.intThrowStdException(False);
+
+ try:
+ result = et.intThrowStdException(True);
+ except:
+ exceptionCount += 1
+
+ result = et.intThrowInt(False);
+
+ try:
+ result = et.intThrowInt(True);
+ except:
+ exceptionCount += 1
+
+ self.assertEqual(exceptionCount, 2)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/global.h b/sources/shiboken2/tests/samplebinding/global.h
index f2add93ff..3984102a8 100644
--- a/sources/shiboken2/tests/samplebinding/global.h
+++ b/sources/shiboken2/tests/samplebinding/global.h
@@ -37,8 +37,10 @@
#include "sbkdate.h"
#include "derived.h"
#include "echo.h"
+#include "exceptiontest.h"
#include "functions.h"
#include "implicitconv.h"
+#include "nontypetemplate.h"
#include "overloadsort.h"
#include "handle.h"
#include "injectcode.h"
diff --git a/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py b/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py
new file mode 100644
index 000000000..9adfa2441
--- /dev/null
+++ b/sources/shiboken2/tests/samplebinding/nontypetemplate_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+#
+#############################################################################
+##
+## Copyright (C) 2018 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of the test suite of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:GPL-EXCEPT$
+## 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 General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 3 as published by the Free Software
+## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+## 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-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import unittest
+
+from sample import IntArray2, IntArray3
+
+class NonTypeTemplateTest(unittest.TestCase):
+
+ def testNonTypeTemplate(self):
+ array2 = IntArray2(3)
+ self.assertEqual(array2.sum(), 6)
+ array3 = IntArray3(5)
+ self.assertEqual(array3.sum(), 15)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
index 00052e881..9b967fc53 100644
--- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml
@@ -520,6 +520,10 @@
<suppress-warning text="skipping function 'ClassWithFunctionPointer::callFunctionPointer', unmatched parameter type 'void (*)(void*)'" />
</value-type>
+ <value-type name="IntArray" generate="no"/>
+ <value-type name="IntArray2"/>
+ <value-type name="IntArray3"/>
+
<enum-type name="OverloadedFuncEnum"/>
<!-- BUG:
renaming the ICOverloadedFuncEnum to the same name
@@ -545,6 +549,7 @@
<enum-type name="SampleNamespace"/>
</object-type>
<value-type name="SomeClass">
+ <enum-type name="PublicScopedEnum"/>
<value-type name="SomeInnerClass">
<object-type name="OkThisIsRecursiveEnough">
<enum-type name="NiceEnum" />
@@ -1964,7 +1969,7 @@
<define-ownership owner="c++"/>
</modify-argument>
</modify-function>
- <modify-function signature="acceptSequence(const char*[])">
+ <modify-function signature="acceptSequence(const char*const[])">
<modify-argument index="1">
<replace-type modified-type="PySequence" />
<conversion-rule class="native">
@@ -2388,6 +2393,8 @@
<value-type name="Expression" />
+ <object-type name="ExceptionTest" exception-handling="auto-on"/>
+
<value-type name="ModelIndex" />
<value-type name="ReferentModelIndex">
<modify-function signature="operator const ModelIndex&amp;()const">
diff --git a/sources/shiboken2/tests/smartbinding/CMakeLists.txt b/sources/shiboken2/tests/smartbinding/CMakeLists.txt
index faaa797b6..43888fae2 100644
--- a/sources/shiboken2/tests/smartbinding/CMakeLists.txt
+++ b/sources/shiboken2/tests/smartbinding/CMakeLists.txt
@@ -16,7 +16,9 @@ ${CMAKE_CURRENT_BINARY_DIR}/smart/registry_wrapper.cpp
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/smart-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt" @ONLY)
-add_custom_command(OUTPUT ${smart_SRC}
+add_custom_command(
+OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+BYPRODUCTS ${smart_SRC}
COMMAND shiboken2 --project-file=${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt ${GENERATOR_EXTRA_FLAGS}
DEPENDS ${smart_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken2
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -40,3 +42,4 @@ target_link_libraries(smart
libsmart
${SBK_PYTHON_LIBRARIES}
libshiboken)
+create_generator_target(smart)
diff --git a/testing/runner.py b/testing/runner.py
index 3c99df71c..baa29408c 100644
--- a/testing/runner.py
+++ b/testing/runner.py
@@ -88,21 +88,14 @@ class TestRunner(object):
os.environ['PATH'] = clang_bin_dir + os.pathsep + path
print("Adding %s as detected by %s to PATH" % (clang_bin_dir, clang_dir[1]))
- def _find_ctest(self):
+ def _find_ctest_in_file(self, file_name):
"""
- Find ctest in the Makefile
-
- We no longer use make, but the ctest command directly.
- It is convenient to look for the ctest program using the Makefile.
- This serves us two purposes:
-
- - there is no dependency of the PATH variable,
- - each project is checked whether ctest was configured.
+ Helper for _find_ctest() that finds the ctest binary in a build
+ system file (ninja, Makefile).
"""
- make_path = os.path.join(self.test_dir, "Makefile")
look_for = "--force-new-ctest-process"
line = None
- with open(make_path) as makefile:
+ with open(file_name) as makefile:
for line in makefile:
if look_for in line:
break
@@ -121,6 +114,25 @@ class TestRunner(object):
ctest = re.search(r'(\S+|"([^"]+)")\s+' + look_for, line).groups()
return ctest[1] or ctest[0]
+ def _find_ctest(self):
+ """
+ Find ctest in a build system file (ninja, Makefile)
+
+ We no longer use make, but the ctest command directly.
+ It is convenient to look for the ctest program using the Makefile.
+ This serves us two purposes:
+
+ - there is no dependency of the PATH variable,
+ - each project is checked whether ctest was configured.
+ """
+ candidate_files = ["Makefile", "build.ninja"]
+ for candidate in candidate_files:
+ path = os.path.join(self.test_dir, candidate)
+ if os.path.exists(path):
+ return self._find_ctest_in_file(path)
+ raise RuntimeError('Cannot find any of the build system files {}.'.format(
+ ', '.join(candidate_files)))
+
def _setup(self):
self.ctestCommand = self._find_ctest()
diff --git a/testing/testing.pyqtc b/testing/testing.pyqtc
new file mode 100644
index 000000000..5a89e69b8
--- /dev/null
+++ b/testing/testing.pyqtc
@@ -0,0 +1,9 @@
+../testrunner.py
+blacklist.py
+buildlog.py
+command.py
+helper.py
+__init__.py
+parser.py
+runner.py
+wheel_tester.py
diff --git a/testing/wheel_tester.py b/testing/wheel_tester.py
new file mode 100644
index 000000000..60fd7a38a
--- /dev/null
+++ b/testing/wheel_tester.py
@@ -0,0 +1,295 @@
+#############################################################################
+##
+## Copyright (C) 2018 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$
+##
+#############################################################################
+
+"""
+This script is used by Coin (coin_test_instructions.py specifically) to
+test installation of generated wheels, and test building of the
+"buildable" examples samplebinding and scriptableapplication.
+
+It can also be invoked regularly from the command line via
+python testing/wheel_tester.py --qmake=some-value --cmake=some-value
+
+The qmake and cmake arguments can also be omitted, and they will be
+looked up in your PATH.
+
+Make sure that some generated wheels already exist in the dist/
+directory (e.g. setup.py bdist_wheel was already executed).
+"""
+
+import os, sys
+
+try:
+ this_file = __file__
+except NameError:
+ this_file = sys.argv[0]
+this_file = os.path.abspath(this_file)
+this_dir = os.path.dirname(this_file)
+setup_script_dir = os.path.abspath(os.path.join(this_dir, '..'))
+sys.path.append(setup_script_dir)
+
+from build_scripts.options import OPTION_QMAKE
+from build_scripts.options import OPTION_CMAKE
+
+from build_scripts.utils import find_files_using_glob
+from build_scripts.utils import find_glob_in_path
+from build_scripts.utils import run_process
+from build_scripts.utils import rmtree
+import distutils.log as log
+
+log.set_verbosity(1)
+
+
+def find_executable_qmake():
+ return find_executable('qmake', OPTION_QMAKE)
+
+
+def find_executable_cmake():
+ return find_executable('cmake', OPTION_CMAKE)
+
+
+def find_executable(executable, command_line_value):
+ value = command_line_value
+ option_str = '--{}'.format(executable)
+
+ if value:
+ log.info("{} option given: {}".format(option_str, value))
+ if not os.path.exists(value):
+ raise RuntimeError("No executable exists at: {}".format(value))
+ else:
+ log.info("No {} option given, trying to find {} in PATH.".format(option_str, executable))
+ paths = find_glob_in_path(executable)
+ log.info("{} executables found in PATH: {}".format(executable, paths))
+ if not paths:
+ raise RuntimeError(
+ "No {} option was specified and no {} was found "
+ "in PATH.".format(option_str, executable))
+ else:
+ value = paths[0]
+ log.info("Using {} found in PATH: {}".format(executable, value))
+ log.info("")
+ return value
+
+
+QMAKE_PATH = find_executable_qmake()
+CMAKE_PATH = find_executable_cmake()
+
+
+def get_wheels_dir():
+ return os.path.join(setup_script_dir, "dist")
+
+
+def get_examples_dir():
+ return os.path.join(setup_script_dir, "examples")
+
+
+def package_prefix_names():
+ return ["shiboken2", "shiboken2_generator", "PySide2"]
+
+
+def clean_egg_info():
+ # After a successful bdist_wheel build, some .egg-info directories
+ # are left over, which confuse pip when invoking it via
+ # python -m pip, making pip think that the packages are already
+ # installed in the root source directory.
+ # Clean up the .egg-info directories to fix this, it should be
+ # safe to do so.
+ paths = find_files_using_glob(setup_script_dir, "*.egg-info")
+ for p in paths:
+ log.info("Removing {}".format(p))
+ rmtree(p)
+
+
+def install_wheel(wheel_path):
+ log.info("Installing wheel: {}".format(wheel_path))
+ exit_code = run_process([sys.executable, "-m", "pip", "install", wheel_path])
+ log.info("")
+ if exit_code:
+ raise RuntimeError("Error while installing wheel {}".format(wheel_path))
+
+
+def try_install_wheels(wheels_dir, py_version):
+ clean_egg_info()
+ all_wheels_pattern = "*.whl"
+ all_wheels = find_files_using_glob(wheels_dir, all_wheels_pattern)
+
+ if len(all_wheels) > 1:
+ log.info("Found the following wheels in {}: ".format(wheels_dir))
+ for wheel in all_wheels:
+ log.info(wheel)
+ else:
+ log.info("No wheels found in {}".format(wheels_dir))
+ log.info("")
+
+ for p in package_prefix_names():
+ pattern = "{}-*cp{}*.whl".format(p, py_version)
+ files = find_files_using_glob(wheels_dir, pattern)
+ if files and len(files) == 1:
+ wheel_path = files[0]
+ install_wheel(wheel_path)
+ elif len(files) > 1:
+ raise RuntimeError("More than one wheel found for specific package and version.")
+ else:
+ raise RuntimeError("No wheels compatible with Python {} found "
+ "for testing.".format(py_version))
+
+
+def is_unix():
+ if sys.platform.startswith("linux") or sys.platform == "darwin":
+ return True
+ return False
+
+
+def generate_build_cmake():
+ args = [CMAKE_PATH]
+ if is_unix():
+ args.extend(["-G", "Unix Makefiles"])
+ else:
+ args.extend(["-G", "NMake Makefiles"])
+ args.append("-DCMAKE_BUILD_TYPE=Release")
+ args.append("-Dpython_interpreter={}".format(sys.executable))
+
+ # Specify prefix path so find_package(Qt5) works.
+ qmake_dir = os.path.abspath(os.path.join(os.path.dirname(QMAKE_PATH), ".."))
+ args.append("-DCMAKE_PREFIX_PATH={}".format(qmake_dir))
+
+ args.append("..")
+
+ exit_code = run_process(args)
+ if exit_code:
+ raise RuntimeError("Failure while running cmake.")
+ log.info("")
+
+
+def generate_build_qmake():
+ exit_code = run_process([QMAKE_PATH, "..", "python_interpreter={}".format(sys.executable)])
+ if exit_code:
+ raise RuntimeError("Failure while running qmake.")
+ log.info("")
+
+
+def run_make():
+ args = []
+ if is_unix():
+ executable = "make"
+ else:
+ executable = "nmake"
+ args.append(executable)
+
+ exit_code = run_process(args)
+ if exit_code:
+ raise RuntimeError("Failure while running {}.".format(executable))
+ log.info("")
+
+
+def run_make_install():
+ args = []
+ if is_unix():
+ executable = "make"
+ else:
+ executable = "nmake"
+ args.append(executable)
+ args.append("install")
+
+ exit_code = run_process(args)
+ if exit_code:
+ raise RuntimeError("Failed while running {} install.".format(executable))
+ log.info("")
+
+
+def execute_script(script_path):
+ args = [sys.executable, script_path]
+ exit_code = run_process(args)
+ if exit_code:
+ raise RuntimeError("Failure while executing script: {}".format(script_path))
+ log.info("")
+
+
+def prepare_build_folder(src_path, build_folder_name):
+ build_path = os.path.join(src_path, build_folder_name)
+
+ # The script can be called for both Python 2 and Python 3 wheels, so
+ # preparing a build folder should clean any previous existing build.
+ if os.path.exists(build_path):
+ log.info("Removing {}".format(build_path))
+ rmtree(build_path)
+
+ log.info("Creating {}".format(build_path))
+ os.makedirs(build_path)
+ os.chdir(build_path)
+
+
+def try_build_examples():
+ examples_dir = get_examples_dir()
+
+ log.info("Attempting to build and run samplebinding using cmake.")
+ src_path = os.path.join(examples_dir, "samplebinding")
+ prepare_build_folder(src_path, "cmake")
+ generate_build_cmake()
+ run_make()
+ run_make_install()
+ execute_script(os.path.join(src_path, "main.py"))
+
+ log.info("Attempting to build scriptableapplication using cmake.")
+ src_path = os.path.join(examples_dir, "scriptableapplication")
+ prepare_build_folder(src_path, "cmake")
+ generate_build_cmake()
+ run_make()
+
+ log.info("Attempting to build scriptableapplication using qmake.")
+ src_path = os.path.join(examples_dir, "scriptableapplication")
+ prepare_build_folder(src_path, "qmake")
+ generate_build_qmake()
+ run_make()
+
+
+def run_wheel_tests():
+ wheels_dir = get_wheels_dir()
+ py_version = sys.version_info[0]
+
+ log.info("Attempting to install wheels.\n")
+ try_install_wheels(wheels_dir, py_version)
+
+ log.info("Attempting to build examples.\n")
+ try_build_examples()
+
+ log.info("All tests passed!")
+
+
+if __name__ == "__main__":
+ run_wheel_tests()