Skip to content

Commit aafe0ae

Browse files
authored
Y068: Don't use @OverRide (#528)
1 parent 541330a commit aafe0ae

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Change Log
22

3+
New error codes:
4+
* Introduce Y068: Don't use `@override` in stub files.
5+
36
## 5.5.0
47

58
New error codes:

ERRORCODES.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ The following warnings are currently emitted by default:
8080
| <a id="Y064" href="#Y064">Y064</a> | Use simpler syntax to define final literal types. For example, use `x: Final = 42` instead of `x: Final[Literal[42]]`. | Style
8181
| <a id="Y065" href="#Y065">Y065</a> | Don't use bare `Incomplete` in argument and return annotations. Instead, leave them unannotated. Omitting an annotation entirely from a function will cause some type checkers to view the parameter or return type as "untyped"; this may result in stricter type-checking on code that makes use of the stubbed function. | Style
8282
| <a id="Y066" href="#Y066">Y066</a> | When using if/else with `sys.version_info`, put the code for new Python versions first. | Style
83-
| <a id="Y067" href="#Y067">Y067</a> | Don't use `Incomplete | None = None` in
84-
argument annotations. Instead, just use `=None`. | Style
83+
| <a id="Y067" href="#Y067">Y067</a> | Don't use `Incomplete \| None = None` in argument annotations. Instead, just use `=None`. | Style
84+
| <a id="Y068" href="#Y068">Y068</a> | Don't use `@override` in stub files. Problems with a function signature deviating from its superclass are inherited from the implementation, and other tools such as stubtest are better placed to recognize deviations between stubs and the implementation. | Understanding stubs
8585

8686
## Warnings disabled by default
8787

flake8_pyi/errors.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ class Error(NamedTuple):
127127
'put the code for new Python versions first, e.g. "{new_syntax}"'
128128
)
129129
Y067 = 'Y067 Use "=None" instead of "Incomplete | None = None"'
130+
Y068 = 'Y068 Do not use "@override" in stub files.'
131+
130132
Y090 = (
131133
'Y090 "{original}" means '
132134
'"a tuple of length 1, in which the sole element is of type {typ!r}". '

flake8_pyi/visitor.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ def _is_object(node: ast.AST | None, name: str, *, from_: Container[str]) -> boo
226226
)
227227
_is_Generic = partial(_is_object, name="Generic", from_=_TYPING_MODULES)
228228
_is_Unpack = partial(_is_object, name="Unpack", from_=_TYPING_MODULES)
229+
_is_override = partial(_is_object, name="override", from_=_TYPING_MODULES)
229230

230231

231232
def _is_union(node: ast.expr | None) -> TypeIs[ast.BinOp]:
@@ -2032,6 +2033,12 @@ def check_protocol_param_kinds(
20322033
pos_or_kw, errors.Y091.format(arg=pos_or_kw.arg, method=node.name)
20332034
)
20342035

2036+
def check_for_override(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:
2037+
for deco in node.decorator_list:
2038+
if _is_override(deco):
2039+
self.error(deco, errors.Y068)
2040+
return
2041+
20352042
@staticmethod
20362043
def _is_positional_pre_570_argname(name: str) -> bool:
20372044
# https://peps.python.org/pep-0484/#positional-only-arguments
@@ -2094,6 +2101,7 @@ def _visit_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:
20942101
self.check_self_typevars(node, decorator_names)
20952102
if self.enclosing_class_ctx.is_protocol_class:
20962103
self.check_protocol_param_kinds(node, decorator_names)
2104+
self.check_for_override(node)
20972105

20982106
def visit_arg(self, node: ast.arg) -> None:
20992107
if _is_NoReturn(node.annotation):

tests/override.pyi

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import typing
2+
import typing as t
3+
from typing import override, override as over
4+
5+
import typing_extensions
6+
7+
class Foo:
8+
def f(self) -> None: ...
9+
def g(self) -> None: ...
10+
def h(self) -> None: ...
11+
def j(self) -> None: ...
12+
def k(self) -> None: ...
13+
14+
class Bar(Foo):
15+
@override # Y068 Do not use "@override" in stub files.
16+
def f(self) -> None: ...
17+
@typing.override # Y068 Do not use "@override" in stub files.
18+
def g(self) -> None: ...
19+
@t.override # Ideally we'd catch this too, but the infrastructure is not in place.
20+
def h(self) -> None: ...
21+
@over # Ideally we'd catch this too, but the infrastructure is not in place.
22+
def j(self) -> None: ...
23+
@typing_extensions.override # Y068 Do not use "@override" in stub files.
24+
def k(self) -> None: ...

0 commit comments

Comments
 (0)