-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for PEP 698 - override decorator #14609
Conversation
class C: | ||
@override | ||
def __init__(self, a: int) -> None: pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure whether to allow it on __init__
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't seem very useful, but I also don't see a reason to explicitly disallow it. @stroxler any thoughts?
Thanks! I'll take a look soon. FYI to @stroxler. |
This comment has been minimized.
This comment has been minimized.
class C: | ||
@override | ||
def __init__(self, a: int) -> None: pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't seem very useful, but I also don't see a reason to explicitly disallow it. @stroxler any thoughts?
I believe the Pyre implementation would allow it, and certainly the rules for the PEP do. Agreed that it probably isn't very useful - if |
Another thing that could be done here is making the compatibility check stricter when class A:
def f(self, x: int) -> str: ...
class B(A):
def f(self, xx: int) -> str: ... even though |
c616e54
to
6c2355a
Compare
This comment has been minimized.
This comment has been minimized.
@stroxler what about from abc import abstractmethod
from typing import overload
from typing_extensions import override
class A:
@abstractmethod
def f(self, x: int) -> str: ...
class B(A):
@overload
def f2(self, x: int) -> str: ...
@overload
def f2(self, x: str) -> str: ...
@override
def f2(self, x: int | str) -> str: # error: Method "f2" is marked as override, but no base method of same name is present (reportGeneralTypeIssues)
return str(x)
class C(A):
@overload
def f(self, y: int) -> str: ...
@overload
def f(self, y: str) -> str: ...
@override
def f(self, y: int | str) -> str: # error: Method "f" overrides class "A" in an incompatible manner
# No overload signature in override is compatible with base method (reportIncompatibleMethodOverride)
return str(y) but I don't see an error in the Pyre playground. |
This comment has been minimized.
This comment has been minimized.
@override | ||
def f2(self, x: int) -> str: pass # E: Method "f2" is marked as an override, but no base method was found with this name | ||
[typing fixtures/typing-full.pyi] | ||
[builtins fixtures/tuple.pyi] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't see a test case that uses overloaded methods (using the @overload
decorator). Can you test overriding when it involves overloaded methods as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the test and also added support for overloads decorated with @override
. The rule is now that if any overload item has the decorator, the whole overload is treated as an explicit override.
Also, mark the import from typing as Python 3.12 only. And change the message a bit.
This reverts commit 94840af.
class C(A): | ||
@overload | ||
def f(self, y: int) -> str: pass | ||
@override | ||
@overload | ||
def f(self, y: str) -> str: pass | ||
@override | ||
def f(self, y: int | str) -> str: pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation allows that multiple overload items are decorated with @override
. I can also disallow this if desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could also restrict it to only the first and the last, or something like that.
Diff from mypy_primer, showing the effect of this PR on open source code: graphql-core (https://github.com/graphql-python/graphql-core) got 1.05x slower (283.0s -> 298.1s)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, thank you for implementing this!
closes #14072
This implements support for PEP 698, which has recently been accepted for Python 3.12. However, this doesn't yet add the "strict mode" that is recommended in the PEP.