Skip to content

Commit ac44038

Browse files
committed
Add support for misplaced members with no "common" modules
Adds support for adding `Qt.QtOpenGl` and other modules. These modules don't actually have any common members because the different bindings used unique module names. For example in Qt6 all QtOpenGL functions are stored under QtOpenGL, but in PySide2 they are stored under QtGui and QtOpenGLFunctions, and PyQt5 is ... complex.
1 parent 8c0d988 commit ac44038

File tree

3 files changed

+100
-1
lines changed

3 files changed

+100
-1
lines changed

membership.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@
3030
BINDING_NAMES_QT5 = ["PySide2", "PyQt5"]
3131
BINDING_NAMES_QT6 = ["PySide6", "PyQt6"]
3232

33+
# Include these module names in common modules even if they have no common
34+
# members. They will be assigned using the misplaced members.
35+
MISPLACED_MODULES = [
36+
"QtAxContainer",
37+
"QtOpenGL",
38+
]
39+
3340

3441
def read_json(filename):
3542
"""Read JSON, return dict"""
@@ -132,6 +139,12 @@ def compare(dicts):
132139
if members:
133140
common_members[k] = members
134141

142+
# Add empty misplaced modules. These are where we will add misplaced members
143+
# for modules that are not common
144+
for module in MISPLACED_MODULES:
145+
if module not in common_members:
146+
common_members[module] = []
147+
135148
return ret
136149

137150

