Skip to content

Commit 33e3558

Browse files
authored
Fix operator error messages for __div__ and __cmp__ on python 2 (#7671)
Currently the code for turning method call errors into operator error messages doesn't detect __div__ and __cmp__, so fix that. One of my main motivations here is that this fixes type ignoring these with an error code, since previously the real error would be `arg-type` but the note would be `operator`.
1 parent c95ecc1 commit 33e3558

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

mypy/messages.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
)
2828
from mypy.typetraverser import TypeTraverserVisitor
2929
from mypy.nodes import (
30-
TypeInfo, Context, MypyFile, op_methods, FuncDef, reverse_builtin_aliases,
30+
TypeInfo, Context, MypyFile, op_methods, op_methods_to_symbols,
31+
FuncDef, reverse_builtin_aliases,
3132
ARG_POS, ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2,
3233
ReturnStmt, NameExpr, Var, CONTRAVARIANT, COVARIANT, SymbolNode,
3334
CallExpr
@@ -353,7 +354,7 @@ def incompatible_argument(self,
353354
else:
354355
base = extract_type(name)
355356

356-
for op, method in op_methods.items():
357+
for method, op in op_methods_to_symbols.items():
357358
for variant in method, '__r' + method[2:]:
358359
# FIX: do not rely on textual formatting
359360
if name.startswith('"{}" of'.format(variant)):
@@ -366,6 +367,11 @@ def incompatible_argument(self,
366367
context, code=codes.OPERATOR)
367368
return codes.OPERATOR
368369

370+
if name.startswith('"__cmp__" of'):
371+
self.unsupported_operand_types("comparison", arg_type, base,
372+
context, code=codes.OPERATOR)
373+
return codes.INDEX
374+
369375
if name.startswith('"__getitem__" of'):
370376
self.invalid_index_type(arg_type, callee.arg_types[n - 1], base, context,
371377
code=codes.INDEX)

test-data/unit/check-expressions.test

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,15 +474,15 @@ class B:
474474

475475
a, b, c, bo = None, None, None, None # type: (A, B, C, bool)
476476
bo = a == a # E: Unsupported operand types for == ("A" and "A")
477-
bo = a != a # E: Argument 1 to "__cmp__" of "A" has incompatible type "A"; expected "B"
477+
bo = a != a # E: Unsupported operand types for comparison ("A" and "A")
478478
bo = a < b
479479
bo = a > b
480480
bo = b <= b
481481
bo = b <= c
482-
bo = b >= c # E: Argument 1 to "__cmp__" of "B" has incompatible type "C"; expected "B"
482+
bo = b >= c # E: Unsupported operand types for comparison ("C" and "B")
483483
bo = a >= b
484484
bo = c >= b
485-
bo = c <= b # E: Argument 1 to "__cmp__" of "C" has incompatible type "B"; expected "A"
485+
bo = c <= b # E: Unsupported operand types for comparison ("B" and "C")
486486
bo = a == c
487487
bo = b == c # E: Unsupported operand types for == ("C" and "B")
488488

@@ -510,6 +510,11 @@ class C:
510510

511511
[builtins_py2 fixtures/bool_py2.pyi]
512512

513+
[case testDiv_python2]
514+
10 / 'no' # E: Unsupported operand types for / ("int" and "str")
515+
'no' / 10 # E: Unsupported operand types for / ("str" and "int")
516+
[builtins_py2 fixtures/ops.pyi]
517+
513518
[case cmpIgnoredPy3]
514519

515520
a, b, bo = None, None, None # type: (A, B, bool)

0 commit comments

Comments
 (0)