Skip to content

Commit

Permalink
Reject promotions when checking against protocols. (#18360)
Browse files Browse the repository at this point in the history
Fixes #18359
Fixes #18257

The change is simple but may be way too general. Making it more precise
should be straightforward, but I want to see the Mypy Primer results and
hear other opinions first.
  • Loading branch information
tyralla authored Dec 29, 2024
1 parent b9056f9 commit ac6151a
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
2 changes: 1 addition & 1 deletion mypy/subtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ def visit_instance(self, left: Instance) -> bool:
return True
if type_state.is_cached_negative_subtype_check(self._subtype_kind, left, right):
return False
if not self.subtype_context.ignore_promotions:
if not self.subtype_context.ignore_promotions and not right.type.is_protocol:
for base in left.type.mro:
if base._promote and any(
self._is_subtype(p, self.right) for p in base._promote
Expand Down
16 changes: 16 additions & 0 deletions test-data/unit/check-type-promotion.test
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,19 @@ if isinstance(x, (float, complex)):
else:
reveal_type(x) # N: Revealed type is "builtins.int"
[builtins fixtures/primitives.pyi]

[case testRejectPromotionsForProtocols]
from typing import Protocol

class H(Protocol):
def hex(self, /) -> str: ...

f: H = 1.0
o: H = object() # E: Incompatible types in assignment (expression has type "object", variable has type "H")
c: H = 1j # E: Incompatible types in assignment (expression has type "complex", variable has type "H")
i: H = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "H")
b: H = False # E: Incompatible types in assignment (expression has type "bool", variable has type "H")

class N(float): ...
n: H = N()
[builtins fixtures/primitives.pyi]
1 change: 1 addition & 0 deletions test-data/unit/fixtures/primitives.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class int:
class float:
def __float__(self) -> float: pass
def __add__(self, x: float) -> float: pass
def hex(self) -> str: pass
class complex:
def __add__(self, x: complex) -> complex: pass
class bool(int): pass
Expand Down

0 comments on commit ac6151a

Please sign in to comment.