aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/PySide2/support/signature/mapping.py
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2017-10-19 11:27:13 +0200
committerChristian Tismer <tismer@stackless.com>2017-11-14 09:39:59 +0000
commitb825eec459a3d5dcddf14061d578ef89e6ad5ee4 (patch)
tree1d01b860a1134fffb31ab0029a4251c939460a4f /sources/pyside2/PySide2/support/signature/mapping.py
parentfa1c97fc2a7f25fe178b0c180b56f78ac00bc4c9 (diff)
Update and complete the signature module
There is now an external typing module for Python 2.7 and Python 3.6 from Guido (PSF license again) that makes the differences between both versions vanish. Also, when generating interface files, some types did not show correctly, and the constant "0" is wrong in almost all cases. Values in signatures looked often bad since they have no nice __repr__, and it was almost impossible to create correct .pyi files. Now, these instances are created as wrapped string types with a nice __repr__. A call of these objects creates the real constant. This way, also objects can be rendered which are dependent from the existence of other objects (i.E. QPixMap). This patch improves the usability of the signature module. We can now generate source code or .pyi files without modifications. Task-number: PYSIDE-510 Change-Id: I55490d76a29fc6c0e4f821c0c77d5e5d1e28976e Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside2/PySide2/support/signature/mapping.py')
-rw-r--r--sources/pyside2/PySide2/support/signature/mapping.py189
1 files changed, 133 insertions, 56 deletions
diff --git a/sources/pyside2/PySide2/support/signature/mapping.py b/sources/pyside2/PySide2/support/signature/mapping.py
index 668ca8df4..33686d4a5 100644
--- a/sources/pyside2/PySide2/support/signature/mapping.py
+++ b/sources/pyside2/PySide2/support/signature/mapping.py
@@ -53,30 +53,23 @@ See _resolve_value() in singature.py
"""
import sys
-import collections
import struct
import PySide2
-PY3 = sys.version_info >= (3,)
-if PY3:
- from . import typing
- ellipsis = eval("...")
- Char = typing.Union[str, int] # how do I model the limitation to 1 char?
- StringList = typing.List[str]
- Variant = typing.Union[str, int, float, Char, StringList, type(ellipsis)]
- # Much more, do we need that? Do we better kill it?
- ModelIndexList = typing.List[int]
- QImageCleanupFunction = typing.Callable[[bytes], None]
- FloatMatrix = typing.List[typing.List[float]]
-else:
- ellipsis = "..."
- Char = str
- StringList = list
- Variant = object
- ModelIndexList = list
- QImageCleanupFunction = object
- FloatMatrix = list
-Pair = collections.namedtuple('Pair', ['first', 'second'])
+from . import typing
+ellipsis = "..."
+Char = typing.Union[str, int] # how do I model the limitation to 1 char?
+StringList = typing.List[str]
+IntList = typing.List[int]
+Variant = typing.Any
+ModelIndexList = typing.List[int]
+QImageCleanupFunction = typing.Callable[[bytes], None]
+FloatMatrix = typing.List[typing.List[float]]
+# Pair could be more specific, but we loose the info in the generator.
+Pair = typing.Tuple[typing.Any, typing.Any]
+MultiMap = typing.DefaultDict[str, typing.List[str]]
+Text = typing.Text
+
# ulong_max is only 32 bit on windows.
ulong_max = 2*sys.maxsize+1 if len(struct.pack("L", 1)) != 4 else 0xffffffff
ushort_max = 0xffff
@@ -90,15 +83,49 @@ WId = int
GL_TEXTURE_2D = 0x0DE1
GL_RGBA = 0x1908
-# Some types are abstract. They just show their name.
-class Virtual(str):
+class _NotCalled(str):
+ """
+ Wrap some text with semantics
+
+ This class is wrapped around text in order to avoid calling it.
+ There are three reasons for this:
+
+ - some instances cannot be created since they are abstract,
+ - some can only be created after qApp was created,
+ - some have an ugly __repr__ with angle brackets in it.
+
+ By using derived classes, good looking instances can be created
+ which can be used to generate source code or .pyi files. When the
+ real object is needed, the wrapper can simply be called.
+ """
def __repr__(self):
- return "Virtual({})".format(self)
+ suppress = "PySide2.support.signature.typing."
+ text = self[len(suppress):] if self.startswith(suppress) else self
+ return "{}({})".format(type(self).__name__, text)
+
+ def __call__(self):
+ from .mapping import __dict__ as namespace
+ text = self if self.endswith(")") else self + "()"
+ return eval(text, namespace)
+
+# Some types are abstract. They just show their name.
+class Virtual(_NotCalled):
+ pass
# Other types I simply could not find.
-class Missing(str):
- def __repr__(self):
- return "Missing({})".format(self)
+class Missing(_NotCalled):
+ pass
+
+class Invalid(_NotCalled):
+ pass
+
+# Helper types
+class Default(_NotCalled):
+ pass
+
+class Instance(_NotCalled):
+ pass
+
class Reloader(object):
def __init__(self):
@@ -117,13 +144,14 @@ class Reloader(object):
if proc_name in g:
g.update(g[proc_name]())
+
update_mapping = Reloader().update
type_map = {}
def init_QtCore():
import PySide2.QtCore
from PySide2.QtCore import Qt, QUrl, QDir, QGenericArgument
- from PySide2.QtCore import QRect, QSize, QPoint
+ from PySide2.QtCore import QRect, QSize, QPoint, QLocale, QByteArray
from PySide2.QtCore import QMarginsF # 5.9
try:
# seems to be not generated by 5.9 ATM.
@@ -159,7 +187,7 @@ def init_QtCore():
"QVariant": Variant,
"QVariant.Type": type, # not so sure here...
"QStringRef": str,
- "QString()": None, # unclear: "" would be isEmpty(), but not isNull()
+ "QString()": "",
"QModelIndexList": ModelIndexList,
"QPair": Pair,
"unsigned char": Char,
@@ -172,13 +200,13 @@ def init_QtCore():
"PyCallable": callable,
"...": ellipsis, # no idea how this should be translated... maybe so?
"PyTypeObject": type,
- "PySequence": list, # needs to be changed, QApplication for instance!
+ "PySequence": typing.Sequence,
"qptrdiff": int,
"true": True,
"Qt.HANDLE": int, # be more explicit with some consts?
"list of QAbstractState": list, # how to use typing.List when we don't have QAbstractState?
"list of QAbstractAnimation": list, # dto.
- "QVariant()": (ellipsis,), # no idea what to use here for "invalid Variant"?
+ "QVariant()": Invalid(Variant),
"QMap": dict,
"PySide2.QtCore.bool": bool,
"QHash": dict,
@@ -197,27 +225,25 @@ def init_QtCore():
"PySide2.QtCore.quint64": int,
"PySide2.QtCore.quint8": int,
"PySide2.QtCore.uchar": Char,
- "QGenericArgument(0)": QGenericArgument(None),
"PySide2.QtCore.long": int,
"PySide2.QtCore.QUrl.ComponentFormattingOptions":
PySide2.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
- "QUrl.FormattingOptions(PrettyDecoded)": QUrl.FormattingOptions(QUrl.PrettyDecoded),
+ "QUrl.FormattingOptions(PrettyDecoded)": Instance(
+ "QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
# from 5.9
- "QDir.Filters(AllEntries | NoDotAndDotDot)": QDir.Filters(QDir.AllEntries |
- QDir.NoDotAndDotDot),
- "QGenericArgument(Q_NULLPTR)": QGenericArgument(None),
+ "QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
+ "QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
"NULL": None, # 5.6, MSVC
- "QGenericArgument(NULL)": QGenericArgument(None), # 5.6, MSVC
- "QDir.SortFlags(Name | IgnoreCase)": QDir.SortFlags(QDir.Name | QDir.IgnoreCase),
+ "QDir.SortFlags(Name | IgnoreCase)": Instance(
+ "QDir.SortFlags(QDir.Name | QDir.IgnoreCase)"),
"PyBytes": bytes,
- "PyUnicode": str if PY3 else unicode,
+ "PyUnicode": Text,
"signed long": int,
"PySide2.QtCore.int": int,
"PySide2.QtCore.char": StringList, # A 'char **' is a list of strings.
"char[]": StringList, # 5.9
"unsigned long int": int, # 5.6, RHEL 6.6
"unsigned short int": int, # 5.6, RHEL 6.6
- "QGenericArgument((0))": None, # 5.6, RHEL 6.6. Is that ok?
"4294967295UL": 4294967295, # 5.6, RHEL 6.6
"PySide2.QtCore.int32_t": int, # 5.9
"PySide2.QtCore.int64_t": int, # 5.9
@@ -228,6 +254,33 @@ def init_QtCore():
"float[][]": FloatMatrix, # 5.9
"PySide2.QtCore.unsigned int": int, # 5.9 Ubuntu
"PySide2.QtCore.long long": int, # 5.9, MSVC 15
+ "QModelIndex()": Invalid("PySide2.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
+ "QGenericArgument((0))": None, # 5.6, RHEL 6.6. Is that ok?
+ "QGenericArgument()": None,
+ "QGenericArgument(0)": None,
+ "QGenericArgument(NULL)": None, # 5.6, MSVC
+ "QGenericArgument(Q_NULLPTR)": None,
+ "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,
})
try:
type_map.update({
@@ -253,8 +306,15 @@ def init_QtGui():
"GL_NEAREST": GL_NEAREST,
"WId": WId,
"PySide2.QtGui.QPlatformSurface": Virtual("PySide2.QtGui.QPlatformSurface"), # hmm...
- "QList< QTouchEvent.TouchPoint >()": list,
- "QPixmap()": lambda:QPixmap(), # we cannot create this without qApp
+ "QList< QTouchEvent.TouchPoint >()": [], # XXX improve?
+ "QPixmap()": Default("PySide2.QtGui.QPixmap"), # can't create without qApp
+ "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,
})
return locals()
@@ -262,19 +322,15 @@ def init_QtWidgets():
import PySide2.QtWidgets
from PySide2.QtWidgets import QWidget, QMessageBox, QStyleOption, QStyleHintReturn, QStyleOptionComplex
from PySide2.QtWidgets import QGraphicsItem, QStyleOptionGraphicsItem # 5.9
- if PY3:
- GraphicsItemList = typing.List[QGraphicsItem]
- StyleOptionGraphicsItemList = typing.List[QStyleOptionGraphicsItem]
- else:
- GraphicsItemList = list
- StyleOptionGraphicsItemList = list
+ GraphicsItemList = typing.List[QGraphicsItem]
+ StyleOptionGraphicsItemList = typing.List[QStyleOptionGraphicsItem]
type_map.update({
- "QMessageBox.StandardButtons(Yes | No)": QMessageBox.StandardButtons(
- QMessageBox.Yes | QMessageBox.No),
- "QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": QWidget.RenderFlags(
- QWidget.DrawWindowBackground | QWidget.DrawChildren),
- "static_cast<Qt.MatchFlags>(Qt.MatchExactly|Qt.MatchCaseSensitive)": (
- Qt.MatchFlags(Qt.MatchExactly | Qt.MatchCaseSensitive)),
+ "QMessageBox.StandardButtons(Yes | No)": Instance(
+ "QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No)"),
+ "QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": Instance(
+ "QWidget.RenderFlags(QWidget.DrawWindowBackground | QWidget.DrawChildren)"),
+ "static_cast<Qt.MatchFlags>(Qt.MatchExactly|Qt.MatchCaseSensitive)": Instance(
+ "Qt.MatchFlags(Qt.MatchExactly | Qt.MatchCaseSensitive)"),
"QVector< int >()": [],
# from 5.9
"Type": PySide2.QtWidgets.QListWidgetItem.Type,
@@ -283,6 +339,16 @@ def init_QtWidgets():
"SO_Complex": QStyleOptionComplex.SO_Complex,
"QGraphicsItem[]": GraphicsItemList,
"QStyleOptionGraphicsItem[]": StyleOptionGraphicsItemList,
+ "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,
})
return locals()
@@ -291,14 +357,17 @@ def init_QtSql():
from PySide2.QtSql import QSqlDatabase
type_map.update({
"QLatin1String(defaultConnection)": QSqlDatabase.defaultConnection,
- "QVariant.Invalid": -1, # not sure what I should create, here...
+ "QVariant.Invalid": Invalid("PySide2.QtCore.QVariant"), # not sure what I should create, here...
})
return locals()
def init_QtNetwork():
import PySide2.QtNetwork
type_map.update({
- "QMultiMap": typing.DefaultDict(list) if PY3 else {},
+ "QMultiMap": MultiMap,
+ "zero(unsigned short)": 0,
+ "zero(PySide2.QtCore.QIODevice)": None,
+ "zero(QList)": [],
})
return locals()
@@ -331,6 +400,9 @@ def init_QtOpenGL():
"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()
@@ -341,6 +413,8 @@ def init_QtQml():
"PySide2.QtQml.bool volatile": bool,
# from 5.9
"QVariantHash()": {},
+ "zero(PySide2.QtQml.QQmlContext)": None,
+ "zero(PySide2.QtQml.QQmlEngine)": None,
})
return locals()
@@ -350,6 +424,8 @@ def init_QtQuick():
"PySide2.QtQuick.QSharedPointer": int,
"PySide2.QtCore.uint": int,
"T": int,
+ "zero(PySide2.QtQuick.QQuickItem)": None,
+ "zero(GLuint)": 0,
})
return locals()
@@ -372,6 +448,7 @@ def init_QtWebEngineWidgets():
import PySide2.QtWebEngineWidgets
type_map.update({
"PySide2.QtTest.QTouchEventSequence": PySide2.QtTest.QTest.QTouchEventSequence,
+ "zero(PySide2.QtWebEngineWidgets.QWebEnginePage.FindFlags)": 0,
})
return locals()