如果放在一个文件中,问题就尽可能简单:
class A():
a = 1
class B():
b = 2
def test(x: A):
return x
def testit():
b = B()
test(b)
Mypy 在这里发现问题
mypy test_folder --check-untyped-defs
但是如果将这些函数/类放在各种文件中,mypy 不会检测到问题。它甚至没有警告说它无法拼凑 IMO 是最大问题的信息。
我花了一些时间来创建一个最小的可复制版本:
文件树如下所示:
src
mb2
base.py
steps
init
step.py
impl.py
jmeter
step.py
test
test.py
涉及的5个文件内容为:
base.py
class BaseCfg:
pass
测试.py
from mb2.steps.jmeter.step import JCfg
from mb2.steps.init.impl import get_resource_costs
class TestCollectMetrics:
def test_get_resource_costs(self):
cfg = JCfg()
get_resource_costs(cfg) # <- Wrong type should be detected
初始化/实现.py
from .step import Cfg
def get_resource_costs(config: Cfg):
pass
初始化/step.py
from mb2.base import BaseCfg
class Cfg(BaseCfg):
pass
jmeter/step.py
from mb2.base import BaseCfg
class JCfg(BaseCfg):
pass
测试将
JCfg
类型的对象传递给方法get_resource_costs
。虽然该方法指定它需要类型Cfg
。这不会被 mypy 检测到。
它只与
--namespace-packages
一起运行,否则重复的 step.py
文件会成为问题。所以重现的命令是:
mypy src --check-untyped-defs --namespace-packages
这返回
Success: no issues found in 5 source files
将
reveal_type(cfg)
和 reveal_type(get_resource_costs)
放入 test.py 返回 Revealed type is "Any"
.
检测到将本地错误放入 5 个文件中的任何一个,因此 mypy 正在检查所有文件。
我假设它连接到命名空间包无法解析路径并且默默地失败。有什么办法解决这个问题吗?
找不到错误的原因是由于
ignore_missing_imports = True
在我的setup.cfg
.
底层问题与模块发现有关:
这使得很难正确发现所有模块,但只能发现它们一次.
最后我需要使用
MYPYPATH=src mypy src --strict --namespace-packages --explicit-package-bases
.
除了使用
MYPYPATH=src
外,设置mypy src
也很重要。我不清楚为什么。