Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,13 @@ def check_method_override_for_base_with_name(
if original_node and is_property(original_node):
original_type = get_property_type(original_type)

if isinstance(original_node, Var):
expanded_type = map_type_from_supertype(original_type, defn.info, base)
expanded_type = expand_self_type(
original_node, expanded_type, fill_typevars(defn.info)
)
original_type = get_proper_type(expanded_type)

if is_property(defn):
inner: FunctionLike | None
if isinstance(typ, FunctionLike):
Expand Down
120 changes: 120 additions & 0 deletions test-data/unit/check-generic-subtyping.test
Original file line number Diff line number Diff line change
Expand Up @@ -1065,3 +1065,123 @@ class F(E[T_co], Generic[T_co]): ... # E: Variance of TypeVar "T_co" incompatib

class G(Generic[T]): ...
class H(G[T_contra], Generic[T_contra]): ... # E: Variance of TypeVar "T_contra" incompatible with variance in parent type

[case testParameterizedGenericOverrideWithProperty]
from typing import TypeVar, Generic

T = TypeVar("T")

class A(Generic[T]):
def __init__(self, val: T):
self.member: T = val

class B(A[str]):
member: str

class GoodPropertyOverride(A[str]):
@property
def member(self) -> str: ...
@member.setter
def member(self, val: str): ...

class BadPropertyOverride(A[str]):
@property # E: Signature of "member" incompatible with supertype "A" \
# N: Superclass: \
# N: str \
# N: Subclass: \
# N: int
def member(self) -> int: ...
@member.setter
def member(self, val: int): ...

class BadGenericPropertyOverride(A[str], Generic[T]):
@property # E: Signature of "member" incompatible with supertype "A" \
# N: Superclass: \
# N: str \
# N: Subclass: \
# N: T
def member(self) -> T: ...
@member.setter
def member(self, val: T): ...
[builtins fixtures/property.pyi]

[case testParameterizedGenericPropertyOverrideWithProperty]
from typing import TypeVar, Generic

T = TypeVar("T")

class A(Generic[T]):
@property
def member(self) -> T: ...
@member.setter
def member(self, val: T): ...

class B(A[str]):
member: str

class GoodPropertyOverride(A[str]):
@property
def member(self) -> str: ...
@member.setter
def member(self, val: str): ...

class BadPropertyOverride(A[str]):
@property # E: Signature of "member" incompatible with supertype "A" \
# N: Superclass: \
# N: str \
# N: Subclass: \
# N: int
def member(self) -> int: ...
@member.setter
def member(self, val: int): ...

class BadGenericPropertyOverride(A[str], Generic[T]):
@property # E: Signature of "member" incompatible with supertype "A" \
# N: Superclass: \
# N: str \
# N: Subclass: \
# N: T
def member(self) -> T: ...
@member.setter
def member(self, val: T): ...
[builtins fixtures/property.pyi]

[case testParameterizedGenericOverrideSelfWithProperty]
from typing_extensions import Self

class A:
def __init__(self, val: Self):
self.member: Self = val

class GoodPropertyOverride(A):
@property
def member(self) -> "GoodPropertyOverride": ...
@member.setter
def member(self, val: "GoodPropertyOverride"): ...

class GoodPropertyOverrideSelf(A):
@property
def member(self) -> Self: ...
@member.setter
def member(self, val: Self): ...
[builtins fixtures/property.pyi]

[case testParameterizedGenericOverrideWithSelfProperty]
from typing import TypeVar, Generic
from typing_extensions import Self

T = TypeVar("T")

class A(Generic[T]):
def __init__(self, val: T):
self.member: T = val

class B(A["B"]):
member: Self

class GoodPropertyOverride(A["GoodPropertyOverride"]):
@property
def member(self) -> Self: ...
@member.setter
def member(self, val: Self): ...
[builtins fixtures/property.pyi]
Loading