You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@bjwest Your tone seems unnecessarily demanding for something someone does for free, in their spare time. Everyone (including @stlehmann, see the comment above) seems to agree that more automation seems like a good idea, so why not start contributing to make the process easier (and thus faster for everyone)?
@bjwest You are very welcome to present some sort of automation concept here. @The-Compiler thanks for pointing that out.
I would very much like to automate the process but it would be good to have someone with experience in this matter. I think the first step would be to create a hook to the PyQt5 repository that creates a new branch and merges the current PyQt5 stubs. Do you guys know someone with experience in git hooks?
@stlehmann IMHO the best way forward would be to see what kind of stub changes makes sense to contribute upstream to sip (maybe hidden behind a commandline flag, if there's a reason to diverge between IDE-friendly autocompletion stubs and mypy-friendly type checking stubs).
Are you at Europython? If so, let's talk or maybe even work on PyQt stubs at the sprints?
(Also, note that there isn't a public PyQt5 repository, you'd need to get new releases from the website or PyPI)
@The-Compiler I would really love to got to Europython but sadly I couldn' t make it :(
What you're suggesting means we should initiate some communication with some PyQt5 guys. That might actually be a good way to go. This way we tackle the issues at their roots. Has somebody got some good contacts to PyQt5 development team?
The PyQt mailing list is the best way to get in contact with the author - I've done so before and provided some observations (before you started PyQt5-stubs IIRC).
What would be needed is a list of concrete issues with the upstream stubs, a proposed solution (e.g. for handling signals correctly) and some testing to make sure it's still usable for autocompletion in IDEs (which I think is the primary goal of PyQt's upstream stubs).
@rwarren There already exists a buildenv that builds latest PyQt5 and yanks the stub files. But they need to get modified in order to work. At the moment this is handy-work that is why it might take some time to react on new releases of PyQt5.
Instead of hooking the PyQt5 repo, there is also another possibility for semi-automation.
Github allows for manual CI/CD pipeline trigger (just click a button).
That manually-fired job could fetch the newest version of Qt and perform the jobs that have to be done to build a new package. I think it's simplier because doesn't require other projects to be involved or modified. I'm aware that there is also manual work, but seems that would be the last obstacle on the way.
@kamichal That's the smallest problem - if it was just about launching a script all 1-2 months, doing that by hand vs. on CI isn't a big difference. The problem is that most of those changes aren't easily scriptable without fixing them at the source where the bindings are generated.
Taking the freedom to rename this issue, because this mostly morphed into a discussion about how those changes could be automated.
From what I've heard, the code generation part of sip (and thus I'm guessing stubs generation as well) should be rewritten in Python (instead of C). I'm not sure when that will be happening though, but if we're going to hack on sip, it'd probably be best to wait until that's done.
After that, I can see a couple of ways forward:
Upstream changes to PyQt/sip. Upstream generally has a different goal with those stubs (mainly making autocompletion in IDEs as usable as possible, not type-checking via mypy), so I suspect this won't be possible for all cases. But at least for things which are clearly errors, this sounds like a reasonable idea. Maybe we could even upstream something like a --bindings-type mypy and all our changes?
Automate the patching of .pyi files. This seems difficult: It needs a way to read/write .pyi files and a way to get more information (e.g. what's a signal?) from somewhere.
Use sip to export to XML (if that's still available?) and write our own generator from there.
Write our own small stubs generator based on the .sip files directly. That might be some effort, but also has a lot of benefits: We can generate whatever we want without having to work with upstream (which can be difficult, due to the "patches via ML and no public repository" style of working), and we can generate the stubs directly from PyQt sources without having to run sip or install Qt.
Okay, so we have 2275 errors with the current master branch and mypy from what it seems... Fun!
Given that:
The current PyQt stubs aren't really high quality (at least when using them with mypy)
It's somewhat difficult to contribute fixes upstream with the only medium available being a mailinglist and a mercurial repository.
The generator for those stubs is written in C, and there's no concrete plans on when that will change.
I wonder it would be easier to generate our own bindings from scratch rather than patching upstream's... Either starting from the XML exports (which still seem to be available, but will need our own build of those modules still), or parsing the .sip files ourselves (perhaps reusing parts of flex/bison based parser from sip via Python).
wonder it would be easier to generate our own bindings from scratch rather than patching upstream's
I can not really estimate the amount of time it would take but that sounds like be a huge amount of work. I actually would like to keep the effort within reasonable amounts because we don't know if they might one day provide high quality upstream stubs which would make this project redundant.
I just came up with another idea which I want to throw in the round. How about automatically parsing the mypy output and applying fixes accordingly. There are a lot of errors that repeat themselves and are easily fixed. E.g. we have a lot of errors with incompatible supertypes like this:
PyQt5-stubs/QtSensors.pyi:71: error: Argument 1 of "filter" is incompatible with supertype "QSensorFilter"; supertype defines the argument type as "QSensorReading"
This is an error that can actually not be fixed because of the class design of Qt being incompatible with the Liskov substitution principle. So the only solution I came up with is adding # typing: ignore at the end of the line.
This means we can parse mypy output looking for let's say "incompatible with supertype" by using Regex and add # type: ignore to all matching lines.
This is just the simplest of examples. But I think that might be aplicable in a way like this:
Checking for a pattern by regex and extract all necessary information (line nr., error type)
Call a function that handles this case (parameters: file, line number)
The function than can modify the stub file to fix the error
I think that could eliminate a fair amount of the errors we get. Additionally we could add the functionality that @The-Compiler proposed and use a list with signals to replace signal definitions.
So the remaining question (at least IMHO) would be how to automatically edit the existing .pyi files (if we don't want to generate new ones). I wonder if LibCST or redbaron or perhaps jedi (or their lower-level equivalents, baron and parso); or perhaps lib2to3 (deprecated) can be used to do those kind of edits...
Since PyQt5 is in maintenance mode, very few new releases are expected, so automating the upstream conversion to our stubs is more work than just merging the latest version.
As for automating some fixes, we already have a reasonable amount of them and this will be expanded in the future.
Activity
stlehmann commentedon Apr 3, 2019
Done :)
stlehmann commentedon Apr 3, 2019
Some sort of automation would be great here.
zdenop commentedon Apr 3, 2019
Thanks. IMO also https://github.com/stlehmann/PyQt5-stubs/tree/5.12.1.0/requirements should be updated....
kazum1kun commentedon Jul 8, 2019
Qt 5.13 is out, would you consider updating it again to latest Qt? Thanks!
bjwest commentedon Jul 10, 2019
Seriously! Should we need to ask for this? I understand you may be busy so how about automating the process somehow?
The-Compiler commentedon Jul 11, 2019
@bjwest Your tone seems unnecessarily demanding for something someone does for free, in their spare time. Everyone (including @stlehmann, see the comment above) seems to agree that more automation seems like a good idea, so why not start contributing to make the process easier (and thus faster for everyone)?
stlehmann commentedon Jul 11, 2019
@bjwest You are very welcome to present some sort of automation concept here.
@The-Compiler thanks for pointing that out.
I would very much like to automate the process but it would be good to have someone with experience in this matter. I think the first step would be to create a hook to the PyQt5 repository that creates a new branch and merges the current PyQt5 stubs. Do you guys know someone with experience in git hooks?
The-Compiler commentedon Jul 11, 2019
@stlehmann IMHO the best way forward would be to see what kind of stub changes makes sense to contribute upstream to sip (maybe hidden behind a commandline flag, if there's a reason to diverge between IDE-friendly autocompletion stubs and mypy-friendly type checking stubs).
Are you at Europython? If so, let's talk or maybe even work on PyQt stubs at the sprints?
(Also, note that there isn't a public PyQt5 repository, you'd need to get new releases from the website or PyPI)
stlehmann commentedon Jul 11, 2019
@The-Compiler I would really love to got to Europython but sadly I couldn' t make it :(
What you're suggesting means we should initiate some communication with some PyQt5 guys. That might actually be a good way to go. This way we tackle the issues at their roots. Has somebody got some good contacts to PyQt5 development team?
The-Compiler commentedon Jul 11, 2019
The PyQt mailing list is the best way to get in contact with the author - I've done so before and provided some observations (before you started PyQt5-stubs IIRC).
What would be needed is a list of concrete issues with the upstream stubs, a proposed solution (e.g. for handling signals correctly) and some testing to make sure it's still usable for autocompletion in IDEs (which I think is the primary goal of PyQt's upstream stubs).
issues.md: Add issue #5 and #6.
stlehmann commentedon Jul 25, 2019
Updated to 5.13.0. I also documented the most common issues in issue.md and wrote to the mailing list about a fixing strategy. Let's see what happens.
kazum1kun commentedon Jul 25, 2019
Thanks a lot! Very helpful to have those.
3 remaining items
stlehmann commentedon Sep 17, 2019
@rwarren There already exists a buildenv that builds latest PyQt5 and yanks the stub files. But they need to get modified in order to work. At the moment this is handy-work that is why it might take some time to react on new releases of PyQt5.
guizhenwei commentedon Nov 19, 2019
Now PyQt5.13.2 was released.
It would be great to keep PyQt5-Stubs updated with upstream.
PyCharm complains about incompatiable with the latest version of PyQt5.13.2 while installing PyQt5-stubs 5.13.1.
kamichal commentedon Feb 13, 2020
Instead of hooking the
PyQt5repo, there is also another possibility for semi-automation.Github allows for manual CI/CD pipeline trigger (just click a button).
That manually-fired job could fetch the newest version of Qt and perform the jobs that have to be done to build a new package. I think it's simplier because doesn't require other projects to be involved or modified. I'm aware that there is also manual work, but seems that would be the last obstacle on the way.
The-Compiler commentedon Feb 13, 2020
@kamichal That's the smallest problem - if it was just about launching a script all 1-2 months, doing that by hand vs. on CI isn't a big difference. The problem is that most of those changes aren't easily scriptable without fixing them at the source where the bindings are generated.
[-]Create version for the latest PyQT5 version[/-][+]Automating patching/generating of bindings[/+][-]Automating patching/generating of bindings[/-][+]Automating patching/generating of stubs[/+]The-Compiler commentedon Apr 22, 2020
Taking the freedom to rename this issue, because this mostly morphed into a discussion about how those changes could be automated.
From what I've heard, the code generation part of sip (and thus I'm guessing stubs generation as well) should be rewritten in Python (instead of C). I'm not sure when that will be happening though, but if we're going to hack on sip, it'd probably be best to wait until that's done.
After that, I can see a couple of ways forward:
--bindings-type mypyand all our changes?.pyifiles. This seems difficult: It needs a way to read/write .pyi files and a way to get more information (e.g. what's a signal?) from somewhere.The-Compiler commentedon May 4, 2020
Okay, so we have 2275 errors with the current
masterbranch andmypyfrom what it seems... Fun!Given that:
I wonder it would be easier to generate our own bindings from scratch rather than patching upstream's... Either starting from the XML exports (which still seem to be available, but will need our own build of those modules still), or parsing the
.sipfiles ourselves (perhaps reusing parts of flex/bison based parser from sip via Python).For reference, here's sip's type hint generation code: https://www.riverbankcomputing.com/hg/sip/file/tip/code_generator/type_hints.c
stlehmann commentedon May 4, 2020
A great bunch of errors it is.
I can not really estimate the amount of time it would take but that sounds like be a huge amount of work. I actually would like to keep the effort within reasonable amounts because we don't know if they might one day provide high quality upstream stubs which would make this project redundant.
I just came up with another idea which I want to throw in the round. How about automatically parsing the mypy output and applying fixes accordingly. There are a lot of errors that repeat themselves and are easily fixed. E.g. we have a lot of errors with incompatible supertypes like this:
This is an error that can actually not be fixed because of the class design of Qt being incompatible with the Liskov substitution principle. So the only solution I came up with is adding
# typing: ignoreat the end of the line.This means we can parse mypy output looking for let's say "incompatible with supertype" by using Regex and add
# type: ignoreto all matching lines.This is just the simplest of examples. But I think that might be aplicable in a way like this:
I think that could eliminate a fair amount of the errors we get. Additionally we could add the functionality that @The-Compiler proposed and use a list with signals to replace signal definitions.
The-Compiler commentedon Dec 1, 2020
As for finding out what is a signal, it just occurred to me that it's easiest to ask Qt directly at runtime. This prints all signals:
So the remaining question (at least IMHO) would be how to automatically edit the existing
.pyifiles (if we don't want to generate new ones). I wonder if LibCST or redbaron or perhaps jedi (or their lower-level equivalents, baron and parso); or perhaps lib2to3 (deprecated) can be used to do those kind of edits...issues.md: Add issue python-qt-tools#5 and python-qt-tools#6.
bluebird75 commentedon Apr 23, 2022
Since PyQt5 is in maintenance mode, very few new releases are expected, so automating the upstream conversion to our stubs is more work than just merging the latest version.
As for automating some fixes, we already have a reasonable amount of them and this will be expanded in the future.