diff --git a/mypy/sharedparse.py b/mypy/sharedparse.py index 88e77ecd0dc2a..97524591a671a 100644 --- a/mypy/sharedparse.py +++ b/mypy/sharedparse.py @@ -6,36 +6,52 @@ _NON_BINARY_MAGIC_METHODS = { "__abs__", + "__bool__" "__call__", + "__ceil__", "__complex__", - "__contains__", "__del__", "__delattr__", + "__delete__", "__delitem__", + "__dir__", "__enter__", "__exit__", "__float__", + "__floor__", + # "__get__", # TODO: breaks testAccessingGenericDescriptorFromClassBadOverload "__getattr__", "__getattribute__", "__getitem__", + "__hash__", "__hex__", + "__index__", "__init__", "__init_subclass__", + "__instancecheck__", "__int__", "__invert__", "__iter__", "__len__", + "__length_hint__", "__long__", + "__missing__", "__neg__", "__new__", + # "__not__", # Not magic -- `not` calls `__bool__` or `__len__`. "__nonzero__", "__oct__", "__pos__", "__repr__", "__reversed__", + "__round__", + "__set__", + "__set_name__", "__setattr__", "__setitem__", "__str__", + "__subclasscheck__", + "__trunc__", "__unicode__", } # type: Final @@ -50,14 +66,17 @@ "__add__", "__and__", "__cmp__", - "__divmod__", + "__concat__", + "__contains__", "__div__", + "__divmod__", "__eq__", "__floordiv__", "__ge__", "__gt__", "__iadd__", "__iand__", + "__iconcat__", "__idiv__", "__ifloordiv__", "__ilshift__", @@ -82,6 +101,7 @@ "__radd__", "__rand__", "__rdiv__", + "__rdivmod__", "__rfloordiv__", "__rlshift__", "__rmatmul__", diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index 40d057ad3fed9..b596ce0d0ec55 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -6142,6 +6142,90 @@ class B: class C(A, B): pass [out] +[case testBinaryMagicMethods] +# flags: --warn-return-any +# See also check-warnings.test [case testReturnAnyForNotImplementedInBinaryMagicMethods] +from typing import Any +class A: + def __init__(self, x: Any) -> None: + self.x = x + def __abs__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __bool__(self) -> bool: return NotImplemented # E: Returning Any from function declared to return "bool" + def __call__(self, *args, **kwargs) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __ceil__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __complex__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __del__(self) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + def __delattr__(self, other: Any) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + def __delete__(self, other: Any) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + def __delitem__(self, other: Any) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + def __dir__(self, other: Any) -> Sequence_str: return NotImplemented # E: Returning Any from function declared to return "Sequence_str" + def __enter__(self, other: Any) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + def __exit__(self, other: Any) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + def __float__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __floor__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __get__(self, instance: Any, other: Any) -> str: return NotImplemented # E: Returning Any from function declared to return "str" + def __getitem__(self, other: Any) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __int__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __index__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __inv__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __invert__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __neg__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __not__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __pos__(self) -> 'A': return NotImplemented # E: Returning Any from function declared to return "A" + def __setitem__(self, other: Any) -> None: return NotImplemented # E: Returning Any from function declared to return "None" + + def __add__(self, other: Any) -> 'A': return NotImplemented + def __and__(self, other: Any) -> 'A': return NotImplemented + def __concat__(self, other: Any) -> 'A': return NotImplemented + def __contains__(self, other: Any) -> 'A': return NotImplemented + def __eq__(self, other: Any) -> bool: return NotImplemented + def __floordiv__(self, other: Any) -> 'A': return NotImplemented + def __ge__(self, other: Any) -> bool: return NotImplemented + def __gt__(self, other: Any) -> bool: return NotImplemented + def __iadd__(self, other: Any) -> 'A': return NotImplemented + def __iand__(self, other: Any) -> 'A': return NotImplemented + def __iconcat__(self, other: Any) -> 'A': return NotImplemented + def __ifloordiv__(self, other: Any) -> 'A': return NotImplemented + def __ilshift__(self, other: Any) -> 'A': return NotImplemented + def __imatmul__(self, other: Any) -> 'A': return NotImplemented + def __imod__(self, other: Any) -> 'A': return NotImplemented + def __imul__(self, other: Any) -> 'A': return NotImplemented + def __ior__(self, other: Any) -> 'A': return NotImplemented + def __ipow__(self, other: Any) -> 'A': return NotImplemented + def __irshift__(self, other: Any) -> 'A': return NotImplemented + def __isub__(self, other: Any) -> 'A': return NotImplemented + def __itruediv__(self, other: Any) -> 'A': return NotImplemented + def __ixor__(self, other: Any) -> 'A': return NotImplemented + def __le__(self, other: Any) -> bool: return NotImplemented + def __lshift__(self, other: Any) -> 'A': return NotImplemented + def __lt__(self, other: Any) -> bool: return NotImplemented + def __matmul__(self, other: Any) -> 'A': return NotImplemented + def __mod__(self, other: Any) -> 'A': return NotImplemented + def __mul__(self, other: Any) -> 'A': return NotImplemented + def __ne__(self, other: Any) -> bool: return NotImplemented + def __or__(self, other: Any) -> 'A': return NotImplemented + def __pow__(self, other: Any) -> 'A': return NotImplemented + def __rshift__(self, other: Any) -> 'A': return NotImplemented + def __sub__(self, other: Any) -> 'A': return NotImplemented + def __truediv__(self, other: Any) -> 'A': return NotImplemented + def __xor__(self, other: Any) -> 'A': return NotImplemented + # The "reverse" methods: + def __radd__(self, other: Any) -> 'A': return NotImplemented + def __rsub__(self, other: Any) -> 'A': return NotImplemented + def __rmul__(self, other: Any) -> 'A': return NotImplemented + def __rmatmul__(self, other: Any) -> 'A': return NotImplemented + def __rtruediv__(self, other: Any) -> 'A': return NotImplemented + def __rfloordiv__(self, other: Any) -> 'A': return NotImplemented + def __rmod__(self, other: Any) -> 'A': return NotImplemented + def __rdivmod__(self, other: Any) -> 'A': return NotImplemented + def __rpow__(self, other: Any) -> 'A': return NotImplemented + def __rlshift__(self, other: Any) -> 'A': return NotImplemented + def __rrshift__(self, other: Any) -> 'A': return NotImplemented + def __rand__(self, other: Any) -> 'A': return NotImplemented + def __rxor__(self, other: Any) -> 'A': return NotImplemented + def __ror__(self, other: Any) -> 'A': return NotImplemented +[builtins fixtures/notimplemented.pyi] + [case testAttributeDefOrder1] import a diff --git a/test-data/unit/fixtures/notimplemented.pyi b/test-data/unit/fixtures/notimplemented.pyi index e619a6c5ad851..f1a2874c8bc48 100644 --- a/test-data/unit/fixtures/notimplemented.pyi +++ b/test-data/unit/fixtures/notimplemented.pyi @@ -1,13 +1,21 @@ # builtins stub used in NotImplemented related cases. -from typing import Any, cast +from typing import Any, Iterable, Mapping, Generic, TypeVar, cast +Tco = TypeVar('Tco', covariant=True) +T = TypeVar('T') +S = TypeVar('S') class object: def __init__(self) -> None: pass + def __eq__(self, o: object) -> bool: pass + def __ne__(self, o: object) -> bool: pass +class dict(Iterable[T], Mapping[T, S], Generic[T, S]): pass +class tuple(Iterable[Tco], Generic[Tco]): pass class type: pass class function: pass class bool: pass class int: pass class str: pass +class Sequence_str: pass # Sequence[str] for testing __dir__ NotImplemented = cast(Any, None)