Skip to content

Qt namespace is littered with service functions #463

Open
@StSav012

Description

@StSav012

The following piece of code shows all the extra stuff QtPy adds to the PyQt/PySide modules:

# coding=utf-8
import importlib
import os
import re
import warnings
from types import ModuleType

warnings.filterwarnings("error")


def bright(text: str) -> str:
    return "\033[97m" + text + "\033[39m"


def italic(text: str) -> str:
    return "\033[3m" + text + "\033[23m"


api: str = 'PyQt5'

os.environ["FORCE_QT_API"] = "1"
os.environ["QT_API"] = api

try:
    import qtpy
except qtpy.PythonQtWarning as ex:
    print(bright(api), italic(str(ex)), sep=": ")

for module_name in [
    "Qsci",
    "Qt3DAnimation",
    "Qt3DCore",
    "Qt3DExtras",
    "Qt3DInput",
    "Qt3DLogic",
    "Qt3DRender",
    "QtAxContainer",
    "QtBluetooth",
    "QtCharts",
    "QtConcurrent",
    "QtCore",
    "QtDataVisualization",
    "QtDBus",
    "QtDesigner",
    "QtGui",
    "QtHelp",
    "QtLocation",
    "QtMacExtras",
    "QtMultimedia",
    "QtMultimediaWidgets",
    "QtNetwork",
    "QtNetworkAuth",
    "QtNfc",
    "QtOpenGL",
    "QtOpenGLWidgets",
    "QtPdf",
    "QtPdfWidgets",
    "QtPositioning",
    "QtPrintSupport",
    "QtPurchasing",
    "QtQml",
    "QtQuick",
    "QtQuick3D",
    "QtQuickControls2",
    "QtQuickWidgets",
    "QtRemoteObjects",
    "QtScxml",
    "QtSensors",
    "QtSerialPort",
    "QtSql",
    "QtStateMachine",
    "QtSvg",
    "QtSvgWidgets",
    "QtTest",
    "QtTextToSpeech",
    "QtUiTools",
    "QtWebChannel",
    "QtWebEngine",
    "QtWebEngineCore",
    "QtWebEngineQuick",
    "QtWebEngineWidgets",
    "QtWebSockets",
    "QtWidgets",
    "QtWinExtras",
    "QtX11Extras",
    "QtXml",
    "QtXmlPatterns",
]:
    try:
        original_module: ModuleType = importlib.import_module(
            f"{qtpy.API_NAME}.{module_name}"
        )
    except ModuleNotFoundError:
        # print(f"{module_name} not loaded from {API_NAME}")
        continue

    try:
        qtpy_module: ModuleType = importlib.import_module(f"qtpy.{module_name}")
    except (qtpy.QtBindingMissingModuleError, qtpy.QtModuleNotInQtVersionError) as ex:
        print(italic(str(ex)).replace(module_name, bright(module_name)))
        continue

    try:
        extra_members: frozenset[str] = (
            frozenset(dir(qtpy_module))
            - frozenset(dir(original_module))
            - frozenset(
                # To test if we are using WebEngine or WebKit
                # NOTE: This constant is imported by other projects
                # (e.g. Spyder), so please don't remove it.
                [
                    "WEBENGINE",
                ]
            )
            - frozenset(
                # These are for the compatibility b/w PySide and PyQt:
                [
                    "ClassInfo",
                    "ListProperty",
                    "MetaFunction",
                    "MetaSignal",
                    "Property",
                    "PyClassProperty",
                    "SIGNAL",
                    "SLOT",
                    "Signal",
                    "SignalInstance",
                    "Slot",
                    "VolatileBool",
                    "qjsEngine",
                    "qmlAttachedPropertiesObject",
                    "qmlClearTypeRegistrations",
                    "qmlRegisterRevision",
                    "qmlRegisterSingletonType",
                    "qmlRegisterUncreatableType",
                    "qmlTypeId",
                    "qtTrId",
                ]
            )
            - frozenset(
                # These are mostly harmless:
                [
                    "PYQT5",
                    "PYQT6",
                    "PYSIDE2",
                    "PYSIDE6",
                ]
            )
        )
    except Exception as ex:
        print(bright(f"{api}.{module_name}"), italic(str(ex)), sep=": ")
    else:
        neither_qt_nor_builtins: list[str] = sorted(
            filter(
                lambda d: re.match("(^(Q|q[A-Z]).+$|(^__[a-z_]+__$))", d) is None,
                extra_members,
            ),
        )
        if neither_qt_nor_builtins:
            print(
                bright(f"{api}.{module_name}"),
                ", ".join(neither_qt_nor_builtins),
                sep=": ",
            )

