summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build_scripts/utils.py3
m---------sources/pyside2-tools0
-rw-r--r--sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in1
-rw-r--r--sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml1
-rw-r--r--sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp19
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp5
-rw-r--r--sources/pyside2/PySide2/support/generate_pyi.py13
-rw-r--r--sources/pyside2/doc/_themes/pysidedocs/static/pyside.css91
-rw-r--r--sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp24
-rw-r--r--sources/pyside2/doc/gettingstarted.rst22
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo.cpp15
-rw-r--r--sources/pyside2/libpyside/pysideclassinfo_p.h2
-rw-r--r--sources/pyside2/libpyside/pysidemetafunction.cpp10
-rw-r--r--sources/pyside2/libpyside/pysideproperty.cpp24
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp64
-rw-r--r--sources/pyside2/libpyside/pysideslot.cpp22
-rw-r--r--sources/pyside2/pyside_version.py2
-rw-r--r--sources/pyside2/tests/QtCore/qslot_object_test.py14
-rw-r--r--sources/shiboken2/doc/_themes/pysidedocs/static/pyside.css91
-rw-r--r--sources/shiboken2/doc/typesystemvariables.rst2
-rw-r--r--sources/shiboken2/generator/shiboken2/cppgenerator.cpp2
-rw-r--r--sources/shiboken2/generator/shiboken2/shibokengenerator.cpp2
-rw-r--r--sources/shiboken2/libshiboken/signature.cpp32
-rw-r--r--sources/shiboken2/shiboken_version.py2
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py38
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py20
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py10
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py8
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py14
-rw-r--r--sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py515
-rw-r--r--sources/shiboken2/tests/samplebinding/objecttype_test.py8
-rw-r--r--sources/shiboken2/tests/smartbinding/smart_pointer_test.py12
32 files changed, 851 insertions, 237 deletions
diff --git a/build_scripts/utils.py b/build_scripts/utils.py
index 5375e9f8..dc90d99b 100644
--- a/build_scripts/utils.py
+++ b/build_scripts/utils.py
@@ -1141,7 +1141,8 @@ def run_instruction(instruction, error, initial_env=None):
def acceptCITestConfiguration(hostOS, hostOSVer, targetArch, compiler):
# Disable unsupported CI configs for now
# NOTE: String must match with QT CI's storagestruct thrift
- if hostOSVer in ["WinRT_10", "WebAssembly", "Ubuntu_18_04"]:
+ if hostOSVer in ["WinRT_10", "WebAssembly", "Ubuntu_18_04"] \
+ or hostOSVer.startswith("SLES_"):
print("Disabled " + hostOSVer + " from Coin configuration")
return False
# With 5.11 CI will create two sets of release binaries, one with msvc 2015 and one with msvc 2017
diff --git a/sources/pyside2-tools b/sources/pyside2-tools
-Subproject 1d4add1920c9c1b08ebb20333c15d6f5ed6b9ab
+Subproject 93c81f1315546ba7519bd5b37b160ab012bfaad
diff --git a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in
index 7949b2da..ff078d19 100644
--- a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in
+++ b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in
@@ -40,7 +40,6 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtPrintSupport">
- <load-typesystem name="QtGui/typesystem_gui.xml" generate="no"/>
<load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<load-typesystem name="QtPrintSupport/typesystem_printsupport_common.xml" generate="yes"/>
</typesystem>
diff --git a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml
index c11a6e04..48710387 100644
--- a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml
+++ b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml
@@ -40,6 +40,7 @@
****************************************************************************/
-->
<typesystem package="PySide2.QtPrintSupport">
+ <load-typesystem name="QtWidgets/typesystem_widgets.xml" generate="no"/>
<object-type name="QPageSetupDialog">
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
index 2386620c..6427e519 100644
--- a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
+++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
@@ -41,6 +41,7 @@
// shiboken
#include <shiboken.h>
+#include <signature.h>
// pyside
#include <pyside.h>
@@ -215,13 +216,13 @@ static int propListTpInit(PyObject *self, PyObject *args, PyObject *kwds)
&data->at,
&data->clear,
&data->count)) {
- return 0;
+ return -1;
}
PySide::Property::setMetaCallHandler(pySelf, &propListMetaCall);
PySide::Property::setTypeName(pySelf, "QQmlListProperty<QObject>");
PySide::Property::setUserData(pySelf, data);
- return 1;
+ return 0;
}
void propListTpFree(void *self)
@@ -469,12 +470,22 @@ PyTypeObject *QtQml_VolatileBoolTypeF(void)
return type;
}
+static const char *PropertyList_SignatureStrings[] = {
+ "PySide2.QtQml.ListProperty(type:type,append:typing.Callable,"
+ "at:typing.Callable=None,clear:typing.Callable=None,count:typing.Callable=None)",
+ nullptr}; // Sentinel
+
+static const char *VolatileBool_SignatureStrings[] = {
+ "PySide2.QtQml.VolatileBool.get()->bool",
+ "PySide2.QtQml.VolatileBool.set(a:object)",
+ nullptr}; // Sentinel
+
void PySide::initQmlSupport(PyObject *module)
{
ElementFactory<PYSIDE_MAX_QML_TYPES - 1>::init();
// Export QmlListProperty type
- if (PyType_Ready(PropertyListTypeF()) < 0) {
+ if (SbkSpecial_Type_Ready(module, PropertyListTypeF(), PropertyList_SignatureStrings) < 0) {
PyErr_Print();
qWarning() << "Error initializing PropertyList type.";
return;
@@ -484,7 +495,7 @@ void PySide::initQmlSupport(PyObject *module)
PyModule_AddObject(module, PepType_GetNameStr(PropertyListTypeF()),
reinterpret_cast<PyObject *>(PropertyListTypeF()));
- if (PyType_Ready(QtQml_VolatileBoolTypeF()) < 0) {
+ if (SbkSpecial_Type_Ready(module, QtQml_VolatileBoolTypeF(), VolatileBool_SignatureStrings) < 0) {
PyErr_Print();
qWarning() << "Error initializing VolatileBool type.";
return;
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp
index 3e1bab97..93f7321a 100644
--- a/sources/pyside2/PySide2/glue/qtcore.cpp
+++ b/sources/pyside2/PySide2/glue/qtcore.cpp
@@ -1289,7 +1289,7 @@ Shiboken::AutoDecRef emptyTuple(PyTuple_New(0));
PyObject *pyTimer = reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_new(Shiboken::SbkType<QTimer>(), emptyTuple, 0);
reinterpret_cast<PyTypeObject *>(Shiboken::SbkType<QTimer>())->tp_init(pyTimer, emptyTuple, 0);
-QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer);
+auto timer = %CONVERTTOCPP[QTimer *](pyTimer);
//XXX /|\ omitting this space crashes shiboken!
Shiboken::AutoDecRef result(
PyObject_CallMethod(pyTimer,
@@ -1484,8 +1484,7 @@ if (PySide::SignalManager::registerMetaMethod(%1, signalName.mid(1).toLatin1().d
if (!PyObject_TypeCheck(%1, PySideSignalInstanceTypeF()))
goto Sbk_%TYPEFunc_%FUNCTION_NAME_TypeError;
PySideSignalInstance *signalInstance = reinterpret_cast<PySideSignalInstance *>(%1);
-QObject * sender = %CONVERTTOCPP[QObject *](PySide::Signal::getObject(signalInstance));
-//XXX /|\ omitting this space crashes shiboken!
+auto sender = %CONVERTTOCPP[QObject *](PySide::Signal::getObject(signalInstance));
QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2);
%PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0);
// @snippet qstate-addtransition-2
diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py
index c732227f..8aa69c98 100644
--- a/sources/pyside2/PySide2/support/generate_pyi.py
+++ b/sources/pyside2/PySide2/support/generate_pyi.py
@@ -141,7 +141,7 @@ class Formatter(Writer):
self.outfile.seek(here)
self.outfile.truncate()
# Note: we cannot use class_str when we have no body.
- self.print("{spaces}class {class_name}: ...".format(**locals()))
+ self.print("{spaces}class {class_str}: ...".format(**locals()))
if "<" in class_name:
# This is happening in QtQuick for some reason:
## class QSharedPointer<QQuickItemGrabResult >:
@@ -168,6 +168,13 @@ class Formatter(Writer):
self.print('{spaces}@staticmethod'.format(**locals()))
self.print('{spaces}def {func_name}{signature}: ...'.format(**locals()))
+ @contextmanager
+ def enum(self, class_name, enum_name, value):
+ spaces = self.spaces
+ hexval = hex(value)
+ self.print("{spaces}{enum_name:20}: {class_name} = ... # {hexval}".format(**locals()))
+ yield
+
def get_license_text():
with io.open(sourcepath) as f:
@@ -247,10 +254,10 @@ def generate_all_pyi(outpath, options):
os.environ["PYTHONPATH"] = pypath
# now we can import
- global PySide2, inspect, HintingEnumerator
+ global PySide2, inspect, HintingEnumerator, EnumType
import PySide2
from PySide2.support.signature import inspect
- from PySide2.support.signature.lib.enum_sig import HintingEnumerator
+ from PySide2.support.signature.lib.enum_sig import HintingEnumerator, EnumType
# propagate USE_PEP563 to the mapping module.
# Perhaps this can be automated?
diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css
index 956e3113..ec48705f 100644
--- a/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css
+++ b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css
@@ -4,7 +4,7 @@
div.admonition {
margin: 1em 0 1em;
- padding: 7px;
+ padding: 0;
}
div.admonition dt {
@@ -43,6 +43,7 @@ div.warning {
div.seealso {
background-color: #ffffcc;
border: 1px solid #ffff66;
+ padding: 3px 0px 3px 10px;
}
div.note {
@@ -291,13 +292,21 @@ tt.descname {
#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
list-style: none;
- margin: 0px;
- padding: 10px;
+ margin: 0;
+ padding: 0;
border: 1px solid #ddd;
background-color: #f4f4f4;
- -moz-border-radius:10px;
- -webkit-border-radius:10px;
- -khtml-border-radius:10px;
+}
+
+#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
+ margin: 0;
+ padding: 0;
+}
+
+#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
+ margin: 5px;
+ padding: 0;
+ font-size: 90%;
}
#synopsis span.pre {
@@ -312,11 +321,63 @@ tt.descname {
margin: 0px;
margin-bottom: 10px;
padding: 10px;
- border: 1px solid #ddd;
+ font-weight: bold;
background-color: #f4f4f4;
- -moz-border-radius:10px;
- -webkit-border-radius:10px;
- -khtml-border-radius:10px;
+}
+
+#detailed-description .class .field-odd,
+#detailed-description .method .field-odd,
+#detailed-description .staticmethod .field-odd,
+#detailed-description .attribute .field-odd {
+ margin: 0;
+ padding: 1px;
+ background-color: #ffffff;
+
+}
+
+#detailed-description .class .field-even,
+#detailed-description .method .field-even,
+#detailed-description .staticmethod .field-even,
+#detailed-description .attribute .field-even {
+ margin: 0;
+ padding: 1px;
+ background-color: #ffffff;
+}
+
+#detailed-description .class .field-odd li,
+#detailed-description .method .field-odd li,
+#detailed-description .staticmethod .field-odd li,
+#detailed-description .attribute .field-odd li {
+ list-style-type: '';
+ margin: 0;
+ padding: 0;
+
+}
+
+#detailed-description .class .field-even li,
+#detailed-description .method .field-even li,
+#detailed-description .staticmethod .field-even li,
+#detailed-description .attribute .field-even li {
+ list-style-type: '';
+ margin: 0;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd p,
+#detailed-description .method .field-odd p,
+#detailed-description .staticmethod .field-odd p,
+#detailed-description .attribute .field-odd p{
+ margin: 0;
+ margin-left: 20px;
+
+}
+
+#detailed-description .class .field-even p,
+#detailed-description .method .field-even p,
+#detailed-description .staticmethod .field-even p,
+#detailed-description .attribute .field-even p{
+ margin: 0;
+ margin-left: 20px;
}
.document dl.attribute,
@@ -1056,9 +1117,15 @@ div.multi-column div {
}
.col-2 h2,.toc h3,.sidebar-content h2,
.sidebar-content h3,.sectionlist h2,
+.sphinxsidebar {
+ position: fixed;
+ overflow: scroll;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
.sphinxsidebar h3 {
- font-weight:400;
- margin-bottom:1em
+ font-weight: bold;
+ margin-bottom:1em;
}
.toc h3 a {
color:#404244
diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp b/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp
index d4dde36b..db11e22f 100644
--- a/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp
+++ b/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp
@@ -49,32 +49,32 @@
****************************************************************************/
//! [0]
- i = QInputDialog().getInteger(self, self.tr("QInputDialog().getInteger()"),
- self.tr("Percentage:"), 25, 0, 100, 1, ok)
+ i, ok = QInputDialog().getInteger(self, "QInputDialog().getInteger()",
+ "Percentage:", 25, 0, 100, 1)
if ok:
- self.integerLabel.setText(self.tr("%1%").arg(i))
+ self.integerLabel.setText("{}%".format(i))
//! [0]
//! [1]
- d = QInputDialog().getDouble(self, self.tr("QInputDialog().getDouble()"),
- self.tr("Amount:"), 37.56, -10000, 10000, 2, ok)
+ d, ok = QInputDialog().getDouble(self, "QInputDialog().getDouble()",
+ "Amount:", 37.56, -10000, 10000, 2)
if ok:
- doubleLabel.setText(QString("$%1").arg(d))
+ doubleLabel.setText("${}".format())
//! [1]
//! [2]
- items = [self.tr("Spring"), self.tr("Summer"), self.tr("Fall"), self.tr("Winter")]
+ items = ["Spring", "Summer", "Fall", "Winter"]
- item = QInputDialog().getItem(self, self.tr("QInputDialog().getItem()"),
- selftr("Season:"), items, 0, False, ok)
+ item, ok = QInputDialog().getItem(self, "QInputDialog().getItem()",
+ "Season:", items, 0, False)
if ok and not item.isEmpty():
itemLabel.setText(item)
//! [2]
//! [3]
- text = QInputDialog::getText(self, self.tr("QInputDialog().getText()"),
- self.tr("User name:"), QLineEdit.Normal,
- QDir().home().dirName(), ok)
+ text, ok = QInputDialog().getText(self, "QInputDialog().getText()",
+ "User name:", QLineEdit.Normal,
+ QDir().home().dirName())
if ok and text:
textLabel.setText(text)
//! [3]
diff --git a/sources/pyside2/doc/gettingstarted.rst b/sources/pyside2/doc/gettingstarted.rst
index cc915a5c..0ee6a917 100644
--- a/sources/pyside2/doc/gettingstarted.rst
+++ b/sources/pyside2/doc/gettingstarted.rst
@@ -30,11 +30,25 @@ Testing the Installation
========================
Now that you have |project| installed, you can test your setup by running the following Python
-constructs to print version information:
+constructs to print version information::
-.. include:: pysideversion.rst
- :start-line: 5
- :end-line: 32
+ import PySide2.QtCore
+
+ # Prints PySide2 version
+ # e.g. 5.11.1a1
+ print(PySide2.__version__)
+
+ # Gets a tuple with each version component
+ # e.g. (5, 11, 1, 'a', 1)
+ print(PySide2.__version_info__)
+
+ # Prints the Qt version used to compile PySide2
+ # e.g. "5.11.2"
+ print(PySide2.QtCore.__version__)
+
+ # Gets a tuple with each version components of Qt used to compile PySide2
+ # e.g. (5, 11, 2)
+ print(PySide2.QtCore.__version_info__)
Creating a Simple Application
=============================
diff --git a/sources/pyside2/libpyside/pysideclassinfo.cpp b/sources/pyside2/libpyside/pysideclassinfo.cpp
index bf2a1307..fe5ca876 100644
--- a/sources/pyside2/libpyside/pysideclassinfo.cpp
+++ b/sources/pyside2/libpyside/pysideclassinfo.cpp
@@ -45,8 +45,7 @@
#include "dynamicqmetaobject.h"
#include <shiboken.h>
-
-#define CLASSINFO_CLASS_NAME "ClassInfo"
+#include <signature.h>
extern "C"
{
@@ -65,7 +64,7 @@ static PyType_Slot PySideClassInfoType_slots[] = {
{0, 0}
};
static PyType_Spec PySideClassInfoType_spec = {
- "PySide2.QtCore." CLASSINFO_CLASS_NAME,
+ "PySide2.QtCore.ClassInfo",
sizeof(PySideClassInfo),
0,
Py_TPFLAGS_DEFAULT,
@@ -161,7 +160,7 @@ int classInfoTpInit(PyObject *self, PyObject *args, PyObject *kwds)
}
}
- return PyErr_Occurred() ? -1 : 1;
+ return PyErr_Occurred() ? -1 : 0;
}
void classInfoFree(void *self)
@@ -179,13 +178,17 @@ void classInfoFree(void *self)
namespace PySide { namespace ClassInfo {
+static const char *ClassInfo_SignatureStrings[] = {
+ "PySide2.QtCore.ClassInfo(**info:typing.Dict[str,str])",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySideClassInfoTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideClassInfoTypeF(), ClassInfo_SignatureStrings) < 0)
return;
Py_INCREF(PySideClassInfoTypeF());
- PyModule_AddObject(module, CLASSINFO_CLASS_NAME, reinterpret_cast<PyObject *>(PySideClassInfoTypeF()));
+ PyModule_AddObject(module, "ClassInfo", reinterpret_cast<PyObject *>(PySideClassInfoTypeF()));
}
bool checkType(PyObject *pyObj)
diff --git a/sources/pyside2/libpyside/pysideclassinfo_p.h b/sources/pyside2/libpyside/pysideclassinfo_p.h
index 426aee13..c0038a71 100644
--- a/sources/pyside2/libpyside/pysideclassinfo_p.h
+++ b/sources/pyside2/libpyside/pysideclassinfo_p.h
@@ -44,7 +44,7 @@
#include <QMetaObject>
#include "pysideclassinfo.h"
-#define __INFO_ATTR_NAME__ "__classInfo__"
+#define __INFO_ATTR_NAME__ "__classInfo__" // not used! ???
struct PySideClassInfo;
diff --git a/sources/pyside2/libpyside/pysidemetafunction.cpp b/sources/pyside2/libpyside/pysidemetafunction.cpp
index 34611720..e0e0c439 100644
--- a/sources/pyside2/libpyside/pysidemetafunction.cpp
+++ b/sources/pyside2/libpyside/pysidemetafunction.cpp
@@ -41,6 +41,7 @@
#include "pysidemetafunction_p.h"
#include <shiboken.h>
+#include <signature.h>
#include <QtCore/QMetaMethod>
@@ -65,7 +66,7 @@ static PyType_Slot PySideMetaFunctionType_slots[] = {
{0, 0}
};
static PyType_Spec PySideMetaFunctionType_spec = {
- "PySide.MetaFunction",
+ "PySide2.QtCore.MetaFunction",
sizeof(PySideMetaFunction),
0,
Py_TPFLAGS_DEFAULT,
@@ -101,11 +102,16 @@ PyObject *functionCall(PyObject *self, PyObject *args, PyObject * /* kw */)
namespace PySide { namespace MetaFunction {
+static const char *MetaFunction_SignatureStrings[] = {
+ "PySide2.QtCore.MetaFunction.__call__(*args:typing.Any)->typing.Any",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySideMetaFunctionTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideMetaFunctionTypeF(), MetaFunction_SignatureStrings) < 0)
return;
+ Py_INCREF(PySideMetaFunctionTypeF());
PyModule_AddObject(module, "MetaFunction", reinterpret_cast<PyObject *>(PySideMetaFunctionTypeF()));
}
diff --git a/sources/pyside2/libpyside/pysideproperty.cpp b/sources/pyside2/libpyside/pysideproperty.cpp
index a2bf5fd2..d9d15eb3 100644
--- a/sources/pyside2/libpyside/pysideproperty.cpp
+++ b/sources/pyside2/libpyside/pysideproperty.cpp
@@ -45,8 +45,7 @@
#include "pysidesignal_p.h"
#include <shiboken.h>
-
-#define QPROPERTY_CLASS_NAME "Property"
+#include <signature.h>
extern "C"
{
@@ -82,7 +81,7 @@ static PyType_Slot PySidePropertyType_slots[] = {
};
// Dotted modulename is crucial for PyType_FromSpec to work. Is this name right?
static PyType_Spec PySidePropertyType_spec = {
- "PySide2.QtCore." QPROPERTY_CLASS_NAME,
+ "PySide2.QtCore.Property",
sizeof(PySideProperty),
0,
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC|Py_TPFLAGS_BASETYPE,
@@ -175,7 +174,7 @@ int qpropertyTpInit(PyObject *self, PyObject *args, PyObject *kwds)
/*s*/ &doc,
/*O*/ &(pData->notify),
/*bbbbbb*/ &(pData->designable), &(pData->scriptable), &(pData->stored), &(pData->user), &(pData->constant), &(pData->final))) {
- return 0;
+ return -1;
}
if (doc) {
@@ -198,7 +197,7 @@ int qpropertyTpInit(PyObject *self, PyObject *args, PyObject *kwds)
Py_XINCREF(pData->freset);
Py_XINCREF(pData->fdel);
Py_XINCREF(pData->notify);
- return 1;
+ return 0;
}
pData->fget = nullptr;
pData->fset = nullptr;
@@ -321,13 +320,24 @@ static PyObject *getFromType(PyTypeObject *type, PyObject *name)
namespace PySide { namespace Property {
+static const char *Property_SignatureStrings[] = {
+ "PySide2.QtCore.Property(type:type,fget:typing.Callable=None,fset:typing.Callable=None,"
+ "freset:typing.Callable=None,fdel:typing.Callable=None,doc:str=None,"
+ "notify:typing.Callable=None,designable:bool=True,scriptable:bool=True,"
+ "stored:bool=True,user:bool=False,constant:bool=False,final:bool=False)",
+ "PySide2.QtCore.Property.getter(func:typing.Callable)",
+ "PySide2.QtCore.Property.read(func:typing.Callable)",
+ "PySide2.QtCore.Property.setter(func:typing.Callable)",
+ "PySide2.QtCore.Property.write(func:typing.Callable)",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySidePropertyTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySidePropertyTypeF(), Property_SignatureStrings) < 0)
return;
Py_INCREF(PySidePropertyTypeF());
- PyModule_AddObject(module, QPROPERTY_CLASS_NAME, reinterpret_cast<PyObject *>(PySidePropertyTypeF()));
+ PyModule_AddObject(module, "Property", reinterpret_cast<PyObject *>(PySidePropertyTypeF()));
}
bool checkType(PyObject *pyObj)
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index 47a5fff4..a09c17a2 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -47,12 +47,11 @@
#include <QtCore/QObject>
#include <QtCore/QMetaMethod>
#include <QtCore/QMetaObject>
+#include <signature.h>
#include <algorithm>
#include <utility>
-#define SIGNAL_CLASS_NAME "Signal"
-#define SIGNAL_INSTANCE_NAME "SignalInstance"
#define QT_SIGNAL_SENTINEL '2'
namespace PySide {
@@ -101,35 +100,35 @@ static PyObject *signalCall(PyObject *, PyObject *, PyObject *);
static PyObject *metaSignalCheck(PyObject *, PyObject *);
-static PyMethodDef Signal_methods[] = {
- {"__instancecheck__", (PyCFunction)metaSignalCheck, METH_O, NULL},
+static PyMethodDef MetaSignal_methods[] = {
+ {"__instancecheck__", (PyCFunction)metaSignalCheck, METH_O|METH_STATIC, NULL},
{0, 0, 0, 0}
};
-static PyType_Slot PySideSignalMetaType_slots[] = {
- {Py_tp_methods, (void *)Signal_methods},
+static PyType_Slot PySideMetaSignalType_slots[] = {
+ {Py_tp_methods, (void *)MetaSignal_methods},
{Py_tp_base, (void *)&PyType_Type},
{Py_tp_free, (void *)PyObject_GC_Del},
{Py_tp_dealloc, (void *)object_dealloc},
{0, 0}
};
-static PyType_Spec PySideSignalMetaType_spec = {
+static PyType_Spec PySideMetaSignalType_spec = {
"PySide2.QtCore.MetaSignal",
0,
// sizeof(PyHeapTypeObject) is filled in by PyType_FromSpecWithBases
// which calls PyType_Ready which calls inherit_special.
0,
Py_TPFLAGS_DEFAULT,
- PySideSignalMetaType_slots,
+ PySideMetaSignalType_slots,
};
-PyTypeObject *PySideSignalMetaTypeF(void)
+PyTypeObject *PySideMetaSignalTypeF(void)
{
static PyTypeObject *type = nullptr;
if (!type) {
PyObject *bases = Py_BuildValue("(O)", &PyType_Type);
- type = (PyTypeObject *)PyType_FromSpecWithBases(&PySideSignalMetaType_spec, bases);
+ type = (PyTypeObject *)PyType_FromSpecWithBases(&PySideMetaSignalType_spec, bases);
Py_XDECREF(bases);
}
return type;
@@ -146,7 +145,7 @@ static PyType_Slot PySideSignalType_slots[] = {
{0, 0}
};
static PyType_Spec PySideSignalType_spec = {
- "PySide2.QtCore." SIGNAL_CLASS_NAME,
+ "PySide2.QtCore.Signal",
sizeof(PySideSignal),
0,
Py_TPFLAGS_DEFAULT,
@@ -160,7 +159,7 @@ PyTypeObject *PySideSignalTypeF(void)
if (!type) {
type = (PyTypeObject *)PyType_FromSpec(&PySideSignalType_spec);
PyTypeObject *hold = Py_TYPE(type);
- Py_TYPE(type) = PySideSignalMetaTypeF();
+ Py_TYPE(type) = PySideMetaSignalTypeF();
Py_INCREF(Py_TYPE(type));
Py_DECREF(hold);
}
@@ -185,7 +184,7 @@ static PyType_Slot PySideSignalInstanceType_slots[] = {
{0, 0}
};
static PyType_Spec PySideSignalInstanceType_spec = {
- "PySide2.QtCore." SIGNAL_INSTANCE_NAME,
+ "PySide2.QtCore.SignalInstance",
sizeof(PySideSignalInstance),
0,
Py_TPFLAGS_DEFAULT,
@@ -211,8 +210,8 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds)
emptyTuple = PyTuple_New(0);
if (!PyArg_ParseTupleAndKeywords(emptyTuple, kwds,
- "|sO:QtCore." SIGNAL_CLASS_NAME, const_cast<char **>(kwlist), &argName, &argArguments))
- return 0;
+ "|sO:QtCore.Signal", const_cast<char **>(kwlist), &argName, &argArguments))
+ return -1;
bool tupledArgs = false;
PySideSignal *data = reinterpret_cast<PySideSignal *>(self);
@@ -257,7 +256,7 @@ int signalTpInit(PyObject *self, PyObject *args, PyObject *kwds)
PySide::Signal::SignalSignature(sig));
}
- return 1;
+ return 0;
}
void signalFree(void *self)
@@ -317,7 +316,7 @@ PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds)
static const char *kwlist[] = {"slot", "type", nullptr};
if (!PyArg_ParseTupleAndKeywords(args, kwds,
- "O|O:" SIGNAL_INSTANCE_NAME, const_cast<char **>(kwlist), &slot, &type))
+ "O|O:SignalInstance", const_cast<char **>(kwlist), &slot, &type))
return 0;
PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self);
@@ -585,9 +584,9 @@ PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw)
return PyCFunction_Call(homonymousMethod, args, kw);
}
-static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *args)
+static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *arg)
{
- if (PyType_IsSubtype(Py_TYPE(args), PySideSignalInstanceTypeF()))
+ if (PyType_IsSubtype(Py_TYPE(arg), PySideSignalInstanceTypeF()))
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
@@ -598,21 +597,36 @@ static PyObject *metaSignalCheck(PyObject * /* klass */, PyObject *args)
namespace PySide {
namespace Signal {
+static const char *MetaSignal_SignatureStrings[] = {
+ "PySide2.QtCore.MetaSignal.__instancecheck__(object:object)->bool",
+ nullptr}; // Sentinel
+
+static const char *Signal_SignatureStrings[] = {
+ "PySide2.QtCore.Signal(*types:type,name:str=nullptr,arguments:str=nullptr)",
+ nullptr}; // Sentinel
+
+static const char *SignalInstance_SignatureStrings[] = {
+ "PySide2.QtCore.SignalInstance.connect(slot:object,type:type=nullptr)",
+ "PySide2.QtCore.SignalInstance.disconnect(slot:object=nullptr)",
+ "PySide2.QtCore.SignalInstance.emit(*args:typing.Any)",
+ nullptr}; // Sentinel
+
void init(PyObject *module)
{
- if (PyType_Ready(PySideSignalMetaTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideMetaSignalTypeF(), MetaSignal_SignatureStrings) < 0)
return;
+ Py_INCREF(PySideSignalTypeF());
+ PyModule_AddObject(module, "MetaSignal", reinterpret_cast<PyObject *>(PySideMetaSignalTypeF()));
- if (PyType_Ready(PySideSignalTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideSignalTypeF(), Signal_SignatureStrings) < 0)
return;
-
Py_INCREF(PySideSignalTypeF());
- PyModule_AddObject(module, SIGNAL_CLASS_NAME, reinterpret_cast<PyObject *>(PySideSignalTypeF()));
+ PyModule_AddObject(module, "Signal", reinterpret_cast<PyObject *>(PySideSignalTypeF()));
- if (PyType_Ready(PySideSignalInstanceTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideSignalInstanceTypeF(), SignalInstance_SignatureStrings) < 0)
return;
-
Py_INCREF(PySideSignalInstanceTypeF());
+ PyModule_AddObject(module, "SignalInstance", reinterpret_cast<PyObject *>(PySideSignalInstanceTypeF()));
}
bool checkType(PyObject *pyObj)
diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp
index 2cdf3262..204253aa 100644
--- a/sources/pyside2/libpyside/pysideslot.cpp
+++ b/sources/pyside2/libpyside/pysideslot.cpp
@@ -45,8 +45,7 @@
#include <QtCore/QMetaObject>
#include <QtCore/QString>
-
-#define SLOT_DEC_NAME "Slot"
+#include <signature.h>
struct SlotData
{
@@ -76,7 +75,7 @@ static PyType_Slot PySideSlotType_slots[] = {
{0, 0}
};
static PyType_Spec PySideSlotType_spec = {
- "PySide2.QtCore." SLOT_DEC_NAME,
+ "PySide2.QtCore.Slot",
sizeof(PySideSlot),
0,
Py_TPFLAGS_DEFAULT,
@@ -102,9 +101,9 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
if (emptyTuple == 0)
emptyTuple = PyTuple_New(0);
- if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore." SLOT_DEC_NAME,
+ if (!PyArg_ParseTupleAndKeywords(emptyTuple, kw, "|sO:QtCore.Slot",
const_cast<char **>(kwlist), &argName, &argResult)) {
- return 0;
+ return -1;
}
PySideSlot *data = reinterpret_cast<PySideSlot *>(self);
@@ -128,7 +127,7 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
data->slotData->resultType = argResult
? PySide::Signal::getTypeName(argResult) : PySide::Signal::voidType();
- return 1;
+ return 0;
}
PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */)
@@ -177,15 +176,20 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */)
} // extern "C"
-namespace PySide { namespace Slot {
+namespace PySide {
+namespace Slot {
+
+static const char *Slot_SignatureStrings[] = {
+ "PySide2.QtCore.Slot(*types:type,name:str=nullptr,result:str=nullptr)->typing.Callable[...,typing.Optional[str]]",
+ nullptr}; // Sentinel
void init(PyObject *module)
{
- if (PyType_Ready(PySideSlotTypeF()) < 0)
+ if (SbkSpecial_Type_Ready(module, PySideSlotTypeF(), Slot_SignatureStrings) < 0)
return;
Py_INCREF(PySideSlotTypeF());
- PyModule_AddObject(module, SLOT_DEC_NAME, reinterpret_cast<PyObject *>(PySideSlotTypeF()));
+ PyModule_AddObject(module, "Slot", reinterpret_cast<PyObject *>(PySideSlotTypeF()));
}
} // namespace Slot
diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py
index d2dd4960..835f1be4 100644
--- a/sources/pyside2/pyside_version.py
+++ b/sources/pyside2/pyside_version.py
@@ -39,7 +39,7 @@
major_version = "5"
minor_version = "13"
-patch_version = "0"
+patch_version = "1"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/pyside2/tests/QtCore/qslot_object_test.py b/sources/pyside2/tests/QtCore/qslot_object_test.py
index b8d5513f..7a2691a0 100644
--- a/sources/pyside2/tests/QtCore/qslot_object_test.py
+++ b/sources/pyside2/tests/QtCore/qslot_object_test.py
@@ -31,7 +31,10 @@
import unittest
from PySide2 import QtCore
-global qApp
+"""
+This is a simple slot test that was updated to use the qApp "macro".
+It is implicitly in builtins and does not need an import.
+"""
class objTest(QtCore.QObject):
@@ -41,21 +44,15 @@ class objTest(QtCore.QObject):
self.ok = False
def slot(self):
- global qApp
-
self.ok = True
qApp.quit()
-
class slotTest(unittest.TestCase):
def quit_app(self):
- global qApp
-
qApp.quit()
def testBasic(self):
- global qApp
timer = QtCore.QTimer()
timer.setInterval(100)
@@ -71,6 +68,5 @@ class slotTest(unittest.TestCase):
if __name__ == '__main__':
- global qApp
- qApp = QtCore.QCoreApplication([])
+ QtCore.QCoreApplication()
unittest.main()
diff --git a/sources/shiboken2/doc/_themes/pysidedocs/static/pyside.css b/sources/shiboken2/doc/_themes/pysidedocs/static/pyside.css
index 956e3113..ec48705f 100644
--- a/sources/shiboken2/doc/_themes/pysidedocs/static/pyside.css
+++ b/sources/shiboken2/doc/_themes/pysidedocs/static/pyside.css
@@ -4,7 +4,7 @@
div.admonition {
margin: 1em 0 1em;
- padding: 7px;
+ padding: 0;
}
div.admonition dt {
@@ -43,6 +43,7 @@ div.warning {
div.seealso {
background-color: #ffffcc;
border: 1px solid #ffff66;
+ padding: 3px 0px 3px 10px;
}
div.note {
@@ -291,13 +292,21 @@ tt.descname {
#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
list-style: none;
- margin: 0px;
- padding: 10px;
+ margin: 0;
+ padding: 0;
border: 1px solid #ddd;
background-color: #f4f4f4;
- -moz-border-radius:10px;
- -webkit-border-radius:10px;
- -khtml-border-radius:10px;
+}
+
+#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
+ margin: 0;
+ padding: 0;
+}
+
+#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
+ margin: 5px;
+ padding: 0;
+ font-size: 90%;
}
#synopsis span.pre {
@@ -312,11 +321,63 @@ tt.descname {
margin: 0px;
margin-bottom: 10px;
padding: 10px;
- border: 1px solid #ddd;
+ font-weight: bold;
background-color: #f4f4f4;
- -moz-border-radius:10px;
- -webkit-border-radius:10px;
- -khtml-border-radius:10px;
+}
+
+#detailed-description .class .field-odd,
+#detailed-description .method .field-odd,
+#detailed-description .staticmethod .field-odd,
+#detailed-description .attribute .field-odd {
+ margin: 0;
+ padding: 1px;
+ background-color: #ffffff;
+
+}
+
+#detailed-description .class .field-even,
+#detailed-description .method .field-even,
+#detailed-description .staticmethod .field-even,
+#detailed-description .attribute .field-even {
+ margin: 0;
+ padding: 1px;
+ background-color: #ffffff;
+}
+
+#detailed-description .class .field-odd li,
+#detailed-description .method .field-odd li,
+#detailed-description .staticmethod .field-odd li,
+#detailed-description .attribute .field-odd li {
+ list-style-type: '';
+ margin: 0;
+ padding: 0;
+
+}
+
+#detailed-description .class .field-even li,
+#detailed-description .method .field-even li,
+#detailed-description .staticmethod .field-even li,
+#detailed-description .attribute .field-even li {
+ list-style-type: '';
+ margin: 0;
+ padding: 0;
+}
+
+#detailed-description .class .field-odd p,
+#detailed-description .method .field-odd p,
+#detailed-description .staticmethod .field-odd p,
+#detailed-description .attribute .field-odd p{
+ margin: 0;
+ margin-left: 20px;
+
+}
+
+#detailed-description .class .field-even p,
+#detailed-description .method .field-even p,
+#detailed-description .staticmethod .field-even p,
+#detailed-description .attribute .field-even p{
+ margin: 0;
+ margin-left: 20px;
}
.document dl.attribute,
@@ -1056,9 +1117,15 @@ div.multi-column div {
}
.col-2 h2,.toc h3,.sidebar-content h2,
.sidebar-content h3,.sectionlist h2,
+.sphinxsidebar {
+ position: fixed;
+ overflow: scroll;
+ overflow-x: hidden;
+ overflow-y: hidden;
+}
.sphinxsidebar h3 {
- font-weight:400;
- margin-bottom:1em
+ font-weight: bold;
+ margin-bottom:1em;
}
.toc h3 a {
color:#404244
diff --git a/sources/shiboken2/doc/typesystemvariables.rst b/sources/shiboken2/doc/typesystemvariables.rst
index b1b9bbfe..73d4dd12 100644
--- a/sources/shiboken2/doc/typesystemvariables.rst
+++ b/sources/shiboken2/doc/typesystemvariables.rst
@@ -150,6 +150,8 @@ Variables
since it otherwise would be indistinguishable from the pointer assignment
above.
+ It is possible to use "auto" as type.
+
.. _converttopython:
**%CONVERTTOPYTHON[CPPTYPE]**
diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
index e36b6edc..68bcfe50 100644
--- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp
@@ -5387,7 +5387,7 @@ void CppGenerator::writeGetattroFunction(QTextStream &s, GeneratorContext &conte
s << INDENT << "PyTypeObject *tp = Py_TYPE(self);" << endl;
s << INDENT << "PyErr_Format(PyExc_AttributeError," << endl;
s << INDENT << " \"'%.50s' object has no attribute '%.400s'\"," << endl;
- s << INDENT << " tp->tp_name, PyBytes_AS_STRING(name));" << endl;
+ s << INDENT << " tp->tp_name, Shiboken::String::toCString(name));" << endl;
s << INDENT << "return nullptr;" << endl;
}
s << INDENT << "} else {" << endl;
diff --git a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
index e41c9171..34e43a4c 100644
--- a/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
+++ b/sources/shiboken2/generator/shiboken2/shibokengenerator.cpp
@@ -2047,7 +2047,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
const QString conversionSignature = conversionType->cppSignature();
- if (varType != conversionSignature)
+ if (varType != QLatin1String("auto") && varType != conversionSignature)
qFatal("%s", qPrintable(msgConversionTypesDiffer(varType, conversionSignature)));
c << getFullTypeName(conversionType) << ' ' << varName;
writeMinimalConstructorExpression(c, conversionType);
diff --git a/sources/shiboken2/libshiboken/signature.cpp b/sources/shiboken2/libshiboken/signature.cpp
index e62f861a..2cade65e 100644
--- a/sources/shiboken2/libshiboken/signature.cpp
+++ b/sources/shiboken2/libshiboken/signature.cpp
@@ -187,8 +187,12 @@ _get_class_of_descr(PyObject *ob)
}
static PyObject *
-GetClassOfFunc(PyObject *ob)
+GetClassOrModOf(PyObject *ob)
{
+ /*
+ * Return the type or module of a function or type.
+ * The purpose is finally to use the name of the object.
+ */
if (PyType_Check(ob)) {
// PySide-928: The type case must do refcounting like the others as well.
Py_INCREF(ob);
@@ -202,7 +206,7 @@ GetClassOfFunc(PyObject *ob)
return _get_class_of_descr(ob);
if (Py_TYPE(ob) == &PyWrapperDescr_Type)
return _get_class_of_descr(ob);
- Py_FatalError("unexpected type in GetClassOfFunc");
+ Py_FatalError("unexpected type in GetClassOrModOf");
return nullptr;
}
@@ -227,7 +231,7 @@ compute_name_key(PyObject *ob)
if (PyType_Check(ob))
return GetTypeKey(ob);
Shiboken::AutoDecRef func_name(get_funcname(ob));
- Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOrModOf(ob)));
return Py_BuildValue("(OO)", type_key.object(), func_name.object());
}
@@ -267,7 +271,7 @@ name_key_to_func(PyObject *ob)
PyObject *ret = PyDict_GetItem(pyside_globals->map_dict, name_key);
if (ret == nullptr) {
// do a lazy initialization
- Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOfFunc(ob)));
+ Shiboken::AutoDecRef type_key(GetTypeKey(GetClassOrModOf(ob)));
PyObject *type = PyDict_GetItem(pyside_globals->map_dict,
type_key);
if (type == nullptr)
@@ -364,7 +368,7 @@ GetSignature_Function(PyObject *obfunc, const char *modifier)
// make sure that we look into PyCFunction, only...
if (Py_TYPE(obfunc) == PepFunction_TypePtr)
Py_RETURN_NONE;
- Shiboken::AutoDecRef obtype_mod(GetClassOfFunc(obfunc));
+ Shiboken::AutoDecRef obtype_mod(GetClassOrModOf(obfunc));
Shiboken::AutoDecRef type_key(GetTypeKey(obtype_mod));
if (type_key.isNull())
Py_RETURN_NONE;
@@ -674,10 +678,16 @@ handle_doc(PyObject *ob, PyObject *old_descr)
{
init_module_1();
init_module_2();
- Shiboken::AutoDecRef ob_type(GetClassOfFunc(ob));
- auto *type = reinterpret_cast<PyTypeObject *>(ob_type.object());
- if (handle_doc_in_progress || strncmp(type->tp_name, "PySide2.", 8) != 0)
- return PyObject_CallMethod(old_descr, const_cast<char *>("__get__"), const_cast<char *>("(O)"), ob);
+ Shiboken::AutoDecRef ob_type_mod(GetClassOrModOf(ob));
+ const char *name;
+ if (PyModule_Check(ob_type_mod))
+ name = PyModule_GetName(ob_type_mod);
+ else
+ name = reinterpret_cast<PyTypeObject *>(ob_type_mod.object())->tp_name;
+ if (handle_doc_in_progress || name == nullptr
+ || strncmp(name, "PySide2.", 8) != 0)
+ return PyObject_CallMethod(old_descr, const_cast<char *>("__get__"),
+ const_cast<char *>("(O)"), ob);
handle_doc_in_progress++;
PyObject *res = PyObject_CallFunction(
pyside_globals->make_helptext_func,
@@ -720,7 +730,9 @@ static int
pyside_set___signature__(PyObject *op, PyObject *value)
{
// By this additional check, this function refuses write access.
- if (get_signature_intern(op, nullptr)) {
+ // We consider both nullptr and Py_None as not been written.
+ Shiboken::AutoDecRef has_val(get_signature_intern(op, nullptr));
+ if (!(has_val.isNull() || has_val == Py_None)) {
PyErr_Format(PyExc_AttributeError,
"Attribute '__signature__' of '%.50s' object is not writable",
Py_TYPE(op)->tp_name);
diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py
index d2dd4960..835f1be4 100644
--- a/sources/shiboken2/shiboken_version.py
+++ b/sources/shiboken2/shiboken_version.py
@@ -39,7 +39,7 @@
major_version = "5"
minor_version = "13"
-patch_version = "0"
+patch_version = "1"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
index bd827f1e..af8ada06 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -174,6 +174,13 @@ def make_signature_nameless(signature):
signature.parameters[key].__class__ = NamelessParameter
+_POSITIONAL_ONLY = inspect._POSITIONAL_ONLY
+_POSITIONAL_OR_KEYWORD = inspect._POSITIONAL_OR_KEYWORD
+_VAR_POSITIONAL = inspect._VAR_POSITIONAL
+_KEYWORD_ONLY = inspect._KEYWORD_ONLY
+_VAR_KEYWORD = inspect._VAR_KEYWORD
+_empty = inspect._empty
+
def create_signature(props, key):
if not props:
# empty signatures string
@@ -204,8 +211,8 @@ def create_signature(props, key):
elif sig_kind == "classmethod":
varnames = ("klass",) + varnames
else:
- raise SystemError("Methods must be function, method, staticmethod or "
- "classmethod")
+ raise SystemError("Methods must be function, method, staticmethod"
+ " or classmethod")
# calculate the modifications
defaults = props["defaults"][:]
if not layout.defaults:
@@ -216,14 +223,25 @@ def create_signature(props, key):
if not layout.return_annotation and "return" in annotations:
del annotations["return"]
- # attach parameters to a fake function and build a signature
- argstr = ", ".join(varnames)
- fakefunc = eval("lambda {}: None".format(argstr))
- fakefunc.__name__ = props["name"]
- fakefunc.__defaults__ = defaults
- fakefunc.__kwdefaults__ = props["kwdefaults"]
- fakefunc.__annotations__ = annotations
- sig = inspect._signature_from_function(inspect.Signature, fakefunc)
+ # Build a signature.
+ kind = inspect._POSITIONAL_OR_KEYWORD
+ params = []
+ for idx, name in enumerate(varnames):
+ if name.startswith("**"):
+ kind = _VAR_KEYWORD
+ elif name.startswith("*"):
+ kind = _VAR_POSITIONAL
+ ann = annotations.get(name, _empty)
+ name = name.lstrip("*")
+ defpos = idx - len(varnames) + len(defaults)
+ default = defaults[defpos] if defpos >= 0 else _empty
+ param = inspect.Parameter(name, kind, annotation=ann, default=default)
+ params.append(param)
+ if kind == _VAR_POSITIONAL:
+ kind = _KEYWORD_ONLY
+ sig = inspect.Signature(params,
+ return_annotation=annotations.get('return', _empty),
+ __validate_parameters__=False)
# the special case of nameless parameters
if not layout.parameter_names:
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index e6f6dc37..42b12304 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -52,6 +52,11 @@ by producing a lot of clarity.
import sys
from shibokensupport.signature import inspect
from shibokensupport.signature import get_signature
+try:
+ from PySide2.QtCore import Qt
+ EnumType = type(Qt.Key)
+except ImportError:
+ EnumType = None
class ExactEnumerator(object):
@@ -82,7 +87,8 @@ class ExactEnumerator(object):
return ret
def klass(self, class_name, klass):
- if not "Shiboken" in repr(klass.mro()):
+ modname = klass.__module__
+ if not (modname.startswith("PySide2") or modname.startswith("shiboken2")):
# don't look into any foreign classes!
ret = self.result_type()
return ret
@@ -111,6 +117,8 @@ class ExactEnumerator(object):
ret.update(self.function(func_name, thing))
for subclass_name, subclass in subclasses:
ret.update(self.klass(subclass_name, subclass))
+ if isinstance(subclass, EnumType):
+ self.enum(subclass)
return ret
def function(self, func_name, func):
@@ -121,6 +129,16 @@ class ExactEnumerator(object):
ret[key] = signature
return ret
+ def enum(self, subclass):
+ if not hasattr(self.fmt, "enum"):
+ # this is an optional feature
+ return
+ class_name = subclass.__name__
+ for enum_name, value in subclass.__dict__.items():
+ if type(type(value)) is EnumType:
+ with self.fmt.enum(class_name, enum_name, int(value)):
+ pass
+
def stringify(signature):
if isinstance(signature, list):
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index 6c76483a..8192f9bc 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -151,12 +151,18 @@ def list_modules(message):
print(" {:23}".format(name), repr(module)[:70])
+orig_typing = True
if sys.version_info >= (3,):
import typing
import inspect
inspect.formatannotation = formatannotation
else:
- from shibokensupport import typing27 as typing
+ if "typing" not in sys.modules:
+ orig_typing = False
+ from shibokensupport import typing27 as typing
+ sys.modules["typing"] = typing
+ else:
+ import typing
import inspect
namespace = inspect.__dict__
from shibokensupport import backport_inspect as inspect
@@ -196,7 +202,7 @@ def move_into_pyside_package():
put_into_package(PySide2.support.signature, parser)
put_into_package(PySide2.support.signature.lib, enum_sig)
- put_into_package(PySide2.support.signature, typing)
+ put_into_package(None if orig_typing else PySide2.support.signature, typing)
put_into_package(PySide2.support.signature, inspect)
from shibokensupport.signature import mapping
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index b8097719..10d0f16a 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -67,6 +67,10 @@ ModelIndexList = typing.List[int]
QImageCleanupFunction = typing.Callable
StringList = typing.List[str]
+# unfortunately, typing.Optional[t] expands to typing.Union[t, NoneType]
+# Until we can force it to create Optional[t] again, we use this.
+NoneType = type(None)
+
_S = TypeVar("_S")
# Building our own Char type, which is much nicer than
@@ -225,7 +229,7 @@ class Reloader(object):
self.sys_module_count = len(sys.modules)
g = globals()
# PYSIDE-1009: Try to recognize unknown modules in errorhandler.py
- candidates = list(mod_name for mod_name in sys.modules
+ candidates = list(mod_name for mod_name in sys.modules.copy()
if self.module_valid(sys.modules[mod_name]))
for mod_name in candidates:
# 'top' is PySide2 when we do 'import PySide.QtCore'
@@ -316,6 +320,7 @@ type_map.update({
"zero(int)": 0,
"zero(object)": None,
"zero(str)": "",
+ "...": "...",
})
@@ -345,6 +350,7 @@ def init_sample():
"Foo.HANDLE": int,
"HANDLE": int,
"Null": None,
+ "nullptr": None,
"ObjectType.Identifier": Missing("sample.ObjectType.Identifier"),
"OddBool": bool,
"PStr": str,
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 6109bcee..3d14ec7b 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -116,7 +116,7 @@ def _parse_line(line):
print("KEYWORD", ret)
name = name + "_"
if "=" in ann:
- ann, default = ann.split("=")
+ ann, default = ann.split("=", 1)
tup = name, ann, default
else:
tup = name, ann
@@ -167,9 +167,11 @@ def try_to_guess(thing, valtype):
def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
- if valtype.startswith("PySide2."):
+ if valtype.startswith("PySide2.") or valtype.startswith("typing."):
return None
- name = type_map[valtype].__name__
+ mapped = type_map[valtype]
+ # typing.Any: '_SpecialForm' object has no attribute '__name__'
+ name = mapped.__name__ if hasattr(mapped, "__name__") else str(mapped)
thing = "zero({})".format(name)
if thing in type_map:
return type_map[thing]
@@ -275,9 +277,9 @@ def calculate_props(line):
for idx, tup in enumerate(arglist):
name, ann = tup[:2]
if ann == "...":
- name = "*args"
- # copy the fields back :()
- ann = 'NULL' # maps to None
+ name = "*args" if name.startswith("arg_") else "*" + name
+ # copy the pathed fields back
+ ann = 'nullptr' # maps to None
tup = name, ann
arglist[idx] = tup
annotations[name] = _resolve_type(ann, line, 0)
diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py
index 786a84ec..44d78c43 100644
--- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py
+++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py
@@ -86,6 +86,10 @@ PSF LICENSE AGREEMENT FOR PYTHON 3.7.0
to be bound by the terms and conditions of this License Agreement.
"""
+# This is the typing module for Python 2.7
+# https://github.com/python/typing
+# 2019-08-22
+
from __future__ import absolute_import, unicode_literals
import abc
@@ -108,8 +112,11 @@ __all__ = [
'Any',
'Callable',
'ClassVar',
+ 'Final',
'Generic',
+ 'Literal',
'Optional',
+ 'Protocol',
'Tuple',
'Type',
'TypeVar',
@@ -141,6 +148,7 @@ __all__ = [
'SupportsAbs',
'SupportsComplex',
'SupportsFloat',
+ 'SupportsIndex',
'SupportsInt',
# Concrete collection types.
@@ -152,17 +160,20 @@ __all__ = [
'Set',
'FrozenSet',
'NamedTuple', # Not really a type.
+ 'TypedDict', # Not really a type.
'Generator',
# One-off things.
'AnyStr',
'cast',
+ 'final',
'get_type_hints',
'NewType',
'no_type_check',
'no_type_check_decorator',
'NoReturn',
'overload',
+ 'runtime_checkable',
'Text',
'TYPE_CHECKING',
]
@@ -447,7 +458,7 @@ def _type_check(arg, msg):
if (
type(arg).__name__ in ('_Union', '_Optional') and
not getattr(arg, '__origin__', None) or
- isinstance(arg, TypingMeta) and arg._gorg in (Generic, _Protocol)
+ isinstance(arg, TypingMeta) and arg._gorg in (Generic, Protocol)
):
raise TypeError("Plain %s is not valid as type argument" % arg)
return arg
@@ -466,7 +477,7 @@ def _type_repr(obj):
return _qualname(obj)
return '%s.%s' % (obj.__module__, _qualname(obj))
if obj is Ellipsis:
- return('...')
+ return '...'
if isinstance(obj, types.FunctionType):
return obj.__name__
return repr(obj)
@@ -537,6 +548,157 @@ class _ClassVar(_FinalTypingBase):
ClassVar = _ClassVar(_root=True)
+class _FinalMeta(TypingMeta):
+ """Metaclass for _Final"""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ self = super(_FinalMeta, cls).__new__(cls, name, bases, namespace)
+ return self
+
+
+class _Final(_FinalTypingBase):
+ """A special typing construct to indicate that a name
+ cannot be re-assigned or overridden in a subclass.
+ For example:
+
+ MAX_SIZE: Final = 9000
+ MAX_SIZE += 1 # Error reported by type checker
+
+ class Connection:
+ TIMEOUT: Final[int] = 10
+ class FastConnector(Connection):
+ TIMEOUT = 1 # Error reported by type checker
+
+ There is no runtime checking of these properties.
+ """
+
+ __metaclass__ = _FinalMeta
+ __slots__ = ('__type__',)
+
+ def __init__(self, tp=None, **kwds):
+ self.__type__ = tp
+
+ def __getitem__(self, item):
+ cls = type(self)
+ if self.__type__ is None:
+ return cls(_type_check(item,
+ '{} accepts only single type.'.format(cls.__name__[1:])),
+ _root=True)
+ raise TypeError('{} cannot be further subscripted'
+ .format(cls.__name__[1:]))
+
+ def _eval_type(self, globalns, localns):
+ new_tp = _eval_type(self.__type__, globalns, localns)
+ if new_tp == self.__type__:
+ return self
+ return type(self)(new_tp, _root=True)
+
+ def __repr__(self):
+ r = super(_Final, self).__repr__()
+ if self.__type__ is not None:
+ r += '[{}]'.format(_type_repr(self.__type__))
+ return r
+
+ def __hash__(self):
+ return hash((type(self).__name__, self.__type__))
+
+ def __eq__(self, other):
+ if not isinstance(other, _Final):
+ return NotImplemented
+ if self.__type__ is not None:
+ return self.__type__ == other.__type__
+ return self is other
+
+
+Final = _Final(_root=True)
+
+
+def final(f):
+ """This decorator can be used to indicate to type checkers that
+ the decorated method cannot be overridden, and decorated class
+ cannot be subclassed. For example:
+
+ class Base:
+ @final
+ def done(self) -> None:
+ ...
+ class Sub(Base):
+ def done(self) -> None: # Error reported by type checker
+ ...
+ @final
+ class Leaf:
+ ...
+ class Other(Leaf): # Error reported by type checker
+ ...
+
+ There is no runtime checking of these properties.
+ """
+ return f
+
+
+class _LiteralMeta(TypingMeta):
+ """Metaclass for _Literal"""
+
+ def __new__(cls, name, bases, namespace):
+ cls.assert_no_subclassing(bases)
+ self = super(_LiteralMeta, cls).__new__(cls, name, bases, namespace)
+ return self
+
+
+class _Literal(_FinalTypingBase):
+ """A type that can be used to indicate to type checkers that the
+ corresponding value has a value literally equivalent to the
+ provided parameter. For example:
+
+ var: Literal[4] = 4
+
+ The type checker understands that 'var' is literally equal to the
+ value 4 and no other value.
+
+ Literal[...] cannot be subclassed. There is no runtime checking
+ verifying that the parameter is actually a value instead of a type.
+ """
+
+ __metaclass__ = _LiteralMeta
+ __slots__ = ('__values__',)
+
+ def __init__(self, values=None, **kwds):
+ self.__values__ = values
+
+ def __getitem__(self, item):
+ cls = type(self)
+ if self.__values__ is None:
+ if not isinstance(item, tuple):
+ item = (item,)
+ return cls(values=item,
+ _root=True)
+ raise TypeError('{} cannot be further subscripted'
+ .format(cls.__name__[1:]))
+
+ def _eval_type(self, globalns, localns):
+ return self
+
+ def __repr__(self):
+ r = super(_Literal, self).__repr__()
+ if self.__values__ is not None:
+ r += '[{}]'.format(', '.join(map(_type_repr, self.__values__)))
+ return r
+
+ def __hash__(self):
+ return hash((type(self).__name__, self.__values__))
+
+ def __eq__(self, other):
+ if not isinstance(other, _Literal):
+ return NotImplemented
+ if self.__values__ is not None:
+ return self.__values__ == other.__values__
+ return self is other
+
+
+Literal = _Literal(_root=True)
+
+
class AnyMeta(TypingMeta):
"""Metaclass for Any."""
@@ -1122,10 +1284,11 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
if base is Generic:
raise TypeError("Cannot inherit from plain Generic")
if (isinstance(base, GenericMeta) and
- base.__origin__ is Generic):
+ base.__origin__ in (Generic, Protocol)):
if gvars is not None:
raise TypeError(
- "Cannot inherit from Generic[...] multiple types.")
+ "Cannot inherit from Generic[...] or"
+ " Protocol[...] multiple times.")
gvars = base.__parameters__
if gvars is None:
gvars = tvars
@@ -1135,8 +1298,10 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
if not tvarset <= gvarset:
raise TypeError(
"Some type variables (%s) "
- "are not listed in Generic[%s]" %
+ "are not listed in %s[%s]" %
(", ".join(str(t) for t in tvars if t not in gvarset),
+ "Generic" if any(b.__origin__ is Generic
+ for b in bases) else "Protocol",
", ".join(str(g) for g in gvars)))
tvars = gvars
@@ -1285,25 +1450,21 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
"Parameter list to %s[...] cannot be empty" % _qualname(self))
msg = "Parameters to generic types must be types."
params = tuple(_type_check(p, msg) for p in params)
- if self is Generic:
+ if self in (Generic, Protocol):
# Generic can only be subscripted with unique type variables.
if not all(isinstance(p, TypeVar) for p in params):
raise TypeError(
- "Parameters to Generic[...] must all be type variables")
+ "Parameters to %s[...] must all be type variables" % self.__name__)
if len(set(params)) != len(params):
raise TypeError(
- "Parameters to Generic[...] must all be unique")
+ "Parameters to %s[...] must all be unique" % self.__name__)
tvars = params
args = params
elif self in (Tuple, Callable):
tvars = _type_vars(params)
args = params
- elif self is _Protocol:
- # _Protocol is internal, don't check anything.
- tvars = params
- args = params
- elif self.__origin__ in (Generic, _Protocol):
- # Can't subscript Generic[...] or _Protocol[...].
+ elif self.__origin__ in (Generic, Protocol):
+ # Can't subscript Generic[...] or Protocol[...].
raise TypeError("Cannot subscript already-subscripted %s" %
repr(self))
else:
@@ -1343,7 +1504,7 @@ class GenericMeta(TypingMeta, abc.ABCMeta):
# latter, we must extend __instancecheck__ too. For simplicity
# we just skip the cache check -- instance checks for generic
# classes are supposed to be rare anyways.
- if not isinstance(instance, type):
+ if hasattr(instance, "__class__"):
return issubclass(instance.__class__, self)
return False
@@ -1690,85 +1851,175 @@ def overload(func):
return _overload_dummy
+_PROTO_WHITELIST = ['Callable', 'Iterable', 'Iterator',
+ 'Hashable', 'Sized', 'Container', 'Collection',
+ 'Reversible', 'ContextManager']
+
+
class _ProtocolMeta(GenericMeta):
- """Internal metaclass for _Protocol.
+ """Internal metaclass for Protocol.
- This exists so _Protocol classes can be generic without deriving
+ This exists so Protocol classes can be generic without deriving
from Generic.
"""
+ def __init__(cls, *args, **kwargs):
+ super(_ProtocolMeta, cls).__init__(*args, **kwargs)
+ if not cls.__dict__.get('_is_protocol', None):
+ cls._is_protocol = any(b is Protocol or
+ isinstance(b, _ProtocolMeta) and
+ b.__origin__ is Protocol
+ for b in cls.__bases__)
+ if cls._is_protocol:
+ for base in cls.__mro__[1:]:
+ if not (base in (object, Generic) or
+ base.__module__ == '_abcoll' and
+ base.__name__ in _PROTO_WHITELIST or
+ isinstance(base, TypingMeta) and base._is_protocol or
+ isinstance(base, GenericMeta) and base.__origin__ is Generic):
+ raise TypeError('Protocols can only inherit from other protocols,'
+ ' got %r' % base)
+ cls._callable_members_only = all(callable(getattr(cls, attr))
+ for attr in cls._get_protocol_attrs())
+
+ def _no_init(self, *args, **kwargs):
+ if type(self)._is_protocol:
+ raise TypeError('Protocols cannot be instantiated')
+ cls.__init__ = _no_init
+
+ def _proto_hook(cls, other):
+ if not cls.__dict__.get('_is_protocol', None):
+ return NotImplemented
+ if not isinstance(other, type):
+ # Similar error as for issubclass(1, int)
+ # (also not a chance for old-style classes)
+ raise TypeError('issubclass() arg 1 must be a new-style class')
+ for attr in cls._get_protocol_attrs():
+ for base in other.__mro__:
+ if attr in base.__dict__:
+ if base.__dict__[attr] is None:
+ return NotImplemented
+ break
+ else:
+ return NotImplemented
+ return True
+ if '__subclasshook__' not in cls.__dict__:
+ cls.__subclasshook__ = classmethod(_proto_hook)
- def __instancecheck__(self, obj):
- if _Protocol not in self.__bases__:
- return super(_ProtocolMeta, self).__instancecheck__(obj)
- raise TypeError("Protocols cannot be used with isinstance().")
+ def __instancecheck__(self, instance):
+ # We need this method for situations where attributes are assigned in __init__
+ if isinstance(instance, type):
+ # This looks like a fundamental limitation of Python 2.
+ # It cannot support runtime protocol metaclasses, On Python 2 classes
+ # cannot be correctly inspected as instances of protocols.
+ return False
+ if ((not getattr(self, '_is_protocol', False) or
+ self._callable_members_only) and
+ issubclass(instance.__class__, self)):
+ return True
+ if self._is_protocol:
+ if all(hasattr(instance, attr) and
+ (not callable(getattr(self, attr)) or
+ getattr(instance, attr) is not None)
+ for attr in self._get_protocol_attrs()):
+ return True
+ return super(GenericMeta, self).__instancecheck__(instance)
def __subclasscheck__(self, cls):
- if not self._is_protocol:
- # No structural checks since this isn't a protocol.
- return NotImplemented
+ if (self.__dict__.get('_is_protocol', None) and
+ not self.__dict__.get('_is_runtime_protocol', None)):
+ if (sys._getframe(1).f_globals['__name__'] in ['abc', 'functools'] or
+ # This is needed because we remove subclasses from unions on Python 2.
+ sys._getframe(2).f_globals['__name__'] == 'typing'):
+ return False
+ raise TypeError("Instance and class checks can only be used with"
+ " @runtime_checkable protocols")
+ if (self.__dict__.get('_is_runtime_protocol', None) and
+ not self._callable_members_only):
+ if sys._getframe(1).f_globals['__name__'] in ['abc', 'functools']:
+ return super(GenericMeta, self).__subclasscheck__(cls)
+ raise TypeError("Protocols with non-method members"
+ " don't support issubclass()")
+ return super(_ProtocolMeta, self).__subclasscheck__(cls)
- if self is _Protocol:
- # Every class is a subclass of the empty protocol.
- return True
+ def _get_protocol_attrs(self):
+ attrs = set()
+ for base in self.__mro__[:-1]: # without object
+ if base.__name__ in ('Protocol', 'Generic'):
+ continue
+ annotations = getattr(base, '__annotations__', {})
+ for attr in list(base.__dict__.keys()) + list(annotations.keys()):
+ if (not attr.startswith('_abc_') and attr not in (
+ '__abstractmethods__', '__annotations__', '__weakref__',
+ '_is_protocol', '_is_runtime_protocol', '__dict__',
+ '__args__', '__slots__', '_get_protocol_attrs',
+ '__next_in_mro__', '__parameters__', '__origin__',
+ '__orig_bases__', '__extra__', '__tree_hash__',
+ '__doc__', '__subclasshook__', '__init__', '__new__',
+ '__module__', '_MutableMapping__marker',
+ '__metaclass__', '_gorg', '_callable_members_only')):
+ attrs.add(attr)
+ return attrs
- # Find all attributes defined in the protocol.
- attrs = self._get_protocol_attrs()
- for attr in attrs:
- if not any(attr in d.__dict__ for d in cls.__mro__):
- return False
- return True
+class Protocol(object):
+ """Base class for protocol classes. Protocol classes are defined as::
- def _get_protocol_attrs(self):
- # Get all Protocol base classes.
- protocol_bases = []
- for c in self.__mro__:
- if getattr(c, '_is_protocol', False) and c.__name__ != '_Protocol':
- protocol_bases.append(c)
+ class Proto(Protocol):
+ def meth(self):
+ # type: () -> int
+ pass
- # Get attributes included in protocol.
- attrs = set()
- for base in protocol_bases:
- for attr in base.__dict__.keys():
- # Include attributes not defined in any non-protocol bases.
- for c in self.__mro__:
- if (c is not base and attr in c.__dict__ and
- not getattr(c, '_is_protocol', False)):
- break
- else:
- if (not attr.startswith('_abc_') and
- attr != '__abstractmethods__' and
- attr != '_is_protocol' and
- attr != '_gorg' and
- attr != '__dict__' and
- attr != '__args__' and
- attr != '__slots__' and
- attr != '_get_protocol_attrs' and
- attr != '__next_in_mro__' and
- attr != '__parameters__' and
- attr != '__origin__' and
- attr != '__orig_bases__' and
- attr != '__extra__' and
- attr != '__tree_hash__' and
- attr != '__module__'):
- attrs.add(attr)
+ Such classes are primarily used with static type checkers that recognize
+ structural subtyping (static duck-typing), for example::
- return attrs
+ class C:
+ def meth(self):
+ # type: () -> int
+ return 0
+
+ def func(x):
+ # type: (Proto) -> int
+ return x.meth()
+
+ func(C()) # Passes static type check
+ See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable
+ act as simple-minded runtime protocols that checks only the presence of
+ given attributes, ignoring their type signatures.
-class _Protocol(object):
- """Internal base class for protocol classes.
+ Protocol classes can be generic, they are defined as::
- This implements a simple-minded structural issubclass check
- (similar but more general than the one-offs in collections.abc
- such as Hashable).
+ class GenProto(Protocol[T]):
+ def meth(self):
+ # type: () -> T
+ pass
"""
__metaclass__ = _ProtocolMeta
__slots__ = ()
-
_is_protocol = True
+ def __new__(cls, *args, **kwds):
+ if cls._gorg is Protocol:
+ raise TypeError("Type Protocol cannot be instantiated; "
+ "it can be used only as a base class")
+ return _generic_new(cls.__next_in_mro__, cls, *args, **kwds)
+
+
+def runtime_checkable(cls):
+ """Mark a protocol class as a runtime protocol, so that it
+ can be used with isinstance() and issubclass(). Raise TypeError
+ if applied to a non-protocol class.
+
+ This allows a simple-minded structural check very similar to the
+ one-offs in collections.abc such as Hashable.
+ """
+ if not isinstance(cls, _ProtocolMeta) or not cls._is_protocol:
+ raise TypeError('@runtime_checkable can be only applied to protocol classes,'
+ ' got %r' % cls)
+ cls._is_runtime_protocol = True
+ return cls
+
# Various ABCs mimicking those in collections.abc.
# A few are simply re-exported for completeness.
@@ -1786,7 +2037,8 @@ class Iterator(Iterable[T_co]):
__extra__ = collections_abc.Iterator
-class SupportsInt(_Protocol):
+@runtime_checkable
+class SupportsInt(Protocol):
__slots__ = ()
@abstractmethod
@@ -1794,7 +2046,8 @@ class SupportsInt(_Protocol):
pass
-class SupportsFloat(_Protocol):
+@runtime_checkable
+class SupportsFloat(Protocol):
__slots__ = ()
@abstractmethod
@@ -1802,7 +2055,8 @@ class SupportsFloat(_Protocol):
pass
-class SupportsComplex(_Protocol):
+@runtime_checkable
+class SupportsComplex(Protocol):
__slots__ = ()
@abstractmethod
@@ -1810,7 +2064,17 @@ class SupportsComplex(_Protocol):
pass
-class SupportsAbs(_Protocol[T_co]):
+@runtime_checkable
+class SupportsIndex(Protocol):
+ __slots__ = ()
+
+ @abstractmethod
+ def __index__(self):
+ pass
+
+
+@runtime_checkable
+class SupportsAbs(Protocol[T_co]):
__slots__ = ()
@abstractmethod
@@ -1823,7 +2087,8 @@ if hasattr(collections_abc, 'Reversible'):
__slots__ = ()
__extra__ = collections_abc.Reversible
else:
- class Reversible(_Protocol[T_co]):
+ @runtime_checkable
+ class Reversible(Protocol[T_co]):
__slots__ = ()
@abstractmethod
@@ -1996,21 +2261,6 @@ 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
@@ -2100,6 +2350,87 @@ def NamedTuple(typename, fields):
return cls
+def _check_fails(cls, other):
+ try:
+ if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools', 'typing']:
+ # Typed dicts are only for static structural subtyping.
+ raise TypeError('TypedDict does not support instance and class checks')
+ except (AttributeError, ValueError):
+ pass
+ return False
+
+
+def _dict_new(cls, *args, **kwargs):
+ return dict(*args, **kwargs)
+
+
+def _typeddict_new(cls, _typename, _fields=None, **kwargs):
+ total = kwargs.pop('total', True)
+ if _fields is None:
+ _fields = kwargs
+ elif kwargs:
+ raise TypeError("TypedDict takes either a dict or keyword arguments,"
+ " but not both")
+
+ ns = {'__annotations__': dict(_fields), '__total__': total}
+ try:
+ # Setting correct module is necessary to make typed dict classes pickleable.
+ ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
+ except (AttributeError, ValueError):
+ pass
+
+ return _TypedDictMeta(_typename, (), ns)
+
+
+class _TypedDictMeta(type):
+ def __new__(cls, name, bases, ns, total=True):
+ # Create new typed dict class object.
+ # This method is called directly when TypedDict is subclassed,
+ # or via _typeddict_new when TypedDict is instantiated. This way
+ # TypedDict supports all three syntaxes described in its docstring.
+ # Subclasses and instances of TypedDict return actual dictionaries
+ # via _dict_new.
+ ns['__new__'] = _typeddict_new if name == b'TypedDict' else _dict_new
+ tp_dict = super(_TypedDictMeta, cls).__new__(cls, name, (dict,), ns)
+
+ anns = ns.get('__annotations__', {})
+ msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"
+ anns = {n: _type_check(tp, msg) for n, tp in anns.items()}
+ for base in bases:
+ anns.update(base.__dict__.get('__annotations__', {}))
+ tp_dict.__annotations__ = anns
+ if not hasattr(tp_dict, '__total__'):
+ tp_dict.__total__ = total
+ return tp_dict
+
+ __instancecheck__ = __subclasscheck__ = _check_fails
+
+
+TypedDict = _TypedDictMeta(b'TypedDict', (dict,), {})
+TypedDict.__module__ = __name__
+TypedDict.__doc__ = \
+ """A simple typed name space. At runtime it is equivalent to a plain dict.
+
+ TypedDict creates a dictionary type that expects all of its
+ instances to have a certain set of keys, with each key
+ associated with a value of a consistent type. This expectation
+ is not checked at runtime but is only enforced by type checkers.
+ Usage::
+
+ Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})
+
+ a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK
+ b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check
+
+ assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first')
+
+ The type info could be accessed via Point2D.__annotations__. TypedDict
+ supports an additional equivalent form::
+
+ Point2D = TypedDict('Point2D', x=int, y=int, label=str)
+ """
+
+
def NewType(name, tp):
"""NewType creates simple unique types with almost zero
runtime overhead. NewType(name, tp) is considered a subtype of tp
diff --git a/sources/shiboken2/tests/samplebinding/objecttype_test.py b/sources/shiboken2/tests/samplebinding/objecttype_test.py
index bda14c69..f1a06c2b 100644
--- a/sources/shiboken2/tests/samplebinding/objecttype_test.py
+++ b/sources/shiboken2/tests/samplebinding/objecttype_test.py
@@ -118,5 +118,13 @@ class ObjectTypeTest(unittest.TestCase):
self.assertLess(abs(before - after), 5)
+ def testInvalidProperty(self):
+ o = ObjectType()
+ try:
+ o.typo
+ self.assertFail()
+ except AttributeError as error:
+ self.assertEqual(error.args[0], "'sample.ObjectType' object has no attribute 'typo'")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
index e07856e6..e1883c7c 100644
--- a/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken2/tests/smartbinding/smart_pointer_test.py
@@ -175,5 +175,17 @@ class SmartPointerTests(unittest.TestCase):
self.assertEqual(len(ptrToObjList), 0)
self.assertEqual(objCount(), 1)
+ def testInvalidParameter(self):
+ # Create Obj.
+ o = Obj()
+ # Create a shared pointer to an Obj together with an Obj.
+ ptrToObj = o.giveSharedPtrToObj()
+ try:
+ ptrToObj.typo
+ self.assertFail()
+ except AttributeError as error:
+ self.assertEqual(error.args[0], "'smart.SharedPtr_Obj' object has no attribute 'typo'")
+
+
if __name__ == '__main__':
unittest.main()