aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2019-07-18 10:18:43 +0200
committerAlex Blasche <alexander.blasche@qt.io>2019-07-18 10:56:11 +0200
commit2228615ac4f55abf07a1f7e28bbbfee9f3ae036a (patch)
treed12f0c1af2b6cdf486ff389607844a657a1b67c1
parent97718de50e14f69048993df4e87dda1cadcc599a (diff)
parent4646b8660721e5b8d06b06d714b4562e375f8c34 (diff)
Merge "Merge remote-tracking branch 'origin/5.12' into 5.13"
-rw-r--r--.gitignore2
-rw-r--r--coin_test_instructions.py3
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml11
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp50
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py4
-rw-r--r--sources/pyside2/tests/QtCore/CMakeLists.txt1
-rw-r--r--sources/pyside2/tests/QtCore/qsettings_test.ini4
-rw-r--r--sources/pyside2/tests/QtCore/qsettings_test.py77
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/CMakeLists.txt0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_1029.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_1029.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_451.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_451.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_456.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_456.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_557.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_726.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_726.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_814.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_814.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_825.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_825.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_847.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_847.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_915.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_926.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_926.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_951.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_951.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_995.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_995.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_997.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/bug_997.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/connect_python_qml.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/hw.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/qqmlnetwork_test.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/qquickview_test.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/registertype.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/registertype.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/signal_arguments.py0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/view.qml0
-rw-r--r--[-rwxr-xr-x]sources/pyside2/tests/QtQml/viewmodel.qml0
-rw-r--r--sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp4
-rw-r--r--sources/shiboken2/ApiExtractor/messages.cpp17
-rw-r--r--sources/shiboken2/ApiExtractor/messages.h2
-rw-r--r--sources/shiboken2/ApiExtractor/parser/codemodel.h1
-rw-r--r--sources/shiboken2/doc/typesystemvariables.rst23
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp10
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp9
-rw-r--r--sources/shiboken2/shibokenmodule/CMakeLists.txt2
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py15
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py135
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py360
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py185
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py15
-rw-r--r--sources/shiboken2/tests/minimalbinding/brace_pattern_test.py121
-rw-r--r--testing/wheel_tester.py16
57 files changed, 773 insertions, 294 deletions
diff --git a/.gitignore b/.gitignore
index b8977159c..c4bc8c8f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,7 +69,7 @@ develop-eggs/
downloads/
eggs/
.eggs/
-lib/
+/lib/
lib64/
parts/
sdist/
diff --git a/coin_test_instructions.py b/coin_test_instructions.py
index c560f2175..8ba82c26f 100644
--- a/coin_test_instructions.py
+++ b/coin_test_instructions.py
@@ -66,7 +66,8 @@ 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, ["pip", "numpy", "PyOpenGL", "setuptools", "six", "pyinstaller", "wheel"])
+ # Keeping PyInstaller 3.4, because 3.5 seems to have broken our test
+ install_pip_dependencies(env_pip, ["pip", "numpy", "PyOpenGL", "setuptools", "six", "pyinstaller==3.4", "wheel"])
cmd = [env_python, "testrunner.py", "test",
"--blacklist", "build_history/blacklist.txt",
"--buildno=" + buildnro]
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 9f8d07733..9ffc7d376 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -2514,11 +2514,12 @@
<define-ownership class="target" owner="default"/>
</modify-argument>
</modify-function>
- <modify-function signature="value(const QString&amp;,const QVariant&amp;)const">
- <inject-documentation mode="append" format="target">
- .. warning:: QSettings.value can return different types (QVariant types) depending on the platform it's running on, so the safest way to use it is always casting the result to the desired type, e.g.: int(settings.value("myKey"))
- </inject-documentation>
- </modify-function>
+ <!-- PYSIDE-1010:
+ We remove the original implementation of value() to include the optional parameter -->
+ <modify-function signature="value(const QString&amp;,const QVariant&amp;)const" remove="all"/>
+ <add-function signature="value(const QString&amp;, const QVariant&amp; @defaultValue@ = 0, PyObject* @type@ = 0)" return-type="PyObject*">
+ <inject-code class="target" position="beginning" file="../glue/qtcore.cpp" snippet="qsettings-value"/>
+ </add-function>
</object-type>
<object-type name="QEvent" polymorphic-id-expression="%1-&gt;type() == QEvent::None">
<enum-type name="Type"/>
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 930ad9349..3e1bab97b 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -56,6 +56,56 @@ bool py2kStrCheck(PyObject *obj)
}
// @snippet pystring-check
+// @snippet qsettings-value
+QVariant out = %CPPSELF.value(%1, %2);
+PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3);
+
+if (typeObj) {
+ if (typeObj == &PyList_Type) {
+ QByteArrayList valuesList = out.toByteArray().split(',');
+ const int valuesSize = valuesList.size();
+ if (valuesSize > 0) {
+ PyObject *list = PyList_New(valuesSize);
+ for (int i = 0; i < valuesSize; i++) {
+ PyObject *item = PyUnicode_FromString(valuesList[i].data());
+ PyList_SET_ITEM(list, i, item);
+ Py_DECREF(item);
+ }
+ %PYARG_0 = list;
+
+ } else {
+ %PYARG_0 = %CONVERTTOPYTHON[QVariant](out);
+ }
+ } else if (typeObj == &PyBytes_Type) {
+ QByteArray asByteArray = out.toByteArray();
+ %PYARG_0 = PyBytes_FromString(asByteArray.data());
+ } else if (typeObj == &PyUnicode_Type) {
+ QByteArray asByteArray = out.toByteArray();
+ %PYARG_0 = PyUnicode_FromString(asByteArray.data());
+#ifdef IS_PY3K
+ } else if (typeObj == &PyLong_Type) {
+ float asFloat = out.toFloat();
+ pyResult = PyLong_FromDouble(asFloat);
+#else
+ } else if (typeObj == &PyInt_Type) {
+ float asFloat = out.toFloat();
+ pyResult = PyInt_FromLong(long(asFloat));
+#endif
+ } else if (typeObj == &PyFloat_Type) {
+ float asFloat = out.toFloat();
+ %PYARG_0 = PyFloat_FromDouble(asFloat);
+ }
+ // TODO: PyDict_Type and PyTuple_Type
+}
+else {
+ if (out == 0)
+ %PYARG_0 = Py_None;
+ else
+ %PYARG_0 = %CONVERTTOPYTHON[QVariant](out);
+}
+
+// @snippet qsettings-value
+
// @snippet qvariant-conversion
static const char *QVariant_resolveMetaType(PyTypeObject *type, int *typeId)
{
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index 294cdc91b..c732227f4 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -252,6 +252,10 @@ def generate_all_pyi(outpath, options):
from PySide2.support.signature import inspect
from PySide2.support.signature.lib.enum_sig import HintingEnumerator
+ # propagate USE_PEP563 to the mapping module.
+ # Perhaps this can be automated?
+ PySide2.support.signature.mapping.USE_PEP563 = USE_PEP563
+
outpath = outpath or os.path.dirname(PySide2.__file__)
name_list = PySide2.__all__ if options.modules == ["all"] else options.modules
errors = ", ".join(set(name_list) - set(PySide2.__all__))
diff --git a/sources/pyside2/tests/QtCore/CMakeLists.txt b/sources/pyside2/tests/QtCore/CMakeLists.txt
index 08e63d043..d05699f16 100644
--- a/sources/pyside2/tests/QtCore/CMakeLists.txt
+++ b/sources/pyside2/tests/QtCore/CMakeLists.txt
@@ -96,6 +96,7 @@ PYSIDE_TEST(qrect_test.py)
PYSIDE_TEST(qregexp_test.py)
PYSIDE_TEST(qregularexpression_test.py)
PYSIDE_TEST(qresource_test.py)
+PYSIDE_TEST(qsettings_test.py)
PYSIDE_TEST(qsize_test.py)
PYSIDE_TEST(qslot_object_test.py)
PYSIDE_TEST(qsocketnotifier_test.py)
diff --git a/sources/pyside2/tests/QtCore/qsettings_test.ini b/sources/pyside2/tests/QtCore/qsettings_test.ini
new file mode 100644
index 000000000..f54ae0029
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/qsettings_test.ini
@@ -0,0 +1,4 @@
+[General]
+var1=a, b, c
+var2=a
+
diff --git a/sources/pyside2/tests/QtCore/qsettings_test.py b/sources/pyside2/tests/QtCore/qsettings_test.py
new file mode 100644
index 000000000..6d64b0db3
--- /dev/null
+++ b/sources/pyside2/tests/QtCore/qsettings_test.py
@@ -0,0 +1,77 @@
+#############################################################################
+##
+## Copyright (C) 2019 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 QDate'''
+
+import unittest
+
+import os
+from helper import adjust_filename
+import py3kcompat as py3k
+from PySide2.QtCore import QSettings
+
+class TestQSettings(unittest.TestCase):
+ def testConversions(self):
+ file_path = adjust_filename('qsettings_test.ini', __file__)
+ settings = QSettings(file_path, QSettings.IniFormat)
+
+ r = settings.value('var1')
+ self.assertEqual(type(r), list)
+
+ r = settings.value('var2')
+ if py3k.IS_PY3K:
+ self.assertEqual(type(r), str)
+ else:
+ self.assertEqual(type(r), unicode)
+
+ r = settings.value('var2', type=list)
+ self.assertEqual(type(r), list)
+
+
+ def testDefaultValueConversion(self):
+ settings = QSettings('foo.ini', QSettings.IniFormat)
+ r = settings.value('lala', 22)
+ if py3k.IS_PY3K:
+ self.assertEqual(type(r), int)
+ else:
+ self.assertEqual(type(r), long)
+
+ r = settings.value('lala', 22, type=str)
+ self.assertEqual(type(r), str)
+
+ r = settings.value('lala', 22, type=bytes)
+ self.assertEqual(type(r), bytes)
+
+ r = settings.value('lala', 22, type=int)
+ self.assertEqual(type(r), int)
+
+ r = settings.value('lala', 22, type=float)
+ self.assertEqual(type(r), float)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/pyside2/tests/QtQml/CMakeLists.txt b/sources/pyside2/tests/QtQml/CMakeLists.txt
index e2beb951e..e2beb951e 100755..100644
--- a/sources/pyside2/tests/QtQml/CMakeLists.txt
+++ b/sources/pyside2/tests/QtQml/CMakeLists.txt
diff --git a/sources/pyside2/tests/QtQml/bug_1029.py b/sources/pyside2/tests/QtQml/bug_1029.py
index 92734cb3b..92734cb3b 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_1029.py
+++ b/sources/pyside2/tests/QtQml/bug_1029.py
diff --git a/sources/pyside2/tests/QtQml/bug_1029.qml b/sources/pyside2/tests/QtQml/bug_1029.qml
index 000a7568b..000a7568b 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_1029.qml
+++ b/sources/pyside2/tests/QtQml/bug_1029.qml
diff --git a/sources/pyside2/tests/QtQml/bug_451.py b/sources/pyside2/tests/QtQml/bug_451.py
index 5a6df7ff2..5a6df7ff2 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_451.py
+++ b/sources/pyside2/tests/QtQml/bug_451.py
diff --git a/sources/pyside2/tests/QtQml/bug_451.qml b/sources/pyside2/tests/QtQml/bug_451.qml
index 71bf691b4..71bf691b4 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_451.qml
+++ b/sources/pyside2/tests/QtQml/bug_451.qml
diff --git a/sources/pyside2/tests/QtQml/bug_456.py b/sources/pyside2/tests/QtQml/bug_456.py
index 9c94e76a6..9c94e76a6 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_456.py
+++ b/sources/pyside2/tests/QtQml/bug_456.py
diff --git a/sources/pyside2/tests/QtQml/bug_456.qml b/sources/pyside2/tests/QtQml/bug_456.qml
index 9b1b8c03c..9b1b8c03c 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_456.qml
+++ b/sources/pyside2/tests/QtQml/bug_456.qml
diff --git a/sources/pyside2/tests/QtQml/bug_557.py b/sources/pyside2/tests/QtQml/bug_557.py
index bc18ba2a2..bc18ba2a2 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_557.py
+++ b/sources/pyside2/tests/QtQml/bug_557.py
diff --git a/sources/pyside2/tests/QtQml/bug_726.py b/sources/pyside2/tests/QtQml/bug_726.py
index 20fa4d196..20fa4d196 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_726.py
+++ b/sources/pyside2/tests/QtQml/bug_726.py
diff --git a/sources/pyside2/tests/QtQml/bug_726.qml b/sources/pyside2/tests/QtQml/bug_726.qml
index 79f960243..79f960243 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_726.qml
+++ b/sources/pyside2/tests/QtQml/bug_726.qml
diff --git a/sources/pyside2/tests/QtQml/bug_814.py b/sources/pyside2/tests/QtQml/bug_814.py
index 31eada2df..31eada2df 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_814.py
+++ b/sources/pyside2/tests/QtQml/bug_814.py
diff --git a/sources/pyside2/tests/QtQml/bug_814.qml b/sources/pyside2/tests/QtQml/bug_814.qml
index 411896770..411896770 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_814.qml
+++ b/sources/pyside2/tests/QtQml/bug_814.qml
diff --git a/sources/pyside2/tests/QtQml/bug_825.py b/sources/pyside2/tests/QtQml/bug_825.py
index fe67f64b9..fe67f64b9 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_825.py
+++ b/sources/pyside2/tests/QtQml/bug_825.py
diff --git a/sources/pyside2/tests/QtQml/bug_825.qml b/sources/pyside2/tests/QtQml/bug_825.qml
index 6ae06d5b8..6ae06d5b8 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_825.qml
+++ b/sources/pyside2/tests/QtQml/bug_825.qml
diff --git a/sources/pyside2/tests/QtQml/bug_847.py b/sources/pyside2/tests/QtQml/bug_847.py
index c38278537..c38278537 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_847.py
+++ b/sources/pyside2/tests/QtQml/bug_847.py
diff --git a/sources/pyside2/tests/QtQml/bug_847.qml b/sources/pyside2/tests/QtQml/bug_847.qml
index 3833b1637..3833b1637 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_847.qml
+++ b/sources/pyside2/tests/QtQml/bug_847.qml
diff --git a/sources/pyside2/tests/QtQml/bug_915.py b/sources/pyside2/tests/QtQml/bug_915.py
index b0f231aee..b0f231aee 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_915.py
+++ b/sources/pyside2/tests/QtQml/bug_915.py
diff --git a/sources/pyside2/tests/QtQml/bug_926.py b/sources/pyside2/tests/QtQml/bug_926.py
index 6eef7b1a7..6eef7b1a7 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_926.py
+++ b/sources/pyside2/tests/QtQml/bug_926.py
diff --git a/sources/pyside2/tests/QtQml/bug_926.qml b/sources/pyside2/tests/QtQml/bug_926.qml
index 9217403a4..9217403a4 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_926.qml
+++ b/sources/pyside2/tests/QtQml/bug_926.qml
diff --git a/sources/pyside2/tests/QtQml/bug_951.py b/sources/pyside2/tests/QtQml/bug_951.py
index 38cf597ef..38cf597ef 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_951.py
+++ b/sources/pyside2/tests/QtQml/bug_951.py
diff --git a/sources/pyside2/tests/QtQml/bug_951.qml b/sources/pyside2/tests/QtQml/bug_951.qml
index 8242223f9..8242223f9 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_951.qml
+++ b/sources/pyside2/tests/QtQml/bug_951.qml
diff --git a/sources/pyside2/tests/QtQml/bug_995.py b/sources/pyside2/tests/QtQml/bug_995.py
index 7363f0e1b..7363f0e1b 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_995.py
+++ b/sources/pyside2/tests/QtQml/bug_995.py
diff --git a/sources/pyside2/tests/QtQml/bug_995.qml b/sources/pyside2/tests/QtQml/bug_995.qml
index 1369dcca6..1369dcca6 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_995.qml
+++ b/sources/pyside2/tests/QtQml/bug_995.qml
diff --git a/sources/pyside2/tests/QtQml/bug_997.py b/sources/pyside2/tests/QtQml/bug_997.py
index 45c777f8b..45c777f8b 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_997.py
+++ b/sources/pyside2/tests/QtQml/bug_997.py
diff --git a/sources/pyside2/tests/QtQml/bug_997.qml b/sources/pyside2/tests/QtQml/bug_997.qml
index f36a7e8f8..f36a7e8f8 100755..100644
--- a/sources/pyside2/tests/QtQml/bug_997.qml
+++ b/sources/pyside2/tests/QtQml/bug_997.qml
diff --git a/sources/pyside2/tests/QtQml/connect_python_qml.qml b/sources/pyside2/tests/QtQml/connect_python_qml.qml
index 249debf91..249debf91 100755..100644
--- a/sources/pyside2/tests/QtQml/connect_python_qml.qml
+++ b/sources/pyside2/tests/QtQml/connect_python_qml.qml
diff --git a/sources/pyside2/tests/QtQml/hw.qml b/sources/pyside2/tests/QtQml/hw.qml
index 8b086f31f..8b086f31f 100755..100644
--- a/sources/pyside2/tests/QtQml/hw.qml
+++ b/sources/pyside2/tests/QtQml/hw.qml
diff --git a/sources/pyside2/tests/QtQml/qqmlnetwork_test.py b/sources/pyside2/tests/QtQml/qqmlnetwork_test.py
index 3e6d1c2aa..3e6d1c2aa 100755..100644
--- a/sources/pyside2/tests/QtQml/qqmlnetwork_test.py
+++ b/sources/pyside2/tests/QtQml/qqmlnetwork_test.py
diff --git a/sources/pyside2/tests/QtQml/qquickview_test.py b/sources/pyside2/tests/QtQml/qquickview_test.py
index 62b20738f..62b20738f 100755..100644
--- a/sources/pyside2/tests/QtQml/qquickview_test.py
+++ b/sources/pyside2/tests/QtQml/qquickview_test.py
diff --git a/sources/pyside2/tests/QtQml/registertype.py b/sources/pyside2/tests/QtQml/registertype.py
index 5be65b7bd..5be65b7bd 100755..100644
--- a/sources/pyside2/tests/QtQml/registertype.py
+++ b/sources/pyside2/tests/QtQml/registertype.py
diff --git a/sources/pyside2/tests/QtQml/registertype.qml b/sources/pyside2/tests/QtQml/registertype.qml
index c41226016..c41226016 100755..100644
--- a/sources/pyside2/tests/QtQml/registertype.qml
+++ b/sources/pyside2/tests/QtQml/registertype.qml
diff --git a/sources/pyside2/tests/QtQml/signal_arguments.py b/sources/pyside2/tests/QtQml/signal_arguments.py
index 096fa6882..096fa6882 100755..100644
--- a/sources/pyside2/tests/QtQml/signal_arguments.py
+++ b/sources/pyside2/tests/QtQml/signal_arguments.py
diff --git a/sources/pyside2/tests/QtQml/view.qml b/sources/pyside2/tests/QtQml/view.qml
index dcc0076a0..dcc0076a0 100755..100644
--- a/sources/pyside2/tests/QtQml/view.qml
+++ b/sources/pyside2/tests/QtQml/view.qml
diff --git a/sources/pyside2/tests/QtQml/viewmodel.qml b/sources/pyside2/tests/QtQml/viewmodel.qml
index 61366a73e..61366a73e 100755..100644
--- a/sources/pyside2/tests/QtQml/viewmodel.qml
+++ b/sources/pyside2/tests/QtQml/viewmodel.qml
diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
index bb9b94a5b..4b31dbb05 100644
--- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp
@@ -1052,6 +1052,10 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
reason = AbstractMetaBuilder::GenerationDisabled;
}
if (reason != AbstractMetaBuilder::NoReason) {
+ if (fullClassName.isEmpty()) {
+ QTextStream(&fullClassName) << "anonymous struct at " << classItem->fileName()
+ << ':' << classItem->startLine();
+ }
m_rejectedClasses.insert(fullClassName, reason);
return nullptr;
}
diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp
index a6e75aac3..5b3a57fcc 100644
--- a/sources/shiboken2/ApiExtractor/messages.cpp
+++ b/sources/shiboken2/ApiExtractor/messages.cpp
@@ -311,6 +311,23 @@ QString msgCannotUseEnumAsInt(const QString &name)
"Compilation errors may occur when used as a function argument.");
}
+QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Types of receiver variable ('" << varType
+ << "') and %%CONVERTTOCPP type system variable ('" << conversionType
+ << "') differ";
+ QString strippedVarType = varType;
+ QString strippedConversionType = conversionType;
+ TypeInfo::stripQualifiers(&strippedVarType);
+ TypeInfo::stripQualifiers(&strippedConversionType);
+ if (strippedVarType == strippedConversionType)
+ str << " in qualifiers. Please make sure the type is a distinct token";
+ str << '.';
+ return result;
+}
+
// main.cpp
QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs)
diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h
index ab2bf64b6..2fee0de8f 100644
--- a/sources/shiboken2/ApiExtractor/messages.h
+++ b/sources/shiboken2/ApiExtractor/messages.h
@@ -115,6 +115,8 @@ QString msgCannotOpenForWriting(const QFile &f);
QString msgCannotUseEnumAsInt(const QString &name);
+QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType);
+
QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs);
QString msgInvalidVersion(const QString &package, const QString &version);
diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h
index 777b2d103..80db2cce5 100644
--- a/sources/shiboken2/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken2/ApiExtractor/parser/codemodel.h
@@ -287,6 +287,7 @@ public:
FileModelItem file() const;
void getStartPosition(int *line, int *column);
+ int startLine() const { return m_startLine; }
void setStartPosition(int line, int column);
void getEndPosition(int *line, int *column);
diff --git a/sources/shiboken2/doc/typesystemvariables.rst b/sources/shiboken2/doc/typesystemvariables.rst
index a07ba0d8c..b1b9bbfe6 100644
--- a/sources/shiboken2/doc/typesystemvariables.rst
+++ b/sources/shiboken2/doc/typesystemvariables.rst
@@ -126,6 +126,29 @@ Variables
Replaced by a |project| conversion call that converts a Python variable
to a C++ variable of the type indicated by ``CPPTYPE``.
+ Typically, this is a variable assignment:
+
+ .. code-block:: c++
+
+ double value = %CONVERTTOCPP[double](pyValue);
+
+ Pointer assignments are also possible:
+
+ .. code-block:: c++
+
+ void f(double *valuePtr)
+ {
+ *valuePtr = %CONVERTTOCPP[double](pyValue);
+
+ Note however, that for variable definitions, the type must
+ be a space-delimited token:
+
+ .. code-block:: c++
+
+ double * valuePtr = %CONVERTTOCPP[double](pyValue);
+
+ since it otherwise would be indistinguishable from the pointer assignment
+ above.
.. _converttopython:
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index 84f0cd1f5..e36b6edc3 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -3032,18 +3032,21 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
s << INDENT << "if (kwds) {" << endl;
{
Indentation indent(INDENT);
- s << INDENT << "PyObject *";
+ s << INDENT << "PyObject *keyName = nullptr;" << endl;
+ s << INDENT << "PyObject *value = nullptr;" << endl;
for (const AbstractMetaArgument *arg : args) {
int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex());
QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex) : QLatin1String(PYTHON_ARG);
- s << "value = PyDict_GetItemString(kwds, \"" << arg->name() << "\");" << endl;
+ s << INDENT << "keyName = Py_BuildValue(\"s\",\"" << arg->name() << "\");" << endl;
+ s << INDENT << "if (PyDict_Contains(kwds, keyName)) {" << endl;
+ s << INDENT << "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 << returnStatement(m_currentErrorCode) << endl;
}
- s << INDENT << "} else if (value) {" << endl;
+ s << INDENT << INDENT << "} else if (value) {" << endl;
{
Indentation indent(INDENT);
s << INDENT << pyArgName << " = value;" << endl;
@@ -3058,6 +3061,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe
s << INDENT << '}' << endl;
if (arg != args.constLast())
s << INDENT;
+ s << "}" << endl;
}
}
s << INDENT << '}' << endl;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index 8e27777d6..e41c91716 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -149,6 +149,8 @@ ShibokenGenerator::ShibokenGenerator()
const char CHECKTYPE_REGEX[] = R"(%CHECKTYPE\[([^\[]*)\]\()";
const char ISCONVERTIBLE_REGEX[] = R"(%ISCONVERTIBLE\[([^\[]*)\]\()";
const char CONVERTTOPYTHON_REGEX[] = R"(%CONVERTTOPYTHON\[([^\[]*)\]\()";
+ // Capture a '*' leading the variable name into the target
+ // so that "*valuePtr = %CONVERTTOCPP..." works as expected.
const char CONVERTTOCPP_REGEX[] =
R"((\*?%?[a-zA-Z_][\w\.]*(?:\[[^\[^<^>]+\])*)(?:\s+)=(?:\s+)%CONVERTTOCPP\[([^\[]*)\]\()";
m_typeSystemConvRegEx[TypeSystemCheckFunction] = QRegularExpression(QLatin1String(CHECKTYPE_REGEX));
@@ -2044,10 +2046,9 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
varType = miniNormalizer(varType);
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
- if (varType != conversionType->cppSignature()) {
- qFatal("Types of receiver variable ('%s') and %%CONVERTTOCPP type system variable ('%s') differ.",
- qPrintable(varType), qPrintable(conversionType->cppSignature()));
- }
+ const QString conversionSignature = conversionType->cppSignature();
+ if (varType != conversionSignature)
+ qFatal("%s", qPrintable(msgConversionTypesDiffer(varType, conversionSignature)));
c << getFullTypeName(conversionType) << ' ' << varName;
writeMinimalConstructorExpression(c, conversionType);
c << ';' << endl;
diff --git a/sources/shiboken2/shibokenmodule/CMakeLists.txt b/sources/shiboken2/shibokenmodule/CMakeLists.txt
index 09731240f..057a995f8 100644
--- a/sources/shiboken2/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken2/shibokenmodule/CMakeLists.txt
@@ -61,6 +61,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/
"${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/__init__.py" COPYONLY)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/enum_sig.py"
"${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/enum_sig.py" COPYONLY)
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/signature/lib/tool.py"
+ "${CMAKE_CURRENT_BINARY_DIR}/files.dir/shibokensupport/signature/lib/tool.py" COPYONLY)
if (PYTHON_VERSION_MAJOR EQUAL 3)
else()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/files.dir/shibokensupport/backport_inspect.py"
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
index c43d6d076..bd827f1ee 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -58,20 +58,7 @@ used literally as strings like "signature", "existence", etc.
from textwrap import dedent
from shibokensupport.signature import inspect
from shibokensupport.signature.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__
+from shibokensupport.signature.lib.tool import SimpleNamespace
class SignatureLayout(SimpleNamespace):
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
new file mode 100644
index 000000000..b34bfb404
--- /dev/null
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
@@ -0,0 +1,135 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import print_function, absolute_import
+
+"""
+tool.py
+
+Some useful stuff, see below.
+"""
+
+from textwrap import dedent
+
+
+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__
+
+try:
+ from types import SimpleNamespace
+except ImportError:
+ pass
+
+
+def build_brace_pattern(level, separators=""):
+ """
+ Build a brace pattern upto a given depth
+
+ The brace pattern parses any pattern with round, square, curly, or angle
+ brackets. Inside those brackets, any characters are allowed.
+
+ The structure is quite simple and is recursively repeated as needed.
+ When separators are given, the match stops at that separator.
+
+ Reason to use this instead of some Python function:
+ The resulting regex is _very_ fast!
+
+ A faster replacement would be written in C, but this solution is
+ sufficient when the nesting level is not too large.
+
+ Because of the recursive nature of the pattern, the size grows by a factor
+ of 4 at every level, as does the creation time. Up to a level of 6, this
+ is below 10 ms.
+
+ There are other regex engines available which allow recursive patterns,
+ avoiding this problem completely. It might be considered to switch to
+ such an engine if the external module is not a problem.
+ """
+ def escape(str):
+ return "".join("\\" + c for c in str)
+
+ ro, rc = round = "()"
+ so, sc = square = "[]"
+ co, cc = curly = "CD" # we insert "{}", later...
+ ao, ac = angle = "<>"
+ qu, bs = '"', "\\"
+ all = round + square + curly + angle
+ __ = " "
+ ro, rc, so, sc, co, cc, ao, ac, separators, qu, bs, all = map(
+ escape, (ro, rc, so, sc, co, cc, ao, ac, separators, qu, bs, all))
+
+ no_brace_sep_q = r"[^{all}{separators}{qu}{bs}]".format(**locals())
+ no_quote = r"(?: [^{qu}{bs}] | {bs}. )*".format(**locals())
+ pattern = dedent(r"""
+ (
+ (?: {__} {no_brace_sep_q}
+ | {qu} {no_quote} {qu}
+ | {ro} {replacer} {rc}
+ | {so} {replacer} {sc}
+ | {co} {replacer} {cc}
+ | {ao} {replacer} {ac}
+ )*
+ )
+ """)
+ no_braces_q = "[^{all}{qu}{bs}]*".format(**locals())
+ repeated = dedent(r"""
+ {indent} (?: {__} {no_braces_q}
+ {indent} | {qu} {no_quote} {qu}
+ {indent} | {ro} {replacer} {rc}
+ {indent} | {so} {replacer} {sc}
+ {indent} | {co} {replacer} {cc}
+ {indent} | {ao} {replacer} {ac}
+ {indent} )*
+ """)
+ for idx in range(level):
+ pattern = pattern.format(replacer = repeated if idx < level-1 else no_braces_q,
+ indent = idx * " ", **locals())
+ return pattern.replace("C", "{").replace("D", "}")
+
+# eof
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index 5f92446cf..b8097719a 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -61,24 +61,13 @@ class ellipsis(object):
return "..."
ellipsis = ellipsis()
-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
+StringList = typing.List[str]
-# First time installing our own Pair type into typing.
-T = TypeVar('T')
-S = TypeVar('S')
-
-class Pair(Generic[T, S]):
- __module__ = "typing"
-
-typing.Pair = Pair
-
+_S = TypeVar("_S")
# Building our own Char type, which is much nicer than
# Char = typing.Union[str, int] # how do I model the limitation to 1 char?
@@ -174,7 +163,12 @@ class _NotCalled(str):
text = self if self.endswith(")") else self + "()"
return eval(text, namespace)
-USE_PEP563 = sys.version_info[:2] >= (3, 7)
+USE_PEP563 = False
+# Note: we cannot know if this feature has been imported.
+# Otherwise it would be "sys.version_info[:2] >= (3, 7)".
+# We *can* eventually inspect sys.modules and look if
+# the calling module has this future statement set,
+# but should we do that?
# Some types are abstract. They just show their name.
@@ -183,10 +177,11 @@ class Virtual(_NotCalled):
# Other types I simply could not find.
class Missing(_NotCalled):
- if not USE_PEP563:
- # The string must be quoted, because the object does not exist.
- def __repr__(self):
- return '{}("{}")'.format(type(self).__name__, self)
+ # The string must be quoted, because the object does not exist.
+ def __repr__(self):
+ if USE_PEP563:
+ return _NotCalled.__repr__(self)
+ return '{}("{}")'.format(type(self).__name__, self)
class Invalid(_NotCalled):
@@ -260,20 +255,76 @@ type_map = {}
namespace = globals() # our module's __dict__
type_map.update({
+ "bool": bool,
+ "char": Char,
+ "char*": str,
+ "char*const": str,
+ "double": float,
+ "float": float,
+ "int": int,
+ "List": typing.List,
+ "long": int,
+ "PyCallable": typing.Callable,
+ "PyObject": object,
+ "PySequence": typing.Iterable, # important for numpy
+ "PyTypeObject": type,
+ "QChar": Char,
+ "QHash": typing.Dict,
+ "qint16": int,
+ "qint32": int,
+ "qint64": int,
+ "qint8": int,
+ "qintptr": int,
"QList": typing.List,
- "QVector": typing.List,
- "QSet": typing.Set,
- "QPair": Pair,
+ "qlonglong": int,
"QMap": typing.Dict,
+ "QPair": typing.Tuple,
+ "qptrdiff": int,
+ "qreal": float,
+ "QSet": typing.Set,
+ "QString": str,
+ "QStringList": StringList,
+ "quint16": int,
+ "quint32": int,
+ "quint32": int,
+ "quint64": int,
+ "quint8": int,
+ "quintptr": int,
+ "qulonglong": int,
+ "QVariant": Variant,
+ "QVector": typing.List,
+ "real": float,
+ "short": int,
+ "signed char": Char,
+ "signed long": int,
+ "str": str,
+ "true": True,
+ "ULONG_MAX": ulong_max,
+ "unsigned char": Char,
+ "unsigned int": int, # should we define an unsigned type?
+ "unsigned long int": int, # 5.6, RHEL 6.6
+ "unsigned long long": int,
+ "unsigned long": int,
+ "unsigned short int": int, # 5.6, RHEL 6.6
+ "unsigned short": int,
+ "UnsignedShortType": int, # 5.9
+ "void": int, # be more specific?
+ "WId": WId,
+ "zero(bytes)": b"",
+ "zero(Char)": 0,
+ "zero(float)": 0,
+ "zero(int)": 0,
+ "zero(object)": None,
+ "zero(str)": "",
})
# The Shiboken Part
def init_Shiboken():
type_map.update({
+ "PyType": type,
"shiboken2.bool": bool,
"size_t": int,
- "PyType": type,
})
return locals()
@@ -288,36 +339,32 @@ def init_minimal():
def init_sample():
import datetime
type_map.update({
- "double": float,
- "sample.int": int,
+ "char": Char,
"Complex": complex,
- "sample.OddBool": bool,
- "sample.bool": bool,
- "sample.PStr": str,
+ "double": float,
+ "Foo.HANDLE": int,
+ "HANDLE": int,
+ "Null": None,
+ "ObjectType.Identifier": Missing("sample.ObjectType.Identifier"),
"OddBool": bool,
"PStr": str,
- "char": Char,
+ "PyDate": datetime.date,
+ "sample.bool": bool,
"sample.char": Char,
- "sample.Point": Point,
+ "sample.double": float,
+ "sample.int": int,
"sample.ObjectType": object,
- "std.string": str,
- "HANDLE": int,
- "Foo.HANDLE": int,
+ "sample.OddBool": bool,
"sample.Photon.TemplateBase": Missing("sample.Photon.TemplateBase"),
- "ObjectType.Identifier": Missing("sample.ObjectType.Identifier"),
- "zero(HANDLE)": 0,
- "Null": None,
- "zero(sample.ObjectType)": None,
+ "sample.Point": Point,
+ "sample.PStr": str,
+ "sample.unsigned char": Char,
"std.size_t": int,
- 'Str("<unknown>")': "<unknown>",
+ "std.string": str,
+ "ZeroIn": 0,
'Str("<unk")': "<unk",
+ 'Str("<unknown>")': "<unknown>",
'Str("nown>")': "nown>",
- "zero(sample.ObjectModel)": None,
- "sample.unsigned char": Char,
- "sample.double": float,
- "zero(sample.bool)": False,
- "PyDate": datetime.date,
- "ZeroIn": 0,
})
return locals()
@@ -325,15 +372,20 @@ def init_sample():
def init_other():
import numbers
type_map.update({
- "other.Number": numbers.Number,
"other.ExtendsNoImplicitConversion": Missing("other.ExtendsNoImplicitConversion"),
+ "other.Number": numbers.Number,
})
return locals()
def init_smart():
+ # This missing type should be defined in module smart. We cannot set it to Missing()
+ # because it is a container type. Therefore, we supply a surrogate:
+ global SharedPtr
+ class SharedPtr(Generic[_S]):
+ __module__ = "smart"
+ smart.SharedPtr = SharedPtr
type_map.update({
- "smart.SharedPtr": Missing("smart.SharedPtr"), # bad object "SharedPtr<Obj >"
"smart.Smart.Integer2": int,
})
return locals()
@@ -349,131 +401,88 @@ def init_PySide2_QtCore():
except ImportError:
pass
type_map.update({
- "str": str,
- "int": int,
- "QString": str,
- "bool": bool,
- "PyObject": object,
- "void": int, # be more specific?
- "char": Char,
- "'%'": "%",
"' '": " ",
- "false": False,
- "double": float,
+ "'%'": "%",
"'g'": "g",
+ "4294967295UL": 4294967295, # 5.6, RHEL 6.6
+ "CheckIndexOption.NoOption": Instance(
+ "PySide2.QtCore.QAbstractItemModel.CheckIndexOptions.NoOption"), # 5.11
+ "false": False,
+ "list of QAbstractAnimation": typing.List[PySide2.QtCore.QAbstractAnimation],
+ "list of QAbstractState": typing.List[PySide2.QtCore.QAbstractState],
"long long": int,
- "unsigned int": int, # should we define an unsigned type?
- "Q_NULLPTR": None,
"long": int,
- "float": float,
- "short": int,
- "unsigned long": int,
- "unsigned long long": int,
- "unsigned short": int,
- "QStringList": StringList,
- "QChar": Char,
- "signed char": Char,
- "QVariant": Variant,
- "QVariant.Type": type, # not so sure here...
- "QStringRef": str,
- "QString()": "",
- "QModelIndexList": ModelIndexList,
- "unsigned char": Char,
- "QJsonObject": typing.Dict[str, PySide2.QtCore.QJsonValue],
- "QStringList()": [],
- "ULONG_MAX": ulong_max,
- "quintptr": int,
+ "NULL": None, # 5.6, MSVC
+ "nullptr": None, # 5.9
+ "PyByteArray": bytearray,
+ "PyBytes": bytes,
"PyCallable": typing.Callable,
- "PyTypeObject": type,
+ "PyObject": object,
"PySequence": typing.Iterable, # important for numpy
- "qptrdiff": int,
- "true": True,
- "Qt.HANDLE": int, # be more explicit with some consts?
- "list of QAbstractState": typing.List[PySide2.QtCore.QAbstractState],
- "list of QAbstractAnimation": typing.List[PySide2.QtCore.QAbstractAnimation],
- "QVariant()": Invalid(Variant),
"PySide2.QtCore.bool": bool,
- "QHash": typing.Dict,
- "PySide2.QtCore.QChar": Char,
- "PySide2.QtCore.qreal": float,
+ "PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
+ "PySide2.QtCore.double": float,
"PySide2.QtCore.float": float,
+ "PySide2.QtCore.int": int,
+ "PySide2.QtCore.int32_t": int, # 5.9
+ "PySide2.QtCore.int64_t": int, # 5.9
+ "PySide2.QtCore.long long": int, # 5.9, MSVC 15
+ "PySide2.QtCore.long": int,
+ "PySide2.QtCore.QCborStreamReader.StringResult": typing.AnyStr,
+ "PySide2.QtCore.QChar": Char,
"PySide2.QtCore.qint16": int,
"PySide2.QtCore.qint32": int,
"PySide2.QtCore.qint64": int,
"PySide2.QtCore.qint8": int,
+ "PySide2.QtCore.qreal": float,
"PySide2.QtCore.QString": str,
"PySide2.QtCore.QStringList": StringList,
- "PySide2.QtCore.QVariant": Variant,
"PySide2.QtCore.quint16": int,
"PySide2.QtCore.quint32": int,
"PySide2.QtCore.quint64": int,
"PySide2.QtCore.quint8": int,
+ "PySide2.QtCore.QUrl.ComponentFormattingOptions":
+ PySide2.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
+ "PySide2.QtCore.QVariant": Variant,
"PySide2.QtCore.short": int,
- "PySide2.QtCore.unsigned short": int,
"PySide2.QtCore.signed char": Char,
"PySide2.QtCore.uchar": Char,
+ "PySide2.QtCore.uint32_t": int, # 5.9
"PySide2.QtCore.unsigned char": Char, # 5.9
- "PySide2.QtCore.long": int,
- "PySide2.QtCore.QUrl.ComponentFormattingOptions":
- PySide2.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
- "QUrl.FormattingOptions(PrettyDecoded)": Instance(
- "QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
- # from 5.9
+ "PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
+ "PySide2.QtCore.unsigned short": int,
+ "PyTypeObject": type,
+ "PyUnicode": typing.Text,
+ "Q_NULLPTR": None,
+ "QChar": Char,
"QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
"QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
- "NULL": None, # 5.6, MSVC
"QDir.SortFlags(Name | IgnoreCase)": Instance(
"QDir.SortFlags(QDir.Name | QDir.IgnoreCase)"),
- "PyBytes": bytes,
- "PyByteArray": bytearray,
- "PyUnicode": typing.Text,
- "signed long": int,
- "PySide2.QtCore.int": int,
- "PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
- "unsigned long int": int, # 5.6, RHEL 6.6
- "unsigned short int": int, # 5.6, RHEL 6.6
- "4294967295UL": 4294967295, # 5.6, RHEL 6.6
- "PySide2.QtCore.int32_t": int, # 5.9
- "PySide2.QtCore.int64_t": int, # 5.9
- "UnsignedShortType": int, # 5.9
- "nullptr": None, # 5.9
- "uint64_t": int, # 5.9
- "PySide2.QtCore.uint32_t": int, # 5.9
- "PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
- "PySide2.QtCore.long long": int, # 5.9, MSVC 15
- "QGenericArgument(nullptr)": ellipsis, # 5.10
- "QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
"QGenericArgument((0))": ellipsis, # 5.6, RHEL 6.6. Is that ok?
"QGenericArgument()": ellipsis,
"QGenericArgument(0)": ellipsis,
"QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
+ "QGenericArgument(nullptr)": ellipsis, # 5.10
"QGenericArgument(Q_NULLPTR)": ellipsis,
- "zero(PySide2.QtCore.QObject)": None,
- "zero(PySide2.QtCore.QThread)": None,
- "zero(quintptr)": 0,
- "zero(str)": "",
- "zero(int)": 0,
- "zero(PySide2.QtCore.QState)": None,
- "zero(PySide2.QtCore.bool)": False,
- "zero(PySide2.QtCore.int)": 0,
- "zero(void)": None,
- "zero(long long)": 0,
- "zero(PySide2.QtCore.QAbstractItemModel)": None,
- "zero(PySide2.QtCore.QJsonParseError)": None,
- "zero(double)": 0.0,
- "zero(PySide2.QtCore.qint64)": 0,
- "zero(PySide2.QtCore.QTextCodec.ConverterState)": None,
- "zero(long long)": 0,
- "zero(QImageCleanupFunction)": None,
- "zero(unsigned int)": 0,
- "zero(PySide2.QtCore.QPoint)": Default("PySide2.QtCore.QPoint"),
- "zero(unsigned char)": 0,
- "zero(PySide2.QtCore.QEvent.Type)": None,
- "CheckIndexOption.NoOption": Instance(
- "PySide2.QtCore.QAbstractItemModel.CheckIndexOptions.NoOption"), # 5.11
+ "QHash": typing.Dict,
+ "QJsonObject": typing.Dict[str, PySide2.QtCore.QJsonValue],
+ "QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
+ "QModelIndexList": ModelIndexList,
+ "qptrdiff": int,
+ "QString": str,
+ "QString()": "",
+ "QStringList": StringList,
+ "QStringList()": [],
+ "QStringRef": str,
+ "Qt.HANDLE": int, # be more explicit with some consts?
+ "quintptr": int,
+ "QUrl.FormattingOptions(PrettyDecoded)": Instance(
+ "QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
+ "QVariant": Variant,
+ "QVariant()": Invalid(Variant),
+ "QVariant.Type": type, # not so sure here...
"QVariantMap": typing.Dict[str, Variant],
- "PySide2.QtCore.QCborStreamReader.StringResult": typing.AnyStr,
- "PySide2.QtCore.double": float,
})
try:
type_map.update({
@@ -488,29 +497,21 @@ def init_PySide2_QtCore():
def init_PySide2_QtGui():
from PySide2.QtGui import QPageLayout, QPageSize # 5.12 macOS
type_map.update({
- "QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
- "USHRT_MAX": ushort_max,
"0.0f": 0.0,
"1.0f": 1.0,
- "uint32_t": int,
- "uint8_t": int,
- "int32_t": int,
"GL_COLOR_BUFFER_BIT": GL_COLOR_BUFFER_BIT,
"GL_NEAREST": GL_NEAREST,
- "WId": WId,
+ "int32_t": int,
+ "PySide2.QtCore.uint8_t": int, # macOS 5.9
+ "PySide2.QtGui.QGenericMatrix": Missing("PySide2.QtGui.QGenericMatrix"),
"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
- "zero(uint32_t)": 0,
- "zero(PySide2.QtGui.QWindow)": None,
- "zero(PySide2.QtGui.QOpenGLContext)": None,
- "zero(PySide2.QtGui.QRegion)": None,
- "zero(PySide2.QtGui.QPaintDevice)": None,
- "zero(PySide2.QtGui.QTextLayout.FormatRange)": None,
- "zero(PySide2.QtGui.QTouchDevice)": None,
- "zero(PySide2.QtGui.QScreen)": None,
- "PySide2.QtGui.QGenericMatrix": Missing("PySide2.QtGui.QGenericMatrix"),
+ "QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
+ "uint32_t": int,
+ "uint8_t": int,
+ "USHRT_MAX": ushort_max,
+ "WId": WId,
})
return locals()
@@ -521,28 +522,15 @@ def init_PySide2_QtWidgets():
type_map.update({
"QMessageBox.StandardButtons(Yes | No)": Instance(
"QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No)"),
+ "QVector< int >()": [],
"QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": Instance(
"QWidget.RenderFlags(QWidget.DrawWindowBackground | QWidget.DrawChildren)"),
+ "SH_Default": QStyleHintReturn.SH_Default,
+ "SO_Complex": QStyleOptionComplex.SO_Complex,
+ "SO_Default": QStyleOption.SO_Default,
"static_cast<Qt.MatchFlags>(Qt.MatchExactly|Qt.MatchCaseSensitive)": Instance(
"Qt.MatchFlags(Qt.MatchExactly | Qt.MatchCaseSensitive)"),
- "QVector< int >()": [],
- "WId": WId,
- # from 5.9
"Type": PySide2.QtWidgets.QListWidgetItem.Type,
- "SO_Default": QStyleOption.SO_Default,
- "SH_Default": QStyleHintReturn.SH_Default,
- "SO_Complex": QStyleOptionComplex.SO_Complex,
- "zero(PySide2.QtWidgets.QWidget)": None,
- "zero(PySide2.QtWidgets.QGraphicsItem)": None,
- "zero(PySide2.QtCore.QEvent)": None,
- "zero(PySide2.QtWidgets.QStyleOption)": None,
- "zero(PySide2.QtWidgets.QStyleHintReturn)": None,
- "zero(PySide2.QtWidgets.QGraphicsLayoutItem)": None,
- "zero(PySide2.QtWidgets.QListWidget)": None,
- "zero(PySide2.QtGui.QKeySequence)": None,
- "zero(PySide2.QtWidgets.QAction)": None,
- "zero(PySide2.QtWidgets.QUndoCommand)": None,
- "zero(WId)": 0,
})
return locals()
@@ -559,9 +547,6 @@ def init_PySide2_QtSql():
def init_PySide2_QtNetwork():
type_map.update({
"QMultiMap": MultiMap,
- "zero(unsigned short)": 0,
- "zero(PySide2.QtCore.QIODevice)": None,
- "zero(QList)": [],
})
return locals()
@@ -569,8 +554,8 @@ def init_PySide2_QtNetwork():
def init_PySide2_QtXmlPatterns():
from PySide2.QtXmlPatterns import QXmlName
type_map.update({
+ "QXmlName.NamespaceCode": Missing("PySide2.QtXmlPatterns.QXmlName.NamespaceCode"),
"QXmlName.PrefixCode": Missing("PySide2.QtXmlPatterns.QXmlName.PrefixCode"),
- "QXmlName.NamespaceCode": Missing("PySide2.QtXmlPatterns.QXmlName.NamespaceCode")
})
return locals()
@@ -588,39 +573,31 @@ def init_PySide2_QtMultimedia():
def init_PySide2_QtOpenGL():
type_map.update({
- "GLuint": int,
+ "GLbitfield": int,
"GLenum": int,
+ "GLfloat": float, # 5.6, MSVC 15
"GLint": int,
- "GLbitfield": int,
+ "GLuint": int,
"PySide2.QtOpenGL.GLint": int,
"PySide2.QtOpenGL.GLuint": int,
- "GLfloat": float, # 5.6, MSVC 15
- "zero(PySide2.QtOpenGL.QGLContext)": None,
- "zero(GLenum)": 0,
- "zero(PySide2.QtOpenGL.QGLWidget)": None,
})
return locals()
def init_PySide2_QtQml():
type_map.update({
- "QJSValueList()": [],
"PySide2.QtQml.bool volatile": bool,
- # from 5.9
+ "QJSValueList()": [],
"QVariantHash()": typing.Dict[str, Variant], # XXX sorted?
- "zero(PySide2.QtQml.QQmlContext)": None,
- "zero(PySide2.QtQml.QQmlEngine)": None,
})
return locals()
def init_PySide2_QtQuick():
type_map.update({
- "PySide2.QtQuick.QSharedPointer": int,
"PySide2.QtCore.uint": int,
+ "PySide2.QtQuick.QSharedPointer": int,
"T": int,
- "zero(PySide2.QtQuick.QQuickItem)": None,
- "zero(GLuint)": 0,
})
return locals()
@@ -638,13 +615,6 @@ def init_PySide2_QtTest():
})
return locals()
-# from 5.9
-def init_PySide2_QtWebEngineWidgets():
- type_map.update({
- "zero(PySide2.QtWebEngineWidgets.QWebEnginePage.FindFlags)": 0,
- })
- return locals()
-
# from 5.6, MSVC
def init_PySide2_QtWinExtras():
type_map.update({
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 72ca35757..6109bceee 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -47,6 +47,8 @@ import keyword
import functools
from shibokensupport.signature.mapping import (type_map, update_mapping,
namespace, typing, _NotCalled)
+from shibokensupport.signature.lib.tool import (SimpleNamespace,
+ build_brace_pattern)
_DEBUG = False
LIST_KEYWORDS = False
@@ -78,6 +80,23 @@ def dprint(*args, **kw):
pprint.pprint(arg)
sys.stdout.flush()
+
+_cache = {}
+
+def _parse_arglist(argstr):
+ # The following is a split re. The string is broken into pieces which are
+ # between the recognized strings. Because the re has groups, both the
+ # strings and the separators are returned, where the strings are not
+ # interesting at all: They are just the commata.
+ key = "_parse_arglist"
+ if key not in _cache:
+ regex = build_brace_pattern(level=3, separators=",")
+ _cache[key] = re.compile(regex, flags=re.VERBOSE)
+ split = _cache[key].split
+ # Note: this list is interspersed with "," and surrounded by ""
+ return [x.strip() for x in split(argstr) if x.strip() not in ("", ",")]
+
+
def _parse_line(line):
line_re = r"""
((?P<multi> ([0-9]+)) : )? # the optional multi-index
@@ -86,38 +105,9 @@ def _parse_line(line):
( -> (?P<returntype> .*) )? # the optional return type
$
"""
- ret = re.match(line_re, line, re.VERBOSE).groupdict()
- arglist = ret["arglist"]
- # The following is a split re. The string is broken into pieces which are
- # between the recognized strings. Because the re has groups, both the
- # strings and the delimiters are returned, where the strings are not
- # interesting at all: They are just the commata.
- # Note that it is necessary to put the characters with special handling in
- # the first group (comma, brace, angle bracket).
- # Then they are not recognized there, and we can handle them differently
- # in the following expressions.
- arglist = list(x.strip() for x in re.split(r"""
- (
- (?: # inner group is not capturing
- [^,()<>] # no commas or braces or angle brackets
- |
- \(
- (?:
- [^()]* # or one brace pair
- |
- \(
- [^()]* # or doubls nested pair
- \)
- )*
- \)
- |
- < # or one angle bracket pair
- [^<>]*
- >
- )+ # longest possible span
- ) # this list is interspersed with "," and surrounded by ""
- """, arglist, flags=re.VERBOSE)
- if x.strip() not in ("", ","))
+ ret = SimpleNamespace(**re.match(line_re, line, re.VERBOSE).groupdict())
+ argstr = ret.arglist
+ arglist = _parse_arglist(argstr)
args = []
for arg in arglist:
name, ann = arg.split(":")
@@ -131,15 +121,16 @@ def _parse_line(line):
else:
tup = name, ann
args.append(tup)
- ret["arglist"] = args
- multi = ret["multi"]
+ ret.arglist = args
+ multi = ret.multi
if multi is not None:
- ret["multi"] = int(multi)
- funcname = ret["funcname"]
+ ret.multi = int(multi)
+ funcname = ret.funcname
parts = funcname.split(".")
if parts[-1] in keyword.kwlist:
- ret["funcname"] = funcname + "_"
- return ret
+ ret.funcname = funcname + "_"
+ return vars(ret)
+
def make_good_value(thing, valtype):
try:
@@ -153,6 +144,7 @@ def make_good_value(thing, valtype):
except Exception:
pass
+
def try_to_guess(thing, valtype):
if "." not in thing and "(" not in thing:
text = "{}.{}".format(valtype, thing)
@@ -172,9 +164,13 @@ def try_to_guess(thing, valtype):
return ret
return None
+
def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
- thing = "zero({})".format(valtype)
+ if valtype.startswith("PySide2."):
+ return None
+ name = type_map[valtype].__name__
+ thing = "zero({})".format(name)
if thing in type_map:
return type_map[thing]
res = make_good_value(thing, valtype)
@@ -192,40 +188,88 @@ def _resolve_value(thing, valtype, line):
""".format(thing, line), RuntimeWarning)
return thing
+
def _resolve_arraytype(thing, line):
- thing = thing[:-2]
- if thing.endswith("[]"):
+ search = re.search(r"\[(\d*)\]$", thing)
+ thing = thing[:search.start()]
+ if thing.endswith("]"):
thing = _resolve_arraytype(thing, line)
- # this mapping is in shiboken
- thing = "QList[" + thing + "]"
+ if search.group(1):
+ # concrete array, use a tuple
+ nelem = int(search.group(1))
+ thing = ", ".join([thing] * nelem)
+ thing = "Tuple[" + thing + "]"
+ else:
+ thing = "QList[" + thing + "]"
return thing
+
def to_string(thing):
if isinstance(thing, str):
return thing
if hasattr(thing, "__name__"):
- dot = "." in str(type(thing))
+ dot = "." in str(thing)
return thing.__module__ + "." + thing.__name__ if dot else thing.__name__
# Note: This captures things from the typing module:
return str(thing)
-def _resolve_type(thing, line):
- if thing.endswith("[]"):
- thing = _resolve_arraytype(thing, line)
+
+matrix_pattern = "PySide2.QtGui.QGenericMatrix"
+
+# The matrix patch is borrowed from the future (extracted).
+# It will work when the parser recognizes matrices.
+def handle_matrix(arg):
+ n, m, typstr = tuple(map(lambda x:x.strip(), arg.split(",")))
+ assert typstr == "float"
+ result = "PySide2.QtGui.QMatrix{n}x{m}".format(**locals())
+ return eval(result, namespace)
+
+
+debugging_aid = """
+from inspect import currentframe
+
+def lno(level):
+ lineno = currentframe().f_back.f_lineno
+ spaces = level * " "
+ return "{lineno}{spaces}".format(**locals())
+"""
+
+
+def _resolve_type(thing, line, level):
+ # Capture total replacements, first. Happens in
+ # "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]"
+ if thing in type_map:
+ return type_map[thing]
+ # Now the nested structures are handled.
if "[" in thing:
+ # handle primitive arrays
+ if re.search(r"\[\d*\]$", thing):
+ thing = _resolve_arraytype(thing, line)
# Handle a container return type. (see PYSIDE-921 in cppgenerator.cpp)
contr, thing = re.match(r"(.*?)\[(.*?)\]$", thing).groups()
- contr = to_string(_resolve_type(contr, line))
- thing = to_string(_resolve_type(thing, line))
+ # Special case: Handle the generic matrices.
+ if contr == matrix_pattern:
+ return handle_matrix(thing)
+ contr = _resolve_type(contr, line, level+1)
+ if isinstance(contr, _NotCalled):
+ raise SystemError("Container types must exist:", repr(contr))
+ contr = to_string(contr)
+ pieces = []
+ for part in _parse_arglist(thing):
+ part = _resolve_type(part, line, level+1)
+ if isinstance(part, _NotCalled):
+ # fix the tag (i.e. "Missing") by repr
+ part = repr(part)
+ pieces.append(to_string(part))
+ thing = ", ".join(pieces)
result = "{contr}[{thing}]".format(**locals())
- if not isinstance(thing, _NotCalled):
- result = eval(result, namespace)
- return result
+ return eval(result, namespace)
return _resolve_value(thing, None, line)
+
def calculate_props(line):
- res = _parse_line(line)
- arglist = res["arglist"]
+ parsed = SimpleNamespace(**_parse_line(line.strip()))
+ arglist = parsed.arglist
annotations = {}
_defaults = []
for idx, tup in enumerate(arglist):
@@ -236,27 +280,33 @@ def calculate_props(line):
ann = 'NULL' # maps to None
tup = name, ann
arglist[idx] = tup
- annotations[name] = _resolve_type(ann, line)
+ annotations[name] = _resolve_type(ann, line, 0)
if len(tup) == 3:
default = _resolve_value(tup[2], ann, line)
_defaults.append(default)
defaults = tuple(_defaults)
- returntype = res["returntype"]
+ returntype = parsed.returntype
if returntype is not None:
- annotations["return"] = _resolve_type(returntype, line)
- props = {}
- props["defaults"] = defaults
- props["kwdefaults"] = {}
- props["annotations"] = annotations
- props["varnames"] = varnames = tuple(tup[0] for tup in arglist)
- funcname = res["funcname"]
- props["fullname"] = funcname
+ annotations["return"] = _resolve_type(returntype, line, 0)
+ props = SimpleNamespace()
+ props.defaults = defaults
+ props.kwdefaults = {}
+ props.annotations = annotations
+ props.varnames = varnames = tuple(tup[0] for tup in arglist)
+ funcname = parsed.funcname
+ props.fullname = funcname
shortname = funcname[funcname.rindex(".")+1:]
- props["name"] = shortname
- props["multi"] = res["multi"]
- return props
+ props.name = shortname
+ props.multi = parsed.multi
+ return vars(props)
+
def fixup_multilines(lines):
+ """
+ Multilines can collapse when certain distinctions between C++ types
+ vanish after mapping to Python.
+ This function fixes this by re-computing multiline-ness.
+ """
res = []
multi_lines = []
for line in lines:
@@ -280,6 +330,7 @@ def fixup_multilines(lines):
res.append(line)
return res
+
def pyside_type_init(type_key, sig_strings):
dprint()
dprint("Initialization of type key '{}'".format(type_key))
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py
index dba8f8c77..786a84ecb 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py
@@ -1996,6 +1996,21 @@ class DefaultDict(collections.defaultdict, MutableMapping[KT, VT]):
return _generic_new(collections.defaultdict, cls, *args, **kwds)
+############################
+# Insertion by CT 2019-02-21
+#
+class OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]):
+ __slots__ = ()
+ __extra__ = collections.OrderedDict
+
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is OrderedDict:
+ return collections.OrderedDict(*args, **kwds)
+ return _generic_new(collections.OrderedDict, cls, *args, **kwds)
+#
+############################
+
+
class Counter(collections.Counter, Dict[T, int]):
__slots__ = ()
__extra__ = collections.Counter
diff --git a/sources/shiboken2/tests/minimalbinding/brace_pattern_test.py b/sources/shiboken2/tests/minimalbinding/brace_pattern_test.py
new file mode 100644
index 000000000..89df998e8
--- /dev/null
+++ b/sources/shiboken2/tests/minimalbinding/brace_pattern_test.py
@@ -0,0 +1,121 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: https://www.qt.io/licensing/
+##
+## This file is part of Qt for Python.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and The Qt Company. For licensing terms
+## and conditions see https://www.qt.io/terms-conditions. For further
+## information use the contact form at https://www.qt.io/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 3 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL3 included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 3 requirements
+## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+##
+## GNU General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU
+## General Public License version 2.0 or (at your option) the GNU General
+## Public license version 3 or any later version approved by the KDE Free
+## Qt Foundation. The licenses are as published by the Free Software
+## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+## included in the packaging of this file. Please review the following
+## information to ensure the GNU General Public License requirements will
+## be met: https://www.gnu.org/licenses/gpl-2.0.html and
+## https://www.gnu.org/licenses/gpl-3.0.html.
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from __future__ import absolute_import, print_function
+
+import re
+import sys
+import os
+
+import shiboken2
+type.__signature__ # trigger bootstrap
+
+from shibokensupport.signature.lib.tool import build_brace_pattern
+import unittest
+
+"""
+This test tests the brace pattern from signature.lib.tool
+against a slower reference implementation.
+The pattern is crucial, because it is used heavily in signature.parser .
+"""
+
+# A slow reference parser for braces and strings
+def check(s):
+ open, close = "[{(<", "]})>"
+ escape, quote = "\\", '"'
+ instring = blind = False
+ stack = []
+ for c in s:
+ if instring:
+ if blind:
+ blind = False
+ elif c == escape:
+ blind = True
+ elif c == quote:
+ instring = False
+ stack.pop()
+ continue
+ if c in open:
+ stack.append(c)
+ elif c in close:
+ pos = close.index(c)
+ if ((len(stack) > 0) and
+ (open[pos] == stack[len(stack)-1])):
+ stack.pop()
+ else:
+ return False
+ elif c == escape:
+ return False
+ elif c == quote:
+ instring = True
+ stack.append(c)
+ return len(stack) == 0
+
+
+class TestBracePattern(unittest.TestCase):
+ tests = [
+ (r'{[]{()}}', True),
+ (r'[{}{})(]', False),
+ (r'[{}{} ")(" ]', True),
+ (r'[{}{} ")(\" ]', False),
+ (r'[{}{} ")(\" ]"]', True),
+ (r'a < b ( c [ d { "} \"\"}" } ] ) >', True),
+ (r'a < b ( c [ d { } ] ) >', True),
+ (r'a < b ( c [ d { "huh" } ] ) >', True),
+ (r'a < b ( c [ d { "huh\" \" \\\"" } ] ) >', True),
+ ]
+
+ def test_checkfunc(self):
+ for test, result in self.tests:
+ if result:
+ self.assertTrue(check(test))
+ else:
+ self.assertFalse(check(test))
+
+ def test_the_brace_pattern(self):
+ func = re.compile(build_brace_pattern(5) + "$", re.VERBOSE).match
+ for test, result in self.tests:
+ if result:
+ self.assertTrue(func(test))
+ else:
+ self.assertFalse(func(test))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/testing/wheel_tester.py b/testing/wheel_tester.py
index 180526b33..535cb3712 100644
--- a/testing/wheel_tester.py
+++ b/testing/wheel_tester.py
@@ -53,6 +53,7 @@ directory (e.g. setup.py bdist_wheel was already executed).
"""
from __future__ import print_function, absolute_import
+from argparse import ArgumentParser, RawTextHelpFormatter
import os, sys
try:
@@ -327,12 +328,13 @@ def try_build_examples():
run_make()
-def run_wheel_tests():
+def run_wheel_tests(install_wheels):
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)
+ if install_wheels:
+ log.info("Attempting to install wheels.\n")
+ try_install_wheels(wheels_dir, py_version)
log.info("Attempting to build examples.\n")
try_build_examples()
@@ -341,4 +343,10 @@ def run_wheel_tests():
if __name__ == "__main__":
- run_wheel_tests()
+ parser = ArgumentParser(description="wheel_tester",
+ formatter_class=RawTextHelpFormatter)
+ parser.add_argument('--no-install-wheels', '-n', action='store_true',
+ help='Do not install wheels'
+ ' (for developer builds with virtualenv)')
+ options = parser.parse_args()
+ run_wheel_tests(not options.no_install_wheels)