From 18b7000acfd82b01ee3844e0e922f23e77203753 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 8 Jan 2016 14:29:30 -0800 Subject: [PATCH] Remove certain checks related to reverse operations -- they no longer serve a purpose. --- mypy/checker.py | 31 +++++-------------------------- mypy/test/data/check-classes.test | 12 ------------ 2 files changed, 5 insertions(+), 38 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 18a7d4f7bd273..7517e7e798d3d 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -596,23 +596,9 @@ def check_reverse_op_method(self, defn: FuncItem, typ: CallableType, method: str) -> None: """Check a reverse operator method such as __radd__.""" - # If the argument of a reverse operator method such as __radd__ - # does not define the corresponding non-reverse method such as __add__ - # the return type of __radd__ may not reliably represent the value of - # the corresponding operation even in a fully statically typed program. - # - # This example illustrates the issue: - # - # class A: pass - # class B: - # def __radd__(self, x: A) -> int: # Note that A does not define - # return 1 # __add__! - # class C(A): - # def __add__(self, x: Any) -> str: return 'x' - # def f(a: A) -> None: - # a + B() # Result would be 'x', even though static type seems to - # # be int! - # f(C()) + # This used to check for some very obscure scenario. It now + # just decides whether it's worth calling + # check_overlapping_op_methods(). if method in ('__eq__', '__ne__'): # These are defined for all objects => can't cause trouble. @@ -634,22 +620,15 @@ def check_reverse_op_method(self, defn: FuncItem, typ: CallableType, # Check for the issue described above. arg_type = typ.arg_types[1] other_method = nodes.normal_from_reverse_op[method] - fail = False if isinstance(arg_type, Instance): if not arg_type.type.has_readable_member(other_method): - fail = True + return elif isinstance(arg_type, AnyType): - self.msg.reverse_operator_method_with_any_arg_must_return_any( - method, defn) return elif isinstance(arg_type, UnionType): if not arg_type.has_readable_member(other_method): - fail = True + return else: - fail = True - if fail: - self.msg.invalid_reverse_operator_signature( - method, other_method, defn) return typ2 = self.expr_checker.analyze_external_member_access( diff --git a/mypy/test/data/check-classes.test b/mypy/test/data/check-classes.test index 440f910e6e1c5..c9076d7217098 100644 --- a/mypy/test/data/check-classes.test +++ b/mypy/test/data/check-classes.test @@ -1004,8 +1004,6 @@ class C: class D: def __radd__(self, x: A) -> object: pass [out] -main: note: In member "__radd__" of class "B": -main:4: error: "Any" return type expected since argument to __radd__ does not support __add__ [case testReverseOperatorMethoddArgumentType2] from typing import Any, Tuple, Callable @@ -1016,12 +1014,6 @@ class B: class C: def __radd__(self, x: Any) -> int: pass [out] -main: note: In member "__radd__" of class "A": -main:3: error: "Any" return type expected since argument to __radd__ does not support __add__ -main: note: In member "__radd__" of class "B": -main:5: error: "Any" return type expected since argument to __radd__ does not support __add__ -main: note: In member "__radd__" of class "C": -main:7: error: "Any" return type expected since argument to __radd__ has type "Any" [case testOverloadedReverseOperatorMethodArgumentType] from typing import overload, Any @@ -1031,8 +1023,6 @@ class A: @overload def __radd__(self, x: 'A') -> Any: pass [out] -main: note: In member "__radd__" of class "A": -main:4: error: "Any" return type expected since argument to __radd__ does not support __add__ [case testReverseOperatorMethodArgumentTypeAndOverloadedMethod] from typing import overload @@ -1055,8 +1045,6 @@ class B: @abstractmethod def __gt__(self, x: 'B') -> int: pass [out] -main: note: In member "__lt__" of class "A": -main:5: error: "Any" return type expected since argument to __lt__ does not support __gt__ [case testOperatorMethodsAndOverloadingSpecialCase] from typing import overload