|
59 | 59 | from mypy.meet import is_overlapping_types |
60 | 60 | from mypy.options import Options |
61 | 61 | from mypy.plugin import Plugin, CheckerPluginInterface |
| 62 | +from mypy.sharedparse import BINARY_MAGIC_METHODS |
62 | 63 |
|
63 | 64 | from mypy import experiments |
64 | 65 |
|
@@ -2179,8 +2180,11 @@ def check_return_stmt(self, s: ReturnStmt) -> None: |
2179 | 2180 | if isinstance(typ, AnyType): |
2180 | 2181 | # (Unless you asked to be warned in that case, and the |
2181 | 2182 | # function is not declared to return Any) |
2182 | | - if (self.options.warn_return_any and not self.current_node_deferred and |
2183 | | - not is_proper_subtype(AnyType(TypeOfAny.special_form), return_type)): |
| 2183 | + if (self.options.warn_return_any |
| 2184 | + and not self.current_node_deferred |
| 2185 | + and not is_proper_subtype(AnyType(TypeOfAny.special_form), return_type) |
| 2186 | + and not (defn.name() in BINARY_MAGIC_METHODS and |
| 2187 | + is_literal_not_implemented(s.expr))): |
2184 | 2188 | self.msg.incorrectly_returning_any(return_type, s) |
2185 | 2189 | return |
2186 | 2190 |
|
@@ -3232,6 +3236,10 @@ def remove_optional(typ: Type) -> Type: |
3232 | 3236 | return typ |
3233 | 3237 |
|
3234 | 3238 |
|
| 3239 | +def is_literal_not_implemented(n: Expression) -> bool: |
| 3240 | + return isinstance(n, NameExpr) and n.fullname == 'builtins.NotImplemented' |
| 3241 | + |
| 3242 | + |
3235 | 3243 | def builtin_item_type(tp: Type) -> Optional[Type]: |
3236 | 3244 | """Get the item type of a builtin container. |
3237 | 3245 |
|
|
0 commit comments