diff --git a/python/PyQt/CMakeLists.txt b/python/PyQt/CMakeLists.txt index 2be5ac1e6b7..54562269bce 100644 --- a/python/PyQt/CMakeLists.txt +++ b/python/PyQt/CMakeLists.txt @@ -2,6 +2,7 @@ set (QGIS_PYQT_DIR ${Python_SITEARCH}/qgis/PyQt) set(PYQT_COMPAT_FILES __init__.py + common.py QtWidgets.py QtCore.py QtGui.py diff --git a/python/PyQt/PyQt/QtNetwork.py.in b/python/PyQt/PyQt/QtNetwork.py.in index 244d615ba1a..e88d2cc7b02 100644 --- a/python/PyQt/PyQt/QtNetwork.py.in +++ b/python/PyQt/PyQt/QtNetwork.py.in @@ -22,6 +22,7 @@ __date__ = 'March 2016' __copyright__ = '(C) 2016, Juergen E. Fischer' from PyQt@QT_VERSION_MAJOR@.QtNetwork import * +from .common import install_extended_enum_wrapper if @QT_VERSION_MAJOR@ == 6: # patch back in Qt flags removed in PyQt @@ -33,3 +34,6 @@ if @QT_VERSION_MAJOR@ == 6: QNetworkInterface.InterfaceFlags = lambda flags=0: QNetworkInterface.InterfaceFlag(flags) QNetworkProxy.Capabilities = lambda flags=0: QNetworkProxy.Capability(flags) QSsl.SslOptions = lambda flags=0: QSsl.SslOption(flags) + + QNetworkRequest.setAttribute = install_extended_enum_wrapper(QNetworkRequest.setAttribute) + diff --git a/python/PyQt/PyQt/common.py.in b/python/PyQt/PyQt/common.py.in new file mode 100644 index 00000000000..8616c284a8a --- /dev/null +++ b/python/PyQt/PyQt/common.py.in @@ -0,0 +1,58 @@ +""" +*************************************************************************** + common.py + --------------------- + Date : January 2024 + Copyright : (C) 2024 by Nyall Dawson + Email : nyall dot dawson at gmail dot com +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +""" + +import functools +from enum import Enum + +def _handle_extended_enum_values(v): + """ + If v is an Enum, returns an integer representation of its value wrapped + in the Enum class. + Otherwise returns v unchanged. + """ + if isinstance(v, Enum): + # v may be an Enum value which itself is an Enum value! + # E.g. QNetworkRequest.Attribute(QgsNetworkRequestParameters.RequestAttributes.AttributeInitiatorClass) + # in this case v is an Enum of the class QNetworkRequest.Attribute, while v.value is an Enum of the + # class QgsNetworkRequestParameters.RequestAttributes. For this to work, we need to extract the integer + # value from QgsNetworkRequestParameters.RequestAttributes.AttributeInitiatorClass and then convert it + # to a QNetworkRequest.Attribute enum value! + if isinstance(v.value, Enum): + return v.__class__(int(v.value.value)) + return v.__class__(int(v.value)) + return v + +def _extended_enum_wrapper(method): + """ + Calls a function, first converting all passed Enum arguments to integer + values so that extended enum values work correctly. + """ + @functools.wraps(method) + def wrapped(*args, **kwargs): + parsed_args = [_handle_extended_enum_values(arg) for arg in args] + parsed_kwargs = {k: _handle_extended_enum_values(v) for k, v in kwargs.items()} + return method(*parsed_args, **parsed_kwargs) + + return wrapped + + +def install_extended_enum_wrapper(f): + """ + Installs a wrapper on a function so that all passed extended Enum arguments are handled correctly. + """ + return _extended_enum_wrapper(f) +