56
56
is_literal_type_like ,
57
57
)
58
58
from mypy import message_registry
59
+ from mypy .message_registry import ErrorMessage
59
60
from mypy .subtypes import (
60
61
is_subtype , is_equivalent , is_proper_subtype , is_more_precise ,
61
62
restrict_subtype_away , is_subtype_ignoring_tvars , is_callable_compatible ,
@@ -1019,10 +1020,9 @@ def check_func_def(self, defn: FuncItem, typ: CallableType, name: Optional[str])
1019
1020
# entirely pass/Ellipsis/raise NotImplementedError.
1020
1021
if isinstance (return_type , UninhabitedType ):
1021
1022
# This is a NoReturn function
1022
- self .msg . fail (message_registry .INVALID_IMPLICIT_RETURN , defn )
1023
+ self .fail (message_registry .INVALID_IMPLICIT_RETURN , defn )
1023
1024
else :
1024
- self .msg .fail (message_registry .MISSING_RETURN_STATEMENT , defn ,
1025
- code = codes .RETURN )
1025
+ self .fail (message_registry .MISSING_RETURN_STATEMENT , defn )
1026
1026
1027
1027
self .return_types .pop ()
1028
1028
@@ -1078,31 +1078,25 @@ def is_unannotated_any(t: Type) -> bool:
1078
1078
if fdef .type is None and self .options .disallow_untyped_defs :
1079
1079
if (not fdef .arguments or (len (fdef .arguments ) == 1 and
1080
1080
(fdef .arg_names [0 ] == 'self' or fdef .arg_names [0 ] == 'cls' ))):
1081
- self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef ,
1082
- code = codes .NO_UNTYPED_DEF )
1081
+ self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef )
1083
1082
if not has_return_statement (fdef ) and not fdef .is_generator :
1084
1083
self .note ('Use "-> None" if function does not return a value' , fdef ,
1085
1084
code = codes .NO_UNTYPED_DEF )
1086
1085
else :
1087
- self .fail (message_registry .FUNCTION_TYPE_EXPECTED , fdef ,
1088
- code = codes .NO_UNTYPED_DEF )
1086
+ self .fail (message_registry .FUNCTION_TYPE_EXPECTED , fdef )
1089
1087
elif isinstance (fdef .type , CallableType ):
1090
1088
ret_type = get_proper_type (fdef .type .ret_type )
1091
1089
if is_unannotated_any (ret_type ):
1092
- self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef ,
1093
- code = codes .NO_UNTYPED_DEF )
1090
+ self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef )
1094
1091
elif fdef .is_generator :
1095
1092
if is_unannotated_any (self .get_generator_return_type (ret_type ,
1096
1093
fdef .is_coroutine )):
1097
- self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef ,
1098
- code = codes .NO_UNTYPED_DEF )
1094
+ self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef )
1099
1095
elif fdef .is_coroutine and isinstance (ret_type , Instance ):
1100
1096
if is_unannotated_any (self .get_coroutine_return_type (ret_type )):
1101
- self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef ,
1102
- code = codes .NO_UNTYPED_DEF )
1097
+ self .fail (message_registry .RETURN_TYPE_EXPECTED , fdef )
1103
1098
if any (is_unannotated_any (t ) for t in fdef .type .arg_types ):
1104
- self .fail (message_registry .ARGUMENT_TYPE_EXPECTED , fdef ,
1105
- code = codes .NO_UNTYPED_DEF )
1099
+ self .fail (message_registry .ARGUMENT_TYPE_EXPECTED , fdef )
1106
1100
1107
1101
def check___new___signature (self , fdef : FuncDef , typ : CallableType ) -> None :
1108
1102
self_type = fill_typevars_with_any (fdef .info )
@@ -1387,7 +1381,7 @@ def check_getattr_method(self, typ: Type, context: Context, name: str) -> None:
1387
1381
if len (self .scope .stack ) == 1 :
1388
1382
# module scope
1389
1383
if name == '__getattribute__' :
1390
- self .msg . fail (message_registry .MODULE_LEVEL_GETATTRIBUTE , context )
1384
+ self .fail (message_registry .MODULE_LEVEL_GETATTRIBUTE , context )
1391
1385
return
1392
1386
# __getattr__ is fine at the module level as of Python 3.7 (PEP 562). We could
1393
1387
# show an error for Python < 3.7, but that would be annoying in code that supports
@@ -2608,7 +2602,7 @@ def check_assignment_to_slots(self, lvalue: Lvalue) -> None:
2608
2602
return
2609
2603
2610
2604
self .fail (
2611
- 'Trying to assign name "{}" that is not in "__slots__" of type "{}"' .format (
2605
+ message_registry . NAME_NOT_IN_SLOTS .format (
2612
2606
lvalue .name , inst .type .fullname ,
2613
2607
),
2614
2608
lvalue ,
@@ -2652,16 +2646,16 @@ def check_assignment_to_multiple_lvalues(self, lvalues: List[Lvalue], rvalue: Ex
2652
2646
elif self .type_is_iterable (typs ) and isinstance (typs , Instance ):
2653
2647
if (iterable_type is not None
2654
2648
and iterable_type != self .iterable_item_type (typs )):
2655
- self .fail ("Contiguous iterable with same type expected" , context )
2649
+ self .fail (message_registry . CONTIGUOUS_ITERABLE_EXPECTED , context )
2656
2650
else :
2657
2651
if last_idx is None or last_idx + 1 == idx_rval :
2658
2652
rvalues .append (rval )
2659
2653
last_idx = idx_rval
2660
2654
iterable_type = self .iterable_item_type (typs )
2661
2655
else :
2662
- self .fail ("Contiguous iterable with same type expected" , context )
2656
+ self .fail (message_registry . CONTIGUOUS_ITERABLE_EXPECTED , context )
2663
2657
else :
2664
- self .fail ("Invalid type '{}' for *expr (iterable expected)" .format (typs ),
2658
+ self .fail (message_registry . ITERABLE_TYPE_EXPECTED .format (typs ),
2665
2659
context )
2666
2660
else :
2667
2661
rvalues .append (rval )
@@ -3194,8 +3188,7 @@ def check_member_assignment(self, instance_type: Type, attribute_type: Type,
3194
3188
3195
3189
dunder_set = attribute_type .type .get_method ('__set__' )
3196
3190
if dunder_set is None :
3197
- self .msg .fail (message_registry .DESCRIPTOR_SET_NOT_CALLABLE .format (attribute_type ),
3198
- context )
3191
+ self .fail (message_registry .DESCRIPTOR_SET_NOT_CALLABLE .format (attribute_type ), context )
3199
3192
return AnyType (TypeOfAny .from_error ), get_type , False
3200
3193
3201
3194
function = function_type (dunder_set , self .named_type ('builtins.function' ))
@@ -3378,8 +3371,7 @@ def check_return_stmt(self, s: ReturnStmt) -> None:
3378
3371
# Functions returning a value of type None are allowed to have a None return.
3379
3372
if is_lambda or isinstance (typ , NoneType ):
3380
3373
return
3381
- self .fail (message_registry .NO_RETURN_VALUE_EXPECTED , s ,
3382
- code = codes .RETURN_VALUE )
3374
+ self .fail (message_registry .NO_RETURN_VALUE_EXPECTED , s )
3383
3375
else :
3384
3376
self .check_subtype (
3385
3377
subtype_label = 'got' ,
@@ -3401,7 +3393,7 @@ def check_return_stmt(self, s: ReturnStmt) -> None:
3401
3393
return
3402
3394
3403
3395
if self .in_checked_function ():
3404
- self .fail (message_registry .RETURN_VALUE_EXPECTED , s , code = codes . RETURN_VALUE )
3396
+ self .fail (message_registry .RETURN_VALUE_EXPECTED , s )
3405
3397
3406
3398
def visit_if_stmt (self , s : IfStmt ) -> None :
3407
3399
"""Type check an if statement."""
@@ -4251,23 +4243,16 @@ def format_expr_type() -> str:
4251
4243
return f'Expression has type "{ t } "'
4252
4244
4253
4245
if isinstance (t , FunctionLike ):
4254
- self .msg .fail (
4255
- f'Function "{ t } " could always be true in boolean context' , expr ,
4256
- code = codes .TRUTHY_BOOL ,
4257
- )
4246
+ self .fail (message_registry .FUNCTION_ALWAYS_TRUE .format (t ), expr )
4258
4247
elif isinstance (t , UnionType ):
4259
- self .msg .fail (
4260
- f"{ format_expr_type ()} of which no members implement __bool__ or __len__ "
4261
- "so it could always be true in boolean context" ,
4248
+ self .fail (
4249
+ message_registry .TYPE_ALWAYS_TRUE_UNIONTYPE .format (format_expr_type ()),
4262
4250
expr ,
4263
- code = codes .TRUTHY_BOOL ,
4264
4251
)
4265
4252
else :
4266
- self .msg .fail (
4267
- f'{ format_expr_type ()} which does not implement __bool__ or __len__ '
4268
- 'so it could always be true in boolean context' ,
4253
+ self .fail (
4254
+ message_registry .TYPE_ALWAYS_TRUE .format (format_expr_type ()),
4269
4255
expr ,
4270
- code = codes .TRUTHY_BOOL ,
4271
4256
)
4272
4257
4273
4258
def find_type_equals_check (self , node : ComparisonExpr , expr_indices : List [int ]
@@ -4400,7 +4385,7 @@ def find_isinstance_check_helper(self, node: Expression) -> Tuple[TypeMap, TypeM
4400
4385
if node .callee .type_guard is not None :
4401
4386
# TODO: Follow keyword args or *args, **kwargs
4402
4387
if node .arg_kinds [0 ] != nodes .ARG_POS :
4403
- self .fail ("Type guard requires positional argument" , node )
4388
+ self .fail (message_registry . TYPE_GUARD_POS_ARG_REQUIRED , node )
4404
4389
return {}, {}
4405
4390
if literal (expr ) == LITERAL_TYPE :
4406
4391
# Note: we wrap the target type, so that we can special case later.
@@ -4946,7 +4931,7 @@ def check_subtype(self,
4946
4931
subtype : Type ,
4947
4932
supertype : Type ,
4948
4933
context : Context ,
4949
- msg : str = message_registry .INCOMPATIBLE_TYPES ,
4934
+ msg : Union [ str , ErrorMessage ] = message_registry .INCOMPATIBLE_TYPES ,
4950
4935
subtype_label : Optional [str ] = None ,
4951
4936
supertype_label : Optional [str ] = None ,
4952
4937
* ,
@@ -4956,9 +4941,14 @@ def check_subtype(self,
4956
4941
if is_subtype (subtype , supertype ):
4957
4942
return True
4958
4943
4944
+ if isinstance (msg , ErrorMessage ):
4945
+ msg_text = msg .value
4946
+ code = msg .code
4947
+ else :
4948
+ msg_text = msg
4959
4949
subtype = get_proper_type (subtype )
4960
4950
supertype = get_proper_type (supertype )
4961
- if self .msg .try_report_long_tuple_assignment_error (subtype , supertype , context , msg ,
4951
+ if self .msg .try_report_long_tuple_assignment_error (subtype , supertype , context , msg_text ,
4962
4952
subtype_label , supertype_label , code = code ):
4963
4953
return False
4964
4954
if self .should_suppress_optional_error ([subtype ]):
@@ -4977,8 +4967,9 @@ def check_subtype(self,
4977
4967
if isinstance (subtype , Instance ) and isinstance (supertype , Instance ):
4978
4968
notes = append_invariance_notes ([], subtype , supertype )
4979
4969
if extra_info :
4980
- msg += ' (' + ', ' .join (extra_info ) + ')'
4981
- self .fail (msg , context , code = code )
4970
+ msg_text += ' (' + ', ' .join (extra_info ) + ')'
4971
+
4972
+ self .fail (ErrorMessage (msg_text , code = code ), context )
4982
4973
for note in notes :
4983
4974
self .msg .note (note , context , code = code )
4984
4975
if note_msg :
@@ -5249,8 +5240,12 @@ def temp_node(self, t: Type, context: Optional[Context] = None) -> TempNode:
5249
5240
"""Create a temporary node with the given, fixed type."""
5250
5241
return TempNode (t , context = context )
5251
5242
5252
- def fail (self , msg : str , context : Context , * , code : Optional [ErrorCode ] = None ) -> None :
5243
+ def fail (self , msg : Union [str , ErrorMessage ], context : Context , * ,
5244
+ code : Optional [ErrorCode ] = None ) -> None :
5253
5245
"""Produce an error message."""
5246
+ if isinstance (msg , ErrorMessage ):
5247
+ self .msg .fail (msg .value , context , code = msg .code )
5248
+ return
5254
5249
self .msg .fail (msg , context , code = code )
5255
5250
5256
5251
def note (self ,
0 commit comments