An empty generic class is covariant even though the doc says "all user-defined generic classes invariant by default"
*Memo:
-
mypy --strict test.py - mypy 1.19.0
- Python 3.14.0
- Windows 11
Invariance vs covariance says mypy considers all user-defined generic classes invariant by default as shown below:
Most mutable generic collections are invariant, and mypy considers all user-defined generic classes invariant by default (see Variance of generic types for motivation). This could lead to some unexpected errors when combined with type inference. For example:
But an empty generic class is covariant against what the doc says as shown below:
class A: ...
class B(A): ...
class C(B): ...
class MyCls[T]: ...
mycls1: MyCls[A] = MyCls[B]() # No error
mycls2: MyCls[B] = MyCls[B]() # No error
mycls3: MyCls[C] = MyCls[B]() # Error
Yes the docs are wrong here. What's true is that under the old syntax T = TypeVar("T"), a TypeVar is invariant by default. But under the new PEP 695 syntax, classes are covariant by default if they don't use the TypeVar.
@JelleZijlstra Hi! I'd like to work on this issue , may take it ?
@khanak0509 there is no process for claiming issues on mypy, so anyone may work on it — including you :)
In this case, the change itself will be easy, but you will probably have to spend a significant amount of time figuring out if your new explanation is entirely correct, as the variance rules can be tricky to phrase in an exactly correct manner. A common problem is that people propose changes without really understanding these situations (I am no exception), inevitably wasting more time in the review process; so, I recommend trying to understand it completely before submitting a PR. Just a tip.