Python mypy 类型检查没有按预期工作

问题描述 投票:0回答:1

我是 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
,它确实会给我一个错误)。

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

python types mypy bottle
1个回答
1
投票

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

获得“真实类型”的唯一方法是

bottle
维护者添加它们。假设这不会发生,您有多种选择:

  1. 生成骨架轮廓(Python存根文件,扩展名

    .pyi
    ),这将有助于完成基本代码。这将捕获变量、函数和类 existence,但不会捕获变量和函数签名类型信息(仅仅是因为
    bottle.py
    一开始就没有)。

    使用 mypy 附带的

    stubgen
    工具可以在大约一秒钟内生成骨骼轮廓,如果您已经安装了 mypy,您应该已经拥有该工具。

  2. 通过在bottle 的测试套件 上运行pyannotateMonkeyType 来收集运行时类型,并使用这些工具生成

    .pyi
    。这比只运行
    stubgen
    更准确,但最终质量取决于测试套件,并且很可能导致 mypy 的大量误报警告,特别是对于 descriptor classes like bottle 的
     DictProperty
    lazy_attribute
    .

  3. 使用pytype的类型推断来生成

    .pyi
    。这通常会产生更多可用的存根,但代价是非常长的推理过程,最终可能会构建依赖图并扫描您的大部分
    site-packages
    ,并且如果
    bottle
    有很多复杂的第三-党的依赖。

你应该最终得到一个单一的

bottle.pyi
,你必须移动到与
bottle.py
相同的目录。这应该在您的虚拟环境的
site-packages
中。完成 2. 或 3. 后,
mypy
应该能够正确识别打字错误。

© www.soinside.com 2019 - 2024. All rights reserved.