Open ben-hearn-sb opened 7 years ago
@MaximeEngel search your venv/.../site-packages/PySide2 for .pyi files and you should see them.
Is your venv activated in Pycharm?
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.
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.
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.
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):
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.
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
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?
Happy to keep it separate until it's confirmed to work in more IDEs.
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:
Not sure I followed this whole thread is it possible to get PyCharm to reconginze the Qt Imports with out a warning?
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.
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.
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/
[tool.poetry.dependencies] "Qt.py" = { path = "./vendor/Qt.py" }
@MrLixm This setup could perhaps be added to the vendoring docs. Nice!
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.
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.
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:
pip install Qt.py
pip install types-PySide2
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?
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!
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.
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.
If we are going to add optional requirements I would highly recommend using extras_require.
This sounds great. Thanks @MHendricks
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?