Open
Description
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. 😢