PySide2 non-migration

I was about to finish another sprint (implementing a saner copy&paste system, as I hinted earlier). So I ran mypy over the sources and saw that it complains about a bunch of things, which are caused by an issue with PyQt5.

PyQt5 seems to not like classes, which explicitly inherit from multiple "Q" classes. E.g. something like that:

class SomeMixin(QtCore.QWidget):
    def someMethod(self):
        self.update()

class SomeLineEdit(SomeMixin, QtCore.QLineEdit):
    ...

QLineEdit is a subclass of QWidget, so the above should be perfectly fine. But not for PyQt5. When I tried to make a minimal example, it just segfaulted, but I vaguely remember seeing some exception being raised. To workaround that, I had to make such mixin classes not inherit from a "Q" class (e.g. just object), which is perfectly fine at runtime. But mypy has no idea that this mixin is only used with some kind of QWidget and that self.update() is a valid method. So I have to make mypy suppress all those false-positive warnings, which makes the code look ugly, and I lose type checking for any real issues.

Besides that PyQt5's support for type annotations was not so great anyway. I'm maintaining my own set of stubs for it, which are based on the original PyQt5 stubs, but with lots of manual tweaks to make them actually useful.

So when I saw that Qt now officially includes Python bindings in the shape of PySide2, I was interested in evaluating a migration. There was an open ticket for adding stubs, but that was fixed for version 5.13.

It's easy to install via pip, so I made a quick test to see if PySide2 was also suffering from the inheritance issue above. It wasn't, so let's give a real migration a try.

PySide2 looks sufficiently similar to PyQt5, that you could think a simple s/PyQt5/PySide2/ might already be enough. For some projects it might already be that, plus some more trivial renames like pyqtSignalSignal or pyqtPropertyProperty.

But there are more subtle differences, which make it much harder (at least for noisicaä)...

Those are the issues, which I have found so far. At least the unittests are now passing, but that doesn't really mean that much, because the test coverage for the UI code isn't that great. And getting there wasn't easy, because PySide2 is also very crash happy. So instead of a nice Python exception telling me where and what was wrong, I just got the unhelpful "Segmentation fault (core dumped)" message. I had to perform the "install from source" dance to get a version with debug symbols, so gdb could at least tell me something about the problem.

And now I'm getting this exception:

Traceback (most recent call last):
  [...]
  File "/home/pink/noisicaa/build/noisicaa/ui/control_value_connector.py", line 62, in __init__
    self.valueChanged.connect(self.__onValueEdited)
TypeError: connect() takes 3 positional arguments but 4 were given

Sorry, but that simply does not make sense.

It would have been nice to have a viable alternative to PyQt5, and perhaps PySide2 is that, if you're starting a new project from scratch. But migrating noisicaä does not seem worth the effort, at least not now. There is at least some hope that development of PySide2 gets a boost, at least for a while, now that it has been included in the Qt canon. Let's give it some more time.

<<< Development update (September 8) Development update (September 23) >>>