attrs
attrs copied to clipboard
Mypy false positive for union validator
Not sure if this is a duplicate but I couldn't find the problem in the open issues. If I overlooked it, please close, of course.
from attrs import define, field
from attrs.validators import instance_of
LeTypeAlias = int | str
@define
class LeClass:
x: LeTypeAlias = field(validator=instance_of(LeTypeAlias))
Works perfectly but mypy complains about:
error: No overload variant of "instance_of" matches argument type "UnionType[int, str]" [call-overload]
That doesn’t sound familiar and should be easy to fix. 🤞
I think, to be completely correct from a static typing perspective, LeTypeAlias should actually be:
type LeTypeAlias = int | str
In that case, Mypy and Pyright think it's a typing.TypeAliasType. Note that type aliases cannot be used with isinstance - it will blow up at runtime. So we should let this be a type error or change _InstanceOfValidator to explicitly work with them.
I don't remember off the top of my head why you're not supposed to just use LeTypeAlias = int | str, and PEP 695 doesn't say much. I think type works better with generics and forward references?
But if you were to just use the union inline:
from attrs import define, field
from attrs.validators import instance_of
@define
class LeClass:
x: int | str = field(validator=instance_of(int | str))
Then the argument to instance_of would be types.UnionType.