src/Qt.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,14 @@
7777
file created by the membership tox environments. See _common_members_sources
7878
for a list of the python and qt bindings used to generate this list.
7979
80+
Note: Some members like QtOpenGL may contain empty lists. These are targets for
81+
assigning misplaced members according to the reference binding(PySide6). We
82+
will need to add them to all bindings including None, so we add them here.
83+
8084
"""
8185

8286
_common_members = {
87+
"QtAxContainer": [],
8388
"QtCore": [
8489
"QAbstractAnimation",
8590
"QAbstractEventDispatcher",
@@ -475,6 +480,7 @@
475480
"QTcpSocket",
476481
"QUdpSocket"
477482
],
483+
"QtOpenGL": [],
478484
"QtPositioning": [
479485
"QGeoAddress",
480486
"QGeoAreaMonitorInfo",
@@ -1380,9 +1386,15 @@ def wrapper(self, descrip):
13801386
}
13811387
}
13821388
1389+
The __misplaced__ key contains any modules that need to be imported to handle
1390+
misplaced members. They are not _common_members but need treated the same way.
1391+
13831392
"""
13841393
_misplaced_members = {
13851394
"PySide6": {
1395+
"QtAxContainer.QAxBase": "QtAxContainer.QAxBase",
1396+
"QtAxContainer.QAxObject": "QtAxContainer.QAxObject",
1397+
"QtAxContainer.QAxWidget": "QtAxContainer.QAxWidget",
13861398
"QtCore.Property": "QtCore.Property",
13871399
"QtCore.QAbstractProxyModel": "QtCore.QAbstractProxyModel",
13881400
"QtCore.QCoreApplication.translate": ["QtCompat.translate", _translate],
@@ -1405,6 +1417,11 @@ def wrapper(self, descrip):
14051417
"QtGui.QUndoCommand": "QtWidgets.QUndoCommand",
14061418
"QtGui.QUndoGroup": "QtWidgets.QUndoGroup",
14071419
"QtGui.QUndoStack": "QtWidgets.QUndoStack",
1420+
"QtOpenGL.QAbstractOpenGLFunctions": "QtOpenGL.QAbstractOpenGLFunctions",
1421+
"QtOpenGL.QOpenGLBuffer": "QtOpenGL.QOpenGLBuffer",
1422+
"QtOpenGL.QOpenGLFunctions_2_0": "QtOpenGL.QOpenGLFunctions_2_0",
1423+
"QtOpenGL.QOpenGLFunctions_2_1": "QtOpenGL.QOpenGLFunctions_2_1",
1424+
"QtOpenGL.QOpenGLFunctions_4_1_Core": "QtOpenGL.QOpenGLFunctions_4_1_Core",
14081425
"QtStateMachine.QState": "QtCore.QState",
14091426
"QtStateMachine.QStateMachine": "QtCore.QStateMachine",
14101427
"QtSvgWidgets.QGraphicsSvgItem": "QtSvg.QGraphicsSvgItem",
@@ -1418,6 +1435,10 @@ def wrapper(self, descrip):
14181435
"shiboken6.wrapInstance": ["QtCompat.wrapInstance", _wrapinstance],
14191436
},
14201437
"PyQt6": {
1438+
"__misplaced__": ["QAxContainer"],
1439+
"QAxContainer.QAxBase": "QtAxContainer.QAxBase",
1440+
"QAxContainer.QAxObject": "QtAxContainer.QAxObject",
1441+
"QAxContainer.QAxWidget": "QtAxContainer.QAxWidget",
14211442
"QtCore.pyqtProperty": "QtCore.Property",
14221443
"QtCore.pyqtSignal": "QtCore.Signal",
14231444
"QtCore.pyqtSlot": "QtCore.Slot",
@@ -1440,6 +1461,11 @@ def wrapper(self, descrip):
14401461
"QtGui.QUndoCommand": "QtWidgets.QUndoCommand",
14411462
"QtGui.QUndoGroup": "QtWidgets.QUndoGroup",
14421463
"QtGui.QUndoStack": "QtWidgets.QUndoStack",
1464+
"QtOpenGL.QAbstractOpenGLFunctions": "QtOpenGL.QAbstractOpenGLFunctions",
1465+
"QtOpenGL.QOpenGLBuffer": "QtOpenGL.QOpenGLBuffer",
1466+
"QtOpenGL.QOpenGLFunctions_2_0": "QtOpenGL.QOpenGLFunctions_2_0",
1467+
"QtOpenGL.QOpenGLFunctions_2_1": "QtOpenGL.QOpenGLFunctions_2_1",
1468+
"QtOpenGL.QOpenGLFunctions_4_1_Core": "QtOpenGL.QOpenGLFunctions_4_1_Core",
14431469
"QtStateMachine.QState": "QtCore.QState",
14441470
"QtStateMachine.QStateMachine": "QtCore.QStateMachine",
14451471
"QtSvgWidgets.QGraphicsSvgItem": "QtSvg.QGraphicsSvgItem",
@@ -1453,6 +1479,10 @@ def wrapper(self, descrip):
14531479
"uic.loadUi": ["QtCompat.loadUi", _loadUi],
14541480
},
14551481
"PySide2": {
1482+
"__misplaced__": ["QtOpenGLFunctions"],
1483+
"QtAxContainer.QAxBase": "QtAxContainer.QAxBase",
1484+
"QtAxContainer.QAxObject": "QtAxContainer.QAxObject",
1485+
"QtAxContainer.QAxWidget": "QtAxContainer.QAxWidget",
14561486
"QtCore.Property": "QtCore.Property",
14571487
"QtCore.QAbstractProxyModel": "QtCore.QAbstractProxyModel",
14581488
"QtCore.QCoreApplication.translate": ["QtCompat.translate", _translate],
@@ -1467,9 +1497,14 @@ def wrapper(self, descrip):
14671497
"QtCore.QStringListModel": "QtCore.QStringListModel",
14681498
"QtCore.Signal": "QtCore.Signal",
14691499
"QtCore.Slot": "QtCore.Slot",
1500+
"QtGui.QAbstractOpenGLFunctions": "QtOpenGL.QAbstractOpenGLFunctions",
1501+
"QtGui.QOpenGLBuffer": "QtOpenGL.QOpenGLBuffer",
14701502
"QtGui.QRegExpValidator": "QtGui.QRegExpValidator",
14711503
# Older versions of PySide2 still left this in QtGui, this accounts for those too
14721504
"QtGui.QStringListModel": "QtCore.QStringListModel",
1505+
"QtOpenGLFunctions.QOpenGLFunctions_2_0": "QtOpenGL.QOpenGLFunctions_2_0",
1506+
"QtOpenGLFunctions.QOpenGLFunctions_2_1": "QtOpenGL.QOpenGLFunctions_2_1",
1507+
"QtOpenGLFunctions.QOpenGLFunctions_4_1_Core": "QtOpenGL.QOpenGLFunctions_4_1_Core",
14731508
"QtSvg.QGraphicsSvgItem": "QtSvg.QGraphicsSvgItem",
14741509
"QtSvg.QSvgWidget": "QtSvg.QSvgWidget",
14751510
"QtUiTools.QUiLoader": ["QtCompat.loadUi", _loadUi],
@@ -1487,6 +1522,18 @@ def wrapper(self, descrip):
14871522
"shiboken2.wrapInstance": ["QtCompat.wrapInstance", _wrapinstance],
14881523
},
14891524
"PyQt5": {
1525+
"__misplaced__": [
1526+
"_QOpenGLFunctions_2_0",
1527+
"_QOpenGLFunctions_2_1",
1528+
"_QOpenGLFunctions_4_1_Core",
1529+
"QAxContainer",
1530+
],
1531+
"_QOpenGLFunctions_2_0.QOpenGLFunctions_2_0": "QtOpenGL.QOpenGLFunctions_2_0",
1532+
"_QOpenGLFunctions_2_1.QOpenGLFunctions_2_1": "QtOpenGL.QOpenGLFunctions_2_1",
1533+
"_QOpenGLFunctions_4_1_Core.QOpenGLFunctions_4_1_Core": "QtOpenGL.QOpenGLFunctions_4_1_Core",
1534+
"QAxContainer.QAxBase": "QtAxContainer.QAxBase",
1535+
"QAxContainer.QAxObject": "QtAxContainer.QAxObject",
1536+
"QAxContainer.QAxWidget": "QtAxContainer.QAxWidget",
14901537
"QtCore.pyqtProperty": "QtCore.Property",
14911538
"QtCore.pyqtSignal": "QtCore.Signal",
14921539
"QtCore.pyqtSlot": "QtCore.Slot",
@@ -1501,6 +1548,8 @@ def wrapper(self, descrip):
15011548
"QtCore.QRegExp": "QtCore.QRegExp",
15021549
"QtCore.QSortFilterProxyModel": "QtCore.QSortFilterProxyModel",
15031550
"QtCore.QStringListModel": "QtCore.QStringListModel",
1551+
"QtGui.QAbstractOpenGLFunctions": "QtOpenGL.QAbstractOpenGLFunctions",
1552+
"QtGui.QOpenGLBuffer": "QtOpenGL.QOpenGLBuffer",
15041553
"QtGui.QRegExpValidator": "QtGui.QRegExpValidator",
15051554
"QtSvg.QGraphicsSvgItem": "QtSvg.QGraphicsSvgItem",
15061555
"QtSvg.QSvgWidget": "QtSvg.QSvgWidget",
@@ -1713,7 +1762,11 @@ def _warn_import_error(exc, module):
17131762
return
17141763
_warn("ImportError(%s): %s" % (module, msg))
17151764

1716-
for name in list(_common_members) + extras:
1765+
# Process the __misplaced__ modules as if they were common
1766+
misplaced = _misplaced_members.get(Qt.__binding__, {})
1767+
misplaced = misplaced.get("__misplaced__", [])
1768+
1769+
for name in list(_common_members) + extras + misplaced:
17171770
try:
17181771
submodule = _import_sub_module(
17191772
module, name)
@@ -1745,6 +1798,9 @@ def _reassign_misplaced_members(binding):
17451798
"""
17461799

17471800
for src, dsts in _misplaced_members[binding].items():
1801+
if src == "__misplaced__":
1802+
# Don't process this key here.
1803+
continue
17481804
# Normalize dsts to a list of potentially multiple misplaced members
17491805
if isinstance(dsts, str):
17501806
# A single string is treated as a single item lists

tests.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,36 @@ def test_mutliple_misplaced():
12241224
assert Qt.QtGui.QAction == Qt.QtWidgets.QAction
12251225

12261226

1227+
def test__misplaced__():
1228+
"""Spot check binding specific imports for missing members.
1229+
1230+
This should check at least one import for each common member that requires
1231+
being added to any bindings `__misplaced__` list.
1232+
"""
1233+
import Qt
1234+
1235+
assert Qt.QtAxContainer.QAxBase
1236+
assert Qt.QtAxContainer.QAxWidget
1237+
assert Qt.QtOpenGL.QAbstractOpenGLFunctions
1238+
assert Qt.QtOpenGL.QOpenGLBuffer
1239+
assert Qt.QtOpenGL.QOpenGLFunctions_2_0
1240+
assert Qt.QtOpenGL.QOpenGLFunctions_2_1
1241+
1242+
1243+
def test__misplaced__none():
1244+
"""Preferring None should add the __misplaced__ modules"""
1245+
1246+
current = os.environ["QT_PREFERRED_BINDING"]
1247+
try:
1248+
os.environ["QT_PREFERRED_BINDING"] = "None"
1249+
import Qt
1250+
1251+
assert Qt.QtAxContainer
1252+
assert Qt.QtOpenGL
1253+
finally:
1254+
os.environ["QT_PREFERRED_BINDING"] = current
1255+
1256+
12271257
def test_missing():
12281258
"""Missing members of Qt.py have been defined with placeholders"""
12291259
import Qt

0 commit comments

Comments
 (0)