aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sources/pyside2/tests/QtCore/bug_826.py4
-rw-r--r--sources/pyside2/tests/QtCore/qenum_test.py18
-rw-r--r--sources/pyside2/tests/QtWidgets/bug_493.py8
-rw-r--r--sources/shiboken2/libshiboken/sbkenum.cpp157
4 files changed, 102 insertions, 85 deletions
diff --git a/sources/pyside2/tests/QtCore/bug_826.py b/sources/pyside2/tests/QtCore/bug_826.py
index 5e3a12146..b5701fc5a 100644
--- a/sources/pyside2/tests/QtCore/bug_826.py
+++ b/sources/pyside2/tests/QtCore/bug_826.py
@@ -46,8 +46,8 @@ class TestEvent(QEvent):
class TestEnums(unittest.TestCase):
def testUserTypesValues(self):
- self.assertTrue(QEvent.User <= int(TestEvent.TestEventType) <= QEvent.MaxUser)
- self.assertTrue(QEvent.User <= int(TEST_EVENT_TYPE) <= QEvent.MaxUser)
+ self.assertTrue(QEvent.User <= TestEvent.TestEventType <= QEvent.MaxUser)
+ self.assertTrue(QEvent.User <= TEST_EVENT_TYPE <= QEvent.MaxUser)
def testUserTypesRepr(self):
self.assertEqual(eval(repr(TestEvent.TestEventType)), TestEvent.TestEventType)
diff --git a/sources/pyside2/tests/QtCore/qenum_test.py b/sources/pyside2/tests/QtCore/qenum_test.py
index eccbfac23..ada625f24 100644
--- a/sources/pyside2/tests/QtCore/qenum_test.py
+++ b/sources/pyside2/tests/QtCore/qenum_test.py
@@ -49,6 +49,24 @@ class TestEnum(unittest.TestCase):
def testToIntInFunction(self):
self.assertEqual(str(int(QIODevice.WriteOnly)), "2")
+ def testOperations(self):
+ k = Qt.Key.Key_1
+
+ # Integers
+ self.assertEqual(k + 2, 2 + k)
+ self.assertEqual(k - 2, -(2 - k))
+ self.assertEqual(k * 2, 2 * k)
+
+ # Floats
+ with self.assertRaises(TypeError):
+ a = k+2.0
+
+ with self.assertRaises(TypeError):
+ a = k-2.0
+
+ with self.assertRaises(TypeError):
+ a = k*2.0
+
class TestQFlags(unittest.TestCase):
def testToItn(self):
om = QIODevice.NotOpen
diff --git a/sources/pyside2/tests/QtWidgets/bug_493.py b/sources/pyside2/tests/QtWidgets/bug_493.py
index 100959fbb..19cbb0023 100644
--- a/sources/pyside2/tests/QtWidgets/bug_493.py
+++ b/sources/pyside2/tests/QtWidgets/bug_493.py
@@ -32,7 +32,7 @@ from PySide2.QtWidgets import QApplication
import unittest
-class TestBug569(unittest.TestCase):
+class TestBug493(unittest.TestCase):
def testIt(self):
# We need a qapp otherwise Qt will crash when trying to detect the
@@ -42,10 +42,8 @@ class TestBug569(unittest.TestCase):
ev2 = QKeyEvent(QEvent.KeyRelease, Qt.Key_Copy, Qt.NoModifier)
ks = QKeySequence.Delete
- self.assertEqual(ev1, ks)
- self.assertEqual(ks, ev1)
- self.assertNotEqual(ev2, ks)
- self.assertNotEqual(ks, ev2)
+ self.assertTrue(ev1.matches(ks))
+ self.assertFalse(ev2.matches(ks))
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken2/libshiboken/sbkenum.cpp b/sources/shiboken2/libshiboken/sbkenum.cpp
index 3c6582adc..26b40c3cb 100644
--- a/sources/shiboken2/libshiboken/sbkenum.cpp
+++ b/sources/shiboken2/libshiboken/sbkenum.cpp
@@ -50,6 +50,8 @@
#include <vector>
#define SBK_ENUM(ENUM) reinterpret_cast<SbkEnumObject*>(ENUM)
+#define SBK_TYPE_CHECK(o) (strcmp(Py_TYPE(Py_TYPE(o))->tp_name, "Shiboken.EnumType") == 0)
+typedef PyObject* (*enum_func)(PyObject*, PyObject*);
extern "C"
{
@@ -75,7 +77,7 @@ struct SbkEnumObject
static PyObject* SbkEnumObject_repr(PyObject* self)
{
- const SbkEnumObject *enumObj = reinterpret_cast<SbkEnumObject *>(self);
+ const SbkEnumObject *enumObj = SBK_ENUM(self);
if (enumObj->ob_name)
return Shiboken::String::fromFormat("%s.%s", (Py_TYPE(self))->tp_name, PyBytes_AS_STRING(enumObj->ob_name));
else
@@ -84,7 +86,7 @@ static PyObject* SbkEnumObject_repr(PyObject* self)
static PyObject* SbkEnumObject_name(PyObject* self, void*)
{
- SbkEnumObject *enum_self = reinterpret_cast<SbkEnumObject *>(self);
+ SbkEnumObject *enum_self = SBK_ENUM(self);
if (enum_self->ob_name == NULL)
Py_RETURN_NONE;
@@ -113,6 +115,43 @@ static PyObject* SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
return reinterpret_cast<PyObject*>(self);
}
+static PyObject* enum_op(enum_func f, PyObject *a, PyObject *b) {
+ PyObject *valA = a;
+ PyObject *valB = b;
+ PyObject *result = nullptr;
+ bool enumA = false;
+ bool enumB = false;
+
+ // We are not allowing floats
+ if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
+ // Check if both variables are SbkEnumObject
+ if (SBK_TYPE_CHECK(valA)) {
+ valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+ enumA = true;
+ }
+ if (SBK_TYPE_CHECK(valB)) {
+ valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+ enumB = true;
+ }
+ }
+
+ // Without an enum we are not supporting the operation
+ if (!(enumA || enumB)) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ } else {
+ result = f(valA, valB);
+ }
+
+ // Decreasing the reference of the used variables a and b.
+ if (enumA)
+ Py_DECREF(valA);
+ if (enumB)
+ Py_DECREF(valB);
+
+ return result;
+}
+
/* Notes:
* On Py3k land we use long type when using integer numbers. However, on older
* versions of Python (version 2) we need to convert it to int type,
@@ -126,48 +165,19 @@ static PyObject* enum_int(PyObject* v)
return PyInt_FromLong(SBK_ENUM(v)->ob_value);
}
-static long getNumberValue(PyObject* v)
-{
- PyObject* number = PyNumber_Long(v);
- long result = PyLong_AsLong(number);
- Py_XDECREF(number);
- return result;
-}
-
static PyObject* enum_and(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA & valB);
+ return enum_op(PyNumber_And, self, b);
}
static PyObject* enum_or(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA | valB);
+return enum_op(PyNumber_Or, self, b);
}
static PyObject* enum_xor(PyObject* self, PyObject* b)
{
- if (!PyNumber_Check(b)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(b);
- return PyInt_FromLong(valA ^ valB);
+ return enum_op(PyNumber_Xor, self, b);
}
static int enum_bool(PyObject* v)
@@ -177,72 +187,63 @@ static int enum_bool(PyObject* v)
static PyObject* enum_add(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA + valB);
+ return enum_op(PyNumber_Add, self, v);
}
static PyObject* enum_subtract(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA - valB);
+ return enum_op(PyNumber_Subtract, self, v);
}
static PyObject* enum_multiply(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyInt_FromLong(valA * valB);
+return enum_op(PyNumber_Multiply, self, v);
}
#ifndef IS_PY3K
static PyObject* enum_divide(PyObject* self, PyObject* v)
{
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(v);
- return PyLong_FromLong(valA / valB);
+ return enum_op(PyNumber_Divide, self, v);
}
#endif
static PyObject* enum_richcompare(PyObject* self, PyObject* other, int op)
{
- int result = 0;
- if (!PyNumber_Check(other)) {
+ PyObject *valA = self;
+ PyObject *valB = other;
+ PyObject *result = nullptr;
+ bool enumA = false;
+ bool enumB = false;
+
+ // We are not allowing floats
+ if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
+
+ // Check if both variables are SbkEnumObject
+ if (SBK_TYPE_CHECK(valA)) {
+ valA = PyLong_FromLong(SBK_ENUM(valA)->ob_value);
+ enumA = true;
+ }
+ if (SBK_TYPE_CHECK(valB)) {
+ valB = PyLong_FromLong(SBK_ENUM(valB)->ob_value);
+ enumB =true;
+ }
+ }
+
+ // Without an enum we are not supporting the operation
+ if (!(enumA || enumB)) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
+ } else {
+ result = PyObject_RichCompare(valA, valB, op);
}
- long valA = SBK_ENUM(self)->ob_value;
- long valB = getNumberValue(other);
-
- switch (op) {
- case Py_EQ:
- result = (valA == valB);
- break;
- case Py_NE:
- result = (valA != valB);
- break;
- case Py_LE:
- result = (valA <= valB);
- break;
- case Py_GE:
- result = (valA >= valB);
- break;
- case Py_LT:
- result = (valA < valB);
- break;
- case Py_GT:
- result = (valA > valB);
- break;
- default:
- PyErr_BadArgument();
- return NULL;
- }
- if (result)
- Py_RETURN_TRUE;
- else
- Py_RETURN_FALSE;
+ // Decreasing the reference of the used variables a and b.
+ if (enumA)
+ Py_DECREF(valA);
+ if (enumB)
+ Py_DECREF(valB);
+
+ return result;
}
static Py_hash_t enum_hash(PyObject* pyObj)