Mypy stubs for the PyQt5 framework

Overview

mypy logo

PyPI version mypy checked Build Status Downloads Downloads

Mypy stubs for the PyQt5 framework

This repository holds the stubs of the PyQt5 framework. It uses the stub files that are produced during compilation process of PyQt5. These stub files have been modified by the author to allow using them for type-checking via Mypy. This repository is far from complete and the author will appreciate any PRs or Issues that help making this stub-repository more reliable.

Installation

Simply install PyQt5-stubs with pip:

$ pip install PyQt5-stubs

Or clone the latest version from Github and install it via Python setuptools:

$ git clone https://github.com/python-qt-tools/PyQt5-stubs
$ python setup.py install

Supported Modules

The following modules are supported by PyQt5-stubs:

  • QtCore
  • QtWidgets
  • QtGui
  • QtDBus
  • QtNetwork
  • QtOpenGL
  • QtPrintSupport
  • QtSql
  • QtTest
  • QtXml
  • sip

Building upstream stubs

The Dockerfile is used to build all of the stubs for the upstream PyQt5 modules. The Dockerfile consists of multiple build layers:

  • core: PyQt5
  • PyQt3D
  • PyQtChart
  • PyQtDataVisualization
  • PyQtPurchasing
  • PyQtWebEngine
  • an output layer

Each module build layer deposits its stub files within /output/ in its filesystem. The output layer then collects the contents of each into its own /output/ dir for export to the host computer. Build args are provided to change the version of each module.

A convenience script, build_upstream.py, is provided. It builds the stubs and copies them to the host computer. Make sure you install docker-py to use it. It builds $PWD/Dockerfile (overridden with --dockerfile) and outputs the stubs to $PWD/PyQt5-stubs (overridden with --output-dir).

* There are a few missing modules: QtAxContainer, QtAndroidExtras, QtMacExtras, and QtWindowsExtras. The current project understanding is that they need to be built on the target platform, something a Linux-based docker image cannot do. The deprecated Enginio module is also missing.

