为啥 mypy 认为缺少库导入?

Posted

技术标签:

【中文标题】为啥 mypy 认为缺少库导入?【英文标题】:Why does mypy think library imports are missing?为什么 mypy 认为缺少库导入? 【发布时间】:2020-01-07 04:11:50 【问题描述】:

当我运行 mypy 时,它抱怨找不到模块:

sal@ahfang:~/workspace/ecs/cx-project-skeleton-repo/src/cx-example-function$ pipenv run python -m mypy .
example_lambda.py:3: error: Cannot find module named 'aws_xray_sdk.core'

但是当尝试使用完全相同的 Python 解释器导入完全相同的模块时,该模块似乎确实存在并且是可导入的。

python 
Python 3.7.3 (default, Apr  3 2019, 05:39:12) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import aws_xray_sdk.core
>>>

除了强制忽略 mypy.ini 文件中的导入,我应该做些什么来帮助 mypy 查看确实存在的可导入模块?

【问题讨论】:

【参考方案1】:

有时,它可能就像在你的包中添加一个__init__.py 文件一样简单。

我遇到了同样的问题,并意识到我试图从中导入的包缺少 __init__.py 文件。因此 mypy 无法“看到”导入。

【讨论】:

我的tests/ 的文件夹中缺少__init__.py。这解决了它【参考方案2】:

所以,问题的关键在于:mypy 会尝试对您导入的每个模块进行类型检查。相反,它只尝试对已明确选择加入打字生态系统的模块进行类型检查。

模块可以通过两种关键机制选择加入打字生态系统:

    在他们的代码中添加类型提示或存根,并在他们分发到 PyPi(或任何其他包存储库)的包中包含一个名为 py.typed 的文件。这个标记的存在使包PEP-561-aware。 mypy 文档还包含有关 PEP-561-aware packages 的更多信息。 或者,将存根添加到 typeshed(标准库的类型提示存储库)并选择第 3 方库。

aws_xray_sdk 包没有做这些事情,所以会被 mypy 忽略。


这有点不幸,那你能怎么办? mypy 文档的Missing imports 部分有一些关于做什么的详细建议,但总而言之,你基本上有三个选项,我将按照从最少到最多的顺序列出:

    只需通过手动将# type: ignore cmets 添加到每个导入来使导入静音。您还可以将以下部分添加到您的 mypy 配置文件中以自动执行此操作:

    [mypy-aws_xray_sdk]
    ignore_missing_imports = True
    

    现在,您从此模块导入的任何内容都将被视为Any 类型。

    四处搜索,看看是否有人为您的库创建了 第三方 存根包:基本上,一个非官方(或有时是半官方的)PEP-561 感知包 only 包含类型提示。例如,对于 django,有 django-stubs,对于 SqlAlchemy,有 sqlalchemy-stubs。

    为此库创建您自己的存根,并通过 mypy 配置文件中的 mypy_path 选项指向它们:

    mypy_path = my_stubs/aws_xray_sdk, my_stubs/some_other_library
    

    这些存根不一定是完整的:您只需为您正在使用的少数东西添加注释即可。 (如果它们最终变得相对完整,您可能会考虑将它们贡献回开源社区。)


最后,您可能想知道为什么 mypy 会这样?

部分原因是在一般情况下,mypy 尝试查找和分析模块是不安全的。只是盲目地导入和使用未准备好类型提示的包有时会导致奇怪的类型错误,或者更糟的是,可能导致代码被错误地标记为类型安全。也就是说,如果您关心类型安全,最好立即通知您正在使用的某些包没有类型提示,而不是 mypy 在您的代码中盲目推断和涂抹 Anys。

Mypy 可以在这里给出更好的错误信息,至少大多数时候是这样。 IMO 事实上,它没有在很大程度上是一个疏忽。 https://github.com/python/mypy/issues/4542 对此进行了一些讨论。

【讨论】:

你也可以使用--ignore-missing-imports标志运行mypy

以上是关于为啥 mypy 认为缺少库导入?的主要内容,如果未能解决你的问题,请参考以下文章

导入的 JSF 项目缺少用户库 JAR

mypy 如何忽略源文件中的一行?

从缺少 setup.py 文件的 git 存储库导入库

为啥 VS Code 认为导入有效但 WebPack 不认为有效?

我很困惑,为啥我必须单独导入函数,如果我导入整个库,这些函数不能导入

Swift 应用程序:导入静态库的框架时“缺少必需的模块”