Skip to content

Commit d528707

Browse files
authored
Fix decorated methods with self-types in protocols (#19484)
Fixes #19482 The regression is caused by overlap of three problems (directly or indirectly): * Using `mx.original_type` instead of `mx.self_type` for expanding (not otherwise bound) self-types. * Having a weird special case for `...` vs self-types in constraint inference. * Not refreshing type variable ids during protocol subtype checks (hack needed for technical reasons). I fix the first one, and limit the blast radius of the second one.
1 parent f42c936 commit d528707

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

mypy/checkmember.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ def expand_and_bind_callable(
956956
) -> Type:
957957
if not mx.preserve_type_var_ids:
958958
functype = freshen_all_functions_type_vars(functype)
959-
typ = get_proper_type(expand_self_type(var, functype, mx.original_type))
959+
typ = get_proper_type(expand_self_type(var, functype, mx.self_type))
960960
assert isinstance(typ, FunctionLike)
961961
if is_trivial_self:
962962
typ = bind_self_fast(typ, mx.self_type)

mypy/constraints.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,10 @@ def visit_callable_type(self, template: CallableType) -> list[Constraint]:
11101110
# like U -> U, should be Callable[..., Any], but if U is a self-type, we can
11111111
# allow it to leak, to be later bound to self. A bunch of existing code
11121112
# depends on this old behaviour.
1113-
and not any(tv.id.is_self() for tv in cactual.variables)
1113+
and not (
1114+
any(tv.id.is_self() for tv in cactual.variables)
1115+
and template.is_ellipsis_args
1116+
)
11141117
):
11151118
# If the actual callable is generic, infer constraints in the opposite
11161119
# direction, and indicate to the solver there are extra type variables

test-data/unit/check-protocols.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4646,3 +4646,17 @@ reveal_type(t.bar) # N: Revealed type is "def () -> builtins.int"
46464646
tt: Type[P] = C
46474647
reveal_type(tt.foo) # N: Revealed type is "def (builtins.object) -> builtins.int"
46484648
reveal_type(tt.bar) # N: Revealed type is "def (builtins.object) -> builtins.int"
4649+
4650+
[case testProtocolDecoratedSelfBound]
4651+
from abc import abstractmethod
4652+
from typing import Protocol, Self
4653+
4654+
class Proto(Protocol):
4655+
@abstractmethod
4656+
def foo(self, x: Self) -> None: ...
4657+
4658+
class Impl:
4659+
def foo(self, x: Self) -> None:
4660+
pass
4661+
4662+
x: Proto = Impl()

0 commit comments

Comments
 (0)