为什么 mypy 认为缺少库导入?

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

当我运行 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 查看确实存在的可导入模块?

python mypy
5个回答
51
投票

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

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

  1. 将类型提示或存根添加到他们的代码中,并在他们分发到 PyPi(或任何其他包存储库)的包中包含一个名为
    py.typed
    的文件。该标记的存在使包能够识别“PEP-561”。 mypy 文档还提供了有关 PEP-561 感知包的更多信息。 或者,将存根添加到
  2. typeshed
  3. (标准库的类型提示存储库)并选择第 3 方库。
aws_xray_sdk

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


这有点不幸,那你能做什么呢? mypy 文档的“缺少导入”部分有一些关于做什么的详细建议,但总而言之,您基本上有三个选项,我将按从最少到最多努力的顺序列出:

只需向每个导入手动添加

# type: ignore
    注释即可使导入静音。您还可以将以下部分添加到 mypy 配置文件中,以自动发生这种情况:
  1. [mypy-aws_xray_sdk] ignore_missing_imports = True

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

    Any

    四处搜索,看看是否有人为您的库创建了

    第三方
  2. 存根包:基本上,一个非官方(或有时半官方)PEP-561感知包,
  3. 包含类型提示。例如,对于 django,有 django-stubs,对于 SqlAlchemy,有 sqlalchemy-stubs 为此库创建您自己的存根,并通过 mypy 配置文件中的

    mypy_path
  4. 选项指向它们:
  5. mypy_path = my_stubs/aws_xray_sdk, my_stubs/some_other_library

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

    
    
    

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

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

不过,至少在大多数情况下,

Mypy

可以
在这里给出更好的错误消息。在我看来,事实并非如此,这在很大程度上是一种疏忽。

https://github.com/python/mypy/issues/4542

中有一些关于此的讨论。 有时,它可能就像在包中添加

__init__.py

26
投票

我遇到了同样的问题,并意识到我尝试导入的包缺少

__init__.py
文件。因此 mypy 无法“看到”导入。

作为@Michael0x2a 答案的补充。有一个选项可以忽略 

mypy.ini

8
投票

[mypy] ignore_missing_imports = True

    

您只需运行此命令即可:

0
投票

请注意,mypy 目前有一个未解决的错误报告,标题为“false“模块已安装,但缺少库存根或 py.typed 标记。”当子模块不存在时”。

0
投票


我发现当其他问题出现时我会收到该错误,例如缺少 init.py。一旦我解决了其他问题,丢失的库存根或标记警告就会消失。

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