如何正确处理mypy中的[import-untyped]错误:实际为模块添加类型注解的可行方案及示例
我完全懂你的困扰——搜了一圈全是教你怎么忽略这些错误的,但你想要的是真正解决问题,给模块补上正经的类型注解,看到一个能直接跑通的例子。别慌,咱们一步步来拆解,最后给你一个完整的可运行方案。
首先得搞明白为啥会报这个错:mypy是个严格的类型检查器,它要求被导入的模块要么自带类型存根(.pyi文件),要么在模块根目录有个py.typed标记文件,不然它就会认为这是“无类型模块”,直接跳过检查并抛出import-untyped错误。
现在给你两种可行的解决思路,一种是从模块本身入手补全类型,另一种是在自己的代码里适配,不用动第三方模块的文件:
方案一:给第三方模块添加类型标记/存根(长期规范方案)
如果这个模块你经常用,建议用这种方法一劳永逸:
找到模块的安装路径
打开终端运行这两个命令,找到Location字段就是模块的安装目录:pip show mypyc pip show setuptools比如输出里的
Location: /Users/xxx/Library/Python/3.9/lib/python/site-packages,那mypyc和setuptools就放在这个路径下。添加
py.typed标记文件
进入对应模块的根目录(比如mypyc的目录就是上面路径下的mypyc文件夹),创建一个空的py.typed文件:cd /Users/xxx/Library/Python/3.9/lib/python/site-packages/mypyc touch py.typed对
setuptools也做同样的操作,这样mypy就会把这两个模块当成“有类型支持”的模块了。(可选)手动编写类型存根文件
如果模块本身没有.pyi存根文件,你还可以自己写一个。比如针对mypyc.build,在mypyc/build.pyi里写:from typing import Sequence, List, Any def mypycify(sources: Sequence[str], **kwargs: Any) -> List[Any]: """类型存根:定义mypycify的参数和返回值类型""" ...这样mypy就能精准检查调用这个函数的代码了。
方案二:在自己的代码中适配(快速解决,不用修改第三方模块)
如果你不想动第三方模块的文件,那可以在自己的代码里给导入的函数补全类型注解,同时配置mypy信任这些注解:
第一步:修正你的代码并添加类型注解
注意哦,你原来的setup代码里有个小错误:package应该是packages(复数),不然setuptools会报错,我已经在下面的示例里修正了:
from typing import TYPE_CHECKING, List, Any # TYPE_CHECKING是个仅在类型检查时为True的常量,这里的导入不会影响运行时 if TYPE_CHECKING: from mypyc.build import mypycify as _mypycify from setuptools import setup as _setup # 给我们要调用的函数添加类型注解,相当于给mypy提供类型信息 def mypycify(sources: List[str], **kwargs: Any) -> List[Any]: from mypyc.build import mypycify return mypycify(sources, **kwargs) def setup(**kwargs: Any) -> None: from setuptools import setup setup(**kwargs) import math from timeit import timeit setup( name="mypycode", packages=["mypycode"], ext_modules=mypycify(["mypycode.py"]) ) print("doing something that I want to optimize with mypy")
第二步:创建mypy配置文件
在项目根目录创建一个mypy.ini文件,内容如下:
[mypy] # 先从宽松模式开始,熟悉后可以改成strict = True strict = False ignore_missing_imports = False # 针对mypyc和setuptools做配置,允许它们的无类型定义,但我们自己的代码已经有注解了 [mypy-mypyc.build] allow_untyped_defs = True [mypy-setuptools] allow_untyped_defs = True
第三步:运行mypy检查
现在再运行你的命令:
mypy mypycode.py
你会发现import-untyped的错误消失了,mypy会正常检查你代码里的类型问题!
最后补充一点
你提到是跟着视频做的setup,那个视频里的代码可能没考虑mypy的类型检查,所以才会出现这个问题。上面的两种方案都能解决你的需求,选哪种取决于你是否愿意修改第三方模块的文件。
备注:内容来源于stack exchange,提问作者Mr. W

