Skip to content

Commit b1ac028

Browse files
authored
stubtest: ignore setattr and delattr inherited from object (#18325)
`__setattr__` and `__delattr__` from object are special cased by type checkers, so defining them on an inheriting class, even with the same signature, has a different meaning. This one is very similar to #18314
1 parent 9fe9525 commit b1ac028

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

mypy/stubtest.py

+20-4
Original file line numberDiff line numberDiff line change
@@ -574,9 +574,23 @@ def verify_typeinfo(
574574

575575
# If it came from the metaclass, consider the runtime_attr to be MISSING
576576
# for a more accurate message
577-
if runtime_attr is not MISSING and type(runtime) is not runtime:
578-
if getattr(runtime_attr, "__objclass__", None) is type(runtime):
579-
runtime_attr = MISSING
577+
if (
578+
runtime_attr is not MISSING
579+
and type(runtime) is not runtime
580+
and getattr(runtime_attr, "__objclass__", None) is type(runtime)
581+
):
582+
runtime_attr = MISSING
583+
584+
# __setattr__ and __delattr__ on object are a special case,
585+
# so if we only have these methods inherited from there, pretend that
586+
# we don't have them. See python/typeshed#7385.
587+
if (
588+
entry in ("__setattr__", "__delattr__")
589+
and runtime_attr is not MISSING
590+
and runtime is not object
591+
and getattr(runtime_attr, "__objclass__", None) is object
592+
):
593+
runtime_attr = MISSING
580594

581595
# Do not error for an object missing from the stub
582596
# If the runtime object is a types.WrapperDescriptorType object
@@ -1092,9 +1106,11 @@ def verify_funcitem(
10921106

10931107

10941108
@verify.register(Missing)
1095-
def verify_none(
1109+
def verify_missing(
10961110
stub: Missing, runtime: MaybeMissing[Any], object_path: list[str]
10971111
) -> Iterator[Error]:
1112+
if runtime is MISSING:
1113+
return
10981114
yield Error(object_path, "is not present in stub", stub, runtime)
10991115

11001116

mypy/test/teststubtest.py

+18
Original file line numberDiff line numberDiff line change
@@ -1496,6 +1496,24 @@ def __call__(*args, **kwds): ...
14961496
runtime="class ClassWithMetaclassOverride: ...",
14971497
error="ClassWithMetaclassOverride.__call__",
14981498
)
1499+
# Test that we ignore object.__setattr__ and object.__delattr__ inheritance
1500+
yield Case(
1501+
stub="""
1502+
from typing import Any
1503+
class FakeSetattrClass:
1504+
def __setattr__(self, name: str, value: Any, /) -> None: ...
1505+
""",
1506+
runtime="class FakeSetattrClass: ...",
1507+
error="FakeSetattrClass.__setattr__",
1508+
)
1509+
yield Case(
1510+
stub="""
1511+
class FakeDelattrClass:
1512+
def __delattr__(self, name: str, /) -> None: ...
1513+
""",
1514+
runtime="class FakeDelattrClass: ...",
1515+
error="FakeDelattrClass.__delattr__",
1516+
)
14991517

15001518
@collect_cases
15011519
def test_missing_no_runtime_all(self) -> Iterator[Case]:

0 commit comments

Comments
 (0)