`attr.Attributes` incompatible with `Literal`
Why-not-now opened this issue · 3 comments
Why-not-now commented
Because attr.Attributes
causes the type it contains to be invariant, Literal
types like Literal[1]
to be incompatible with attr.Attributes[int]
from __future__ import annotations
from attr import Attribute
from attrs import define, field
def _check(self, attribute: Attribute[int], value: int):
print(type(attribute))
if value > 42:
msg = "x must be smaller or equal to 42"
raise ValueError(msg)
def trick_type_hinter() -> int:
return 1
a = trick_type_hinter()
@define
class LiteralDefault:
x: int = field(default=1, validator=_check)
@define
class LiteralFactory:
x: int = field(factory=lambda: 1, validator=_check)
@define
class CustomDefault:
x: int = field(default=a, validator=_check)
@define
class CustomFactory:
x: int = field(factory=lambda: a, validator=_check)
LiteralDefault
error:
Type "(self: Unknown, attribute: Attribute[int], value: int) -> None" cannot be assigned to type "_ValidatorArgType[_T@field] | None"
Type "(self: Unknown, attribute: Attribute[int], value: int) -> None" cannot be assigned to type "(Any, Attribute[_T@field], _T@field) -> Any"
Parameter 2: type "Attribute[_T@field]" cannot be assigned to type "Attribute[int]"
"Attribute[Literal[1]]" is incompatible with "Attribute[int]"
Type parameter "_T@Attribute" is invariant, but "Literal[1]" is not the same as "int"
"function" is incompatible with "Sequence[(Any, Attribute[_T@field], _T@field) -> Any]"
Type cannot be assigned to type "None"
LiteralFactory
error:
Type "(self: Unknown, attribute: Attribute[int], value: int) -> None" cannot be assigned to type "_ValidatorArgType[_T@field] | None"
Type "(self: Unknown, attribute: Attribute[int], value: int) -> None" cannot be assigned to type "(Any, Attribute[_T@field], _T@field) -> Any"
Parameter 2: type "Attribute[_T@field]" cannot be assigned to type "Attribute[int]"
"Attribute[Literal[1]]" is incompatible with "Attribute[int]"
Type parameter "_T@Attribute" is invariant, but "Literal[1]" is not the same as "int"
"function" is incompatible with "Sequence[(Any, Attribute[_T@field], _T@field) -> Any]"
Type cannot be assigned to type "None"
Why-not-now commented
While casting 1 to int using Typing.cast(int, 1)
fixes it, I think this is not the behaviour I expected.
Tinche commented
Hm yeah, something here should be covariant I guess?
Why-not-now commented
I think default and default factory should be covariant. (I may be wrong, covariance/contravariance breaks my head)