我为 `typeshed` 做出了贡献,因为我无法忍受缺少类型信息的错误

扳机

在我参与的一个项目中,有一个从 Python 操作 COM 的脚本。

为了处理那里发生的错误,我经常编写如下代码。

from _ctypes import COMError

try:
    ...
except COMError as e:
    ...

但,_ctypes 没有类型存根,所以在导入时就发出了 VSCode 的 pylance (pyright) 错误,即使被抑制了,COMError 也被视为 Unknown。

结果异常的信息没有传递给类型检查器,如果有COMError,类型检查器就会发出警告,很难做到。

很长一段时间我都把这种情况视作无可奈何,但我参与这个项目已经快两年了,我终于受不了了。

所以我决定为typeshed 做出贡献,他正在为 Python 库整理类型存根。

关于typeshed

有关角色描述,请参阅 PEP484。

点击这里翻译

问题讨论

现在,我犹豫要不要突然为一个模块添加一个存根,更不用说在标准库中公开某些内容而不与其他贡献者共享信息。所以,我提出了一个问题,首先告诉他们我想做什么,然后问他们这与什么情况有关。

在我的项目中,我使用了一些 COM-ffi 包。

_ctypes.COMError 和 _ctypes.CopyComPointer 也使用 mypy 类型检查器可以抛出 Cannot find implementation or library stub for module named "_ctypes" 错误,因为它们没有定义类型存根。

我想添加这样的类型存根。

# githubのissueカンバンにあるスニペット

但我对这些以外的 API 了解不多。

哪里需要if sys.platform == "win32":?

如果您有任何意见,请告诉我。

之后,贡献者typeshed 给了我各种建议。下面是一个总结。

欢迎 PR 型情報がないこと由来のエラーに耐えられなかったので、`typeshed`にコントリビュートしたお話 stdlib/ 下面已经有很多类似_foo.pyi 的模块

阅读CONTRIBUTING.md 并将_ctypes 标记为不完整 我已经验证Linux环境下不存在COM元素,所以COM关系在if sys.platform == "win32":下

已定义为stdlib/ctypes/__init__.pyi 的元素实际上在运行时定义为_ctypes。如果添加了_ctypes 存根,我认为***将它移动到运行时(尽管第一个 PR 是最小的并且可以)

请在stdlib/VERSIONS 中包含_ctypes 信息

公关合并前的故事

我根据建议做了一个存根并做了一个 PR。

存根中的文档字符串是不需要的,并且经过审查和修复以将其删除。

但是,即使在修复之后,CI 仍然无法正常工作!

看到CI报错信息,我很生气,原来在runtime中定义的_ctypes._Pointer等都不在了。

CONTRIBUTING.md 说,“当你创建一个不完整的存根时,在模块级别定义 def __getattr__(name: str) -> Any: ... # incomplete。”

当我不知所措时,审稿人指出了各种更正。

stubtest 和 allowlist 的存在

stubtest 是一个与类型检查器捆绑在一起的测试,例如 mypy,它将运行时实现的命名空间与类型存根进行比较,如果类型存根丢失,则失败。

大纲写在下面的问题“1)使用stubtest查找stubs中缺少的东西或有问题的东西。”

就这样,reviewer 将每个尚未添加到 stub 的对象添加到allowlist,CI 通过并合并。

现在的情况

mypy 和 pylance 现在包括存根更新,不再是 Unknown!

在那之后

我将继续致力于使存根与运行时定义保持同步。

其中,难免会出现循环导入,所以提了一个问题,咨询了下。

我松了口气,因为我得到了答案,我即将发布PR来一点一点地移动定义。

但是,目前(截至 2022 年 9 月 20 日),即使您将定义写入 _ctypes 并写入存根以导入到 ctypes,测试失败且 CI 未通过.对此,pytype这边已经提了一个问题,计划近期更正。

(以上问题解决后)我们期待您的贡献。

原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308626377.html

59人参与, 0条评论 登录后显示评论回复

你需要登录后才能评论 登录/ 注册