aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/shibokenmodule/support/signature/mapping.py
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2019-02-01 11:12:43 +0100
committerChristian Tismer <tismer@stackless.com>2019-02-05 14:17:48 +0000
commit3748e8fa9830e97466f12104501d4acf104260a5 (patch)
tree67dc037767dce0f87568b4a27beac69010742026 /sources/shiboken2/shibokenmodule/support/signature/mapping.py
parent295061d00be3dedf60d8adc97bd14ff46931ef4c (diff)
Type Hints: Handle Container Types Correctly
An error was reported that we had a bug in this .pyi line: def parseErrors(self) -> PySide2.QtScxml.QScxmlError: ... which actually had to be a list like def parseErrors(self) -> typing.List[PySide2.QtScxml.QScxmlError]: ... A deeper look revealed that we had very many other examples, also in the argument lists, were we did not handle containers properly. (For example, 90 times in QtCore!) This is a leftover from the type error messages which were generated in C++, and never really understood. This is now a clean rewrite of the C++ part to expose all information and an extension of the Python parser that systematically uses the container types from the typing module. The implementation became a bit more complex because of Python 2: We need to provide our own copy of the public typing module, because it is not safe to assume that this module can be loaded. Importing it from support.signature gave a problem because we now need to find the names of instances to produce List[...], which needed to be implemented in the loader. Implemented the "Pair" type now as a native generic type. This is more correct than the former implementation and shorter in the .pyi files. Additionally, an own definition of "Char" was provided for brevity. This was not important to implement and could also be done with "int", but it is helpful for the future to know how to implement own types (and it was fun). Task-number: PYSIDE-921 Task-number: PYSIDE-795 Change-Id: I0e565b38d7b4fff39dd606950f9f8d97c45acbf5 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/shiboken2/shibokenmodule/support/signature/mapping.py')
-rw-r--r--sources/shiboken2/shibokenmodule/support/signature/mapping.py87
1 files changed, 77 insertions, 10 deletions
diff --git a/sources/shiboken2/shibokenmodule/support/signature/mapping.py b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
index 40db43729..d4c630aca 100644
--- a/sources/shiboken2/shibokenmodule/support/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/support/signature/mapping.py
@@ -55,12 +55,13 @@ import os
import pkgutil
from signature_loader import typing
+from signature_loader.typing import TypeVar, Generic
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]
@@ -69,10 +70,72 @@ 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]
+
+# 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
+
+
+# Building our own Char type, which is much nicer than
+# Char = typing.Union[str, int] # how do I model the limitation to 1 char?
+
+# Copied from the six module:
+def with_metaclass(meta, *bases):
+ """Create a base class with a metaclass."""
+ # This requires a bit of explanation: the basic idea is to make a dummy
+ # metaclass for one level of class instantiation that replaces itself with
+ # the actual metaclass.
+ class metaclass(type):
+
+ def __new__(cls, name, this_bases, d):
+ return meta(name, bases, d)
+
+ @classmethod
+ def __prepare__(cls, name, this_bases):
+ return meta.__prepare__(name, bases)
+ return type.__new__(metaclass, 'temporary_class', (), {})
+
+class _CharMeta(type):
+ def __repr__(self):
+ return '%s.%s' % (self.__module__, self.__name__)
+
+
+class Char(with_metaclass(_CharMeta)):
+ """
+ From http://doc.qt.io/qt-5/qchar.html :
+
+ In Qt, Unicode characters are 16-bit entities without any markup or
+ structure. This class represents such an entity. It is lightweight,
+ so it can be used everywhere. Most compilers treat it like an
+ unsigned short.
+
+ Here, we provide a simple implementation just to avoid long aliases.
+ """
+ __module__ = "typing"
+
+ def __init__(self, code):
+ if isinstance(code, int):
+ self.code = code & 0xffff
+ else:
+ self.code = ord(code)
+
+ def __add__(self, other):
+ return chr(self.code) + other
+
+ def __radd__(self, other):
+ return other + chr(self.code)
+
+ def __repr__(self):
+ return "typing.Char({})".format(self.code)
+
+typing.Char = Char
+
+
MultiMap = typing.DefaultDict[str, typing.List[str]]
# ulong_max is only 32 bit on windows.
@@ -205,6 +268,13 @@ update_mapping = Reloader().update
type_map = {}
namespace = globals() # our module's __dict__
+type_map.update({
+ "QList": typing.List,
+ "QVector": typing.List,
+ "QSet": typing.Set,
+ "QPair": Pair,
+ })
+
def init_Shiboken():
type_map.update({
@@ -225,18 +295,16 @@ def init_minimal():
def init_sample():
import datetime
type_map.update({
+ "double": float,
"sample.int": int,
"Complex": complex,
"sample.OddBool": bool,
"sample.bool": bool,
"sample.PStr": str,
- "double[]": FloatList,
"OddBool": bool,
"PStr": str,
+ "char": Char,
"sample.char": Char,
- "double[][]": FloatMatrix,
- "int[]": IntList,
- "int[][]": IntMatrix,
"sample.Point": Point,
"sample.ObjectType": object,
"std.string": str,
@@ -257,7 +325,6 @@ def init_sample():
"zero(sample.bool)": False,
"PyDate": datetime.date,
"ZeroIn": 0,
- "Point[]": PointList,
})
return locals()