Skip to content
Open
3 changes: 2 additions & 1 deletion mypy/subtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2208,7 +2208,8 @@ def infer_variance(info: TypeInfo, i: int) -> bool:
settable = False

# TODO: handle settable properties with setter type different from getter.
typ = find_member(member, self_type, self_type)
plain_self = Instance(info.mro[0], []) # self-type without type variables
typ = find_member(member, self_type, plain_self)
if typ:
# It's okay for a method in a generic class with a contravariant type
# variable to return a generic instance of the class, if it doesn't involve
Expand Down
15 changes: 15 additions & 0 deletions test-data/unit/check-python312.test
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,21 @@ class Contra2[T]:
d1: Contra2[int] = Contra2[float]()
d2: Contra2[float] = Contra2[int]() # E: Incompatible types in assignment (expression has type "Contra2[int]", variable has type "Contra2[float]")

[case testPEP695InferVariancePolymorphicMethod]
class Cov[T]:
def get(self) -> T: ...
def new[S](self: "Cov[S]", arg: list[S]) -> "Cov[S]": ...

cov_pos: Cov[object] = Cov[int]()
cov_neg: Cov[int] = Cov[object]() # E: Incompatible types in assignment (expression has type "Cov[object]", variable has type "Cov[int]")

class Contra[T]:
def set(self, arg: T) -> None: ...
def new[S](self: "Contra[S]", arg: list[S]) -> "Contra[S]": ...

contra_pos: Contra[object] = Contra[int]() # E: Incompatible types in assignment (expression has type "Contra[int]", variable has type "Contra[object]")
contra_neg: Contra[int] = Contra[object]()

[case testPEP695InheritInvariant]
class Invariant[T]:
x: T
Expand Down