diff options
Diffstat (limited to 'sources/pyside2/PySide2/glue/qtcore.cpp')
-rw-r--r-- | sources/pyside2/PySide2/glue/qtcore.cpp | 194 |
1 files changed, 156 insertions, 38 deletions
diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp index 47b3dd6db..306a2239c 100644 --- a/sources/pyside2/PySide2/glue/qtcore.cpp +++ b/sources/pyside2/PySide2/glue/qtcore.cpp @@ -43,6 +43,7 @@ // @snippet include-pyside #include <pyside.h> +#include <limits> // @snippet include-pyside // @snippet pystring-check @@ -63,10 +64,15 @@ bool py2kStrCheck(PyObject *obj) // defaultValue can also be passed as positional argument, // not only as keyword. QVariant out; -if (kwds || numArgs > 1) +if (kwds || numArgs > 1) { + Py_BEGIN_ALLOW_THREADS out = %CPPSELF.value(%1, %2); -else + Py_END_ALLOW_THREADS +} else { + Py_BEGIN_ALLOW_THREADS out = %CPPSELF.value(%1); + Py_END_ALLOW_THREADS +} PyTypeObject *typeObj = reinterpret_cast<PyTypeObject*>(%PYARG_3); @@ -81,7 +87,6 @@ if (typeObj) { for (int i = 0; i < valuesSize; i++) { PyObject *item = PyUnicode_FromString(valuesList[i].data()); PyList_SET_ITEM(list, i, item); - Py_DECREF(item); } %PYARG_0 = list; @@ -110,15 +115,23 @@ if (typeObj) { float asFloat = out.toFloat(); %PYARG_0 = PyFloat_FromDouble(asFloat); } else if (typeObj == &PyBool_Type) { - %PYARG_0 = out.toBool() ? Py_True : Py_False; + if (out.toBool()) { + Py_INCREF(Py_True); + %PYARG_0 = Py_True; + } else { + Py_INCREF(Py_False); + %PYARG_0 = Py_False; + } } // TODO: PyDict_Type and PyTuple_Type } else { - if (!out.isValid()) + if (!out.isValid()) { + Py_INCREF(Py_None); %PYARG_0 = Py_None; - else + } else { %PYARG_0 = %CONVERTTOPYTHON[QVariant](out); + } } // @snippet qsettings-value @@ -361,9 +374,15 @@ static bool getReceiver(QObject *source, const char *signal, PyObject *callback, usingGlobalReceiver = true; } + const auto receiverThread = *receiver ? (*receiver)->thread() : nullptr; + if (usingGlobalReceiver) { PySide::SignalManager &signalManager = PySide::SignalManager::instance(); *receiver = signalManager.globalReceiver(source, callback); + // PYSIDE-1354: Move the global receiver to the original receivers's thread + // so that autoconnections work correctly. + if (receiverThread && receiverThread != (*receiver)->thread()) + (*receiver)->moveToThread(receiverThread); *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1(); } @@ -386,9 +405,7 @@ static bool qobjectConnect(QObject *source, const char *signal, QObject *receive slot++; PySide::SignalManager::registerMetaMethod(receiver, slot, isSignal ? QMetaMethod::Signal : QMetaMethod::Slot); bool connection; - Py_BEGIN_ALLOW_THREADS connection = QObject::connect(source, signal - 1, receiver, slot - 1, type); - Py_END_ALLOW_THREADS return connection; } @@ -444,9 +461,7 @@ static bool qobjectConnectCallback(QObject *source, const char *signal, PyObject } } bool connection; - Py_BEGIN_ALLOW_THREADS connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type); - Py_END_ALLOW_THREADS if (connection) { if (usingGlobalReceiver) signalManager.notifyGlobalReceiver(receiver); @@ -492,9 +507,7 @@ static bool qobjectDisconnectCallback(QObject *source, const char *signal, PyObj slotMethod = metaObject->method(slotIndex); bool disconnected; - Py_BEGIN_ALLOW_THREADS disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex); - Py_END_ALLOW_THREADS if (disconnected) { if (usingGlobalReceiver) @@ -570,14 +583,28 @@ bool %0 = qobjectConnect(%1, %2, %3, %4, %5); // qFatal doesn't have a stream version, so we do a // qWarning call followed by a qFatal() call using a // literal. +Py_BEGIN_ALLOW_THREADS qWarning() << %1; qFatal("[A qFatal() call was made from Python code]"); +Py_END_ALLOW_THREADS // @snippet qfatal // @snippet moduleshutdown PySide::runCleanupFunctions(); // @snippet moduleshutdown +// @snippet qt-qenum +%PYARG_0 = PySide::QEnum::QEnumMacro(%1, false); +// @snippet qt-qenum + +// @snippet qt-qflag +%PYARG_0 = PySide::QEnum::QEnumMacro(%1, true); +// @snippet qt-qflag + +// @snippet qt-init-feature +PySide::Feature::init(); +// @snippet qt-init-feature + // @snippet qt-pysideinit Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode"); Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "str"); @@ -599,7 +626,7 @@ static void msgHandlerCallback(QtMsgType type, const QMessageLogContext &ctx, co Shiboken::AutoDecRef arglist(PyTuple_New(3)); PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QtMsgType](type)); PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMessageLogContext &](ctx)); - QByteArray array = msg.toLocal8Bit(); + QByteArray array = msg.toUtf8(); // Python handler requires UTF-8 char *data = array.data(); PyTuple_SET_ITEM(arglist, 2, %CONVERTTOPYTHON[char *](data)); Shiboken::AutoDecRef ret(PyObject_CallObject(qtmsghandler, arglist)); @@ -630,7 +657,7 @@ if (%PYARG_0 == Py_None) // @snippet qline-hash namespace PySide { - template<> inline uint hash(const QLine &v) { + template<> inline Py_ssize_t hash(const QLine &v) { return qHash(qMakePair(qMakePair(v.x1(), v.y1()), qMakePair(v.x2(), v.y2()))); } }; @@ -662,9 +689,7 @@ if (!PyDateTimeAPI) // @snippet qdate-getdate int year, month, day; -%BEGIN_ALLOW_THREADS %CPPSELF.%FUNCTION_NAME(&year, &month, &day); -%END_ALLOW_THREADS %PYARG_0 = PyTuple_New(3); PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](year)); PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](month)); @@ -673,9 +698,7 @@ PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](day)); // @snippet qdate-weeknumber int yearNumber; -%BEGIN_ALLOW_THREADS int week = %CPPSELF.%FUNCTION_NAME(&yearNumber); -%END_ALLOW_THREADS %PYARG_0 = PyTuple_New(2); PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](week)); PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](yearNumber)); @@ -702,7 +725,7 @@ if (!PyDateTimeAPI) PySideDateTime_IMPORT; // @snippet qpoint namespace PySide { - template<> inline uint hash(const QPoint &v) { + template<> inline Py_ssize_t hash(const QPoint &v) { return qHash(qMakePair(v.x(), v.y())); } }; @@ -710,7 +733,7 @@ namespace PySide { // @snippet qrect namespace PySide { - template<> inline uint hash(const QRect &v) { + template<> inline Py_ssize_t hash(const QRect &v) { return qHash(qMakePair(qMakePair(v.x(), v.y()), qMakePair(v.width(), v.height()))); } }; @@ -718,7 +741,7 @@ namespace PySide { // @snippet qsize namespace PySide { - template<> inline uint hash(const QSize &v) { + template<> inline Py_ssize_t hash(const QSize &v) { return qHash(qMakePair(v.width(), v.height())); } }; @@ -793,6 +816,11 @@ static inline bool _findChildrenComparator(const QObject *&child, const QRegExp return name.indexIn(child->objectName()) != -1; } +static inline bool _findChildrenComparator(const QObject *&child, const QRegularExpression &name) +{ + return name.match(child->objectName()).hasMatch(); +} + static inline bool _findChildrenComparator(const QObject *&child, const QString &name) { return name.isNull() || name == child->objectName(); @@ -815,15 +843,10 @@ QObject *child = _findChildHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *> %PYARG_0 = %CONVERTTOPYTHON[QObject *](child); // @snippet qobject-findchild-2 -// @snippet qobject-findchildren-1 +// @snippet qobject-findchildren %PYARG_0 = PyList_New(0); _findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %PYARG_0); -// @snippet qobject-findchildren-1 - -// @snippet qobject-findchildren-2 -%PYARG_0 = PyList_New(0); -_findChildrenHelper(%CPPSELF, %2, reinterpret_cast<PyTypeObject *>(%PYARG_1), %PYARG_0); -// @snippet qobject-findchildren-2 +// @snippet qobject-findchildren // @snippet qobject-tr QString result; @@ -1039,6 +1062,7 @@ static int SbkQByteArray_getbufferproc(PyObject *obj, Py_buffer *view, int flags QByteArray * cppSelf = %CONVERTTOCPP[QByteArray *](obj); //XXX /|\ omitting this space crashes shiboken! + #ifdef Py_LIMITED_API view->obj = obj; view->buf = reinterpret_cast<void *>(cppSelf->data()); view->len = cppSelf->size(); @@ -1046,13 +1070,20 @@ static int SbkQByteArray_getbufferproc(PyObject *obj, Py_buffer *view, int flags view->itemsize = 1; view->format = const_cast<char *>("c"); view->ndim = 1; - view->shape = NULL; + view->shape = (flags & PyBUF_ND) == PyBUF_ND ? &(view->len) : nullptr; view->strides = &view->itemsize; view->suboffsets = NULL; view->internal = NULL; Py_XINCREF(obj); return 0; +#else // Py_LIMITED_API + const int result = PyBuffer_FillInfo(view, obj, reinterpret_cast<void *>(cppSelf->data()), + cppSelf->size(), 0, flags); + if (result == 0) + Py_XINCREF(obj); + return result; +#endif } #if PY_VERSION_HEX < 0x03000000 @@ -1275,6 +1306,14 @@ QByteArray ba(1 + int(%2), char(0)); %CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1)); // @snippet qcryptographichash-adddata +// @snippet qsocketdescriptor +#ifdef WIN32 +using DescriptorType = Qt::HANDLE; +#else +using DescriptorType = int; +#endif +// @snippet qsocketdescriptor + // @snippet qsocketnotifier PyObject *socket = %PYARG_1; if (socket != nullptr) { @@ -1415,8 +1454,8 @@ if (qApp) { // this will keep app live after python exit (extra ref) } // PYSIDE-571: make sure that we return the singleton "None" -if (pyApp == Py_None) - Py_DECREF(MakeSingletonQAppWrapper(nullptr)); // here qApp and instance() diverge +if (Py_TYPE(pyApp) == Py_TYPE(Py_None)) + Py_DECREF(MakeQAppWrapper(nullptr)); %PYARG_0 = pyApp; Py_XINCREF(%PYARG_0); // @snippet qcoreapplication-instance @@ -1424,7 +1463,10 @@ Py_XINCREF(%PYARG_0); // @snippet qdatastream-readrawdata QByteArray data; data.resize(%2); -int result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size()); +int result = 0; +Py_BEGIN_ALLOW_THREADS +result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size()); +Py_END_ALLOW_THREADS if (result == -1) { Py_INCREF(Py_None); %PYARG_0 = Py_None; @@ -1434,7 +1476,10 @@ if (result == -1) { // @snippet qdatastream-readrawdata // @snippet qdatastream-writerawdata -int r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1)); +int r = 0; +Py_BEGIN_ALLOW_THREADS +r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1)); +Py_END_ALLOW_THREADS %PYARG_0 = %CONVERTTOPYTHON[int](r); // @snippet qdatastream-writerawdata @@ -1565,7 +1610,9 @@ QT_END_NAMESPACE // @snippet use-stream-for-format-security // Uses the stream version for security reasons // see gcc man page at -Wformat-security +Py_BEGIN_ALLOW_THREADS %FUNCTION_NAME() << %1; +Py_END_ALLOW_THREADS // @snippet use-stream-for-format-security // @snippet qresource-registerResource @@ -1579,12 +1626,16 @@ QT_END_NAMESPACE // @snippet qstring-return // @snippet stream-write-method +Py_BEGIN_ALLOW_THREADS (*%CPPSELF) << %1; +Py_END_ALLOW_THREADS // @snippet stream-write-method // @snippet stream-read-method %RETURN_TYPE _cpp_result; +Py_BEGIN_ALLOW_THREADS (*%CPPSELF) >> _cpp_result; +Py_END_ALLOW_THREADS %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](_cpp_result); // @snippet stream-read-method @@ -1606,7 +1657,9 @@ if (PyBytes_Check(%PYARG_0)) { // @snippet qiodevice-readData QByteArray ba(1 + int(%2), char(0)); +Py_BEGIN_ALLOW_THREADS %CPPSELF.%FUNCTION_NAME(ba.data(), int(%2)); +Py_END_ALLOW_THREADS %PYARG_0 = Shiboken::String::fromCString(ba.constData()); // @snippet qiodevice-readData @@ -1651,14 +1704,30 @@ QByteArray ba(1 + int(%2), char(0)); %out = %OUTTYPE(PyLong_AsUnsignedLong(%in)); // @snippet conversion-pylong-unsigned +// @snippet conversion-pylong-quintptr +#if defined(IS_PY3K) && QT_POINTER_SIZE == 8 +%out = %OUTTYPE(PyLong_AsUnsignedLongLong(%in)); +#else +%out = %OUTTYPE(PyLong_AsUnsignedLong(%in)); +#endif +// @snippet conversion-pylong-quintptr + // @snippet conversion-pyunicode #ifndef Py_LIMITED_API Py_UNICODE *unicode = PyUnicode_AS_UNICODE(%in); -# if defined(Py_UNICODE_WIDE) +# if defined(Py_UNICODE_WIDE) // cast as Py_UNICODE can be a different type -%out = QString::fromUcs4((const uint *)unicode); -# else -%out = QString::fromUtf16((const ushort *)unicode, PyUnicode_GET_SIZE(%in)); +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +%out = QString::fromUcs4(reinterpret_cast<const char32_t *>(unicode)); +# else +%out = QString::fromUcs4(reinterpret_cast<const uint *>(unicode)); +# endif // Qt 6 +# else // Py_UNICODE_WIDE +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +%out = QString::fromUtf16(reinterpret_cast<const char16_t *>(unicode), PepUnicode_GetLength(%in)); +# else +%out = QString::fromUtf16(reinterpret_cast<const ushort *>(unicode), PepUnicode_GetLength(%in)); +# endif // Qt 6 # endif #else wchar_t *temp = PyUnicode_AsWideCharString(%in, NULL); @@ -1690,8 +1759,11 @@ int i = %CONVERTTOCPP[int](%in); // @snippet conversion-pyint // @snippet conversion-qlonglong +// PYSIDE-1250: For QVariant, if the type fits into an int; use int preferably. qlonglong in = %CONVERTTOCPP[qlonglong](%in); -%out = %OUTTYPE(in); +constexpr qlonglong intMax = qint64(std::numeric_limits<int>::max()); +constexpr qlonglong intMin = qint64(std::numeric_limits<int>::min()); +%out = in >= intMin && in <= intMax ? %OUTTYPE(int(in)) : %OUTTYPE(in); // @snippet conversion-qlonglong // @snippet conversion-qstring @@ -1840,6 +1912,14 @@ return PyLong_FromLong(%in); return PyLong_FromUnsignedLong(%in); // @snippet return-pylong-unsigned +// @snippet return-pylong-quintptr +#if defined(IS_PY3K) && QT_POINTER_SIZE == 8 +return PyLong_FromUnsignedLongLong(%in); +#else +return PyLong_FromUnsignedLong(%in); +#endif +// @snippet return-pylong-quintptr + // @snippet return-pyunicode QByteArray ba = %in.toUtf8(); return PyUnicode_FromStringAndSize(ba.constData(), ba.size()); @@ -1914,3 +1994,41 @@ PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first)); PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second)); return %out; // @snippet return-qpair + +// @snippet qthread_pthread_cleanup +#ifdef Q_OS_UNIX +# include <stdio.h> +# include <pthread.h> +static void qthread_pthread_cleanup(void *arg) +{ + // PYSIDE 1282: When terminating a thread using QThread::terminate() + // (pthread_cancel()), QThread::run() is aborted and the lock is released, + // but ~GilState() is still executed for some reason. Prevent it from + // releasing. + auto gil = reinterpret_cast<Shiboken::GilState *>(arg); + gil->abandon(); +} +#endif // Q_OS_UNIX +// @snippet qthread_pthread_cleanup + +// @snippet qthread_pthread_cleanup_install +#ifdef Q_OS_UNIX +pthread_cleanup_push(qthread_pthread_cleanup, &gil); +#endif +// @snippet qthread_pthread_cleanup_install + +// @snippet qthread_pthread_cleanup_uninstall +#ifdef Q_OS_UNIX +pthread_cleanup_pop(0); +#endif +// @snippet qthread_pthread_cleanup_uninstall + +// @snippet qlibraryinfo_build +#if defined(IS_PY3K) && defined(Py_LIMITED_API) +auto suffix = PyUnicode_FromString(" [limited API]"); +auto oldResult = pyResult; +pyResult = PyUnicode_Concat(pyResult, suffix); +Py_DECREF(oldResult); +Py_DECREF(suffix); +#endif +// @snippet qlibraryinfo_build |