diff --git a/qtpy/Qt3DAnimation.py b/qtpy/Qt3DAnimation.py index 8d68e593..08357630 100644 --- a/qtpy/Qt3DAnimation.py +++ b/qtpy/Qt3DAnimation.py @@ -25,7 +25,14 @@ ) from error elif PYQT6: try: + from PyQt6 import Qt3DAnimation from PyQt6.Qt3DAnimation import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(Qt3DAnimation) + del Qt3DAnimation except ModuleNotFoundError as error: raise QtModuleNotInstalledError( name="Qt3DAnimation", diff --git a/qtpy/Qt3DRender.py b/qtpy/Qt3DRender.py index 72f44f2c..e995d5f4 100644 --- a/qtpy/Qt3DRender.py +++ b/qtpy/Qt3DRender.py @@ -25,7 +25,14 @@ ) from error elif PYQT6: try: + from PyQt6 import Qt3DRender from PyQt6.Qt3DRender import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(Qt3DRender) + del Qt3DRender except ModuleNotFoundError as error: raise QtModuleNotInstalledError( name="Qt3DRender", diff --git a/qtpy/QtDBus.py b/qtpy/QtDBus.py index 1d41aab9..18b2250a 100644 --- a/qtpy/QtDBus.py +++ b/qtpy/QtDBus.py @@ -21,7 +21,14 @@ if PYQT5: from PyQt5.QtDBus import * elif PYQT6: + from PyQt6 import QtDBus from PyQt6.QtDBus import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtDBus) + del QtDBus elif PYSIDE2: raise QtBindingMissingModuleError(name="QtDBus") elif PYSIDE6: diff --git a/qtpy/QtDesigner.py b/qtpy/QtDesigner.py index acf61d57..f716db72 100644 --- a/qtpy/QtDesigner.py +++ b/qtpy/QtDesigner.py @@ -18,7 +18,14 @@ if PYQT5: from PyQt5.QtDesigner import * elif PYQT6: + from PyQt6 import QtDesigner from PyQt6.QtDesigner import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtDesigner) + del QtDesigner elif PYSIDE2: raise QtBindingMissingModuleError(name="QtDesigner") elif PYSIDE6: diff --git a/qtpy/QtHelp.py b/qtpy/QtHelp.py index d0e2babb..ee6df4c8 100644 --- a/qtpy/QtHelp.py +++ b/qtpy/QtHelp.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtHelp import * elif PYQT6: + from PyQt6 import QtHelp from PyQt6.QtHelp import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtHelp) + del QtHelp elif PYSIDE2: from PySide2.QtHelp import * elif PYSIDE6: diff --git a/qtpy/QtMultimedia.py b/qtpy/QtMultimedia.py index 7403e64d..80a9cb17 100644 --- a/qtpy/QtMultimedia.py +++ b/qtpy/QtMultimedia.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtMultimedia import * elif PYQT6: + from PyQt6 import QtMultimedia from PyQt6.QtMultimedia import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtMultimedia) + del QtMultimedia elif PYSIDE2: from PySide2.QtMultimedia import * elif PYSIDE6: diff --git a/qtpy/QtNetwork.py b/qtpy/QtNetwork.py index 2c4e5476..a4b9c929 100644 --- a/qtpy/QtNetwork.py +++ b/qtpy/QtNetwork.py @@ -13,7 +13,14 @@ if PYQT5: from PyQt5.QtNetwork import * elif PYQT6: + from PyQt6 import QtNetwork from PyQt6.QtNetwork import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtNetwork) + del QtNetwork elif PYSIDE2: from PySide2.QtNetwork import * elif PYSIDE6: diff --git a/qtpy/QtOpenGL.py b/qtpy/QtOpenGL.py index af881ed9..071e87cf 100644 --- a/qtpy/QtOpenGL.py +++ b/qtpy/QtOpenGL.py @@ -36,8 +36,15 @@ from PyQt5.QtGui import QOpenGLTimeMonitor, QOpenGLTimerQuery elif PYQT6: + from PyQt6 import QtOpenGL from PyQt6.QtGui import QOpenGLContext, QOpenGLContextGroup from PyQt6.QtOpenGL import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtOpenGL) + del QtOpenGL elif PYSIDE6: from PySide6.QtGui import QOpenGLContext, QOpenGLContextGroup from PySide6.QtOpenGL import * diff --git a/qtpy/QtOpenGLWidgets.py b/qtpy/QtOpenGLWidgets.py index c000e0fd..02db86a4 100644 --- a/qtpy/QtOpenGLWidgets.py +++ b/qtpy/QtOpenGLWidgets.py @@ -18,7 +18,14 @@ if PYQT5: raise QtBindingMissingModuleError(name="QtOpenGLWidgets") elif PYQT6: + from PyQt6 import QtOpenGLWidgets from PyQt6.QtOpenGLWidgets import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtOpenGLWidgets) + del QtOpenGLWidgets elif PYSIDE2: raise QtBindingMissingModuleError(name="QtOpenGLWidgets") elif PYSIDE6: diff --git a/qtpy/QtPositioning.py b/qtpy/QtPositioning.py index 5083cee7..508d5607 100644 --- a/qtpy/QtPositioning.py +++ b/qtpy/QtPositioning.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtPositioning import * elif PYQT6: + from PyQt6 import QtPositioning from PyQt6.QtPositioning import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtPositioning) + del QtPositioning elif PYSIDE2: from PySide2.QtPositioning import * elif PYSIDE6: diff --git a/qtpy/QtPrintSupport.py b/qtpy/QtPrintSupport.py index d78ff4cc..0b3725de 100644 --- a/qtpy/QtPrintSupport.py +++ b/qtpy/QtPrintSupport.py @@ -12,6 +12,7 @@ if PYQT5: from PyQt5.QtPrintSupport import * elif PYQT6: + from PyQt6 import QtPrintSupport from PyQt6.QtPrintSupport import * QPageSetupDialog.exec_ = lambda self, *args, **kwargs: self.exec( @@ -26,6 +27,12 @@ *args, **kwargs, ) + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtPrintSupport) + del QtPrintSupport elif PYSIDE6: from PySide6.QtPrintSupport import * diff --git a/qtpy/QtQml.py b/qtpy/QtQml.py index 9d07f0e8..1a229813 100644 --- a/qtpy/QtQml.py +++ b/qtpy/QtQml.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtQml import * elif PYQT6: + from PyQt6 import QtQml from PyQt6.QtQml import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtQml) + del QtQml elif PYSIDE6: from PySide6.QtQml import * elif PYSIDE2: diff --git a/qtpy/QtQuick.py b/qtpy/QtQuick.py index 1c2b7da3..39dc5fb2 100644 --- a/qtpy/QtQuick.py +++ b/qtpy/QtQuick.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtQuick import * elif PYQT6: + from PyQt6 import QtQuick from PyQt6.QtQuick import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtQuick) + del QtQuick elif PYSIDE6: from PySide6.QtQuick import * elif PYSIDE2: diff --git a/qtpy/QtQuickWidgets.py b/qtpy/QtQuickWidgets.py index 136b411e..cc5d0df3 100644 --- a/qtpy/QtQuickWidgets.py +++ b/qtpy/QtQuickWidgets.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtQuickWidgets import * elif PYQT6: + from PyQt6 import QtQuickWidgets from PyQt6.QtQuickWidgets import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtQuickWidgets) + del QtQuickWidgets elif PYSIDE6: from PySide6.QtQuickWidgets import * elif PYSIDE2: diff --git a/qtpy/QtSensors.py b/qtpy/QtSensors.py index 25b29190..472cb30c 100644 --- a/qtpy/QtSensors.py +++ b/qtpy/QtSensors.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtSensors import * elif PYQT6: + from PyQt6 import QtSensors from PyQt6.QtSensors import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtSensors) + del QtSensors elif PYSIDE6: from PySide6.QtSensors import * elif PYSIDE2: diff --git a/qtpy/QtSql.py b/qtpy/QtSql.py index 76a63760..dd257637 100644 --- a/qtpy/QtSql.py +++ b/qtpy/QtSql.py @@ -12,6 +12,7 @@ if PYQT5: from PyQt5.QtSql import * elif PYQT6: + from PyQt6 import QtSql from PyQt6.QtSql import * QSqlDatabase.exec_ = lambda self, *args, **kwargs: self.exec( @@ -20,6 +21,12 @@ ) QSqlQuery.exec_ = lambda self, *args, **kwargs: self.exec(*args, **kwargs) QSqlResult.exec_ = lambda self, *args, **kwargs: self.exec(*args, **kwargs) + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtSql) + del QtSql elif PYSIDE6: from PySide6.QtSql import * diff --git a/qtpy/QtStateMachine.py b/qtpy/QtStateMachine.py index 391da17d..d2cf2546 100644 --- a/qtpy/QtStateMachine.py +++ b/qtpy/QtStateMachine.py @@ -48,7 +48,14 @@ from PyQt6.QtCore import PYQT_VERSION_STR if int(PYQT_VERSION_STR.split(".")[1]) >= 9: + from PyQt6 import QtStateMachine from PyQt6.QtStateMachine import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtStateMachine) + del QtStateMachine else: from . import QtBindingInNewerVersionError diff --git a/qtpy/QtWebEngineCore.py b/qtpy/QtWebEngineCore.py index 69aa4eea..62d532d1 100644 --- a/qtpy/QtWebEngineCore.py +++ b/qtpy/QtWebEngineCore.py @@ -25,7 +25,14 @@ ) from error elif PYQT6: try: + from PyQt6 import QtWebEngineCore from PyQt6.QtWebEngineCore import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtWebEngineCore) + del QtWebEngineCore except ModuleNotFoundError as error: raise QtModuleNotInstalledError( name="QtWebEngineCore", diff --git a/qtpy/QtWebEngineQuick.py b/qtpy/QtWebEngineQuick.py index 717ac94d..4798045b 100644 --- a/qtpy/QtWebEngineQuick.py +++ b/qtpy/QtWebEngineQuick.py @@ -20,7 +20,14 @@ raise QtBindingMissingModuleError(name="QtWebEngineQuick") elif PYQT6: try: + from PyQt6 import QtWebEngineQuick from PyQt6.QtWebEngineQuick import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtWebEngineQuick) + del QtWebEngineQuick except ModuleNotFoundError as error: raise QtModuleNotInstalledError( name="QtWebEngineQuick", diff --git a/qtpy/QtXml.py b/qtpy/QtXml.py index 5f1e3b82..be370327 100644 --- a/qtpy/QtXml.py +++ b/qtpy/QtXml.py @@ -12,7 +12,14 @@ if PYQT5: from PyQt5.QtXml import * elif PYQT6: + from PyQt6 import QtXml from PyQt6.QtXml import * + + # Allow unscoped access for enums + from .enums_compat import promote_enums + + promote_enums(QtXml) + del QtXml elif PYSIDE2: from PySide2.QtXml import * elif PYSIDE6: diff --git a/qtpy/tests/test_qtdbus.py b/qtpy/tests/test_qtdbus.py index a4d9233a..411d92a9 100644 --- a/qtpy/tests/test_qtdbus.py +++ b/qtpy/tests/test_qtdbus.py @@ -1,5 +1,6 @@ import pytest +from qtpy import PYQT5, PYQT_VERSION from qtpy.tests.utils import pytest_importorskip @@ -11,3 +12,20 @@ def test_qtdbus(): assert QtDBus.QDBusAbstractInterface is not None assert QtDBus.QDBusArgument is not None assert QtDBus.QDBusConnection is not None + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + QtDBus = pytest_importorskip("qtpy.QtDBus") + + assert ( + QtDBus.QDBusError.InvalidSignature + == QtDBus.QDBusError.ErrorType.InvalidSignature + ) diff --git a/qtpy/tests/test_qtdesigner.py b/qtpy/tests/test_qtdesigner.py index 2ec8d9c4..8c01c868 100644 --- a/qtpy/tests/test_qtdesigner.py +++ b/qtpy/tests/test_qtdesigner.py @@ -1,6 +1,6 @@ import pytest -from qtpy import PYSIDE2 +from qtpy import PYQT5, PYQT_VERSION, PYSIDE2 from qtpy.tests.utils import pytest_importorskip @@ -28,3 +28,20 @@ def test_qtdesigner(): assert QtDesigner.QExtensionFactory is not None assert QtDesigner.QExtensionManager is not None assert QtDesigner.QFormBuilder is not None + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + QtDesigner = pytest_importorskip("qtpy.QtDesigner") + + assert ( + QtDesigner.QDesignerFormWindowInterface.EditFeature + == QtDesigner.QDesignerFormWindowInterface.FeatureFlag.EditFeature + ) diff --git a/qtpy/tests/test_qthelp.py b/qtpy/tests/test_qthelp.py index 1107bc57..e2f6915d 100644 --- a/qtpy/tests/test_qthelp.py +++ b/qtpy/tests/test_qthelp.py @@ -1,10 +1,12 @@ """Test for QtHelp namespace.""" +import pytest + +from qtpy import PYQT5, PYQT_VERSION, QtHelp + def test_qthelp(): """Test the qtpy.QtHelp namespace.""" - from qtpy import QtHelp - assert QtHelp.QHelpContentItem is not None assert QtHelp.QHelpContentModel is not None assert QtHelp.QHelpContentWidget is not None @@ -16,3 +18,18 @@ def test_qthelp(): assert QtHelp.QHelpSearchQuery is not None assert QtHelp.QHelpSearchQueryWidget is not None assert QtHelp.QHelpSearchResultWidget is not None + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + assert ( + QtHelp.QHelpSearchQuery.DEFAULT + == QtHelp.QHelpSearchQuery.FieldName.DEFAULT + ) diff --git a/qtpy/tests/test_qtmultimedia.py b/qtpy/tests/test_qtmultimedia.py index 354bcd65..8e493e13 100644 --- a/qtpy/tests/test_qtmultimedia.py +++ b/qtpy/tests/test_qtmultimedia.py @@ -1,14 +1,10 @@ -import sys - import pytest -from qtpy import PYQT6, PYSIDE6 +from qtpy import PYQT5, PYQT6, PYQT_VERSION, PYSIDE6, QtMultimedia def test_qtmultimedia(): """Test the qtpy.QtMultimedia namespace""" - from qtpy import QtMultimedia - assert QtMultimedia.QAudio is not None assert QtMultimedia.QAudioInput is not None @@ -16,3 +12,18 @@ def test_qtmultimedia(): assert QtMultimedia.QAbstractVideoBuffer is not None assert QtMultimedia.QAudioDeviceInfo is not None assert QtMultimedia.QSound is not None + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + assert ( + QtMultimedia.QAudio.LinearVolumeScale + == QtMultimedia.QAudio.VolumeScale.LinearVolumeScale + ) diff --git a/qtpy/tests/test_qtnetwork.py b/qtpy/tests/test_qtnetwork.py index 77b91d23..b4f6980d 100644 --- a/qtpy/tests/test_qtnetwork.py +++ b/qtpy/tests/test_qtnetwork.py @@ -1,4 +1,6 @@ -from qtpy import PYQT6, PYSIDE2, PYSIDE6, QtNetwork +import pytest + +from qtpy import PYQT5, PYQT6, PYQT_VERSION, PYSIDE2, PYSIDE6, QtNetwork def test_qtnetwork(): @@ -38,3 +40,18 @@ def test_qtnetwork(): assert QtNetwork.QSslError is not None assert QtNetwork.QSslKey is not None assert QtNetwork.QSslSocket is not None + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + assert ( + QtNetwork.QAbstractSocket.ShareAddress + == QtNetwork.QAbstractSocket.BindFlag.ShareAddress + ) diff --git a/qtpy/tests/test_qtopengl.py b/qtpy/tests/test_qtopengl.py index 93bb5bb6..2ff05ae5 100644 --- a/qtpy/tests/test_qtopengl.py +++ b/qtpy/tests/test_qtopengl.py @@ -1,7 +1,10 @@ +import pytest + +from qtpy import PYQT5, PYQT_VERSION, QtOpenGL + + def test_qtopengl(): """Test the qtpy.QtOpenGL namespace""" - from qtpy import QtOpenGL - assert QtOpenGL.QOpenGLBuffer is not None assert QtOpenGL.QOpenGLContext is not None assert QtOpenGL.QOpenGLContextGroup is not None @@ -19,3 +22,18 @@ def test_qtopengl(): assert QtOpenGL.QOpenGLWindow is not None # We do not test for QOpenGLTimeMonitor or QOpenGLTimerQuery as # they are not present on some architectures such as armhf + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + assert ( + QtOpenGL.QOpenGLBuffer.RangeRead + == QtOpenGL.QOpenGLBuffer.RangeAccessFlag.RangeRead + ) diff --git a/qtpy/tests/test_qtopenglwidgets.py b/qtpy/tests/test_qtopenglwidgets.py index 2271e926..953c9d5c 100644 --- a/qtpy/tests/test_qtopenglwidgets.py +++ b/qtpy/tests/test_qtopenglwidgets.py @@ -9,3 +9,14 @@ def test_qtopenglwidgets(): from qtpy import QtOpenGLWidgets assert QtOpenGLWidgets.QOpenGLWidget is not None + + +@pytest.mark.skipif(PYSIDE2 or PYQT5, reason="Not available in PySide2/PyQt5") +def test_enum_access(): + """Test scoped and unscoped enum access.""" + from qtpy import QtOpenGLWidgets + + assert ( + QtOpenGLWidgets.QOpenGLWidget.NoPartialUpdate + == QtOpenGLWidgets.QOpenGLWidget.UpdateBehavior.NoPartialUpdate + ) diff --git a/qtpy/tests/test_qtpositioning.py b/qtpy/tests/test_qtpositioning.py index adf8f45a..99d9609b 100644 --- a/qtpy/tests/test_qtpositioning.py +++ b/qtpy/tests/test_qtpositioning.py @@ -1,6 +1,6 @@ import pytest -from qtpy import QT6 +from qtpy import PYQT5, PYQT_VERSION, QT6 from qtpy.tests.utils import using_conda @@ -31,3 +31,24 @@ def test_qtpositioning(): assert QtPositioning.QGeoSatelliteInfoSource is not None assert QtPositioning.QGeoShape is not None assert QtPositioning.QNmeaPositionInfoSource is not None + + +@pytest.mark.skipif( + QT6 and using_conda(), + reason="QPositioning bindings not included in Conda qt-main >= 6.4.3.", +) +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access.""" + from qtpy import QtPositioning + + assert ( + QtPositioning.QGeoShape.PolygonType + == QtPositioning.QGeoShape.ShapeType.PolygonType + ) diff --git a/qtpy/tests/test_qtprintsupport.py b/qtpy/tests/test_qtprintsupport.py index 6a36aa16..ab7655ff 100644 --- a/qtpy/tests/test_qtprintsupport.py +++ b/qtpy/tests/test_qtprintsupport.py @@ -1,10 +1,8 @@ """Test QtPrintSupport.""" -import sys - import pytest -from qtpy import QtPrintSupport +from qtpy import PYQT5, PYQT_VERSION, QtPrintSupport def test_qtprintsupport(): @@ -34,3 +32,18 @@ def test_qprintpreviewwidget_print_(qtbot): assert QtPrintSupport.QPrintPreviewWidget.print_ is not None preview_widget = QtPrintSupport.QPrintPreviewWidget() preview_widget.print_() + + +@pytest.mark.skipif( + PYQT5 and PYQT_VERSION.startswith("5.9"), + reason=( + "A specific setup with at least sip 4.9.9 is needed for PyQt5 5.9.* " + "to work with scoped enum access" + ), +) +def test_enum_access(): + """Test scoped and unscoped enum access""" + assert ( + QtPrintSupport.QPrinter.HighResolution + == QtPrintSupport.QPrinter.PrinterMode.HighResolution + )