Giter VIP home page Giter VIP logo

types-pyside's Introduction

Type stubs for PySide2 (and soon PySide6)

The most accurate type stubs for PySide! They have been tested using mypy on 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

PySide2-stubs is pretty good, but it still produced hundreds of errors in our code base. 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.

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) and myobject.mysignal[type].connect(func)
    • Fixed slot arg of SignalInstance.connect() to be typing.Callable instead of object
    • Fixed Signal.emit()
    • Fixed Signal.connect() return value to bool instead of None
    • Fixed Object.disconnect()
  • Added all methods to flag classes: __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 args 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
  • For methods that implement both classmethod and instancemethod overloads, the classmethod overloads have been removed. Unfortunately, mypy disallows mixing these and does not correctly analyze them.
  • Corrected all arguments typed as typing.Sequence to be typing.Iterable. Tests so far have indicated that this is true as a general rule.
  • Added sub-types to Iterable annotations, e.g. Iterable[str], Iterable[int], etc
  • Replaced object with typing.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 and int
    • QBrush: QLinearGradient and QColor (and by extension Qt.GlobalColor)
    • QCursor: Qt.CursorShape
    • QEasingCurve: QEasingCurve.Type
  • Corrected numerous annotations from bytes/QByteArray to str:
    • QObject.setProperty()
    • QObject.property()
    • QState.assignProperty()
    • QCoreApplication.translate()
    • format args on all methods
  • Fixed QTreeWidgetItemIterator.__iter__() to return Iterator[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 as int
  • Fixed return type for QApplication.instance() and QGuiApplication.instance()
  • Fixed return type for QObject.findChild() and QObject.findChildren()
  • Fixed support for initializing QDate from datetime.date
  • Fixed support for initializing QDateTime from datetime.datetime
  • Fixed QByteArray.__iter__() to return Iterator[bytes]
  • Fixed support for bytes(QByteArray(b'foo'))
  • Added support for all QSize and QSizeF operations
  • Added support for all QPolygon operations
  • Fixed QTextEdit.setFontWeight() to accept QFont.Weight
  • Fixed return type for qVersion()
  • Add QSpacerItem.__init__/changeSize overloads that use alternate names: hData->hPolicy, vData->vPolicy

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.
Yes, the name of the pypi package is types-PySide2 but the python package it installs is PySide2-stubs.
It's confusing, but PEP 561 requires that the installed package name is of the form $PACKAGE-stubs, so all of us PySide stub developers are installing a package with the same name.

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

  • 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()

types-pyside's People

Contributors

chadrik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

koltesdigital

types-pyside's Issues

Can't use these stubs in vscode, mypy has a number of errors

When I tried to use these stubs in vscode they didn't work, then checking the Output window (under python) I discovered a number of errors like this:

/stubs/PySide2-stubs/QtCore.pyi:377:5: error: Signature of "columnCount" incompatible with supertype "QAbstractItemModel"

I'm guessing vscode does a pass with mypy.stubtest first and doesn't use them unless it passes. (That's just a guess, I haven't gone to the trouble of testing this myself yet)

Cannot manage to make the stubs used by PyCharm.

Hello, I have been trying to get your stubs working alongside my PyCharm project.

I am using Qt.py from which types-PySide is perfectly installed using 1.3.8. But they are not being picked by PyCharm at all.

The reasons for now are :

  • PyCharm create some pre-build "binary skeletons", I need to remove them from External Libraries/Binary Skeletons.
  • Then it seems PySide2 comes with its own stubs file installed along. You can just perform a pip install PySide2 --target "somedir/", look at the content of somedir and notice a .pyi file for each root Qt module. Again I can deleted those manually but though it's not a good practice as this need to be performed at each venv update.

Here is a screenshot of the site-packages directory of the venv :

image

So this would actually be more of a "discussion" than an "issue" as there is no issue with types-PySide directly, just PyCharm being annoying to work with. I'm still creating the issue so it can maybe help other people having the same issue.

I'm looking for any advice on the resolution that would involve minimal hackery.

  • Is there any flag when installing PySide2 so it doesn't install stubs
  • Can I make PySide2-stubs stubs take priority over the .pyi files in PySide2 directory ?
Context

PyCharm 2022.3.2
Poetry 1.2.0
Qt.py 1.3.8
types-PySide2 5.15.2.1.5

Feel free to close this if you don't estimate it's the right place to discuss it.
Cheers.
Liam.

QTextEdit.setFontWeight() type error

This produces a type error:

self.setFontWeight(QtGui.QFont.DemiBold)
Argument of type "Weight" cannot be assigned to parameter "w" of type "int" in function "setFontWeight"
  "Weight" is incompatible with "int"

setFontWeight() allows QFont predefined weight enums, but they don't register as compatible with ints, even though they are

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.