mottosso / Qt.py

Minimal Python 2 & 3 shim around all Qt bindings - PySide, PySide2, PyQt4 and PyQt5.
MIT License
896 stars 252 forks source link

Code completion inserts references to PySide2 #400

Open chadrik opened 3 months ago

chadrik commented 3 months ago

Hi @mottosso!
A Qt.py user reported this to me, and luckily I can take care of the problem on my own, but I need your input.

Here's a quick refresher.

In https://github.com/mottosso/Qt.py/pull/371 we decided to add simple .pyi files to the Qt.py distribution that redirect to PySide2 stubs, and we added install_requires=["types-PySide2"]. We arrived at this design for a few reasons:

  1. users get code completion without needing to install something separate, since most users will want completion, but they won't be educated on how to get it
  2. redirecting to PySide2 means that users can replacetypes-PySide2 -- which is installed by default with Qt.py -- with alternate PySide2 stubs of their choosing, and Qt.py will use those, by virtue of the redirect.

Problem

A downside of this approach has been pointed out to me. IDEs (correctly) infer that the owner of the Qt objects is PySide2, so they will often generates code for users that refer to PySide2 objects. For example, when overriding a method, it produces this result for the argument type of showEvent:

from Qt import QtWidgets, QtGui

class TestWidget(QtWidgets.QWidget):
    def showEvent(self, event: PySide2.QtGui.QShowEvent) -> None:
        ...

Expectation

What we want is the following:

from Qt import QtWidgets, QtGui

class TestWidget(QtWidgets.QWidget):
    def showEvent(self, event: QtGui.QShowEvent) -> None:
        ...

(Depending on the IDE, it may add Qt.QtGui.QShowEvent)

Solution

The only fool-proof solution that I know of that should work for all IDEs that understand pyi files is to create stubs explicitly for Qt.py, which would be a copy of types-PySide2 with all references to PySide2 replaced with Qt. This would be extremely easy for me to do as part of my https://github.com/chadrik/cg-stubs project. With your permission I would publish these to pypi as types-Qt, and I would add a PR here to replace install_requires=["types-PySide2"] with install_requires=["types-Qt"].

The primary downside that I see is that we lose benefit 2, above. A future challenge will be how to deal with PySide6 support (https://github.com/mottosso/Qt.py/issues/367) as it pertains to the stubs, but the suggested plan does not make that situation any worse, in fact having custom-generated Qt stubs gives us more flexibility.

For the record, this relates to the long-standing issue https://github.com/mottosso/Qt.py/issues/199

Let me know what you think.

mottosso commented 3 months ago

With your permission I would publish these to pypi as types-Qt, and I would add a PR here to replace install_requires=["types-PySide2"] with install_requires=["types-Qt"].

Sure, go right ahead. I have no opinion on it, as I don't use typing with Qt myself.

A future challenge will be how to deal with PySide6 support (#367) as it pertains to the stubs

It looks like we're keeping compatibility with Qt 4 and 5 when introducing 6 (https://github.com/mottosso/Qt.py/pull/394), so the resulting types should remain unchanged.