PyQt: Mixin that inherits from typing.Protocol : metaclass conflict: must be a subclass of the metaclasses of all its bases
Unsolved
Qt for Python
-
I am using PyQt and mypy for type checking. When I create a mixin class for a QWidget or a QMainWindow I use typing.Protocol to satisfy mypy, but then I get a run time error instead:
$ ./main.py Traceback (most recent call last): File "/home/hakon/test/python/pyqt/./main.py", line 8, in <module> from window import Window File "/home/hakon/test/python/pyqt/window.py", line 7, in <module> class Window(QMainWindow, ResizeWindowMixin): TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
#! /usr/bin/env python3 import logging import sys from PyQt6.QtWidgets import QApplication from window import Window def main() -> None: logging.basicConfig(level=logging.INFO) app = QApplication(sys.argv) config = {'X': '100', 'Y': '100', 'Width': '500', 'Height': '500'} window = Window(config) window.show() app.exec() if __name__ == "__main__": main()
from mixin import ResizeWindowMixin from PyQt6.QtWidgets import QLabel, QVBoxLayout, QMainWindow class Window(QMainWindow, ResizeWindowMixin): def __init__(self, config: dict[str, str]) -> None: super().__init__() self.window_config = config self.fontsize = self.window_config["FontSize"] self.setWindowTitle("Test Window") layout = QVBoxLayout() layout.addWidget(QLabel("Hello world!")) self.setLayout(layout) self.resize_window_from_config()
from typing import Protocol # from PyQt6.QtCore import QMetaObject class ConfigWindow(Protocol): window_config: dict[str, str] def move(self, x: int, y: int) -> None: ... def resize(self, w: int, h: int) -> None: ... class ResizeWindowMixin(ConfigWindow): def resize_window_from_config(self: ConfigWindow) -> None: if ("X" in self.window_config) and ("Y" in self.window_config): self.move( int(self.window_config["X"]), int(self.window_config["Y"]), ) self.resize(int(self.window_config["Width"]), int(self.window_config["Height"]))
How to resolve this issue?
Note: also posted on stackoverflow: https://stackoverflow.com/q/77543597/2173773 -
@hakonhagland
For PyQt you will surely get answer from the PyQt mailing list if you do not elsewhere.