Type Error with tagged Unions (working code but mypy/pyright error) #690
Copy link
Copy link
Closed
Labels
Description
functionally this code does what I expect it to (asserts go through) but there is a type error in the signature of Converter.structure, it accepts cl: type[T] and UnionType does not match that
from typing import Literal, Union
from dataclasses import dataclass
import cattrs
@dataclass
class Add:
t: Literal["ADD"]
v: int
@dataclass
class Sub:
t: Literal["SUB"]
v: int
Op = Union[Add, Sub]
Op2 = Add | Sub
assert cattrs.structure(dict(t="ADD", v=10), Op) == Add(t="ADD", v=10)
assert cattrs.structure(dict(t="SUB", v=5), Op2) == Sub(t="SUB", v=5)if I change this https://github.com/python-attrs/cattrs/blob/main/src/cattrs/converters.py#L587 to
def structure(self, obj: UnstructuredValue, cl: type[T] | UnionType) -> T:the type error goes away but I'm not sure if that is the right solution
Reactions are currently unavailable
Activity
Tinche commentedon Oct 15, 2025
There's not really a way to improve this on our own. We need PEP 747 to be accepted and implemented: https://peps.python.org/pep-0747/
The good news is that it's almost certainly going to be accepted, and the Mypy PR is in the final stages. I think pyright might already support it (when imported from a newer version of
typing_extensions).I don't want to add support until the PEP is formally accepted though. It's on our immediate radar though ;)
For now you'll have to use a
# type: ignoreunfortunately :/Gentle commentedon Oct 15, 2025
that was quick, thanks for the link, great to know you are aware and tracking this issue :)
Gentle commentedon Oct 15, 2025
I just noticed that pyrefly can handle this, the type for x here is inferred as
Add | Subby the LSP