2626from mypy .erasetype import erase_type , erase_typevars , remove_instance_last_known_values
2727from mypy .errorcodes import TYPE_VAR , UNUSED_AWAITABLE , UNUSED_COROUTINE , ErrorCode
2828from mypy .errors import (
29+ ErrorInfo ,
2930 Errors ,
3031 ErrorWatcher ,
3132 IterationErrorWatcher ,
123124 TypeAlias ,
124125 TypeAliasStmt ,
125126 TypeInfo ,
126- TypeVarExpr ,
127127 UnaryExpr ,
128128 Var ,
129129 WhileStmt ,
@@ -673,11 +673,9 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
673673 assert isinstance (defn .items [0 ], Decorator )
674674 self .visit_decorator (defn .items [0 ])
675675 if defn .items [0 ].var .is_settable_property :
676- # TODO: here and elsewhere we assume setter immediately follows getter.
677- assert isinstance (defn .items [1 ], Decorator )
678676 # Perform a reduced visit just to infer the actual setter type.
679- self .visit_decorator_inner (defn .items [ 1 ] , skip_first_item = True )
680- setter_type = defn .items [ 1 ] .var .type
677+ self .visit_decorator_inner (defn .setter , skip_first_item = True )
678+ setter_type = defn .setter .var .type
681679 # Check if the setter can accept two positional arguments.
682680 any_type = AnyType (TypeOfAny .special_form )
683681 fallback_setter_type = CallableType (
@@ -688,7 +686,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
688686 fallback = self .named_type ("builtins.function" ),
689687 )
690688 if setter_type and not is_subtype (setter_type , fallback_setter_type ):
691- self .fail ("Invalid property setter signature" , defn .items [ 1 ] .func )
689+ self .fail ("Invalid property setter signature" , defn .setter .func )
692690 setter_type = self .extract_callable_type (setter_type , defn )
693691 if not isinstance (setter_type , CallableType ) or len (setter_type .arg_types ) != 2 :
694692 # TODO: keep precise type for callables with tricky but valid signatures.
@@ -2147,7 +2145,7 @@ def check_setter_type_override(self, defn: OverloadedFuncDef, base: TypeInfo) ->
21472145 assert typ is not None and original_type is not None
21482146
21492147 if not is_subtype (original_type , typ ):
2150- self .msg .incompatible_setter_override (defn .items [ 1 ] , typ , original_type , base )
2148+ self .msg .incompatible_setter_override (defn .setter , typ , original_type , base )
21512149
21522150 def check_method_override_for_base_with_name (
21532151 self , defn : FuncDef | OverloadedFuncDef | Decorator , name : str , base : TypeInfo
@@ -2836,29 +2834,6 @@ def check_multiple_inheritance(self, typ: TypeInfo) -> None:
28362834 if name in base2 .names and base2 not in base .mro :
28372835 self .check_compatibility (name , base , base2 , typ )
28382836
2839- def determine_type_of_member (self , sym : SymbolTableNode ) -> Type | None :
2840- # TODO: this duplicates both checkmember.py and analyze_ref_expr(), delete.
2841- if sym .type is not None :
2842- return sym .type
2843- if isinstance (sym .node , SYMBOL_FUNCBASE_TYPES ):
2844- return self .function_type (sym .node )
2845- if isinstance (sym .node , TypeInfo ):
2846- if sym .node .typeddict_type :
2847- # We special-case TypedDict, because they don't define any constructor.
2848- return self .expr_checker .typeddict_callable (sym .node )
2849- else :
2850- return type_object_type (sym .node , self .named_type )
2851- if isinstance (sym .node , TypeVarExpr ):
2852- # Use of TypeVars is rejected in an expression/runtime context, so
2853- # we don't need to check supertype compatibility for them.
2854- return AnyType (TypeOfAny .special_form )
2855- if isinstance (sym .node , TypeAlias ):
2856- with self .msg .filter_errors ():
2857- # Suppress any errors, they will be given when analyzing the corresponding node.
2858- # Here we may have incorrect options and location context.
2859- return self .expr_checker .alias_type_in_runtime_context (sym .node , ctx = sym .node )
2860- return None
2861-
28622837 def check_compatibility (
28632838 self , name : str , base1 : TypeInfo , base2 : TypeInfo , ctx : TypeInfo
28642839 ) -> None :
@@ -7195,7 +7170,7 @@ def check_subtype(
71957170 if extra_info :
71967171 msg = msg .with_additional_msg (" (" + ", " .join (extra_info ) + ")" )
71977172
7198- self .fail (msg , context )
7173+ error = self .fail (msg , context )
71997174 for note in notes :
72007175 self .msg .note (note , context , code = msg .code )
72017176 if note_msg :
@@ -7206,7 +7181,7 @@ def check_subtype(
72067181 and supertype .type .is_protocol
72077182 and isinstance (subtype , (CallableType , Instance , TupleType , TypedDictType ))
72087183 ):
7209- self .msg .report_protocol_problems (subtype , supertype , context , code = msg . code )
7184+ self .msg .report_protocol_problems (subtype , supertype , context , parent_error = error )
72107185 if isinstance (supertype , CallableType ) and isinstance (subtype , Instance ):
72117186 call = find_member ("__call__" , subtype , subtype , is_operator = True )
72127187 if call :
@@ -7535,12 +7510,11 @@ def temp_node(self, t: Type, context: Context | None = None) -> TempNode:
75357510
75367511 def fail (
75377512 self , msg : str | ErrorMessage , context : Context , * , code : ErrorCode | None = None
7538- ) -> None :
7513+ ) -> ErrorInfo :
75397514 """Produce an error message."""
75407515 if isinstance (msg , ErrorMessage ):
7541- self .msg .fail (msg .value , context , code = msg .code )
7542- return
7543- self .msg .fail (msg , context , code = code )
7516+ return self .msg .fail (msg .value , context , code = msg .code )
7517+ return self .msg .fail (msg , context , code = code )
75447518
75457519 def note (
75467520 self ,
0 commit comments