为什么 mypy 认为缺少库导入? [英] Why does mypy think library imports are missing?

查看:48
本文介绍了为什么 mypy 认为缺少库导入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I run mypy it complains that modules cannot be found:

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 解释器导入完全相同的模块时,该模块似乎确实存在并且是可导入的.

But when trying to import that exact same module with the exact same Python interpreter, it seems that the module does exist and is importable.

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

Other than to force ignore the imports in the mypy.ini file, is there anything I should be doing to help mypy see importable modules that definitely do exist?

推荐答案

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

So, here's the crux of the issue: mypy does not try type-checking every single module you've imported. Instead, it only attempts to type-check modules that have explicitly opted-in to the typing ecosystem.

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

Modules can opt-in to the typing ecosystem via two key mechanisms:

  1. 向他们的代码添加类型提示或存根,并在他们分发给 PyPi(或任何其他包存储库)的包中包含一个名为 py.typed 的文件.这个标记的存在使得包PEP-561-aware.mypy 文档还有关于PEP-561-aware 包的更多信息.立>
  2. 或者,将存根添加到 typeshed(标准库的类型提示存储库)并选择第 3 方图书馆.
  1. Add type hints or stubs to their code, and include a file named py.typed within the package they distribute to PyPi (or any other package repository). The presence of this marker makes the package PEP-561-aware. The mypy docs also have more info about PEP-561-aware packages.
  2. Alternatively, add stubs to typeshed, the repository of type hints for the standard library and select 3rd party libraries.

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

The aws_xray_sdk package has done neither of these things, so will be ignored by mypy.

这有点不幸,你能怎么办?mypy 文档的 缺失导入 部分有一些关于该怎么做,但总而言之,您基本上有三个选项,我将按照从最少到最努力的顺序列出:

This is a bit unfortunate, so what can you do? The Missing imports section of the mypy docs has some detailed recommendations on what to do, but to summarize, you basically have three options which I'll list in order from least to most effort:

  1. 只需在每次导入时手动添加 # type: ignore 注释即可使导入静音.您还可以将以下部分添加到 mypy 配置文件中以自动执行此操作:

  1. Just silence the import by manually add # type: ignore comments to each import. You can also add the following section to your mypy config file to have this happen automatically:

[mypy-aws_xray_sdk]
ignore_missing_imports = True

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

Now, anything you import from this module will be treated as being of type Any.

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

Search around and see if anybody has created a third party stubs package for your library: basically, an unofficial (or sometimes semi-official) PEP-561-aware package that only contains type hints. For example, for django, there's django-stubs, for SqlAlchemy, there's sqlalchemy-stubs.

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

Create your own stubs for this library and point to them via the mypy_path option in your mypy config file:

mypy_path = my_stubs/aws_xray_sdk, my_stubs/some_other_library

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

These stubs don't have to be complete, necessarily: you can get away with just adding annotations for the few things you're using. (And if they do end up becoming relatively complete, you perhaps look into contributing them back to the open-source community.)

<小时>

现在,您可能想知道 为什么 mypy 会这样?

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

Part of this is because it's not safe in the general case for mypy to just try finding and analyzing the module. Just blindly importing and using packages that are not type-hinting ready can sometimes result in odd type errors, or worse, can result in code incorrectly being marked as type-safe. That is, if you care about type-safety, it's better to be immediately notified that some package you're using has no type hints instead of mypy blindly inferring and smearing Anys all over your code.

Mypy 可以在这里给出更好的错误信息,至少在大多数情况下是这样.IMO 事实并非如此,这在很大程度上是一种疏忽.https://github.com/python/mypy/issues/4542 对此有一些讨论一>.

Mypy could give a better error message here though, at least most of the time. IMO the fact that it doesn't is largely an oversight. There's some discussion about this in https://github.com/python/mypy/issues/4542.

这篇关于为什么 mypy 认为缺少库导入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