aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ez_setup.py2
-rw-r--r--sources/pyside2/PySide2/support/signature/mapping.py24
-rw-r--r--sources/pyside2/tests/QtGui/qmatrix_test.py3
-rw-r--r--sources/pyside2/tests/registry/existence_test.py14
-rw-r--r--sources/pyside2/tests/registry/init_platform.py117
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp46
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py4
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/mapping.py72
8 files changed, 221 insertions, 61 deletions
diff --git a/ez_setup.py b/ez_setup.py
index ddc630e7a..eb37479b9 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -224,7 +224,7 @@ def download_file_powershell(url, target):
"[System.Net.CredentialCache]::DefaultCredentials; "
"(new-object System.Net.WebClient).DownloadFile({}, {})".format(
url, target))
- )
+# )
cmd = [
'powershell',
'-Command',
diff --git a/sources/pyside2/PySide2/support/signature/mapping.py b/sources/pyside2/PySide2/support/signature/mapping.py
index 1a769484d..c39821f05 100644
--- a/sources/pyside2/PySide2/support/signature/mapping.py
+++ b/sources/pyside2/PySide2/support/signature/mapping.py
@@ -56,7 +56,7 @@ from signature_loader.sbk_mapping import *
Sbk_Reloader = Reloader
class Reloader(Sbk_Reloader):
- _uninitialized = Sbk_Reloader._uninitialized + PySide2.__all__
+ _uninitialized = Sbk_Reloader._uninitialized + PySide2.__all__ + ["testbinding"]
_prefixes = Sbk_Reloader._prefixes + ["PySide2."]
def update(self):
@@ -66,7 +66,6 @@ update_mapping = Reloader().update
def init_QtCore():
- import PySide2.QtCore
from PySide2.QtCore import Qt, QUrl, QDir
from PySide2.QtCore import QRect, QSize, QPoint, QLocale, QByteArray
from PySide2.QtCore import QMarginsF # 5.9
@@ -217,7 +216,6 @@ def init_QtCore():
def init_QtGui():
- import PySide2.QtGui
from PySide2.QtGui import QPageLayout, QPageSize # 5.12 macOS
type_map.update({
"QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
@@ -248,7 +246,6 @@ def init_QtGui():
def init_QtWidgets():
- import PySide2.QtWidgets
from PySide2.QtWidgets import QWidget, QMessageBox, QStyleOption, QStyleHintReturn, QStyleOptionComplex
from PySide2.QtWidgets import QGraphicsItem, QStyleOptionGraphicsItem # 5.9
GraphicsItemList = typing.List[QGraphicsItem]
@@ -285,7 +282,6 @@ def init_QtWidgets():
def init_QtSql():
- import PySide2.QtSql
from PySide2.QtSql import QSqlDatabase
type_map.update({
"QLatin1String(defaultConnection)": QSqlDatabase.defaultConnection,
@@ -295,7 +291,6 @@ def init_QtSql():
def init_QtNetwork():
- import PySide2.QtNetwork
type_map.update({
"QMultiMap": MultiMap,
"zero(unsigned short)": 0,
@@ -306,7 +301,6 @@ def init_QtNetwork():
def init_QtXmlPatterns():
- import PySide2.QtXmlPatterns
from PySide2.QtXmlPatterns import QXmlName
type_map.update({
"QXmlName.PrefixCode": Missing("PySide2.QtXmlPatterns.QXmlName.PrefixCode"),
@@ -315,7 +309,7 @@ def init_QtXmlPatterns():
return locals()
-def init_QtMultimediaWidgets():
+def init_QtMultimedia():
import PySide2.QtMultimediaWidgets
type_map.update({
"QGraphicsVideoItem": PySide2.QtMultimediaWidgets.QGraphicsVideoItem,
@@ -325,7 +319,6 @@ def init_QtMultimediaWidgets():
def init_QtOpenGL():
- import PySide2.QtOpenGL
type_map.update({
"GLuint": int,
"GLenum": int,
@@ -342,7 +335,6 @@ def init_QtOpenGL():
def init_QtQml():
- import PySide2.QtQml
type_map.update({
"QJSValueList()": [],
"PySide2.QtQml.bool volatile": bool,
@@ -355,7 +347,6 @@ def init_QtQml():
def init_QtQuick():
- import PySide2.QtQuick
type_map.update({
"PySide2.QtQuick.QSharedPointer": int,
"PySide2.QtCore.uint": int,
@@ -367,7 +358,6 @@ def init_QtQuick():
def init_QtScript():
- import PySide2.QtScript
type_map.update({
"QScriptValueList()": [],
})
@@ -375,7 +365,6 @@ def init_QtScript():
def init_QtTest():
- import PySide2.QtTest
type_map.update({
"PySide2.QtTest.QTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
})
@@ -383,7 +372,6 @@ def init_QtTest():
# from 5.9
def init_QtWebEngineWidgets():
- import PySide2.QtWebEngineWidgets
type_map.update({
"zero(PySide2.QtWebEngineWidgets.QWebEnginePage.FindFlags)": 0,
})
@@ -391,7 +379,6 @@ def init_QtWebEngineWidgets():
# from 5.6, MSVC
def init_QtWinExtras():
- import PySide2.QtWinExtras
type_map.update({
"QList< QWinJumpListItem* >()": [],
})
@@ -409,4 +396,11 @@ def init_QtDataVisualization():
})
return locals()
+
+def init_testbinding():
+ type_map.update({
+ "testbinding.PySideCPP2.TestObjectWithoutNamespace": testbinding.TestObjectWithoutNamespace,
+ })
+ return locals()
+
# end of file
diff --git a/sources/pyside2/tests/QtGui/qmatrix_test.py b/sources/pyside2/tests/QtGui/qmatrix_test.py
index 7cfe9ea60..bc6a2b8ae 100644
--- a/sources/pyside2/tests/QtGui/qmatrix_test.py
+++ b/sources/pyside2/tests/QtGui/qmatrix_test.py
@@ -47,7 +47,8 @@ class QMatrixTest(unittest.TestCase):
def testMatrixWithWrongType(self):
matrix = QMatrix(11, 12, 21, 22, 100, 200)
point = QPoint(3, 3)
- self.assertRaises(TypeError, matrix.__mul__, point)
+ # This exception may move from a TypeError to a ValueError.
+ self.assertRaises((TypeError, ValueError), matrix.__mul__, point)
def testMatrix2x2(self):
matrix = QMatrix2x2([1.0, 2.0, 3.0, 4.0])
diff --git a/sources/pyside2/tests/registry/existence_test.py b/sources/pyside2/tests/registry/existence_test.py
index 0d8014ad8..762a5888e 100644
--- a/sources/pyside2/tests/registry/existence_test.py
+++ b/sources/pyside2/tests/registry/existence_test.py
@@ -39,17 +39,23 @@
from __future__ import print_function, absolute_import
+"""
+existence_test.py
+
+A test that checks all function signatures if they still exist.
+"""
+
import os
import sys
import unittest
from textwrap import dedent
from init_platform import (enum_all, generate_all, is_ci,
- getEffectiveRefPath, getRefPath, qtVersion)
+ get_effective_refpath, get_refpath, qt_version)
from util import isolate_warnings, check_warnings, suppress_warnings, warn
from PySide2 import *
-refPath = getRefPath()
-effectiveRefPath = getEffectiveRefPath()
+refPath = get_refpath()
+effectiveRefPath = get_effective_refpath()
effectiveRefPathRoot = os.path.splitext(effectiveRefPath)[0]
pyc = effectiveRefPathRoot + ".pyc"
if os.path.exists(pyc) and not os.path.exists(effectiveRefPath):
@@ -132,7 +138,7 @@ class TestSignaturesExists(unittest.TestCase):
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:
+if not have_refmodule and is_ci and qt_version()[:2] in tested_versions:
class TestFor_CI_Init(unittest.TestCase):
"""
This helper class generates the reference file for CI.
diff --git a/sources/pyside2/tests/registry/init_platform.py b/sources/pyside2/tests/registry/init_platform.py
index ded8ba81c..ca2b2cb68 100644
--- a/sources/pyside2/tests/registry/init_platform.py
+++ b/sources/pyside2/tests/registry/init_platform.py
@@ -40,21 +40,98 @@
from __future__ import print_function, absolute_import
"""
+init_platform.py
+
Existence registry
+==================
This is a registry for all existing function signatures.
One file is generated with all signatures of a platform and version.
+
+The scope has been extended to generate all signatures from the
+shiboken and pysidetest projects.
"""
import sys
import os
import re
-import PySide2
from contextlib import contextmanager
from textwrap import dedent
+script_dir = os.path.normpath(os.path.join(__file__, *".. .. .. .. ..".split()))
+history_dir = os.path.join(script_dir, 'build_history')
+
+# Find out if we have the build dir, already. Then use it.
+look_for = os.path.join("pyside2", "tests", "pysidetest")
+have_build_dir = [x for x in sys.path if x.endswith(look_for)]
+if have_build_dir:
+ all_build_dir = os.path.normpath(os.path.join(have_build_dir[0], "..", "..", ".."))
+elif os.path.exists(history_dir):
+ # Using the last build to find the build dir.
+ # Note: This is not reliable when building in parallel!
+ last_build = max(x for x in os.listdir(history_dir) if x.startswith("20"))
+ fpath = os.path.join(history_dir, last_build, "build_dir.txt")
+ if os.path.exists(fpath):
+ with open(fpath) as f:
+ all_build_dir = f.read().strip()
+else:
+ print(dedent("""
+ Can't find the build dir in the history.
+ Compile again and don't forget to specify "--build-tests".
+ """))
+ sys.exit(1)
+
+if not os.path.exists(os.path.join(all_build_dir, look_for)):
+ print(dedent("""
+ PySide has not been built with tests enabled.
+ Compile again and don't forget to specify "--build-tests".
+ """))
+ sys.exit(1)
+
+pyside_build_dir = os.path.join(all_build_dir, "pyside2")
+shiboken_build_dir = os.path.join(all_build_dir, "shiboken2")
+
+# now we compute all paths:
+def set_ospaths(build_dir):
+ ps = os.pathsep
+ ospath_var = "PATH" if sys.platform == "win32" else "LD_LIBRARY_PATH"
+ old_val = os.environ.get(ospath_var, "")
+ lib_path = [os.path.join(build_dir, "pyside2", "libpyside"),
+ os.path.join(build_dir, "pyside2", "tests", "pysidetest"),
+ os.path.join(build_dir, "shiboken2", "tests", "libminimal"),
+ os.path.join(build_dir, "shiboken2", "tests", "libsample"),
+ os.path.join(build_dir, "shiboken2", "tests", "libother"),
+ os.path.join(build_dir, "shiboken2", "tests", "libsmart"),
+ os.path.join(build_dir, "shiboken2", "libshiboken")]
+ ospath = ps.join(lib_path + old_val.split(ps))
+ os.environ[ospath_var] = ospath
+
+set_ospaths(all_build_dir)
+sys.path[:0] = [os.path.join(shiboken_build_dir, "shibokenmodule"),
+ pyside_build_dir]
+
+import PySide2
+
all_modules = list("PySide2." + x for x in PySide2.__all__)
+# now we should be able to do all imports:
+if not have_build_dir:
+ sys.path.insert(0, os.path.join(pyside_build_dir, "tests", "pysidetest"))
+import testbinding
+all_modules.append("testbinding")
+
+# Note: This is not the shiboken dir as usual, but the binary.
+import shiboken2 as Shiboken
+Shiboken.__name__ = "Shiboken"
+sys.modules["Shiboken"] = sys.modules.pop("shiboken2")
+all_modules.append("Shiboken")
+
+# 'sample' seems to be needed by 'other', so import it first.
+for modname in "minimal sample other smart".split():
+ sys.path.insert(0, os.path.join(shiboken_build_dir, "tests", modname + "binding"))
+ __import__(modname)
+ all_modules.append(modname)
+
from PySide2.QtCore import __version__
from PySide2.support.signature.lib.enum_sig import SimplifyingEnumerator
@@ -79,36 +156,35 @@ else:
# Make sure not to get .pyc in Python2.
sourcepath = os.path.splitext(__file__)[0] + ".py"
-def qtVersion():
+def qt_version():
return tuple(map(int, __version__.split(".")))
-# Format a registry file name for version
-def _registryFileName(version):
+# Format a registry file name for version.
+def _registry_filename(version):
name = "exists_{}_{}_{}_{}{}.py".format(platform_name,
version[0], version[1], version[2], "_ci" if is_ci else "")
return os.path.join(os.path.dirname(__file__), name)
-# Return the expected registry file name
-def getRefPath():
- return _registryFileName(qtVersion())
+# Return the expected registry file name.
+def get_refpath():
+ return _registry_filename(qt_version())
# Return the registry file name, either that of the current
-# version or fall back to a previous patch release
-def getEffectiveRefPath():
- refpath = getRefPath()
+# version or fall back to a previous patch release.
+def get_effective_refpath():
+ refpath = get_refpath()
if os.path.exists(refpath):
return refpath
- version = qtVersion()
- majorVersion = version[0]
- minorVersion = version[1]
- patchVersion = version[2]
- while patchVersion >= 0:
- file = _registryFileName((majorVersion, minorVersion, patchVersion))
+ version = qt_version()
+ major, minor, patch = version[:3]
+ while patch >= 0:
+ file = _registry_filename((major, minor, patch))
if os.path.exists(file):
return file
- patchVersion = patchVersion - 1
+ patch = patch - 1
return refpath
+
class Formatter(object):
"""
Formatter is formatting the signature listing of an enumerator.
@@ -163,8 +239,9 @@ def enum_all():
ret.update(enu.module(mod_name))
return ret
+
def generate_all():
- refPath = getRefPath()
+ refPath = get_refpath()
module = os.path.basename(os.path.splitext(refPath)[0])
with open(refPath, "w") as outfile, open(sourcepath) as f:
fmt = Formatter(outfile)
@@ -190,10 +267,12 @@ def generate_all():
enu.module(mod_name)
fmt.print("# eof")
+
def __main__():
print("+++ generating {}. You should probably check this file in."
- .format(getRefPath()))
+ .format(get_refpath()))
generate_all()
+
if __name__ == "__main__":
__main__()
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index 922f85906..564e5fcef 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -129,13 +129,16 @@ 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;
+ if (selftype == nullptr) {
+ selftype = PyDict_GetItem(pyside_globals->map_dict, ob_cf);
+ if (selftype == nullptr) {
+ // This must be an overloaded function that we handled special.
+ Shiboken::AutoDecRef special(Py_BuildValue("(Os)", ob_cf, "overload"));
+ selftype = PyDict_GetItem(pyside_globals->map_dict, special);
+ }
}
+ assert(selftype);
+
PyObject *typemod = (PyType_Check(selftype) || PyModule_Check(selftype))
? selftype : (PyObject *)Py_TYPE(selftype);
// do we support module functions?
@@ -175,19 +178,26 @@ GetClassOfFunc(PyObject *ob)
}
static PyObject *
-compute_name_key(PyObject *ob)
+get_funcname(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__"));
+ PyObject *func_name = PyObject_GetAttrString(func, "__name__");
Py_DECREF(func);
- if (func_name.isNull())
+ if (func_name == nullptr)
Py_FatalError("unexpected name problem in compute_name_key");
+ return func_name;
+}
+
+static PyObject *
+compute_name_key(PyObject *ob)
+{
+ if (PyType_Check(ob))
+ return GetClassKey(ob);
+ Shiboken::AutoDecRef func_name(get_funcname(ob));
Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
@@ -201,9 +211,11 @@ build_name_key_to_func(PyObject *obtype)
if (meth == 0)
return 0;
+ Shiboken::AutoDecRef type_key(GetClassKey(obtype));
for (; meth->ml_name != NULL; meth++) {
Shiboken::AutoDecRef func(PyCFunction_NewEx(meth, obtype, NULL));
- Shiboken::AutoDecRef name_key(compute_name_key(func));
+ Shiboken::AutoDecRef func_name(get_funcname(func));
+ Shiboken::AutoDecRef name_key(Py_BuildValue("(OO)", type_key.object(), func_name.object()));
if (func.isNull() || name_key.isNull()
|| PyDict_SetItem(pyside_globals->map_dict, name_key, func) < 0)
return -1;
@@ -224,7 +236,7 @@ name_key_to_func(PyObject *ob)
Py_RETURN_NONE;
PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
- if (ret == NULL) {
+ if (ret == nullptr) {
// do a lazy initialization
Shiboken::AutoDecRef type_key(GetClassKey(GetClassOfFunc(ob)));
PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
@@ -233,7 +245,7 @@ name_key_to_func(PyObject *ob)
Py_RETURN_NONE;
assert(PyType_Check(type));
if (build_name_key_to_func(type) < 0)
- return NULL;
+ return nullptr;
ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
}
Py_XINCREF(ret);
@@ -901,6 +913,12 @@ _build_func_to_type(PyObject *obtype)
strcat(mangled_name, ".overload");
if (PyDict_SetItemString(dict, mangled_name, descr) < 0)
return -1;
+ if (meth->ml_flags & METH_STATIC) {
+ // This is the special case where a static method is hidden.
+ Shiboken::AutoDecRef special(Py_BuildValue("(Os)", cfunc.object(), "overload"));
+ if (PyDict_SetItem(pyside_globals->map_dict, special, obtype) < 0)
+ return -1;
+ }
if (PyDict_SetItemString(pyside_globals->map_dict, mangled_name, obtype) < 0)
return -1;
continue;
diff --git a/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py b/sources/shiboken2/shibokenmodule/support/signature/backport_inspect.py
index 6b97470e2..e890dcdcf 100644
--- a/sources/shiboken2/shibokenmodule/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) == 'support.signature.typing':
- return repr(annotation).replace('support.signature.typing', 'typing')
+ if getattr(annotation, '__module__', None) == 'support.signature.typing27':
+ return repr(annotation).replace('support.signature.typing27', 'typing')
if isinstance(annotation, type):
if annotation.__module__ in ('__builtin__', base_module):
return annotation.__name__
diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
index 3e76cd94a..f638bc42b 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
@@ -88,6 +88,7 @@ WId = int
GL_TEXTURE_2D = 0x0DE1
GL_RGBA = 0x1908
+
class _NotCalled(str):
"""
Wrap some text with semantics
@@ -104,7 +105,7 @@ class _NotCalled(str):
real object is needed, the wrapper can simply be called.
"""
def __repr__(self):
- suppress = "support.signature.typing."
+ suppress = "support.signature.typing27."
text = self[len(suppress):] if self.startswith(suppress) else self
return "{}({})".format(type(self).__name__, text)
@@ -113,14 +114,20 @@ class _NotCalled(str):
text = self if self.endswith(")") else self + "()"
return eval(text, namespace)
+USE_PEP563 = sys.version_info[:2] >= (3, 7)
+
+
# 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)
+ if not USE_PEP563:
+ # The string must be quoted, because the object does not exist.
+ def __repr__(self):
+ return '{}("{}")'.format(type(self).__name__, self)
+
class Invalid(_NotCalled):
pass
@@ -129,12 +136,20 @@ class Invalid(_NotCalled):
class Default(_NotCalled):
pass
+
class Instance(_NotCalled):
pass
class Reloader(object):
- _uninitialized = ["sample"]
+ """
+ Reloder class
+
+ This is a singleton class which provides the update function for the
+ shiboken and PySide classes.
+ """
+ ## Note: We needed to rename shiboken2 in order to avoid a name clash.
+ _uninitialized = "Shiboken minimal sample other smart".split()
_prefixes = [""]
def __init__(self):
@@ -142,6 +157,14 @@ class Reloader(object):
self.uninitialized = self._uninitialized
def update(self, g=None):
+ """
+ update is responsible to import all modules from shiboken and PySide
+ which are already in sys.modules.
+ The purpose is to follow all user imports without introducing new
+ ones.
+ This function is called by pyside_type_init to adapt imports
+ when the number of imported modules has changed.
+ """
if self.sys_module_count == len(sys.modules):
return
self.sys_module_count = len(sys.modules)
@@ -160,6 +183,14 @@ class Reloader(object):
self.uninitialized.remove(mod_name)
proc_name = "init_" + mod_name
if proc_name in g:
+ # Do the 'import {import_name}' first.
+ # 'top' is PySide2 when we do 'import PySide.QtCore'
+ # or Shiboken if we do 'import Shiboken'.
+ # Convince yourself that these two lines below have the same
+ # global effect as "import Shiboken" or "import PySide2.QtCore".
+ top = __import__(import_name)
+ g[top.__name__] = top
+ # Modules are in place, we can update the type_map.
g.update(g[proc_name]())
@@ -167,8 +198,23 @@ update_mapping = Reloader().update
type_map = {}
+def init_Shiboken():
+ type_map.update({
+ "shiboken2.bool": bool,
+ "size_t": int,
+ "PyType": type,
+ })
+ return locals()
+
+
+def init_minimal():
+ type_map.update({
+ "MinBool": bool,
+ })
+ return locals()
+
+
def init_sample():
- import sample
import datetime
type_map.update({
"sample.int": int,
@@ -207,4 +253,20 @@ def init_sample():
})
return locals()
+
+def init_other():
+ import numbers
+ type_map.update({
+ "other.Number": numbers.Number,
+ "other.ExtendsNoImplicitConversion": Missing("other.ExtendsNoImplicitConversion"),
+ })
+ return locals()
+
+
+def init_smart():
+ type_map.update({
+ "smart.SharedPtr": Missing("smart.SharedPtr"), # bad object "SharedPtr<Obj >"
+ })
+ return locals()
+
# end of file