Python mypy 类型检查未按预期工作

标签 python types mypy bottle

我是 python 新手,并且是静态类型检查器的忠实粉丝。我有一些使用 Bottle 框架处理文件上传的代码。见下文。

def transcribe_upload(upload: FileUpload) -> Alternative:
  audio:AudioSource = upload_source(upload)
  ...

def upload_source(upload:FileUpload) -> AudioSource:
  ...

我犯了一个非常简单的错误,将 upload.file (类似文件的对象)传递给 upload_source 而不是整个 FileUpload 对象.

def transcribe_upload(upload: FileUpload) -> Alternative:
  audio:AudioSource = upload_source(upload.file) # This is incorrect!

类型检查器没有捕获它。事实上,它没有捕获任何传递给 upload_source 的错误参数:

def transcribe_upload(upload: FileUpload) -> Alternative:
  audio:AudioSource = upload_source(4)           # Why isn't mypy giving me an error?
  audio:AudioSource = upload_source(upload.asdf) # Why isn't mypy giving me an error?

发生什么事了?我分别测试了一些基本函数,当我尝试将数字传递给需要字符串的函数时,类型检查器捕获,并且它起作用了。我在这里缺少什么?

编辑

@kojiro 建议 FileUpload 等同于 Any。我认为这可能是正确的。这是 FileUpload 的来源。它的导入方式如下:from Bottle import FileUpload

如果是这样的话,为什么它让我使用 FileUpload 就好像它是一种类型一样? (如果我弄乱了名称,例如 FileUpld ,它确实会给我一个错误)。

更重要的是,我如何获得真实类型?我想 Bottle 作者必须添加它们?

最佳答案

bottle 不是静态类型库(它在 bottle.py 中不提供类型注释)。它作为单个 bottle.py 的组织(而不是 package )也会阻止您创建 py.typed 。否则,这将允许 mypy 至少获取类属性、函数/方法签名和全局变量(即使它们没有任何类型信息)。

获得“真实类型”的唯一方法是让 bottle 维护者添加它们。假设这种情况不会发生,您有多种选择:

  1. 生成骨架轮廓 ( Python stub file, extension .pyi ),这将有助于完成基本代码。这将捕获变量、函数和类存在,但不会捕获变量和函数签名类型信息(仅仅是因为bottle.py一开始就没有任何信息)。

    使用 mypy 提供的 stubgen 可以在大约一秒内生成骨架轮廓。工具,如果您安装了 mypy,您应该已经拥有该工具。

  2. 通过运行 pyannotate 收集运行时类型或MonkeyTypebottle's test suite ,并使用这些工具生成 .pyi。这比仅仅运行stubgen更准确,但最终的质量取决于测试套件,并且很可能导致mypy发出大量误报警告,尤其是descriptor classes像 Bottle 的DictPropertylazy_attribute .

  3. 使用pytype的类型推断来生成 .pyi。这通常会产生更多可用的 stub ,但代价是非常长的推理过程,最终可能会构建依赖关系图并扫描大部分站点包,并且如果会经常失败Bottle 有很多复杂的第三方依赖项。 (编辑:看起来 bottle 仅依赖于 Python 标准库,在这种情况下,您应该通过 pytype 获得相当快的推理)

您最终应该得到一个 bottle.pyi,您必须将其移动到与 bottle.py 相同的目录中。它应该位于虚拟环境的 site-packages 中。完成 2. 或 3. 后,mypy 应该能够正确检测输入错误。

关于Python mypy 类型检查未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75653850/

相关文章:

python - Pyinstaller 错误 ImportError : No module named 'requests. packages.chardet.sys

python - 高效,快速的numpy直方图

c - vim:显示 C 聚合(结构/union )成员的类型,即使是嵌套的

python - 为什么 mypy 检查我排除的文件?

python - Python 单元测试中具有可变值的字典?

c# - 当缺少System指令时,如何解析类型别名?

typescript - 从 NPM 模块中向界面添加属性

twisted - 升级到 Twisted 21.2.0 时出现 Mypy 输入错误

python-3.x - 如何向 scikit-learn 函数添加类型提示?

python - 找不到满足 UnityEngine 要求的版本