-
Parameter here is inferred to be invariant and I can't for the life of me figure out why. type ParameterSerializer = HeaderSerializer | PathSerializer | QuerySerializer | CookieSerializer
@dataclass(slots=True, frozen=True)
class Parameter[T: ParameterSerializer]:
name: ParamName # Just a newtype of str
required: bool
description: str
type: Type # this isn't typing.Type. It's a custom class
serializer: T
path: Sequence[Parameter[PathSerializer]] = []
x: Sequence[Parameter[ParameterSerializer]] = path # T@Parameter is invariant. And yet, when I try to recreate the same scenario, I can't get it to work. type Bound = int | str
@dataclass(slots=True, frozen=True)
class Foo[T: Bound]:
x: T
foo_ints: Sequence[Foo[int]] = []
x: Sequence[Foo[Bound]] = foo_ints # No problems Any idea on how these are different? |
Beta Was this translation helpful? Give feedback.
Answered by
erictraut
Aug 10, 2024
Replies: 1 comment 3 replies
-
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I was wondering that myself, so I dug into it. The difference is that
attr
default toorder=True
whereas the stdlibdataclass
does not. Whenorder=True
, methods are synthesized for__lt__
,__gt__
, etc. The signature that pyright generates for these comparison operations uses a parameter annotation ofother: Foo[T]
. This causes the variance ofT
to be invariant.I think it's better for these synthesized methods to use
Self
rather thanFoo[T]
in this case. This preserves the covariance ofT
. I've made this change, and it will be included in the next release of pyright.