未调用 mypy 插件回调

mypy plugin callback not being called

我正在尝试制作我的第一个 mypy 插件来为此代码添加类型检查

adt.py

from dataclasses import make_dataclass

def adt(datatype, *ctrs: str):
    basecls = type(datatype, (), {})
    klass = lambda x: x.split()[0]
    fields = lambda x: x.split()[1:]
    clss = (make_dataclass(klass(cls),
                           bases=(basecls,),
                           fields=fields(cls))
            for cls in ctrs)
    return (basecls, *clss)


Maybe, Just, None_ = adt("Maybe", "Just x", "None")

j = Just(1)


def foo(m: Maybe):
    pass

我创建了一个 adt_plugin.py 文件保存到磁盘并配置 mypy.ini 加载它,它正在加载(我可以看到一些打印),但我的插件回调似乎不是被调用,我缺少什么?

我的插件代码什么都不做,现在就失败了

adt_plugin.py

from typing import *
from mypy.plugin import Plugin, DynamicClassDefContext

T = TypeVar('T')
CB = Optional[Callable[[T], None]]


class AdtPlugin(Plugin):
    def get_dynamic_class_hook(self, fullname: str) -> 'CB[DynamicClassDefContext]':
        print(fullname)
        if fullname == "adt.adt":
            print("foo")
            print(decl_info_hook)
            return decl_info_hook
        return None


def plugin(version: str):
    # ignore version argument if the plugin works with all mypy versions.
    return AdtPlugin

def decl_info_hook(ctx : DynamicClassDefContext) -> None:
    ctx.api.fail("Not able to calculate MRO for declarative base", ctx.call)

mypy.ini(在当前文件夹)

[mypy]
plugins = /home/geckos/code/python/adt_plugin.py

当我运行mypy adt.py我看到:

 python mypy --no-incremental adt.py
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
builtins.object
adt.adt
foo
<function decl_info_hook at 0x7f55cabf9ab0>
adt.Just
builtins.type
adt.py:19: error: Variable "adt.Maybe" is not valid as a type
adt.py:19: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
Found 1 error in 1 file (checked 1 source file)

所以有foo,所以调用了AdtPlugin.get_dynamic_class_hook,它也返回了decl_info_hook,函数名是正确的,我们可以在打印中看到它,但是这个函数根本没有被调用,我在上面放了一个错误,我也试过 raise Exception("foooo") 在里面但是没有任何反应。

知道如何调试吗?

好的,我遇到了问题,mypy 不会将此 x, y, ..., z = something() 检测为动态 class 创建。该语句需要具有 a = f() 形式,其中分配了单个值,否则它不会调用插件挂钩。