(It might be better to test the APIs one by one.)

For most of the modules, it's just PYQT5, PYQT6, PYSIDE2, and PYSIDE6. This can easily be cured with

del PYQT5, PYQT6, PYSIDE2, PYSIDE6

appended to the files. So, I've excluded them from the results for now. Still, I've got the following:

PyQt5.QtCore: TYPE_CHECKING, _qt_version, contextlib, parse, possibly_static_exec, possibly_static_exec_
PyQt5.QtDBus: sys
PyQt5.QtGui: _QAction, _QTOPENGL_NAMES, __QPointF, _action_set_shortcut, _action_set_shortcuts, _missing_optional_names, _qt_version, getattr_missing_optional_dep, parse, partialmethod, possibly_static_exec, set_shortcut, set_shortcuts
PyQt5.QtOpenGL: contextlib
PyQt5.QtWidgets: _QMenu, _QToolBar, _menu_add_action, _missing_optional_names, _qt_version, _toolbar_add_action, add_action, getattr_missing_optional_dep, parse, partialmethod, possibly_static_exec, static_method_kwargs_wrapper
PyQt5.QtX11Extras: sys

PySide2.QtCore: PySide2, TYPE_CHECKING, _qt_version, contextlib, parse, possibly_static_exec, possibly_static_exec_
PySide2.QtGui: _QAction, _QTOPENGL_NAMES, __QPointF, _action_set_shortcut, _action_set_shortcuts, _missing_optional_names, _qt_version, getattr_missing_optional_dep, movePosition, movePositionPatched, parse, partialmethod, possibly_static_exec, set_shortcut, set_shortcuts
PySide2.QtOpenGL: contextlib
PySide2.QtWidgets: _QMenu, _QToolBar, _menu_add_action, _missing_optional_names, _qt_version, _toolbar_add_action, add_action, getattr_missing_optional_dep, parse, partialmethod, possibly_static_exec, static_method_kwargs_wrapper
PySide2.QtX11Extras: sys

PyQt6.QtCore: TYPE_CHECKING, _qt_version, contextlib, parse, possibly_static_exec, possibly_static_exec_, promote_enums
PyQt6.QtDBus: sys
PyQt6.QtGui: _QTOPENGL_NAMES, _class, _missing_optional_names, _obsolete_function, _qt_version, getattr_missing_optional_dep, parse, partialmethod, possibly_static_exec, promote_enums, set_shortcut, set_shortcuts
PyQt6.QtOpenGL: contextlib
PyQt6.QtTest: promote_enums
PyQt6.QtWidgets: _missing_optional_names, _qt_version, add_action, getattr_missing_optional_dep, parse, partialmethod, possibly_static_exec, promote_enums, static_method_kwargs_wrapper

PySide6.QtCore: PySide6, TYPE_CHECKING, _qt_version, contextlib, parse, possibly_static_exec, possibly_static_exec_
PySide6.QtDBus: sys
PySide6.QtGui: _QTOPENGL_NAMES, _class, _missing_optional_names, _obsolete_function, _qt_version, getattr_missing_optional_dep, movePosition, movePositionPatched, parse, partialmethod, possibly_static_exec, set_shortcut, set_shortcuts
PySide6.QtOpenGL: contextlib
PySide6.QtWidgets: _missing_optional_names, _qt_version, add_action, getattr_missing_optional_dep, parse, partialmethod, possibly_static_exec, static_method_kwargs_wrapper

That's a lot, and most of this is what I've brought. 😢

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions