Consider a dataclass with a mutable default value for an argument. To be able to instantiate an object with a new default value and not a shared mutable object, we can do something like:
@dataclass
class ClassWithState:
name: str
items: Optional[List[str]] = None
def __post_init__(self) -> None:
if self.items is None:
self.items = []
This works as expected. However, whenever I refer to items
in some instance of this class, mypy warns that items
may be None. For example:
c = ClassWithState("object name")
c.items.append("item1")
MyPy will complain with something like:
Item "None" of "Optional[List[str]]" has no attribute "append".
I don't want to have to add unnecissary checks every time I refer to items
such as
assert c.items is not None
everywhere I refer to items
. How can I convince mypy that items
will never be None?
I'd use field
with the default_factory
option set:
from dataclasses import dataclass, field
from typing import List
@dataclass
class ClassWithState:
name: str
items: List[str] = field(default_factory=list)
>>> ClassWithState("Hello")
ClassWithState(name='Hello', items=[])