新注释打破了数据类检查

New annotations break inspection of dataclasses

使用 PEP 563,from __future__ import annotations 更改了类型注释,以便它们被延迟评估,这提供了很多好处,例如前向引用。

但是,这似乎与其他功能(如数据classes)配合得不好。例如,我有一些代码检查 class 的 __init__ 方法的类型参数。 (真正的用例是为 class 提供一个默认的序列化器,但这在这里并不重要。)

from dataclasses import dataclass
from typing import get_type_hints

class Foo:
    pass

@dataclass
class Bar:
    foo: Foo

print(get_type_hints(Bar.__init__))

在 Python 3.6 和 3.7 中,这符合预期;它打印 {'foo': <class '__main__.Foo'>, 'return': <class 'NoneType'>}.

但是,如果在 Python 3.7 中,我添加了 from __future__ import annotations,则会失败并出现错误:

NameError: name 'Foo' is not defined

我想我明白为什么会这样。 __init__ 方法在 dataclasses 中定义,它的环境中没有 Foo 对象,并且 Foo 注释被传递给 dataclass 并附加到__init__ 作为字符串 "Foo" 而不是作为原始对象 Foo,但是新注释的 get_type_hints 仅在 __init__ 所在的模块中进行名称查找定义不是定义注释的地方。

我觉得我一定是做错了什么。我很惊讶这两个新功能在一起玩得这么差。是否有正确的方法来检查 __init__ 方法的类型提示,以便它像在正常 classes 上一样处理数据classes?

reported to the Python mailing list, this was considered a "good catch" by the BDFL. According to the issue, this has been fixed. The pull request 合并和向后移植修复程序时。它从 Python 3.7.6 和 Python 3.8.1.

开始按预期工作