I want my dataclass to have a field that can either be provided manually, or if it isn't, it is inferred at initialization from the other fields. MWE:
from collections.abc import Sized
from dataclasses import dataclass
from typing import Optional
@dataclass
class Foo:
data: Sized
index: Optional[list[int]] = None
def __post_init__(self):
if self.index is None:
self.index = list(range(len(self.data)))
reveal_type(Foo.index) # Union[None, list[int]]
reveal_type(Foo([1,2,3]).index) # Union[None, list[int]]
How can this be implemented in a way such that:
mypy
type checkingindex
is guaranteed to be of type list[int]
I considered using default_factory(list)
, however, then how does one distinguish the User passing index=[]
from the sentinel value? Is there a proper solution besides doing
index: list[int] = None # type: ignore[assignment]
Use NotImplemented
from collections.abc import Sized
from dataclasses import dataclass
@dataclass
class Foo:
data: Sized
index: list[int] = NotImplemented
def __post_init__(self):
if self.index is NotImplemented:
self.index = list(range(len(self.data)))