From ec802befa45f500fe3d4fb2584c5fb800324c249 Mon Sep 17 00:00:00 2001 From: hauntsaninja <> Date: Fri, 4 Mar 2022 19:08:13 -0800 Subject: [PATCH] stubtest: ignore more dunder positional-only errors This isn't actually a reversion. This logic was asymmetrical for reasons lost to time. Although I suspect it was this way because it introduced only a few errors on typeshed. What changed was that as a result of #12203 we actually started checking a lot more dunder methods. Previously, we only checked dunders if either: a) it was a special dunder, like __init__ or __call, or b) the dunder was defined on the actual stub class itself In particular, we started checking every dunder redefined at runtime that the stub just inherited from object. A possible intermediate option would be to not check positional-only arguments in the case where a stub inherits the definition. I'll experiment with that once typeshed CI is green. --- mypy/stubtest.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 3320f2370735..b568017cfa5f 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -288,13 +288,14 @@ class SubClass(runtime): # type: ignore # Examples: ctypes.Array, ctypes._SimpleCData pass - # Check everything already defined in the stub + # Check everything already defined on the stub class itself (i.e. not inherited) to_check = set(stub.names) + # Check all public things on the runtime class to_check.update( # cast to workaround mypyc complaints m for m in cast(Any, vars)(runtime) - if not is_probably_private(m) and m not in ALLOW_MISSING_CLASS_DUNDERS + if not is_probably_private(m) and m not in IGNORABLE_CLASS_DUNDERS ) for entry in sorted(to_check): @@ -629,6 +630,7 @@ def _verify_signature( if ( runtime_arg.kind != inspect.Parameter.POSITIONAL_ONLY and stub_arg.variable.name.startswith("__") + and not is_dunder(function_name, exclude_special=True) # noisy for dunder methods ): yield ( 'stub argument "{}" should be positional or keyword ' @@ -985,16 +987,16 @@ def verify_typealias( } ) -ALLOW_MISSING_CLASS_DUNDERS = frozenset( +IGNORABLE_CLASS_DUNDERS = frozenset( { # Special attributes "__dict__", "__text_signature__", "__weakref__", "__del__", # Only ever called when an object is being deleted, who cares? - # These two are basically useless for type checkers "__hash__", "__getattr__", # resulting behaviour might be typed explicitly + "__setattr__", # defining this on a class can cause worse type checking # isinstance/issubclass hooks that type-checkers don't usually care about "__instancecheck__", "__subclasshook__",