aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside2/PySide2
diff options
context:
space:
mode:
authorCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2018-04-25 17:49:25 +0200
committerChristian Tismer <tismer@stackless.com>2018-06-21 14:42:51 +0000
commitaa75437f9119d997dd290471ac3e2cc88ca88bf1 (patch)
tree25bd1488cde8b60c14190d40dd03725f11f8d537 /sources/pyside2/PySide2
parent27a3402507364e15c37fcabfa025c2fed36146f0 (diff)
Fix QVariant conversions when using PySequences
Currently we transform QVariant arguments to internal types, starting from the Python ones, to others related to shiboken. After checking if the current object is a PyDict we proceed to check if it's a PySequence. PySequence is the complementary 'sequence-like' type of PyDict, and allows finite and infinite sequences, like lists or generators. The problem is that when one implements a class which includes the __getitem__ method, Python already thinks that it correspond to a PySequence, then we try to get the elements to transform into a QList<QVariant> but it fails at the first attempt. The solution was to not assume that all PySequences have finite length (or a length), and also to have a fallback case similarly to the PyDict treatment, wrapping the PyObject as a QVariant. Task-number: PYSIDE-641 Change-Id: I3b755f47ed076147024de38e5e0a86932d981f88 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources/pyside2/PySide2')
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml44
1 files changed, 34 insertions, 10 deletions
diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
index 47d43f2eb..488ee068b 100644
--- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
+++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml
@@ -430,7 +430,8 @@
%out = ret.isValid() ? ret : QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
</add-conversion>
<add-conversion type="PySequence">
- %out = QVariant_convertToVariantList(%in);
+ QVariant ret = QVariant_convertToVariantList(%in);
+ %out = ret.isValid() ? ret : QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
</add-conversion>
<add-conversion type="PyObject">
// Is a shiboken type not known by Qt
@@ -480,8 +481,12 @@
}
static QVariant QVariant_convertToValueList(PyObject *list)
{
- if (PySequence_Size(list) &lt; 1)
- return QVariant();
+ if (PySequence_Size(list) &lt; 0) {
+ // clear the error if &lt; 0 which means no length at all
+ PyErr_Clear();
+ return QVariant();
+ }
+
Shiboken::AutoDecRef element(PySequence_GetItem(list, 0));
int typeId;
const char *typeName = QVariant_resolveMetaType(element.cast&lt;PyTypeObject*&gt;(), &amp;typeId);
@@ -505,14 +510,26 @@
static bool QVariant_isStringList(PyObject *list)
{
bool allString = true;
- Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
- Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
- for (int i = 0; i &lt; size; ++i) {
- PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
- if (!%CHECKTYPE[QString](item)) {
- allString = false;
- break;
+
+ if (PySequence_Check(list)) {
+ if (PySequence_Size(list) &lt; 0) {
+ // clear the error if &lt; 0 which means no length at all
+ PyErr_Clear();
+ return false;
}
+ Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
+ Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
+ for (int i = 0; i &lt; size; ++i) {
+ PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i);
+ if (!%CHECKTYPE[QString](item)) {
+ allString = false;
+ break;
+ }
+ }
+ } else {
+ // If it is not a list or a derived list class
+ // we assume that will not be a String list neither.
+ allString = false;
}
return allString;
}
@@ -541,6 +558,13 @@
QVariant valueList = QVariant_convertToValueList(list);
if (valueList.isValid())
return valueList;
+
+ if (PySequence_Size(list) &lt; 0) {
+ // clear the error if &lt; 0 which means no length at all
+ PyErr_Clear();
+ return QVariant();
+ }
+
QList&lt;QVariant&gt; lst;
Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());