mottosso / Qt.py

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

Intellisense/Autocomplete for PyCharm #199

Open ben-hearn-sb opened 7 years ago

ben-hearn-sb commented 7 years ago

I cannot seem to get Qt.py to autocomplete for PyCharm. Is there any concise instructions on how to do this? Or is it not possible?

I have dug in a little and my suspicion is that because Qt.py is using Qt5 bindings and my system Python is 2.7. Could this be the case?

fredrikaverpil commented 5 years ago

@MaximeEngel search your venv/.../site-packages/PySide2 for .pyi files and you should see them.

Is your venv activated in Pycharm?

fredrikaverpil commented 5 years ago

Apparently, the .pyi files are not bundled with PySide2 on Windows for some reason...

Here is a quick test of using .pyi files in vscode: https://github.com/davidhalter/jedi/issues/1318#issuecomment-495796223 Unfortunately, the PySide2-bundled .pyi files are not picked up by Qt.py - which that issue is all about.

herronelou commented 5 years ago

The pyi files bundled with PySide2 are also quite incomplete, I'm getting a lot of missing classes, for example QtCore.Signal is unknown, as are all the things in QtCore.Qt. To that extent, the Qt.py pyi files were doing a better job, though they we not understanding some_signal.connect() and a few other things.

fredrikaverpil commented 5 years ago

Ping @ctismer (see above two posts about incomplete .pyi files and missing ones on Windows).

From what I have understood, they are about to be substantially improved in the next PySide2 version.

fredrikaverpil commented 5 years ago

If you rearrange the files in site-packages, the vanilla PySide2 .pyi files actually work with Qt.py in vscode (you need to be running jedi 0.14.0, which vscode is not yet bundled with):

Screenshot 2019-05-26 at 21 31 21

Screenshot 2019-05-26 at 21 30 47

Instead of having the lone Qt.py file, make a directory called Qt. Move the Qt.py file inside and rename it to __init__.py. Then copy all the .pyi files from PySide2 into the Qt directory.

⚠️ this will obviously mess up your Qt.py install ... But if you are vendoring Qt.py, this should be easy to get working.

voltuer commented 4 years ago

https://github.com/mottosso/Qt.py/issues/199#issuecomment-303765184

You could put this inside qt.py If False: from PySide2 import QtWidgets, QtCore, QtGui And then have that for all 4 bindings in a row. PyCharm should try and find it for one of them.

thank you SO DAMN MUCH @dgovil , this fixed the issue for me on PyShit. My personal problem was that I wasn't getting suggestions for things like PySide2.QtWidgets.QComboBox.textActivated, it just showed a few suggestions for the combo box but not all like textActivated or many others found on Qt documentation

matiascodesal commented 4 years ago

Continuing from where @fredrikaverpil left off, I got this working in PyCharm by creating a stubs package using the pyi files from the latest PySide2: pip install git+https://github.com/matiascodesal/Qt.py-stubs.git@5a07e53 Once it's installed, you're good to go. I think think this should work for other IDEs too. Do you want to fold this into the main repo or keep it separate?

mottosso commented 4 years ago

Happy to keep it separate until it's confirmed to work in more IDEs.

matiascodesal commented 4 years ago

Verified that it's working with VSCode. For PyCharm, it's working with 2018.3.7 and older. Not sure if it's a regression in the newer versions, but they don't pick up the stubs. The issue seems to be related to the fact that Qt is installed as a module, but we use it as a package. It'd make more sense and work without issues if Qt.py was distributed as a package instead of a single module. Something like:

or:

aspartamed commented 4 years ago

Not sure I followed this whole thread is it possible to get PyCharm to reconginze the Qt Imports with out a warning?

mottosso commented 3 years ago

This issue seems popular still, our options are to support this with the default install of Qt.py, or let this issue continue to be found via the interwebs and act as a guide for those using PyCharm.

For support, the only remaining question is whether the .pyi files also work with IDEs other than PyCharm? If not, would people be happy having those files installed even though they aren't used or relevant to your IDE? As a Sublime user it's less interesting and would be considered bloat.

I've added a quick summary up-top to those stumbling in here from an internet search.

MrLixm commented 2 years ago

Hello, thanks again for this thread, it was very helpful. Today let me present to you my workflow for poetry (package and env manager). You have to be familiar with poetry of course.

At the root of my repository, I usually have a vendor/ directory where I put non-pip dependencies. Here you can create a new Qt.py/ dir. Inside, download the stubs so you have Qt.py/Qt/__init__.pyi. Then apply the trick 1. explained above where you create a new __init__.py file so you have Qt.py/Qt/__init__.py. In this file you paste the content of the Qt.py module. Now we have a proper package we can create the Qt.py/pyproject.toml file. Here is its content :

[tool.poetry]
name = "Qt.py"
version = "1.3.7"
description = "Python 2 & 3 compatibility wrapper around all Qt bindings - PySide, PySide2, PyQt4 and PyQt5."
authors = ["Marcus Ottosson <konstruktion@gmail.com>"]
packages = [
    { include = "Qt" },
]

[tool.poetry.dependencies]
python = ">2"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

This means you can now register as a dependency in your initial project. So in the project's pyprojet.toml file you can now add `

[tool.poetry.dependencies]
"Qt.py" = { path = "./vendor/Qt.py" }

πŸ’‘Using "Qt.py" as the package's name will make the IDE complains that the package "Qt" is not listed in the project requirements when imported. So instead you could replace all the "Qt.py" strings with just "Qt" (not tested)

