Skip to content

Commit 30a5263

Browse files
stubtest: do not require @disjoint_base if there are __slots__ (#19701)
1 parent 8da097d commit 30a5263

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

mypy/stubtest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,9 @@ def _verify_disjoint_base(
510510
if stub.is_final:
511511
return
512512
is_disjoint_runtime = _is_disjoint_base(runtime)
513-
if is_disjoint_runtime and not stub.is_disjoint_base:
513+
# Don't complain about missing @disjoint_base if there are __slots__, because
514+
# in that case we can infer that it's a disjoint base.
515+
if is_disjoint_runtime and not stub.is_disjoint_base and not runtime.__dict__.get("__slots__"):
514516
yield Error(
515517
object_path,
516518
"is a disjoint base at runtime, but isn't marked with @disjoint_base in the stub",

mypy/test/teststubtest.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,31 @@ class BytesEnum(bytes, enum.Enum):
14301430
""",
14311431
error=None,
14321432
)
1433+
yield Case(
1434+
stub="""
1435+
class HasSlotsAndNothingElse:
1436+
__slots__ = ("x",)
1437+
x: int
1438+
1439+
class HasInheritedSlots(HasSlotsAndNothingElse):
1440+
pass
1441+
1442+
class HasEmptySlots:
1443+
__slots__ = ()
1444+
""",
1445+
runtime="""
1446+
class HasSlotsAndNothingElse:
1447+
__slots__ = ("x",)
1448+
x: int
1449+
1450+
class HasInheritedSlots(HasSlotsAndNothingElse):
1451+
pass
1452+
1453+
class HasEmptySlots:
1454+
__slots__ = ()
1455+
""",
1456+
error=None,
1457+
)
14331458

14341459
@collect_cases
14351460
def test_decorator(self) -> Iterator[Case]:

0 commit comments

Comments
 (0)