-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Bug Report
This bug appears to be a regression in mypy 1.17.0, version 1.16.1 works as expected.
To Reproduce
Consider the following code snippet:
from typing import Protocol, Self
class Proto(Protocol):
def foo(self, x: Self) -> None: ...
class Impl:
def foo(self, x: Self) -> None:
pass
x: Proto = Impl()This is fine on both mypy 1.17.0 and 1.16.1. When we decorate foo in Proto (e.g., with @abstractmethod, @deprecated, or @classmethod), then the assignability check fails in mypy 1.17.0 only. Here are some snippets revealing the bug (the links use the master branch version because 1.17.0 is not available on mypy-play.net yet):
- Using
@abstractmethod: https://mypy-play.net/?mypy=master&python=3.13&gist=6ca38235427121b221eb1f2971c4205b - Using
@deprecated: https://mypy-play.net/?mypy=master&python=3.13&gist=59bcf4be17a8924e7b1ba8df158daad6 - Using
@classmethod: https://mypy-play.net/?mypy=master&python=3.13&gist=18ab582214b1c2a87b9e99606f7fd15e - Using
@classmethod, but withSequence[Self]: https://mypy-play.net/?mypy=master&python=3.13&gist=9c335818a610c248a6546c090b0ac617
I played around with some other variants:
- The bug only shows if
Selfis used as the type of an argument. UsingSelfas a return type only is fine in 1.17.0. - When
Impldeclares compatibility withProtoexplicitly (i.e.,class Impl(Proto)), the bug does not show. - Whether
fooinImplis decorated or not does not appear to matter (only tested with@deprecated). - Whether
fooinImplhasx: Selforx: Impldoes not matter
Expected Behavior
There should not be an error for all playground links above, as with mypy 1.16.1 or pyright.
Actual Behavior
mypy 1.17.0 shows errors like these (here for the example with @abstractmethod):
main.py:18: error: Incompatible types in assignment (expression has type "Impl", variable has type "Proto") [assignment]
main.py:18: note: Following member(s) of "Impl" have conflicts:
main.py:18: note: Expected:
main.py:18: note: def [Self: Proto] foo(self, x: Proto) -> None
main.py:18: note: Got:
main.py:18: note: def foo(self, x: Impl) -> None
Found 1 error in 1 file (checked 1 source file)
mypy 1.16.1 and pyright do not print any diagnostics.
Your Environment
- Mypy version used: 1.17.0 (bug) / 1.16.1 (expected behavior)
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.13.5