Final projet's arbo :

projectName/
β”œβ”€ pyprojet.toml
β”œβ”€ projetPackage/
β”œβ”€ vendor/
β”‚  β”œβ”€ Qt.py/
β”‚  β”‚  β”œβ”€ Qt/
β”‚  β”‚  β”‚  β”œβ”€ __init__.py
β”‚  β”‚  β”‚  β”œβ”€ __init__.pyi
β”‚  β”‚  β”‚  └─ ... .pyi
β”‚  β”‚  └─ pyproject.toml

Hope this helps, cheers.

fredrikaverpil commented 2 years ago

For support, the only remaining question is whether the .pyi files also work with IDEs other than PyCharm?

Hey @mottosso πŸ‘‹ long time! πŸ˜‹

I'm a vscode user and I believe vscode will read .pyi files if you are using the Pylance language server. From their README:

  • python.analysis.stubPath

Used to allow a user to specify a path to a directory that contains custom type stubs. Each package's type stub file(s) are expected to be in its own subdirectory. Default value: ./typings

But in the case of Qt.py, and back in the day when I was using it on a daily basis, I remember I sorely missed having this. I think it should probably just be bundled next to the Qt.py file in the pypi wheel. I can't really come to think of a situation when you wouldn't want that? πŸ€”

The stubs can also be shipped as a separate package: https://peps.python.org/pep-0561/

fredrikaverpil commented 2 years ago
[tool.poetry.dependencies]
"Qt.py" = { path = "./vendor/Qt.py" }

@MrLixm This setup could perhaps be added to the vendoring docs. Nice!

mottosso commented 2 years ago

Heya! πŸ‘‹

But in the case of Qt.py, and back in the day when I was using it on a daily basis, I remember I sorely missed having this. I think it should probably just be bundled next to the Qt.py file in the pypi wheel. I can't really come to think of a situation when you wouldn't want that? πŸ€”

Happy with this. I'm not familiar with pyi files and am not the one to do it, but would welcome a PR that implemented it.

chadrik commented 2 years ago

Hi all, I've spent some time making some very accurate type stubs for PySide2: types-PySide2. They're good enough to get all of the Qt.py-based code at our company passing under mypy, which is a high bar that none of the other stubs that I tried could pass.

Since there are a number of competing stubs for PySide out there, and someone may prefer to pip install one stub package over another, what I recommend is creating a set of .pyi files that defer to PySide2, since that's the layout that Qt.py standardizes everything to. For example,

# Qt/QtCore.pyi
from PySide2.QtCore import *

This is what we're doing at Luma and it's working well with the new types-PySide2 stubs.

If you wanted to make it work "out of the box" you could make Qt.py require types-PySide2 so that it gets installed when you pip install Qt.py. A user could also follow this up by installing a different stub library, if they had a strong preference.

I think we can add a version switch in there to control PySide2 vs 6, which you can enable with mpy --always-true=PYSIDE6 or something like that.

Let me know what you think.

mottosso commented 2 years ago

Thanks for sharing @chadrik. I'll defer the decision on this to those using stubs with Qt.py, other than to ask that we don't make it a requirement to installing Qt.py, but rather an optional requirement or optional addon.

Am I understanding it correctly that in order to use this right now as-is, one would:

  1. pip install Qt.py
  2. pip install types-PySide2
  3. ..profit?

Is there a step 3, or would this be enough for it to automagically get picked up in PyCharm? And other editors?

Finally, if we do follow through with your proposal, what needs to happen in this project? E.g. is it enough to update the setup.py/cfg, does something need to be added to the Qt.py module itself? Can you make a PR with the changes?

chadrik commented 2 years ago

Is there a step 3, or would this be enough for it to automagically get picked up in PyCharm? And other editors?

these two steps are all that's required for PyCharm. I'll let others chime in about their favorite editors.

Finally, if we do follow through with your proposal, what needs to happen in this project? E.g. is it enough to update the setup.py/cfg, does something need to be added to the Qt.py module itself?

We'll need the .pyi files that redirect to PySide2, and some adjustments to setup.cfg.

Can you make a PR with the changes?

yep!

chadrik commented 2 years ago

Done: https://github.com/mottosso/Qt.py/pull/371

MHendricks commented 2 years ago

If we are going to add optional requirements I would highly recommend using extras_require.

Users can continue to use pip install Qt.py like they always have, but for those that want to use these new features, you can use pip install Qt.py[pyi] where pyi is the name of the set of optional requirements.

https://setuptools.pypa.io/en/latest/userguide/dependency_management.html?highlight=extras_require#optional-dependencies

To add this optional requirements is pretty easy.

diff --git a/setup.py b/setup.py
index ec7b526..0de9ff9 100644
--- a/setup.py
+++ b/setup.py
@@ -34,5 +34,8 @@ setup(
     packages=["Qt"],
     package_data={'Qt': ['*.pyi']},
     include_package_data=True,
-    classifiers=classifiers
+    classifiers=classifiers,
+    extras_require={
+        "pyi": ["types-PySide2"],
+    },
 )

This doesn't affect the structure of the installed files, it just adds the extra types-PySide2 pip requirement to the pip install, and allows us to add/remove those optional requirements in the future as needed for each release of Qt.py.

mottosso commented 2 years ago

If we are going to add optional requirements I would highly recommend using extras_require.

This sounds great. Thanks @MHendricks