Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions mypy/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,11 @@ def infer_constraints_from_protocol_members(
"""
res = []
for member in protocol.type.protocol_members:
if member == "__class__":
# Every object exposes __class__, but it is not a useful
# structural constraint and can infer an unrelated protocol
# type variable from the concrete class object.
continue
inst = mypy.subtypes.find_member(member, instance, subtype, class_obj=class_obj)
temp = mypy.subtypes.find_member(member, template, subtype)
if inst is None or temp is None:
Expand Down
28 changes: 28 additions & 0 deletions mypy/test/testsubtypes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from mypy import api
from mypy.nodes import CONTRAVARIANT, COVARIANT, INVARIANT
from mypy.subtypes import is_subtype
from mypy.test.helpers import Suite
Expand All @@ -8,6 +9,33 @@


class SubtypingSuite(Suite):
def test_protocol_overload_with_class_override(self) -> None:
source = """
from collections.abc import Iterator, Sequence
from typing import Any, Protocol, overload
from typing_extensions import TypeVar, reveal_type

T = TypeVar("T", covariant=True)

class ReducedCovariantList(Protocol[T]):
@property # type: ignore[misc]
def __class__(self) -> type[list[Any]]: ... # type: ignore[override]
def __iter__(self) -> Iterator[T]: ...

@overload
def choose(value: ReducedCovariantList[str]) -> str: ...
@overload
def choose(value: Sequence[int]) -> int: ...
def choose(value: Any) -> Any: ...

reveal_type(choose([1]))
"""
stdout, stderr, returncode = api.run(
["--python-version", "3.14", "--no-incremental", "--show-error-codes", "-c", source]
)
assert returncode == 0, stderr
assert 'Revealed type is "int"' in stdout

def setUp(self) -> None:
self.fx = TypeFixture(INVARIANT)
self.fx_contra = TypeFixture(CONTRAVARIANT)
Expand Down
Loading