Why is the variance of Generic Protocols not decided by the inputs? #1298
Replies: 2 comments 1 reply
-
I rather think we should be moving in the opposite direction, where variance is automatically determined by the use of a type variable in context, rather than explicitly specified as part of the typevar itself. Whether a typevar can soundly be variant or contravariant is in general determined by where it appears in method signatures of the type: if it appears as an argument type, it cannot safely be variant; if it appears as a return type, it cannot safely be contravariant; if it appears as both, it must be invariant. |
Beta Was this translation helpful? Give feedback.
-
I am starting to understand now. One example that has always bothered me is the following: from typing import TypeVar, Mapping, Hashable
value_co = TypeVar("value_co", covariant=True)
def unpack(x: Mapping[Hashable, value_co]) -> list[value_co]:
return list(x.values())
d: dict[str, int] = {"a": 1}
values: list[int] = unpack(d) # ✘ expected Mapping[Hashable, int] My thoughts now, after carljm's comment and re-reading the wikipedia article on covariance, it seems the following is true:
value_co = TypeVar("value_co", covariant=True)
HashableT = TypeVar("HashableT")
def unpack(x: Mapping[HashableT, value_co]) -> list[value_co]:
return list(x.values())
d: dict[str, int] = {"a": 1}
values: list[int] = unpack(d) where now, we basically tell the typing system that Is that roughly it? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
There is/was a lot of debate about whether
Mapping
should be covariant in the Key/Value Type.My question is: why don't the input types themselves decide this?
I.e.
Mapping[key_co, value_co]
would be covariant in both,Mapping[key_contra, value_contra]
would be contra-variant in both, etc. Currently, this gives errors of the formerror: Variance of TypeVar "key_co" incompatible with variance in parent type
inmypy
.So, e.g.
mypy
won't let me make aclass CoContraMapping(Mapping[key_co, value_contra])
.Beta Was this translation helpful? Give feedback.
All reactions