The most accurate stubs for PySide2
Project description
Type stubs for PySide2 (and soon PySide6)
The most accurate type stubs for PySide! They have been tested against a code base with many thousands of lines of PySide code.
Comparison to other PySide stubs
I tried a number of projects before deciding to create my own. Here's my super-biased assessment:
Stub Project | Technique | Rating |
---|---|---|
Official stubs | Uses PySide's generate_pyi stub generator |
abysmal |
PySide2-Stubs-Gen | Uses a modified version of generate_pyi |
marginal |
PySide2-stubs | Reprocesses official stubs using libcst | better |
types-PySide2 | Uses mypy's stubgen | best |
python-qt-tools/PySide2-stubs
is pretty good, but it still produced hundreds of errors in our code base.
One thing I really like about the project, however, is the set of tests that serves to both demonstrate PySide runtime behavior and prove that the stubs are accurate, so I've heavily borrowed from that.
I considered contributing new features to that project, but the approach of using an AST/CST parser to modify
an upstream set of bad official stubs to make them good is convoluted and prone to errors from upstream changes.
This project uses mypy's official stubgen
tool to directly generate stubs, with a set of corrections applied.
Corrections are primarily defined through a dictionaries that map classes/methods/args to fixes which are applied during stub generation.
In the process of creating these stubs I made a bunch of improvements to mypy's stubgen
tool which should benefit me and other stub creators in the future, rather than persisting and working around PySide's own mediocre PySide2.support.generate_pyi
tool.
Features and fixes
General fixes
- Fixed an issue where methods/attributes were not detected, due to presence of
QObject.__getattr__()
- Added all signals and made new-style signal patterns work
- e.g.
myobject.mysignal.connect(func)
andmyobject.mysignal[type].connect(func)
- Fixed slot arg of
SignalInstance.connect()
to betyping.Callable
instead ofobject
- Fixed
Signal.emit()
- Fixed
Signal.connect()
return value tobool
instead ofNone
- Fixed
Object.disconnect()
- e.g.
- Fixed flag classes to add all methods:
__or__
,__xor__
, ...
Rule-based fixes
- When instantiating subclasses of
QObject
it is possible to pass the values of properties and signals as**kwargs
to__init__
. The stubs have been fix to include these on all relevant__init__
methods. - Qt/PySide has special "flag" enumerator classes that work as pairs: one represents a single flag value, while the other represents multiple combined. The stubs have been fix to allow either type of flag -- single or multiple -- anywhere that one of the would have been accepted, which is the correct behavior (technically
typing.SupportsInt
is the most correct, but using this would undermine the type enforcement provided by the stubs). - Removed redundant overlapping overloads, so that satisfying mypy/liskov on subclassed methods is easier
- Fixed all arguments typed as
typing.Sequence
to betyping.Iterable
. Tests so far have indicated that this is true as a general rule. Also note that unlike other projects,typing.Iterable
includes the subtype, e.g.typing.Iterable[str]
- Replaced
object
withtyping.Any
in return types. e.g.:QSettings.value() -> Any
QModelIndex.internalPointer() -> Any
QPersistentModelIndex.internalPointer() -> Any
Specific fixes
- Certain argument types implicitly accept alternative types for brevity. Below are the known fixes so far (Note that I've debated not including these, since one of the advantages of static typing is it gives you the confidence to be explicit rather than ambiguous. I could introduce a strict mode in the future that would disable these):
QKeySequence
:str
QColor
:Qt.GlobalColor
andint
QBrush
:QLinearGradient
andQColor
(and by extensionQt.GlobalColor
)QCursor
:Qt.CursorShape
QEasingCurve
:QEasingCurve.Type
- Corrected numerous annotations from
bytes/QByteArray
tostr
:QObject.setProperty()
QObject.property()
QState.assignProperty()
QCoreApplication.translate()
format
args on all methods
- Fixed
QTreeWidgetItemIterator.__iter__()
to returnIterator[QTreeWidgetItemIterator]
- Added missing
QDialog.exec()
method - Fixed numerous methods which accept
None
:QPainter.drawText(..., br)
QPainter.drawPolygon(..., arg__2)
QProgressDialog.setCancelButton(button)
*.setModel(model)
QLabel.setPixmap(arg__1)
- Fixed numerous arguments that accept
QModelIndex
which were typed asint
- Fixed return type for
QApplication.instance()
andQGuiApplication.instance()
- Fixed return type for
QObject.findChild()
andQObject.findChildren()
- Fixed support for initializing
QDate
fromdatetime.date
- Fixed support for initializing
QDateTime
fromdatetime.datetime
- Fixed
QByteArray.__iter__()
to returnIterator[bytes]
- Fixed support for
bytes(QByteArray(b'foo'))
- Added support for all
QSize
andQSizeF
operations - Added support for all
QPolygon
operations - Fixed
QTextEdit.setFontWeight()
to acceptQFont.Weight
- Fixed return type for
qVersion()
Licensing
As a derived work from PySide2, the stubs are delivered under the LGPL v2.1 . See file LICENSE for more details.
Installation
Install the latest stub packages from pypi:
$ pip install types-PySide2
This will add the PySide2-stubs
and shiboken2-stubs
packages into your site-packages directory.
Note, you may need to uninstall other PySide2 stubs first:
$ pip uninstall PySide2-stubs
Help improve the stubs
If you notice incorrect or missing typing information (i.e. mypy reports errors even though your code is correct), please report it or make a PR to fix it.
Testing
python3 -m venv .venv
. .venv/bin/activate
tox
TODO
- Get all my stubgen changes merged into mypy
- Build PySide6 stubs
- Merge overloads where a
Union
would do instead of multiple overloads - Add type enforcement for signal types, to protect against incorrect callables provided to
connect()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file types_PySide2-5.15.2.1.1-py3-none-any.whl
.
File metadata
- Download URL: types_PySide2-5.15.2.1.1-py3-none-any.whl
- Upload date:
- Size: 578.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 50e7882de41328cca5e641be8c732ab3fd03bcf22fd97c9f0740990cd0b2be95 |
|
MD5 | da59b534b13c721f702bd7cae8d2cb06 |
|
BLAKE2b-256 | 397b90d68e5bdf6db1efbd1e236c382cbd49187b1060b37963d6f33663bc39f4 |