summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2019-02-07 14:19:53 +0100
committerChristian Tismer <tismer@stackless.com>2019-02-07 21:07:27 +0000
commitb2a09c05e9cc2503f1609f720060558c0db2fe03 (patch)
tree662a156797ab038560d855483c88ff91cfaeedcd
parentbf0c928b13fb2d512c6a80ba3d1d447a4daeaa75 (diff)
Fix Shiboken.ObjectType.__new__ for Python 2.7
type(QtWidgets.QWidget).__new__(type(QtWidgets.QWidget), "", (), {}) gave a problem in Python 2.7 after transition to PEP 384. The reason for the problem is a check in Python 2.7 that tries to find out if the function used to create a new object is a secure (builtin) one. Therefore, all new types that are generated by a Python function are filtered out. Unfortunately, Python 2.7 did that assuming that only Python classes are heap types. This is at least no longer true since Python 3 migrated to the new type API where all new types are heap types. The internal check was therefore changed to do the test for a builtin "new" function differently. But not in Python 2.7 . The workaround was to create the Shiboken.ObjectType as a heap type and then remove that flag from the type. This seems to have no bad effects, probably because the types did barely change when doing the transition. Anyway, I will stay tuned and watch out if this later creates a problem. Task-number: PYSIDE-816 Change-Id: Ia596716b0e5dff3f1a7155ab6765186ef0b9d179 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/pyside2/tests/QtWidgets/qwidget_test.py7
-rw-r--r--sources/shiboken2/libshiboken/basewrapper.cpp13
2 files changed, 19 insertions, 1 deletions
diff --git a/sources/pyside2/tests/QtWidgets/qwidget_test.py b/sources/pyside2/tests/QtWidgets/qwidget_test.py
index 028751ba..d0a4a8df 100644
--- a/sources/pyside2/tests/QtWidgets/qwidget_test.py
+++ b/sources/pyside2/tests/QtWidgets/qwidget_test.py
@@ -1,6 +1,6 @@
#############################################################################
##
-## Copyright (C) 2016 The Qt Company Ltd.
+## Copyright (C) 2019 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of Qt for Python.
@@ -52,6 +52,11 @@ class QWidgetTest(UsesQApplication):
def testInheritance(self):
self.assertRaises(TypeError, QWidgetInherit)
+ if sys.version_info[0] < 3:
+ def testCallType_Issue_816(self):
+ thing = type(QWidget).__new__(type(QWidget), "", (), {})
+ self.assertEqual(repr(thing), "<class '__main__.'>")
+
class QWidgetVisible(UsesQApplication):
def testBasic(self):
diff --git a/sources/shiboken2/libshiboken/basewrapper.cpp b/sources/shiboken2/libshiboken/basewrapper.cpp
index 8fe4710d..a008fece 100644
--- a/sources/shiboken2/libshiboken/basewrapper.cpp
+++ b/sources/shiboken2/libshiboken/basewrapper.cpp
@@ -101,6 +101,15 @@ PyTypeObject *SbkObjectType_TypeF(void)
SbkObjectType_Type_spec.basicsize =
PepHeapType_SIZE + sizeof(SbkObjectTypePrivate);
type = reinterpret_cast<PyTypeObject *>(PyType_FromSpec(&SbkObjectType_Type_spec));
+#if PY_VERSION_HEX < 0x03000000
+ // PYSIDE-816: Python 2.7 has a bad check for Py_TPFLAGS_HEAPTYPE in
+ // typeobject.c func tp_new_wrapper. In Python 3 it was updated after
+ // the transition to the new type API, but not in 2.7 . Fortunately,
+ // the types did not change much when transitioning to heaptypes. We
+ // pretend that this type is a normal type in 2.7 and hope that this
+ // has no bad effect.
+ type->tp_flags &= ~Py_TPFLAGS_HEAPTYPE;
+#endif
}
return type;
}
@@ -290,6 +299,10 @@ void SbkObjectTypeDealloc(PyObject* pyObj)
SbkObjectTypePrivate *sotp = PepType_SOTP(pyObj);
PyTypeObject *type = reinterpret_cast<PyTypeObject*>(pyObj);
+#if PY_VERSION_HEX < 0x03000000
+ // PYSIDE-816: Restore the heap type flag. Better safe than sorry.
+ type->tp_flags |= Py_TPFLAGS_HEAPTYPE;
+#endif
PyObject_GC_UnTrack(pyObj);
#ifndef Py_LIMITED_API
Py_TRASHCAN_SAFE_BEGIN(pyObj);