Mypy 拒绝使用 `type(name, (bases,), {})` 创建的类型对象

Mypy rejects type objects created with `type(name, (bases,), {})`

我在让 mypy 接受类型对象时遇到了一些问题。我是 确信我只是做错了,但我的 google 搜索到目前为止还没有给我任何答案。

class Good(object):
    a = 1

def works(thing: Good):
    print(thing.a)

o = Good()
works(o)

Bad = type('Bad', (object, ), dict(a=1))

def fails_mypy(thing: Bad):
    print(thing.a)

s = Bad()
fails_mypy(s)

像“Good”这样构造的东西没问题,而像“Bad”这样构造的东西在 mypy 检查中失败:

error: Invalid type "test.Bad"
error: Bad? has no attribute "a"

根据 mypys wiki 的 Unsupported Python Features 部分,目前不支持像这样在运行时创建 类。它无法理解函数定义中的 Bad 是什么。在执行 mypy 时使用 reveal_type(Good)reveal_type(Bad) 应该清楚这一点。

消除这些声音的一种方法是使用 Any。要么使用 Python 3.6 变量注释语法:

Bad: Any = type('Bad', (), {'a':1})

或者,Python < 3.6:

Bad = type('Bad', (), {'a':1}) # type: Any

(在这两种情况下,Any 应首先从 typing 导入)

当然,这基本上意味着您的函数现在可以接受任何东西。需要付出代价,但这就是动态语言所带来的;因为 Bar 是在运行时定义的,所以它 可以 理论上可以是任何东西:-)