Comments
  • Plans for PyQt6?

    Plans for PyQt6?

    PyQt6 snapshots just came out. Currently they're nothing more than PyQt5 with some deprecated features removed. But it begs the question: will PyQt5-stubs support PyQt6?

    opened by BryceBeagle 32
  • Missing attribute not detected and inheritance not followed ?

    Missing attribute not detected and inheritance not followed ?

    Hi,

    Maybe this is not the right place to ask, if so thanks to redirect me...

    Code:

    from PyQt5.QtWidgets import QDialog
    from PyQt5.QtCore import QObject
    
    a = QDialog()
    b = a.result()  # ok inferred type int
    c = a.qsdf()  # should be error missing method but inferred type is any
    d = a.isWidgetType()  # method of QObject, parent class of QDialog, a bool should be inferred but inferred tye is any
    
    e = QObject()
    f = e.isWidgetType()  # ok inferred type bool
    
    class G:
        def yo(self) -> str:
            return "yo"
    
    class H(G):
        pass
    
    i = H()
    j = i.yo()  # ok inferred type str
    k = i.qsdf()  # ok error no attribute
    
    reveal_locals()
    

    mypy output is:

    27:5: error: "H" has no attribute "qsdf"
    29:1: note: Revealed local types are:
    29:1: note:     a: PyQt5.QtWidgets.QDialog
    29:1: note:     b: builtins.int
    29:1: note:     c: Any
    29:1: note:     d: Any
    29:1: note:     e: PyQt5.QtCore.QObject
    29:1: note:     f: builtins.bool
    29:1: note:     i: test_module.H
    29:1: note:     j: builtins.str
    29:1: note:     k: Any
    

    The question is: why does mypy does not detect these errors with PyQt objects?

    I am using version 5.11.3.0 of PyQt5-stubs

    Thanks

    opened by Djedouas 21
  • Merge new upstream stubs in master

    Merge new upstream stubs in master

    Thanks to @BryceBeagle we now have much more stubs to offer. I didn't have a closer look at them. But I guess they also need to be altered to be usable with mypy.

    help wanted 
    opened by stlehmann 20
  • Package looking for a new maintainer

    Package looking for a new maintainer

    I have created the PyQt5-stubs to add proper type annotations mainly for my personal PyQt5 applications without thinking much about a future-proof update strategy. It turns out that it is very cumbersome to take care of any version changes and keep the whole thing up-to-date with the upstream PyQt5 repository. Additionally I find myself using PySide2 more and more. PySide2 provides proper type annotations out of the box and has a more open licensing model. Because of this I decided to stop maintaining this package in the future. However, I would love to find a new maintainer that keeps this package alive. So if someone likes to take care of this package please contact me.

    opened by stlehmann 20
  • Fix WindowType and WindowFlags integer operations

    Fix WindowType and WindowFlags integer operations

    Before the fix, the test would report:

    windowflags.py:10: error: Incompatible types in assignment (expression has type "int", variable has type "WindowType")
    windowflags.py:18: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:19: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:20: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:21: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:22: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:27: error: Unsupported operand types for + ("WindowFlags" and "WindowType")
    windowflags.py:27: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:28: error: Unsupported operand types for - ("WindowFlags" and "WindowType")
    windowflags.py:28: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:29: error: Unsupported operand types for | ("WindowFlags" and "WindowType")
    windowflags.py:29: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:30: error: Unsupported operand types for & ("WindowFlags" and "WindowType")
    windowflags.py:30: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:31: error: Unsupported operand types for ^ ("WindowFlags" and "WindowType")
    windowflags.py:31: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:34: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:34: error: Unsupported operand types for + ("WindowType" and "WindowFlags")
    windowflags.py:35: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:35: error: Unsupported operand types for - ("WindowType" and "WindowFlags")
    windowflags.py:36: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:36: error: Unsupported operand types for | ("WindowType" and "WindowFlags")
    windowflags.py:37: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:37: error: Unsupported operand types for & ("WindowType" and "WindowFlags")
    windowflags.py:38: error: Incompatible types in assignment (expression has type "int", variable has type "WindowFlags")
    windowflags.py:38: error: Unsupported operand types for ^ ("WindowType" and "WindowFlags")
    windowflags.py:41: error: Unsupported left operand type for + ("WindowFlags")
    windowflags.py:42: error: Unsupported left operand type for - ("WindowFlags")
    windowflags.py:43: error: Unsupported left operand type for | ("WindowFlags")
    windowflags.py:44: error: Unsupported left operand type for & ("WindowFlags")
    windowflags.py:45: error: Unsupported left operand type for ^ ("WindowFlags")
    
    opened by bluebird75 17
  • Dockerfile to build upstream stubs

    Dockerfile to build upstream stubs

    Here's a draft pull request for a Dockerfile to build the upstream stubs, along with the new/updated stubs. Some existing stubs receive new annotations to work data types from the new stubs.

    There's also a build script (build_upstream.py) that handles building the image and extracting the files to the host.

    Some things worth discussion:

    • No idea how to build only stubs with the new sip-install command. The stubs are all generated at the beginning of the PyQt build and then I have to wait for it to finish. I'm sure there's a way I could kill the build early, but I didn't bother.
    • I'm unable to build QtAxContainer, QtAndroidExtras, QtMacExtras, and QtWindowsExtras in Docker, to my understanding
    • Even though I install their dependencies, I'm missing stubs for the following. Maybe they don't generate?
      • Qt3d
      • QtCharts
      • QtDataVisualization
      • QtPurchasing
      • QtWebEngine
      • Enginio (deprecated so probably doesn't matter)

    For reference: all the modules that PyQt supports: https://www.riverbankcomputing.com/static/Docs/PyQt5/module_index.html#ref-module-index

    opened by BryceBeagle 16
  • Widen PyQt5 dependency to 5.*

    Widen PyQt5 dependency to 5.*

    I understand that it is quite cumbersome to track all the releases (major and minor) of PyQt5 and keep this stub package up-to-date from a pip dependency point of view.

    However, if you think about it :

    • all versions of PyQt5 and Qt5 are backward compatible.
    • so, a stub file valid for PyQt 5.13 will also be useful and valid for 5.12 . Maybe there are a few extra methods but that's a small issue
    • also, a stub file valid for PyQt 5.13 is certainly useful and valid for PyQt 5.14 and 5.15 . Same story, a few new methods or objects could be missing but that's about 0.01% of the codebase.

    So my suggestion : declare PyQt5 5.* as a dependency.

    This means that basically every user of PyQt5 can take advnatage of the stubs, whatever the version he is using. It means more potential contributors !

    opened by bluebird75 13
  • Handling of operation on WindowType and WindowFlags

    Handling of operation on WindowType and WindowFlags

    Hi,

    Thanks for the great work on PyQt5 stubs, it is a pleasure to use it.

    In my code, I often disable the annoying help button of the window bar with the following code dialog.setWindowFlags(dialog.windowFlags() & ~Qt.WindowContextHelpButtonHint)

    Mypy fails on it with : src\mg_dialog_run_git_cmd.py:29: error: Unsupported operand types for & ("WindowFlags" and "int")

    I am trying to enhance type checking for this case. There are actually two issues :

    • Qt.WindowType (the class of Qt.WindowContextHelpButtonHint) is not typechecked for the operator ~
    • Qt.WindowFlags (the class of dialog.windowFlags()) is not typechecked for the operator &

    I have "implemented" the solution by annotating additional operations for both types. Is it something worth adding to the official stubs ?

    opened by bluebird75 12
  • Add all qflags bases classes

    Add all qflags bases classes

    I started from my work on windowFlags and look for ways to make it generic. I failed at defining a generic approach with mypy, protocols and generics inheriting from int, it is really above my understanding of mypy.

    But, it's easy enough to generate a file for each QFlag based class which can be used to assert both the actual implementation types and values, and which ensures that the class is being correctly checked. This is what I am doing here for two classes : WindowFlags and Alignment.

    With a few more hours, I should be able to cover all qflags based class. This would remove a big hole in PyQt stubs.

    opened by bluebird75 10
  • PyQt5 wheels will be shipped with stubs in the future

    PyQt5 wheels will be shipped with stubs in the future

    According to the PyQt mailinglist, the next PyQt release will ship wheels with its own stubs:

    https://www.riverbankcomputing.com/pipermail/pyqt/2020-April/042854.html

    My first thought was "hey, cool, so we don't need to build anything to get the stubs files!" (cc @BryceBeagle)... However, my second thought was "wait a minute... what will happen when people have both PyQt5 and PyQt5-stubs installed"? No idea which of the two will take precedence then, even after reading the relevant part of the PEP I don't understand what precedence stubs as part of the installed package (i.e. not inline types) have...

    opened by The-Compiler 9
  • QMessageBox expects

    QMessageBox expects "StandardButtons" and fails

    This code seems to fail with the stubs:

    QMessageBox.question(self, "Confirm", "Are you sure?", QMessageBox.Yes | QMessageBox.No)
    

    Tells me:

    Argument 4 to "question" of "QMessageBox" has incompatible type "int"; expected "Union[StandardButtons, StandardButton]"
    

    But the code should work, should it not?

    opened by pmiddend 8
  • Deprecate the docker build process

    Deprecate the docker build process

    Hi,

    Now that the PyQt5 stubs are released as part of PyQt5 pypi package, do we really need to keep this build process in place ?

    A few facts :

    • the build process is not documented. For somebody not familiar with docker, it might be difficult to grab. Adding a proper section in doc/developer_guide.md would be a very good idea
    • last time I checked, the pyi coming from the stubs are really the same as the one generated from the build process. I'll double-check that point though.
    • this build process is linux centric and fails to capture the specifics of the pyi for each platform. This won't be addressed in this issue directly but downloading the pyi from the different platforms allows us to capture the specifics of each platform

    @The-Compiler shared in an email that PyQtWebkit pyi generation depends on the Docker file for its stubs generation. However, the Docker file does not contain anything related to PyQtWebkit and PyQt5 does not ship QtWebkit modules.

    So, I am under the impression that the Docker file can be removed because pyi provides the same services.

    For QtWebkit, if it's not shipped with PyQt5, it might be a good idea to create a dedicated stub project file on pypi (PyQtWebkit-stubs) else people are unlikely to find the corresponding stubs.

    opened by bluebird75 9
  • version 5.15.2.0  in pycharm didn't wok.

    version 5.15.2.0 in pycharm didn't wok.

    after I upgrade to pyqt5-stubs version 5.15.2.0, the XXX.clickked.XXX 's autocompletion in pycharm(2021.1) didn"t work.But in Vscode(with pylance) it works well.Then i downgrade to pyqt5-stubds version 5.14.2.2 ,the XXX.clickked.XXX 's autocompletion in pycharm(2021.1) starts working.

    opened by jyc001 6
  • Add stubs for uic

    Add stubs for uic

    Steps

    Install PyQt5 package and type the import statement: from PyQt5 import QtGui, uic PyCharm will offer to install PyQt5-stubs. Agree. Actual - uic submodule is marked as unresolved. The code runs.

    Reported to JetBrains, and listed as an issue: https://youtrack.jetbrains.com/issue/PY-47685

    enhancement good first issue 
    opened by AranaFireheartSNHU 1
  • Set properties using keyword arguments in constructor

    Set properties using keyword arguments in constructor

    "self.scroll_area = QtWidgets.QScrollArea(widgetResizable=True)"

    generates following error message:

    error: Unexpected keyword argument "widgetResizable" for "QScrollArea"

    opened by ThePhilgrim 15
Releases(5.15.2.0)
  • 5.15.2.0(Feb 22, 2021)

    5.15.2.0

    Added

    • #125 on QtWidgets.QMessageBox, enumerators are also attributes of their enumerations
    • #99 enable mypy's strict mode
    • #92 add Sequence methods and .__setitem__() to sip.array
    • #94 add several operators to QIODevice.OpenMode and QIODevice.OpenModeFlag
    • #93 test against 3.5, 3.6, 3.7, 3.8, and 3.9
    • #71 update to PyQt5 5.15.1
    • #56 adds pyqtBoundSignal.__getitem__() allowing for indexing
    • #51 adds pyqtBoundSignal.signal hinted as str

    Changed

    • #129 fixes QThread and QNetworkAccessManager signals
    • #109 .__or__() for QMessageBox.StandardButton and QMessageBox.StandardButtons
    • #126 fix QCoreApplication.instance() return type to be optional
    • #102 fix pyqtSlot parameter typing and overloads
    • #104 sip.voidptr handles integer values and sequences and takes self
    • #103 pyqtBoundSignal.disconnect()'s slot parameter is optional
    • #100 fill generic parameter as sip.array[int] for QtDataVisualization textures
    • #92 remove self from qDefaultSurfaceFormat() and qIdForNode()
    • #83 fixes sip.array to be generic
    • #79 fixes extra class layer in several modules
    • #57 fixes PYQT_SLOT to allow callables returning any object
    • #56 fixes pyqtSignal as a descriptor and moves .emit(), .connect(), and .disconnect() to pyqtBoundSignal
    • #54 fixes pyqtSignal.connect() and pyqtSignal.disconnect() to support QMetaObject.Connection
    • #59 fixes QGuiApplication.lastWindowClosed to be a signal
    • #58 improves QObject.findChild and QObject.findChildren
    • #50 fixes QAbstractItemModelTester.FailureReportingMode attributes
    • #46 fixes QCoreApplication and QObject signals
    • #48 fixes some signals for QClipBoard, QWindows, QQuickView, QQmlApplicationEngine and QQmlEngine
    • #49 fixes QAbstractItemView.setModel() to accept None
    Source code(tar.gz)
    Source code(zip)
  • 5.14.2.2(May 2, 2020)

  • 5.14.2.1(May 1, 2020)

:sparkles: Surface lint errors during code review

✨ Linty Fresh ✨ Keep your codebase sparkly clean with the power of LINT! Linty Fresh parses lint errors and report them back to GitHub as comments on

Lyft 183 Dec 18, 2022
Flake8 wrapper to make it nice, legacy-friendly, configurable.

THE PROJECT IS ARCHIVED Forks: https://github.com/orsinium/forks It's a Flake8 wrapper to make it cool. Lint md, rst, ipynb, and more. Shareable and r

Life4 232 Dec 16, 2022
A framework for detecting, highlighting and correcting grammatical errors on natural language text.

Gramformer Human and machine generated text often suffer from grammatical and/or typographical errors. It can be spelling, punctuation, grammatical or

Prithivida 1.3k Jan 08, 2023
❄️ A flake8 plugin to help you write better list/set/dict comprehensions.

flake8-comprehensions A flake8 plugin that helps you write better list/set/dict comprehensions. Requirements Python 3.6 to 3.9 supported. Installation

Adam Johnson 398 Dec 23, 2022
The official GitHub mirror of https://gitlab.com/pycqa/flake8

Flake8 Flake8 is a wrapper around these tools: PyFlakes pycodestyle Ned Batchelder's McCabe script Flake8 runs all the tools by launching the single f

Python Code Quality Authority 2.6k Jan 03, 2023
Simple Python style checker in one Python file

pycodestyle (formerly called pep8) - Python style guide checker pycodestyle is a tool to check your Python code against some of the style conventions

Python Code Quality Authority 4.7k Jan 01, 2023
An enhanced version of the Python typing library.

typingplus An enhanced version of the Python typing library that always uses the latest version of typing available, regardless of which version of Py

Contains 6 Mar 26, 2021
Enforce the same configuration across multiple projects

Nitpick Flake8 plugin to enforce the same tool configuration (flake8, isort, mypy, Pylint...) across multiple Python projects. Useful if you maintain

Augusto W. Andreoli 315 Dec 25, 2022
Reference implementation of sentinels for the Python stdlib

Sentinels This is a reference implementation of a utility for the definition of sentinel values in Python. This also includes a draft PEP for the incl

Tal Einat 22 Aug 27, 2022
Pyright extension for coc.nvim

coc-pyright Pyright extension for coc.nvim Install :CocInstall coc-pyright Note: Pyright may not work as expected if can't detect project root correct

Heyward Fann 1.1k Jan 02, 2023
Tool for automatically reordering python imports. Similar to isort but uses static analysis more.

reorder_python_imports Tool for automatically reordering python imports. Similar to isort but uses static analysis more. Installation pip install reor

Anthony Sottile 589 Dec 26, 2022
MyPy types for WSGI applications

WSGI Types for Python This is an attempt to bring some type safety to WSGI applications using Python's new typing features (TypedDicts, Protocols). It

Blake Williams 2 Aug 18, 2021
A plugin for flake8 integrating Mypy.

flake8-mypy NOTE: THIS PROJECT IS DEAD It was created in early 2017 when Mypy performance was often insufficient for in-editor linting. The Flake8 plu

Łukasz Langa 103 Jun 23, 2022
coala provides a unified command-line interface for linting and fixing all your code, regardless of the programming languages you use.

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." ― John F. Woods coala provides a

coala development group 3.4k Dec 29, 2022
Convert relative imports to absolute

absolufy-imports A tool and pre-commit hook to automatically convert relative imports to absolute. Installation $ pip install absolufy-imports Usage a

Marco Gorelli 130 Dec 30, 2022
Flake8 plugin to find commented out or dead code

flake8-eradicate flake8 plugin to find commented out (or so called "dead") code. This is quite important for the project in a long run. Based on eradi

wemake.services 277 Dec 27, 2022
An open-source, mini imitation of GitHub Copilot for Emacs.

Second Mate An open-source, mini imitation of GitHub Copilot using EleutherAI GPT-Neo-2.7B (via Huggingface Model Hub) for Emacs. This is a much small

Sam Rawal 238 Dec 27, 2022
Flake8 plugin for managing type-checking imports & forward references

flake8-type-checking Lets you know which imports to put in type-checking blocks. For the imports you've already defined inside type-checking blocks, i

snok 67 Dec 16, 2022
Design by contract for Python. Write bug-free code. Add a few decorators, get static analysis and tests for free.

A Python library for design by contract (DbC) and checking values, exceptions, and side-effects. In a nutshell, deal empowers you to write bug-free co

Life4 473 Dec 28, 2022
🦆 Better duck-typing with mypy-compatible extensions to Protocol

🦆 Quacks If it walks like a duck and it quacks like a duck, then it must be a duck Thanks to PEP544, Python now has protocols: a way to define duck t

Arie Bovenberg 9 Nov 14, 2022