Skip to content

Commit e0b4932

Browse files
authored
Introduce Y040: Ban explicit inheritance from object (#217)
1 parent 3debb73 commit e0b4932

4 files changed

Lines changed: 10 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Features:
88
acceptable as an annotation for an `__(a)exit__` method argument.
99
* Teach the Y029 check to emit errors for `__repr__` and `__str__` methods that return
1010
`builtins.str` (as opposed to the unqualified `str`).
11+
* Introduce Y040: Never explicitly inherit from `object` in Python 3 stubs.
1112

1213
## 22.4.1
1314

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ currently emitted:
7171
| Y037 | Use PEP 604 syntax instead of `typing.Union` and `typing.Optional`. E.g. use `str \| int` instead of `Union[str, int]`, and use `str \| None` instead of `Optional[str]`.
7272
| Y038 | Use `from collections.abc import Set as AbstractSet` instead of `from typing import AbstractSet`. Like Y027, this error code should be switched off in your config file if your stubs support Python 2.
7373
| Y039 | Use `str` instead of `typing.Text`. This error code is incompatible with stubs supporting Python 2.
74+
| Y040 | Never explicitly inherit from `object`, as all classes implicitly inherit from `object` in Python 3. This error code is incompatible with stubs supporting Python 2.
7475

7576
Many error codes enforce modern conventions, and some cannot yet be used in
7677
all cases:
7778

78-
* Y027, Y038 and Y039 are incompatible with Python 2. These should only be used in stubs
79+
* Y027, Y038, Y039 and Y040 are incompatible with Python 2. These should only be used in stubs
7980
that are meant only for Python 3.
8081
* Y037 (enforcing PEP 604 syntax everywhere) is not yet fully compatible with
8182
the mypy type checker, which has

pyi.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,9 @@ def visit_ClassDef(self, node: ast.ClassDef) -> None:
11301130
self.generic_visit(node)
11311131
self.current_class_node = old_class_node
11321132

1133+
if any(_is_builtins_object(base_node) for base_node in node.bases):
1134+
self.error(node, Y040)
1135+
11331136
# empty class body should contain "..." not "pass"
11341137
if len(node.body) == 1:
11351138
statement = node.body[0]
@@ -1598,3 +1601,4 @@ def parse_options(
15981601
Y037 = "Y037 Use PEP 604 union types instead of {old_syntax} (e.g. {example})."
15991602
Y038 = 'Y038 Use "from collections.abc import Set as AbstractSet" instead of "from typing import AbstractSet" (PEP 585 syntax)'
16001603
Y039 = 'Y039 Use "str" instead of "typing.Text"'
1604+
Y040 = 'Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3'

tests/classdefs.pyi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ from typing import Any, overload
99
from _typeshed import Self
1010
from typing_extensions import final
1111

12-
class Bad:
12+
class Bad(object): # Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3
1313
def __new__(cls, *args: Any, **kwargs: Any) -> Bad: ... # Y034 "__new__" methods usually return "self" at runtime. Consider using "_typeshed.Self" in "Bad.__new__", e.g. "def __new__(cls: type[Self], *args: Any, **kwargs: Any) -> Self: ..."
1414
def __repr__(self) -> str: ... # Y029 Defining __repr__ or __str__ in a stub is almost always redundant
1515
def __str__(self) -> builtins.str: ... # Y029 Defining __repr__ or __str__ in a stub is almost always redundant
@@ -19,6 +19,8 @@ class Bad:
1919
async def __aenter__(self) -> Bad: ... # Y034 "__aenter__" methods in classes like "Bad" usually return "self" at runtime. Consider using "_typeshed.Self" in "Bad.__aenter__", e.g. "async def __aenter__(self: Self) -> Self: ..."
2020
def __iadd__(self, other: Bad) -> Bad: ... # Y034 "__iadd__" methods in classes like "Bad" usually return "self" at runtime. Consider using "_typeshed.Self" in "Bad.__iadd__", e.g. "def __iadd__(self: Self, other: Bad) -> Self: ..."
2121

22+
class AlsoBad(int, builtins.object): ... # Y040 Do not inherit from "object" explicitly, as it is redundant in Python 3
23+
2224
class Good:
2325
def __new__(cls: type[Self], *args: Any, **kwargs: Any) -> Self: ...
2426
@abstractmethod

0 commit comments

Comments
 (0)