Imagine I have an object which is an instance of a class such as the following:
@dataclass
class Foo:
bar: int
baz: str
I'm using dataclasses
for convenience, but in the context of this question, there is no requirement that the class be a dataclass
.
Normally, if I want to unpack the attributes of such an object, I must implement __iter__
, e.g. as follows:
class Foo:
...
def __iter__(self) -> Iterator[Any]:
return iter(dataclasses.astuple(self))
bar, baz = Foo(1, "qux")
However, from the perspective of a static type checker like pyright, I've now lost any type information for bar
and baz
, which it can only infer are of type Any
. I could improve slightly by creating the iter
tuple parameter manually:
def __iter__(self) -> Iterator[Union[str, int]]:
return iter((self.bar, self.baz))
But I still don't have specific types for bar
and baz
. I can annotate bar
and baz
and then use dataclasses.astuple
directly as follows:
bar: str
baz: int
bar, baz = dataclasses.astuple(Foo(1, "qux"))
but that necessitates less readable multi-level list comprehensions such as
bars: list[int] = [
bar for bar, _ in [dataclasses.astuple(foo) for foo in [(Foo(1, "qux"))]]
]
and also ties me to dataclasses
.
Obviously, none of this is insurmountable. If I want to use a type checker, I can just not use the unpack syntax, but I would really like to if there's a clean way to do it.
An answer that is specific to dataclasses
, or better yet, attrs
, is acceptable if a general method is not currently possible.