MyPy 使用可选的对象类型列表失败数据类参数

MyPy fails dataclass argument with optional list of objects type

我无法让 MyPy 传递我的脚本,该脚本包含一个 dataclass Bar 和一个包含 Foo 对象列表的可选参数 foos 和默认为空列表。

仍然是陌生人,添加一个遍历 self.foos 的方法 Bar.sum_foos() 会引发第二个 MyPy 错误。是我误解了如何设置正确的类型,还是其他原因?

script.py

from __future__ import annotations
from typing import Optional
from dataclasses import dataclass, field


class Foo():
    pass


@dataclass
class Bar():
    foos: Optional[list[Foo]] = field(default_factory = list)

    def sum_foos(self) -> float:
        for foo in self.foos:
            pass
        return 0.0

2 个 MyPy 错误

$ mypy script.py
script.py:12: error: Incompatible types in assignment (expression has type "List[_T]", variable has type "Optional[List[Foo]]")
script.py:15: error: Item "None" of "Optional[List[Foo]]" has no attribute "__iter__" (not iterable)
Found 2 errors in 1 file (checked 1 source file)

版本

$ python --version
Python 3.8.12
$ mypy --version
mypy 0.950 (compiled: yes)

好吧,你问题中的代码几乎没问题as-is。 Optional[X] 等同于 X | None - 为什么你的列表是可选的?该字段永远不会是 None,工厂意味着 foos 属性将是一个空列表,如果不传递给构造函数的话。因此声明为 list[Foo] 更正确并消除了所有错误。

from __future__ import annotations
from typing import Optional
from dataclasses import dataclass, field


class Foo():
    pass


@dataclass
class Bar():
    foos: list[Foo] = field(default_factory=list)

    def sum_foos(self) -> float:
        for foo in self.foos:
            pass
        return 0.0