如何规避stubtest的「类型别名在运行时不存在」错误?
关于stubtest检测类型别名缺失的问题
示例
给定实现文件 ./mylib/minimalistic_repro.py:
class Foo: def __init__(self, param): self.param = param class Bar: def __init__(self, param): self.param = param def foobar(par1, par2): return par1.param + par2.param
对应的存根文件 ./mylib/minimalistic_repro.pyi:
from typing import TypeAlias FooBar: TypeAlias = Foo | Bar class Foo: param: int def __init__(self, param: int) -> None: ... class Bar: param: int def __init__(self, param: int) -> None: ... def foobar(par1: FooBar, par2: FooBar) -> int: ...
注意存根文件第三行的类型别名定义:FooBar: TypeAlias = Foo | Bar
当前执行情况:
mypy --strict mylib、flake8 mylib和ruff check --select E,F,B,SIM均检测通过- 运行
python -m mypy.stubtest mylib时,报错:error: mylib.minimalistic_repro.FooBar is not present at runtime
临时解决方案:使用stubtest的允许列表(通过stubtest --generate-allowlist生成)
问题
- 是否有更优方法规避该错误?
- 我的实现方式是否存在根本性错误?
- 若不存在,是否值得提交功能请求?
已尝试的其他方案
- 直接在函数签名中写
def foobar(par1: Foo | Bar, par2: Foo | Bar),但实际任务是为第三方PyPI包编写类型提示,需要合并多达18种类型,这种写法过于繁琐不可行。 - 将
FooBar类型别名定义放在.py文件(如tp_aliases.py)中再导入,虽然能让示例通过stubtest,但实际场景中tp_aliases.py不属于目标包,无法采用。
解答
1. 更优的规避方法
可以利用TYPE_CHECKING常量将类型别名标记为仅用于类型检查,避免stubtest检测其运行时存在性:
修改后的存根文件:
from typing import TypeAlias from typing import TYPE_CHECKING if TYPE_CHECKING: FooBar: TypeAlias = Foo | Bar class Foo: param: int def __init__(self, param: int) -> None: ... class Bar: param: int def __init__(self, param: int) -> None: ... def foobar(par1: "FooBar", par2: "FooBar") -> int: ...
关键细节:
TYPE_CHECKING在运行时始终为False,因此包裹的类型别名不会被视为需要在运行时存在的符号- 函数签名中的
FooBar需要用字符串引号包裹(或导入from __future__ import annotations),因为全局作用域中并未定义该别名,仅在类型检查阶段可见
2. 实现方式是否有根本性错误?
没有根本性错误。类型别名本身就是类型检查工具专属的语法,不需要在运行时存在——存根文件的核心作用是提供类型信息,而非运行时代码。stubtest的报错源于其默认行为:未区分“运行时可见符号”和“仅类型检查用符号”,误将类型别名纳入了运行时存在性的检测范围。
3. 是否值得提交功能请求?
值得提交。stubtest应该默认识别并忽略用TypeAlias定义的别名,或提供配置选项跳过这类仅用于类型检查的符号。当前的允许列表方案只是临时 workaround,对于需要大量类型别名的场景(如你提到的18种类型合并),维护允许列表会非常繁琐。
你可以在mypy的GitHub仓库提交issue,说明场景:为第三方包编写存根时,需要用类型别名简化签名,但stubtest误报运行时缺失,希望工具能自动识别TypeAlias并跳过检测,或添加专属参数排除这类符号。
内容的提问来源于stack exchange,提问作者Patrick C
相关产品推荐
相关产品推荐

