Skip to main content

PySide2 最准确的存根

项目描述

PySide2(很快 PySide6)的类型存根

PySide 最准确的类型存根!它们已经针对包含数千行 PySide 代码的代码库进行了测试。

与其他 PySide 存根的比较

在决定创建自己的项目之前,我尝试了许多项目。这是我的超级偏见评估:

存根项目 技术 评分
官方存根 使用 PySide 的generate_pyi存根生成器 糟糕透了
PySide2-Stubs-Gen 使用修改后的版本generate_pyi 边缘
PySide2-存根 使用libcs​​t 重新处理官方存根 更好的
类型-PySide2 使用 mypy 的stubgen 最好的

python-qt-tools/PySide2-stubs相当不错,但它仍然在我们的代码库中产生了数百个错误。然而,我真正喜欢这个项目的一件事是,一组测试既可以展示 PySide 运行时行为,又可以证明存根是准确的,所以我大量借鉴了它。我考虑为那个项目贡献新的特性,但是使用 AST/CST 解析器来修改上游的一组糟糕的官方存根以使其成为好的方法是复杂的,并且容易因上游更改而出错。本项目使用mypy的官方stubgen直接生成存根的工具,并应用了一组更正。更正主要通过将类/方法/参数映射到存根生成期间应用的修复的字典来定义。在创建这些存根的过程中,我对 mypy 的stubgen工具进行了一系列改进,这将使我和其他存根创建者在未来受益,而不是坚持和围绕 PySide 自己的平庸PySide2.support.generate_pyi工具工作。

功能和修复

一般修复

  • 修复了由于存在而未检测到方法/属性的问题QObject.__getattr__()
  • 添加所有信号并使新型信号模式工作
    • 例如myobject.mysignal.connect(func)myobject.mysignal[type].connect(func)
    • 将插槽 arg 固定SignalInstance.connect()typing.Callable代替object
    • 固定的Signal.emit()
    • Signal.connect()将返回值固定为 bool 而不是 None
    • 固定的Object.disconnect()
  • 将标志类固定为 Aad 所有方法:__or__, __xor__, ...

基于规则的修复

  • 在实例化子类时QObject,可以将属性和信号的值传递**kwargs__init__. 已修复存根以将这些包含在所有相关__init__方法中。
  • Qt/PySide 有特殊的“标志”枚举器类,它们成对工作:一个代表单个标志值,而另一个代表多个组合。存根已修复以允许任何一种类型的标志 - 单个或多个 - 任何一个会被接受的地方,这是正确的行为(技术上typing.SupportsInt是最正确的,但使用它会破坏提供的类型强制存根)。
  • 删除了多余的重叠重载,以便更容易满足子类方法上的 mypy/liskov
  • 修复了所有键入为typing.Sequence的参数typing.Iterable。迄今为止的测试表明,这作为一般规则是正确的。另请注意,与其他项目不同,typing.Iterable包括子类型,例如typing.Iterable[str]
  • 替换objecttyping.Any返回类型。例如:
    • QSettings.value() -> Any
    • QModelIndex.internalPointer() -> Any
    • QPersistentModelIndex.internalPointer() -> Any

具体修复

  • 为简洁起见,某些参数类型隐式接受替代类型。以下是迄今为止已知的修复(请注意,我已经讨论过不包括这些修复,因为静态类型的优点之一是它让您有信心明确而不是模棱两可。我可以在未来引入一个严格模式,它将禁用这些):
    • QKeySequencestr
    • QColorQt.GlobalColor
    • QBrush:QLinearGradientQColor(以及扩展名Qt.GlobalColor
    • QCursorQt.CursorShape
    • QEasingCurveQEasingCurve.Type
  • bytes/QByteArray更正了从到 的大量注释str
    • QObject.setProperty()
    • QObject.property()
    • QState.assignProperty()
    • QCoreApplication.translate()
    • format所有方法的参数
  • 固定QTreeWidgetItemIterator.__iter__()返回Iterator[QTreeWidgetItemIterator]
  • 添加了缺失的QDialog.exec()方法
  • 修复了许多接受的方法None
    • QPainter.drawText(..., br)
    • QPainter.drawPolygon(..., arg__2)
    • QProgressDialog.setCancelButton(button)
    • *.setModel(model)
    • QLabel.setPixmap(arg__1)
  • 修复了许多接受QModelIndex输入为的参数int
  • QApplication.instance()和的固定返回类型QGuiApplication.instance()
  • QObject.findChild()和的固定返回类型QObject.findChildren()
  • QDate修复了对从初始化的支持datetime.date
  • QDateTime修复了对从初始化的支持datetime.datetime
  • 固定QByteArray.__iter__()返回Iterator[bytes]
  • 固定支持bytes(QByteArray(b'foo'))
  • 增加了对 allQSizeQSizeF操作的支持
  • 增加了对所有QPolygon操作的支持

许可

作为 PySide2 的派生作品,存根在 LGPL v2.1 下交付。有关详细信息,请参阅文件许可证。

安装

从 pypi 安装最新的存根包:

$ pip install types-PySide2

这会将PySide2-stubsshiboken2-stubs包添加到您的站点包目录中。

注意,您可能需要先卸载其他 PySide2 存根:

$ pip uninstall PySide2-stubs

帮助改进存根

如果您发现输入信息不正确或丢失(即即使您的代码正确,mypy 也会报告错误),请报告或提交 PR 以修复它。

去做

  • 将我所有的 stubgen 更改合并到 mypy 中
  • 构建 PySide6 存根
  • 合并重载,Union而不是多个重载
  • 为信号类型添加类型强制,以防止提供给connect()

项目详情


下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

内置分布

types_PySide2-5.15.2.1.0-py3-none-any.whl (577.6 kB 查看哈希

已上传 py3