diff options
38 files changed, 187 insertions, 96 deletions
diff --git a/build_scripts/config.py b/build_scripts/config.py index b1b32068d..00cbd3fc9 100644 --- a/build_scripts/config.py +++ b/build_scripts/config.py @@ -93,6 +93,7 @@ class Config(object): 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ] self.setup_script_dir = None @@ -135,7 +136,7 @@ class Config(object): setup_kwargs['zip_safe'] = False setup_kwargs['cmdclass'] = cmd_class_dict setup_kwargs['version'] = package_version - setup_kwargs['python_requires'] = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.10" + setup_kwargs['python_requires'] = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.11" if quiet: # Tells distutils / setuptools to be quiet, and only print warnings or errors. diff --git a/build_scripts/main.py b/build_scripts/main.py index 461e5a712..c7e67ac12 100644 --- a/build_scripts/main.py +++ b/build_scripts/main.py @@ -1056,7 +1056,7 @@ class PysideBuild(_build, DistUtilsCommandMixin): OPTION["CMAKE"], "-L", # Lists variables "-N", # Just inspects the cache (faster) - "--build", # Specifies the build dir + "-B", # Specifies the build dir self.shiboken_build_dir ] out = run_process_output(cmake_cmd) diff --git a/build_scripts/wheel_override.py b/build_scripts/wheel_override.py index 66141763b..3f3c12a2e 100644 --- a/build_scripts/wheel_override.py +++ b/build_scripts/wheel_override.py @@ -90,7 +90,7 @@ class PysideBuildWheel(_bdist_wheel, DistUtilsCommandMixin): limited_api_enabled = (OPTION["LIMITED_API"] == 'yes' and sys.version_info[0] >= 3) if limited_api_enabled: - self.py_limited_api = "cp35.cp36.cp37.cp38.cp39" + self.py_limited_api = "cp35.cp36.cp37.cp38.cp39.cp310" self._package_version = get_package_version() diff --git a/coin/dependencies.yaml b/coin/dependencies.yaml index 032c8c4bd..c9df27bbb 100644 --- a/coin/dependencies.yaml +++ b/coin/dependencies.yaml @@ -1,6 +1,6 @@ product_dependency: ../../qt/tqtc-qt5.git: - ref: "4f71992dd5c14023330332538c84cb5fb5ac5a14" + ref: "715f5bca3972b1841701f4ef10b7a582a1be2723" dependency_source: supermodule dependencies: [ "../../qt/qt3d", diff --git a/coin_build_instructions.py b/coin_build_instructions.py index cf5dca62e..6a4d5dfd7 100644 --- a/coin_build_instructions.py +++ b/coin_build_instructions.py @@ -112,7 +112,7 @@ def call_setup(python_ver, phase): if phase in ["BUILD"]: rmtree(_env, True) # Pinning the virtualenv before creating one - run_instruction(["pip", "install", "--user", "virtualenv==20.0.25"], "Failed to pin virtualenv") + run_instruction(["pip", "install", "--user", "virtualenv==20.7.2"], "Failed to pin virtualenv") # installing to user base might not be in PATH by default. env_path = os.path.join(site.USER_BASE, "bin") v_env = os.path.join(env_path, "virtualenv") diff --git a/coin_test_instructions.py b/coin_test_instructions.py index 3b8f7e39c..4ba5ac9ff 100644 --- a/coin_test_instructions.py +++ b/coin_test_instructions.py @@ -67,7 +67,7 @@ def call_testrunner(python_ver, buildnro): _pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH) rmtree(_env, True) # Pinning the virtualenv before creating one - run_instruction(["pip", "install", "--user", "virtualenv==20.0.25"], "Failed to pin virtualenv") + run_instruction(["pip", "install", "--user", "virtualenv==20.7.2"], "Failed to pin virtualenv") # installing to user base might not be in PATH by default. env_path = os.path.join(site.USER_BASE, "bin") v_env = os.path.join(env_path, "virtualenv") diff --git a/dist/changes-5.15.8 b/dist/changes-5.15.8 new file mode 100644 index 000000000..f3dac46e4 --- /dev/null +++ b/dist/changes-5.15.8 @@ -0,0 +1,41 @@ +Qt for Python 5.15.8 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - Backporting changes from PySide6 to enable Python 3.10 + - [PYSIDE-803] Allow threads in QtGui.QTextDocument.print_ + - [PYSIDE-1556] Fix cmake argument for standalone macOS + - [PYSIDE-1675] PySide6: Fix a bug in Slot.__call__ + - [PYSIDE-1703] Fix build with MSVC 19.29.30136 + - [PYSIDE-1710] signature: improve error handling for embedded applications + - [PYSIDE-1710] scriptable: make it work by default on macOS, too + - [PYSIDE-1715] PySide6: Fix crash when connecting slot after disconnecting + non-existent connection to same slot + - [PYSIDE-1716] PySide2: Add QSGRendererInterface + - [PYSIDE-1727] Signature: fix the __doc__ attribute of classes + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1710] Error handling was improved for embedded + applications and builtin modules are trusted as valid modules. + - [PYSIDE-1684] shiboken6: Do not crash when class cannot be found in the + overload sorter + - [PYSIDE-1697] shiboken6: Fix a leak in keyword arguments handling + diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt index 999206425..5277d17d1 100644 --- a/examples/scriptableapplication/CMakeLists.txt +++ b/examples/scriptableapplication/CMakeLists.txt @@ -16,7 +16,7 @@ find_package(Qt5 5.12 REQUIRED COMPONENTS Core Gui Widgets) # Use provided python interpreter if given. if(NOT python_interpreter) - find_program(python_interpreter "python") + find_program(python_interpreter NAMES python3 python) endif() message(STATUS "Using python interpreter: ${python_interpreter}") diff --git a/examples/scriptableapplication/mainwindow.cpp b/examples/scriptableapplication/mainwindow.cpp index 53aea3c71..4e4135fc6 100644 --- a/examples/scriptableapplication/mainwindow.cpp +++ b/examples/scriptableapplication/mainwindow.cpp @@ -67,6 +67,7 @@ #include <QtCore/QTextStream> static const char defaultScript[] = R"( +import AppLib print("Hello, world") mainWindow.testFunction1() )"; diff --git a/examples/scriptableapplication/pythonutils.cpp b/examples/scriptableapplication/pythonutils.cpp index c5e18f256..920d3e22e 100644 --- a/examples/scriptableapplication/pythonutils.cpp +++ b/examples/scriptableapplication/pythonutils.cpp @@ -68,8 +68,11 @@ extern "C" PyObject *PyInit_AppLib(); #else extern "C" void initAppLib(); +# define PyInit_AppLib initAppLib #endif +static const char moduleName[] = "AppLib"; + // This variable stores all Python types exported by this module. extern PyTypeObject **SbkAppLibTypes; @@ -113,6 +116,11 @@ State init() if (qEnvironmentVariableIsSet(virtualEnvVar)) initVirtualEnvironment(); + if (PyImport_AppendInittab(moduleName, PyInit_AppLib) == -1) { + qWarning("Failed to add the module '%s' to the table of built-in modules.", moduleName); + return state; + } + Py_Initialize(); qAddPostRoutine(cleanup); state = PythonInitialized; diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml index e66ee48ce..617d64355 100644 --- a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml @@ -1824,7 +1824,7 @@ <define-ownership class="target" owner="target"/> </modify-argument> </modify-function> - <modify-function signature="print(QPagedPaintDevice*)const" rename="print_"/> + <modify-function signature="print(QPagedPaintDevice*)const" allow-thread="yes" rename="print_"/> </object-type> <object-type name="QTextDocumentWriter" since="4.5"/> <object-type name="QTextTable"> diff --git a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt index 0f453c90e..a500f3bcd 100644 --- a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt +++ b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt @@ -40,6 +40,7 @@ ${QtQuick_GEN_DIR}/qsgopacitynode_wrapper.cpp #${QtQuick_GEN_DIR}/qsgopaquetexturematerial_wrapper.cpp #${QtQuick_GEN_DIR}/qsgsimplematerial_wrapper.cpp #${QtQuick_GEN_DIR}/qsgsimplematerialshader_wrapper.cpp +${QtQuick_GEN_DIR}/qsgrendererinterface_wrapper.cpp ${QtQuick_GEN_DIR}/qsgsimplerectnode_wrapper.cpp ${QtQuick_GEN_DIR}/qsgsimpletexturenode_wrapper.cpp ${QtQuick_GEN_DIR}/qsgtexture_wrapper.cpp diff --git a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml index 223eff773..4f6d9086c 100644 --- a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml +++ b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml @@ -150,6 +150,13 @@ <object-type name="QSGOpacityNode"/> <!-- <object-type name="QSGOpaqueTextureMaterial"/> --> <object-type name="QSGSimpleRectNode"/> + <object-type name="QSGRendererInterface"> + <enum-type name="GraphicsApi"/> + <enum-type name="Resource"/> + <enum-type name="ShaderType"/> + <enum-type name="ShaderCompilationType" flags="ShaderCompilationTypes"/> + <enum-type name="ShaderSourceType" flags="ShaderSourceTypes"/> + </object-type> <object-type name="QSGSimpleTextureNode"> <enum-type name="TextureCoordinatesTransformFlag" flags="TextureCoordinatesTransformMode"/> </object-type> diff --git a/sources/pyside2/libpyside/feature_select.cpp b/sources/pyside2/libpyside/feature_select.cpp index 7604f69aa..3011b3584 100644 --- a/sources/pyside2/libpyside/feature_select.cpp +++ b/sources/pyside2/libpyside/feature_select.cpp @@ -408,6 +408,8 @@ static inline PyObject *SelectFeatureSet(PyTypeObject *type) if (!SelectFeatureSetSubtype(sub_type, select_id)) break; } + // PYSIDE-1436: Clear all caches for the type and subtypes. + PyType_Modified(type); } return type->tp_dict; } diff --git a/sources/pyside2/libpyside/globalreceiverv2.cpp b/sources/pyside2/libpyside/globalreceiverv2.cpp index b16a923dd..88bba9338 100644 --- a/sources/pyside2/libpyside/globalreceiverv2.cpp +++ b/sources/pyside2/libpyside/globalreceiverv2.cpp @@ -291,8 +291,10 @@ void GlobalReceiverV2::notify() #endif Py_BEGIN_ALLOW_THREADS for (const QObject *o : objSet) { - QMetaObject::disconnect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID); - QMetaObject::connect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID); + if (o) { + QMetaObject::disconnect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID); + QMetaObject::connect(o, DESTROY_SIGNAL_ID, this, DESTROY_SLOT_ID); + } } Py_END_ALLOW_THREADS } diff --git a/sources/pyside2/libpyside/pysideslot.cpp b/sources/pyside2/libpyside/pysideslot.cpp index 7911b21de..660b93caf 100644 --- a/sources/pyside2/libpyside/pysideslot.cpp +++ b/sources/pyside2/libpyside/pysideslot.cpp @@ -134,11 +134,13 @@ int slotTpInit(PyObject *self, PyObject *args, PyObject *kw) PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */) { static PyObject *pySlotName = nullptr; - PyObject *callback; - callback = PyTuple_GetItem(args, 0); + PyObject *callback = nullptr; + + if (!PyArg_UnpackTuple(args, "Slot.__call__", 1, 1, &callback)) + return nullptr; Py_INCREF(callback); - if (Py_TYPE(callback)->tp_call != nullptr) { + if (PyCallable_Check(callback)) { PySideSlot *data = reinterpret_cast<PySideSlot *>(self); if (!data->slotData) @@ -147,7 +149,7 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */) if (data->slotData->name.isEmpty()) { // PYSIDE-198: Use PyObject_GetAttr instead of PepFunction_GetName to support Nuitka. AutoDecRef funcName(PyObject_GetAttr(callback, PyMagicName::name())); - data->slotData->name = String::toCString(funcName); + data->slotData->name = funcName.isNull() ? "<no name>" : String::toCString(funcName); } const QByteArray returnType = QMetaObject::normalizedType(data->slotData->resultType); const QByteArray signature = @@ -157,7 +159,7 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */) pySlotName = String::fromCString(PYSIDE_SLOT_LIST_ATTR); PyObject *pySignature = String::fromCString(signature); - PyObject *signatureList = 0; + PyObject *signatureList = nullptr; if (PyObject_HasAttr(callback, pySlotName)) { signatureList = PyObject_GetAttr(callback, pySlotName); } else { @@ -172,7 +174,6 @@ PyObject *slotCall(PyObject *self, PyObject *args, PyObject * /* kw */) //clear data delete data->slotData; data->slotData = nullptr; - return callback; } return callback; } diff --git a/sources/pyside2/pyside_version.py b/sources/pyside2/pyside_version.py index 9ec9b0e70..ba6e714b1 100644 --- a/sources/pyside2/pyside_version.py +++ b/sources/pyside2/pyside_version.py @@ -39,7 +39,7 @@ major_version = "5" minor_version = "15" -patch_version = "7" +patch_version = "8" # For example: "a", "b", "rc" # (which means "alpha", "beta", "release candidate"). diff --git a/sources/pyside2/tests/QtWidgets/signature_test.py b/sources/pyside2/tests/QtWidgets/signature_test.py index 57fcf3874..cacb576d7 100644 --- a/sources/pyside2/tests/QtWidgets/signature_test.py +++ b/sources/pyside2/tests/QtWidgets/signature_test.py @@ -65,8 +65,9 @@ class PySideSignatureTest(unittest.TestCase): for thing in obj.__signature__: self.assertEqual(type(thing), inspect.Signature) sm = PySide2.QtWidgets.QApplication.__dict__["palette"] - self.assertFalse(callable(sm)) - self.assertEqual(sm.__func__, obj) + # PYSIDE-1436: staticmethod is a callable since Python 3.10 + # Instead of checking callable(sm), we check the type: + self.assertEqual(type(sm), staticmethod) self.assertTrue(hasattr(sm, "__signature__") and sm.__signature__ is not None) diff --git a/sources/pyside2/tests/registry/scrape_testresults.py b/sources/pyside2/tests/registry/scrape_testresults.py index c5c0e8689..56bb8058c 100644 --- a/sources/pyside2/tests/registry/scrape_testresults.py +++ b/sources/pyside2/tests/registry/scrape_testresults.py @@ -188,7 +188,7 @@ def write_data(name, text): lines.pop() text = "\n".join(lines) + "\n" modname = re.search(r"'(..*?)'", text).group(1) - fn = os.path.join(test_path, f"{ts}-{name}-{modname}.py") + fn = os.path.join(test_path, "{}-{}-{}.py".format(ts, name, modname)) if os.path.exists(fn): # do not change the file, we want to skip it return @@ -321,31 +321,31 @@ def get_test_results(starturl): minutes, seconds = divmod(remainder, 60) runtime_formatted = '%d:%02d:%06.3f' % (hours, minutes, seconds) - print(f"Run time: {runtime_formatted}s") + print("Run time: {}s".format(runtime_formatted)) if ok: found = eval_data() - print(f"Successful scan, {found} new files.") + print("Successful scan, {} new files.".format(found)) if found: print("Please check if a git push is necessary.") if __name__ == "__main__": parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, - usage=dedent(f"""\ - {os.path.basename(my_name)} [-h] scan + usage=dedent("""\ + {} [-h] scan - Scan the COIN testresults website for embedded exists_{{platf}}_{{version}}_ci.py files. + Scan the COIN testresults website for embedded exists_{{}}_{{}}_ci.py files. Warning: On the first call, this script may take almost 30 minutes to run. Subsequent calls are *much* faster due to caching. - {os.path.basename(my_name)} [-h] eval + {} [-h] eval Enforces evaluation when a scan did not complete yet. For more information, see the file sources/shiboken2/libshiboken/signature_doc.rst - """)) + """.format(os.path.basename(my_name), platf, version, os.path.basename(my_name))) subparsers = parser.add_subparsers(dest="command", metavar="", title="required argument") # create the parser for the "scan" command parser_scan = subparsers.add_parser("scan", help="run the scan") diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp index 723a13164..bf16b85ac 100644 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp @@ -1862,10 +1862,7 @@ QDebug operator<<(QDebug d, const AbstractMetaField *af) static void formatMetaEnumValue(QDebug &d, const AbstractMetaEnumValue *v) { - const QString &name = v->stringValue(); - if (!name.isEmpty()) - d << name << '='; - d << v->value(); + d << v->name() << '=' << v->value(); } QDebug operator<<(QDebug d, const AbstractMetaEnumValue *v) diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp index 95dcda558..cbcf0986b 100644 --- a/sources/shiboken2/ApiExtractor/messages.cpp +++ b/sources/shiboken2/ApiExtractor/messages.cpp @@ -678,3 +678,16 @@ QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &contex message += QLatin1String(" [") + identifier + QLatin1Char(']'); return msgTagWarning(reader, context, tag, message); } + +QString msgArgumentClassNotFound(const AbstractMetaFunction *func, + const TypeEntry *t) +{ + QString result; + QTextStream str(&result); + str << "Internal Error: Class \"" << t->qualifiedCppName() + << "\" for \""; + if (auto *ic = func->implementingClass()) + str << ic->qualifiedCppName() << "::"; + str << func->signature() << "\" not found!"; + return result; +} diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h index 3f1a8650b..b20ee6f91 100644 --- a/sources/shiboken2/ApiExtractor/messages.h +++ b/sources/shiboken2/ApiExtractor/messages.h @@ -203,4 +203,7 @@ QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &contex const QString &tag, const QString &location, const QString &identifier, const QString &fallback); +QString msgArgumentClassNotFound(const AbstractMetaFunction *func, + const TypeEntry *t); + #endif // MESSAGES_H diff --git a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp index 6572fca9a..b42ee2927 100644 --- a/sources/shiboken2/generator/shiboken2/cppgenerator.cpp +++ b/sources/shiboken2/generator/shiboken2/cppgenerator.cpp @@ -3257,7 +3257,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe { Indentation indent(INDENT); s << INDENT << "PyObject *value{};\n"; - s << INDENT << "PyObject *kwds_dup = PyDict_Copy(kwds);\n"; + s << INDENT << "Shiboken::AutoDecRef kwds_dup(PyDict_Copy(kwds));\n"; for (const AbstractMetaArgument *arg : args) { const int pyArgIndex = arg->argumentIndex() - OverloadData::numberOfRemovedArguments(func, arg->argumentIndex()); @@ -3302,7 +3302,7 @@ void CppGenerator::writeNamedArgumentResolution(QTextStream &s, const AbstractMe s << INDENT << "if (PyDict_Size(kwds_dup) > 0) {\n"; { Indentation indent(INDENT); - s << INDENT << "errInfo = kwds_dup;\n"; + s << INDENT << "errInfo = kwds_dup.release();\n"; if (!(func->isConstructor() && func->ownerClass()->isQObject())) s << INDENT << "goto " << cpythonFunctionName(func) << "_TypeError;\n"; else @@ -5230,6 +5230,10 @@ void CppGenerator::writeFlagsBinaryOperator(QTextStream &s, const AbstractMetaEn << ">(int(PyLong_AsLong(self)));\n"; s << INDENT << "cppArg = static_cast<" << flagsEntry->originalName() << ">(int(PyLong_AsLong(" << PYTHON_ARG << ")));\n"; + // PYSIDE-1436: Need to error check self as well because operators are used + // sometimes with swapped args. + s << INDENT << "if (PyErr_Occurred())\n" << INDENT + << "return nullptr;\n"; s << "#else\n"; s << INDENT << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName() << ">(int(PyInt_AsLong(self)));\n"; diff --git a/sources/shiboken2/generator/shiboken2/overloaddata.cpp b/sources/shiboken2/generator/shiboken2/overloaddata.cpp index 193384853..5edb65630 100644 --- a/sources/shiboken2/generator/shiboken2/overloaddata.cpp +++ b/sources/shiboken2/generator/shiboken2/overloaddata.cpp @@ -30,6 +30,7 @@ #include <reporthandler.h> #include <graph.h> #include "overloaddata.h" +#include "messages.h" #include "ctypenames.h" #include "indentor.h" #include "shibokengenerator.h" @@ -153,28 +154,6 @@ static QString getImplicitConversionTypeName(const AbstractMetaType *containerTy + types.join(QLatin1String(", ")) + QLatin1String(" >"); } -// overloaddata.cpp -static QString msgCyclicDependency(const QString &funcName, const QString &graphName, - const OverloadData::MetaFunctionList &involvedConversions) -{ - QString result; - QTextStream str(&result); - str << "Cyclic dependency found on overloaddata for \"" << funcName - << "\" method! The graph boy saved the graph at \"" << QDir::toNativeSeparators(graphName) - << "\"."; - if (const int count = involvedConversions.size()) { - str << " Implicit conversions (" << count << "): "; - for (int i = 0; i < count; ++i) { - if (i) - str << ", \""; - str << involvedConversions.at(i)->signature() << '"'; - if (const AbstractMetaClass *c = involvedConversions.at(i)->implementingClass()) - str << '(' << c->name() << ')'; - } - } - return result; -} - static inline int overloadNumber(const OverloadData *o) { return o->referenceFunction()->overloadNumber(); @@ -330,7 +309,10 @@ void OverloadData::sortNextOverloads() // Process inheritance relationships if (targetType->isValue() || targetType->isObject()) { - const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), targetType->typeEntry()); + auto *te = targetType->typeEntry(); + const AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_generator->classes(), te); + if (!metaClass) + qFatal("%s", qPrintable(msgArgumentClassNotFound(m_overloads.constFirst(), te))); const AbstractMetaClassList &ancestors = m_generator->getAllAncestors(metaClass); for (const AbstractMetaClass *ancestor : ancestors) { QString ancestorTypeName = ancestor->typeEntry()->name(); diff --git a/sources/shiboken2/libshiboken/autodecref.h b/sources/shiboken2/libshiboken/autodecref.h index 498b1aec4..6e6d5db95 100644 --- a/sources/shiboken2/libshiboken/autodecref.h +++ b/sources/shiboken2/libshiboken/autodecref.h @@ -101,6 +101,14 @@ public: m_pyObj = other; Py_XDECREF(_py_tmp); } + + PyObject *release() + { + PyObject *result = m_pyObj; + m_pyObj = nullptr; + return result; + } + private: PyObject *m_pyObj; }; diff --git a/sources/shiboken2/libshiboken/pep384impl.cpp b/sources/shiboken2/libshiboken/pep384impl.cpp index cb8042561..66df0fd94 100644 --- a/sources/shiboken2/libshiboken/pep384impl.cpp +++ b/sources/shiboken2/libshiboken/pep384impl.cpp @@ -754,11 +754,13 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name) #ifndef Py_LIMITED_API return _Py_Mangle(privateobj, name); #else - // For some reason, _Py_Mangle is not in the Limited API. Why? - size_t plen = PyUnicode_GET_LENGTH(privateobj); + // PYSIDE-1436: _Py_Mangle is no longer exposed; implement it always. + // The rest of this function is our own implementation of _Py_Mangle. + // Please compare the original function in compile.c . + size_t plen = PyUnicode_GET_LENGTH(privateobj.object()); /* Strip leading underscores from class name */ size_t ipriv = 0; - while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') + while (PyUnicode_READ_CHAR(privateobj.object(), ipriv) == '_') ipriv++; if (ipriv == plen) { Py_INCREF(name); diff --git a/sources/shiboken2/libshiboken/pep384impl.h b/sources/shiboken2/libshiboken/pep384impl.h index 7a6f57fcd..eb65596cc 100644 --- a/sources/shiboken2/libshiboken/pep384impl.h +++ b/sources/shiboken2/libshiboken/pep384impl.h @@ -40,6 +40,11 @@ #ifndef PEP384IMPL_H #define PEP384IMPL_H +// PYSIDE-1436: Adapt to Python 3.10 +#if PY_VERSION_HEX < 0x030900A4 +# define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0) +#endif + extern "C" { @@ -327,7 +332,7 @@ LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject * // But this is no problem as we check it's validity for every version. #define PYTHON_BUFFER_VERSION_COMPATIBLE (PY_VERSION_HEX >= 0x03030000 && \ - PY_VERSION_HEX < 0x0309FFFF) + PY_VERSION_HEX < 0x030AFFFF) #if !PYTHON_BUFFER_VERSION_COMPATIBLE # error Please check the buffer compatibility for this python version! #endif diff --git a/sources/shiboken2/libshiboken/sbkstring.cpp b/sources/shiboken2/libshiboken/sbkstring.cpp index 918aae756..077fb531b 100644 --- a/sources/shiboken2/libshiboken/sbkstring.cpp +++ b/sources/shiboken2/libshiboken/sbkstring.cpp @@ -247,7 +247,7 @@ static void finalizeStaticStrings() { auto &set = staticStrings(); for (PyObject *ob : set) { - Py_REFCNT(ob) = 1; + Py_SET_REFCNT(ob, 1); Py_DECREF(ob); } set.clear(); diff --git a/sources/shiboken2/libshiboken/signature/signature.cpp b/sources/shiboken2/libshiboken/signature/signature.cpp index 3051c50d5..191af3d9b 100644 --- a/sources/shiboken2/libshiboken/signature/signature.cpp +++ b/sources/shiboken2/libshiboken/signature/signature.cpp @@ -471,6 +471,9 @@ static PyObject *adjustFuncName(const char *func_name) // Run `eval` on the type string to get the object. AutoDecRef obtype(PyRun_String(_path, Py_eval_input, ns, ns)); + if (obtype.isNull()) + return String::fromCString(func_name); + if (PyModule_Check(obtype.object())) { // This is a plain function. Return the unmangled name. return String::fromCString(func_name); diff --git a/sources/shiboken2/libshiboken/signature/signature_extend.cpp b/sources/shiboken2/libshiboken/signature/signature_extend.cpp index 1490a6003..c1918c492 100644 --- a/sources/shiboken2/libshiboken/signature/signature_extend.cpp +++ b/sources/shiboken2/libshiboken/signature/signature_extend.cpp @@ -157,25 +157,25 @@ static PyObject *handle_doc(PyObject *ob, PyObject *old_descr) init_module_2(); AutoDecRef ob_type_mod(GetClassOrModOf(ob)); const char *name; - if (PyModule_Check(ob_type_mod)) - name = PyModule_GetName(ob_type_mod); + if (PyModule_Check(ob_type_mod.object())) + name = PyModule_GetName(ob_type_mod.object()); 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_CallMethodObjArgs(old_descr, - PyMagicName::get(), - ob, nullptr); - handle_doc_in_progress++; - PyObject *res = PyObject_CallFunction( - pyside_globals->make_helptext_func, - const_cast<char *>("(O)"), ob); - handle_doc_in_progress--; - if (res == nullptr) { - PyErr_Print(); - Py_FatalError("handle_doc did not receive a result"); + PyObject *res{}; + + if (handle_doc_in_progress || name == nullptr || strncmp(name, "PySide2.", 8) != 0) { + res = PyObject_CallMethodObjArgs(old_descr, PyMagicName::get(), ob, nullptr); + } else { + handle_doc_in_progress++; + res = PyObject_CallFunction(pyside_globals->make_helptext_func, "(O)", ob); + handle_doc_in_progress--; } - return res; + + if (res) + return res; + + PyErr_Clear(); + Py_RETURN_NONE; } static PyObject *pyside_cf_get___doc__(PyObject *cf) diff --git a/sources/shiboken2/libshiboken/signature/signature_helper.cpp b/sources/shiboken2/libshiboken/signature/signature_helper.cpp index 2b360c786..0246ec61d 100644 --- a/sources/shiboken2/libshiboken/signature/signature_helper.cpp +++ b/sources/shiboken2/libshiboken/signature/signature_helper.cpp @@ -236,7 +236,7 @@ static PyObject *_build_new_entry(PyObject *new_name, PyObject *value) PyObject *new_value = PyDict_Copy(value); PyObject *multi = PyDict_GetItem(value, PyName::multi()); if (multi != nullptr && Py_TYPE(multi) == &PyList_Type) { - ssize_t len = PyList_Size(multi); + Py_ssize_t len = PyList_Size(multi); AutoDecRef list(PyList_New(len)); if (list.isNull()) return nullptr; @@ -314,7 +314,7 @@ PyObject *_address_to_stringlist(PyObject *numkey) * When needed in `PySide_BuildSignatureProps`, the strings are * finally materialized. */ - ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError); + Py_ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError); if (address == -1 && PyErr_Occurred()) return nullptr; char **sig_strings = reinterpret_cast<char **>(address); diff --git a/sources/shiboken2/shiboken_version.py b/sources/shiboken2/shiboken_version.py index 9ec9b0e70..ba6e714b1 100644 --- a/sources/shiboken2/shiboken_version.py +++ b/sources/shiboken2/shiboken_version.py @@ -39,7 +39,7 @@ major_version = "5" minor_version = "15" -patch_version = "7" +patch_version = "8" # For example: "a", "b", "rc" # (which means "alpha", "beta", "release candidate"). diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py index 352644f7a..47ab89ab8 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py @@ -96,12 +96,11 @@ def matched_type(args, sigs): def seterror_argument(args, func_name, info): - func = None try: func = eval(func_name, namespace) except Exception as e: - msg = "Internal error evaluating {func_name}: {e}".format(**locals()) - return TypeError, msg + msg = "Error evaluating `{func_name}`: {e}".format(**locals()) + return type(e), msg if info and type(info) is str: err = TypeError if info == "<": diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py index 24e75e42c..c8dbd51cc 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py @@ -47,6 +47,7 @@ On the function with_metaclass see the answer from Martijn Pieters on https://stackoverflow.com/questions/18513821/python-metaclass-understanding-the-with-metaclass """ +from inspect import currentframe from textwrap import dedent @@ -151,4 +152,11 @@ def with_metaclass(meta, *bases): return meta.__prepare__(name, bases) return type.__new__(metaclass, 'temporary_class', (), {}) + +# A handy tool that shows the current line number and indents. +def lno(level): + lineno = currentframe().f_back.f_lineno + spaces = level * " " + return "{}{}".format(lineno, spaces) + # eof diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py index 92511df32..fa6c6c2f1 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py @@ -57,6 +57,12 @@ from shibokensupport.signature import typing from shibokensupport.signature.typing import TypeVar, Generic from shibokensupport.signature.lib.tool import with_metaclass +if sys.version_info[0] == 3: + # Avoid a deprecation warning + from _imp import is_builtin +else: + from imp import is_builtin + class ellipsis(object): def __repr__(self): return "..." @@ -181,7 +187,8 @@ class Reloader(object): if getattr(mod, "__file__", None) and not os.path.isdir(mod.__file__): ending = os.path.splitext(mod.__file__)[-1] return ending not in (".py", ".pyc", ".pyo", ".pyi") - return False + # Python 2 leaves lots of empty crap in sys.modules + return bool(hasattr(mod, "__name__") and is_builtin(mod.__name__)) def update(self): """ @@ -300,6 +307,7 @@ type_map.update({ "zero(object)": None, "zero(str)": "", "zero(typing.Any)": None, + "zero(Any)": None, }) type_map.update({ diff --git a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py index a1cb58074..3e448d9e5 100644 --- a/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py +++ b/sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py @@ -43,10 +43,11 @@ import sys import re import warnings import types +import typing import keyword import functools from shibokensupport.signature.mapping import (type_map, update_mapping, - namespace, typing, _NotCalled, ResultVariable, ArrayLikeVariable) + namespace, _NotCalled, ResultVariable, ArrayLikeVariable) from shibokensupport.signature.lib.tool import (SimpleNamespace, build_brace_pattern) @@ -222,7 +223,7 @@ def _resolve_arraytype(thing, line): def to_string(thing): if isinstance(thing, str): return thing - if hasattr(thing, "__name__"): + if hasattr(thing, "__name__") and thing.__module__ != "typing": dot = "." in str(thing) name = get_name(thing) return thing.__module__ + "." + name if dot else name @@ -239,16 +240,6 @@ def handle_matrix(arg): return eval(result, namespace) -debugging_aid = """ -from inspect import currentframe - -def lno(level): - lineno = currentframe().f_back.f_lineno - spaces = level * " " - return "{lineno}{spaces}".format(**locals()) -""" - - def _resolve_type(thing, line, level, var_handler): # Capture total replacements, first. Happens in # "PySide2.QtCore.QCborStreamReader.StringResult[PySide2.QtCore.QByteArray]" diff --git a/sources/shiboken2/tests/samplebinding/time_test.py b/sources/shiboken2/tests/samplebinding/time_test.py index f8b35e7b7..3b8f232c7 100644 --- a/sources/shiboken2/tests/samplebinding/time_test.py +++ b/sources/shiboken2/tests/samplebinding/time_test.py @@ -130,6 +130,7 @@ class TimeTest(unittest.TestCase): result = time.somethingCompletelyDifferent(1, 2, ImplicitConv.CtorOne) self.assertEqual(result, Time.ThreeArgs) + # PYSIDE-1436: These tests crash at shutdown due to `assert(Not)?Equal`. def testCompareWithPythonTime(self): time = Time(12, 32, 5) py = datetime.time(12, 32, 5) diff --git a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml index 595afb9ae..70fabcf73 100644 --- a/sources/shiboken2/tests/samplebinding/typesystem_sample.xml +++ b/sources/shiboken2/tests/samplebinding/typesystem_sample.xml @@ -1953,6 +1953,7 @@ %PYARG_0 = Py_False; else %PYARG_0 = Py_True; + Py_INCREF(%PYARG_0); } </inject-code> </add-function> @@ -1970,6 +1971,7 @@ %PYARG_0 = Py_True; else %PYARG_0 = Py_False; + Py_INCREF(%PYARG_0); } </inject-code> </add-function> |