@@ -3108,112 +3108,141 @@ def infer_lambda_type_using_context(self, e: LambdaExpr) -> Tuple[Optional[Calla
3108
3108
3109
3109
def visit_super_expr (self , e : SuperExpr ) -> Type :
3110
3110
"""Type check a super expression (non-lvalue)."""
3111
- self .check_super_arguments (e )
3112
- t = self .analyze_super (e , False )
3113
- return t
3114
3111
3115
- def check_super_arguments (self , e : SuperExpr ) -> None :
3116
- """Check arguments in a super(...) call."""
3117
- if ARG_STAR in e .call .arg_kinds :
3112
+ # We have an expression like super(T, var).member
3113
+
3114
+ # First compute the types of T and var
3115
+ types = self ._super_arg_types (e )
3116
+ if isinstance (types , tuple ):
3117
+ type_type , instance_type = types
3118
+ else :
3119
+ return types
3120
+
3121
+ # Now get the MRO
3122
+ type_info = type_info_from_type (type_type )
3123
+ if type_info is None :
3124
+ self .chk .fail (message_registry .UNSUPPORTED_ARG_1_FOR_SUPER , e )
3125
+ return AnyType (TypeOfAny .from_error )
3126
+
3127
+ instance_info = type_info_from_type (instance_type )
3128
+ if instance_info is None :
3129
+ self .chk .fail (message_registry .UNSUPPORTED_ARG_2_FOR_SUPER , e )
3130
+ return AnyType (TypeOfAny .from_error )
3131
+
3132
+ mro = instance_info .mro
3133
+
3134
+ # The base is the first MRO entry *after* type_info that has a member
3135
+ # with the right name
3136
+ try :
3137
+ index = mro .index (type_info )
3138
+ except ValueError :
3139
+ self .chk .fail (message_registry .SUPER_ARG_2_NOT_INSTANCE_OF_ARG_1 , e )
3140
+ return AnyType (TypeOfAny .from_error )
3141
+
3142
+ for base in mro [index + 1 :]:
3143
+ if e .name in base .names or base == mro [- 1 ]:
3144
+ if e .info and e .info .fallback_to_any and base == mro [- 1 ]:
3145
+ # There's an undefined base class, and we're at the end of the
3146
+ # chain. That's not an error.
3147
+ return AnyType (TypeOfAny .special_form )
3148
+
3149
+ return analyze_member_access (name = e .name ,
3150
+ typ = instance_type ,
3151
+ is_lvalue = False ,
3152
+ is_super = True ,
3153
+ is_operator = False ,
3154
+ original_type = instance_type ,
3155
+ override_info = base ,
3156
+ context = e ,
3157
+ msg = self .msg ,
3158
+ chk = self .chk ,
3159
+ in_literal_context = self .is_literal_context ())
3160
+
3161
+ assert False , 'unreachable'
3162
+
3163
+ def _super_arg_types (self , e : SuperExpr ) -> Union [Type , Tuple [Type , Type ]]:
3164
+ """
3165
+ Computes the types of the type and instance expressions in super(T, instance), or the
3166
+ implicit ones for zero-argument super() expressions. Returns a single type for the whole
3167
+ super expression when possible (for errors, anys), otherwise the pair of computed types.
3168
+ """
3169
+
3170
+ if not self .chk .in_checked_function ():
3171
+ return AnyType (TypeOfAny .unannotated )
3172
+ elif len (e .call .args ) == 0 :
3173
+ if self .chk .options .python_version [0 ] == 2 :
3174
+ self .chk .fail (message_registry .TOO_FEW_ARGS_FOR_SUPER , e )
3175
+ return AnyType (TypeOfAny .from_error )
3176
+ elif not e .info :
3177
+ # This has already been reported by the semantic analyzer.
3178
+ return AnyType (TypeOfAny .from_error )
3179
+ elif self .chk .scope .active_class ():
3180
+ self .chk .fail (message_registry .SUPER_OUTSIDE_OF_METHOD_NOT_SUPPORTED , e )
3181
+ return AnyType (TypeOfAny .from_error )
3182
+
3183
+ # Zero-argument super() is like super(<current class>, <self>)
3184
+ current_type = fill_typevars (e .info )
3185
+ type_type = TypeType (current_type ) # type: Type
3186
+
3187
+ # Use the type of the self argument, in case it was annotated
3188
+ method = self .chk .scope .top_function ()
3189
+ assert method is not None
3190
+ if method .arguments :
3191
+ instance_type = method .arguments [0 ].variable .type or current_type # type: Type
3192
+ else :
3193
+ self .chk .fail (message_registry .SUPER_ENCLOSING_POSITIONAL_ARGS_REQUIRED , e )
3194
+ return AnyType (TypeOfAny .from_error )
3195
+ elif ARG_STAR in e .call .arg_kinds :
3118
3196
self .chk .fail (message_registry .SUPER_VARARGS_NOT_SUPPORTED , e )
3119
- elif e .call .args and set (e .call .arg_kinds ) != {ARG_POS }:
3197
+ return AnyType (TypeOfAny .from_error )
3198
+ elif set (e .call .arg_kinds ) != {ARG_POS }:
3120
3199
self .chk .fail (message_registry .SUPER_POSITIONAL_ARGS_REQUIRED , e )
3200
+ return AnyType (TypeOfAny .from_error )
3121
3201
elif len (e .call .args ) == 1 :
3122
3202
self .chk .fail (message_registry .SUPER_WITH_SINGLE_ARG_NOT_SUPPORTED , e )
3123
- elif len (e .call .args ) > 2 :
3124
- self .chk .fail (message_registry .TOO_MANY_ARGS_FOR_SUPER , e )
3125
- elif self .chk .options .python_version [0 ] == 2 and len (e .call .args ) == 0 :
3126
- self .chk .fail (message_registry .TOO_FEW_ARGS_FOR_SUPER , e )
3203
+ return AnyType (TypeOfAny .from_error )
3127
3204
elif len (e .call .args ) == 2 :
3128
- type_obj_type = self .accept (e .call .args [0 ])
3205
+ type_type = self .accept (e .call .args [0 ])
3129
3206
instance_type = self .accept (e .call .args [1 ])
3130
- if isinstance (type_obj_type , FunctionLike ) and type_obj_type .is_type_obj ():
3131
- type_info = type_obj_type .type_object ()
3132
- elif isinstance (type_obj_type , TypeType ):
3133
- item = type_obj_type .item
3134
- if isinstance (item , AnyType ):
3135
- # Could be anything.
3136
- return
3137
- if isinstance (item , TupleType ):
3138
- # Handle named tuples and other Tuple[...] subclasses.
3139
- item = tuple_fallback (item )
3140
- if not isinstance (item , Instance ):
3141
- # A complicated type object type. Too tricky, give up.
3142
- # TODO: Do something more clever here.
3143
- self .chk .fail (message_registry .UNSUPPORTED_ARG_1_FOR_SUPER , e )
3144
- return
3145
- type_info = item .type
3146
- elif isinstance (type_obj_type , AnyType ):
3147
- return
3207
+ else :
3208
+ self .chk .fail (message_registry .TOO_MANY_ARGS_FOR_SUPER , e )
3209
+ return AnyType (TypeOfAny .from_error )
3210
+
3211
+ # Imprecisely assume that the type is the current class
3212
+ if isinstance (type_type , AnyType ):
3213
+ if e .info :
3214
+ type_type = TypeType (fill_typevars (e .info ))
3148
3215
else :
3149
- self .msg .first_argument_for_super_must_be_type (type_obj_type , e )
3150
- return
3216
+ return AnyType (TypeOfAny .from_another_any , source_any = type_type )
3217
+ elif isinstance (type_type , TypeType ):
3218
+ type_item = type_type .item
3219
+ if isinstance (type_item , AnyType ):
3220
+ if e .info :
3221
+ type_type = TypeType (fill_typevars (e .info ))
3222
+ else :
3223
+ return AnyType (TypeOfAny .from_another_any , source_any = type_item )
3151
3224
3152
- if isinstance (instance_type , (Instance , TupleType , TypeVarType )):
3153
- if isinstance (instance_type , TypeVarType ):
3154
- # Needed for generic self.
3155
- instance_type = instance_type .upper_bound
3156
- if not isinstance (instance_type , (Instance , TupleType )):
3157
- # Too tricky, give up.
3158
- # TODO: Do something more clever here.
3159
- self .chk .fail (message_registry .UNSUPPORTED_ARG_2_FOR_SUPER , e )
3160
- return
3161
- if isinstance (instance_type , TupleType ):
3162
- # Needed for named tuples and other Tuple[...] subclasses.
3163
- instance_type = tuple_fallback (instance_type )
3164
- if type_info not in instance_type .type .mro :
3165
- self .chk .fail (message_registry .SUPER_ARG_2_NOT_INSTANCE_OF_ARG_1 , e )
3166
- elif isinstance (instance_type , TypeType ) or (isinstance (instance_type , FunctionLike )
3167
- and instance_type .is_type_obj ()):
3168
- # TODO: Check whether this is a valid type object here.
3169
- pass
3170
- elif not isinstance (instance_type , AnyType ):
3171
- self .chk .fail (message_registry .UNSUPPORTED_ARG_2_FOR_SUPER , e )
3172
-
3173
- def analyze_super (self , e : SuperExpr , is_lvalue : bool ) -> Type :
3174
- """Type check a super expression."""
3175
- if e .info and e .info .bases :
3176
- # TODO fix multiple inheritance etc
3177
- if len (e .info .mro ) < 2 :
3178
- self .chk .fail ('Internal error: unexpected mro for {}: {}' .format (
3179
- e .info .name (), e .info .mro ), e )
3180
- return AnyType (TypeOfAny .from_error )
3181
- for base in e .info .mro [1 :]:
3182
- if e .name in base .names or base == e .info .mro [- 1 ]:
3183
- if e .info .fallback_to_any and base == e .info .mro [- 1 ]:
3184
- # There's an undefined base class, and we're
3185
- # at the end of the chain. That's not an error.
3186
- return AnyType (TypeOfAny .special_form )
3187
- if not self .chk .in_checked_function ():
3188
- return AnyType (TypeOfAny .unannotated )
3189
- if self .chk .scope .active_class () is not None :
3190
- self .chk .fail (message_registry .SUPER_OUTSIDE_OF_METHOD_NOT_SUPPORTED , e )
3191
- return AnyType (TypeOfAny .from_error )
3192
- method = self .chk .scope .top_function ()
3193
- assert method is not None
3194
- args = method .arguments
3195
- # super() in a function with empty args is an error; we
3196
- # need something in declared_self.
3197
- if not args :
3198
- self .chk .fail (message_registry .SUPER_ENCLOSING_POSITIONAL_ARGS_REQUIRED , e )
3199
- return AnyType (TypeOfAny .from_error )
3200
- declared_self = args [0 ].variable .type or fill_typevars (e .info )
3201
- return analyze_member_access (name = e .name ,
3202
- typ = fill_typevars (e .info ),
3203
- is_lvalue = False ,
3204
- is_super = True ,
3205
- is_operator = False ,
3206
- original_type = declared_self ,
3207
- override_info = base ,
3208
- context = e ,
3209
- msg = self .msg ,
3210
- chk = self .chk ,
3211
- in_literal_context = self .is_literal_context ())
3212
- assert False , 'unreachable'
3213
- else :
3214
- # Invalid super. This has been reported by the semantic analyzer.
3225
+ if (not isinstance (type_type , TypeType )
3226
+ and not (isinstance (type_type , FunctionLike ) and type_type .is_type_obj ())):
3227
+ self .msg .first_argument_for_super_must_be_type (type_type , e )
3215
3228
return AnyType (TypeOfAny .from_error )
3216
3229
3230
+ # Imprecisely assume that the instance is of the current class
3231
+ if isinstance (instance_type , AnyType ):
3232
+ if e .info :
3233
+ instance_type = fill_typevars (e .info )
3234
+ else :
3235
+ return AnyType (TypeOfAny .from_another_any , source_any = instance_type )
3236
+ elif isinstance (instance_type , TypeType ):
3237
+ instance_item = instance_type .item
3238
+ if isinstance (instance_item , AnyType ):
3239
+ if e .info :
3240
+ instance_type = TypeType (fill_typevars (e .info ))
3241
+ else :
3242
+ return AnyType (TypeOfAny .from_another_any , source_any = instance_item )
3243
+
3244
+ return type_type , instance_type
3245
+
3217
3246
def visit_slice_expr (self , e : SliceExpr ) -> Type :
3218
3247
expected = make_optional_type (self .named_type ('builtins.int' ))
3219
3248
for index in [e .begin_index , e .end_index , e .stride ]:
@@ -4001,3 +4030,22 @@ def has_bytes_component(typ: Type) -> bool:
4001
4030
if isinstance (typ , Instance ) and typ .type .fullname () == 'builtins.bytes' :
4002
4031
return True
4003
4032
return False
4033
+
4034
+
4035
+ def type_info_from_type (typ : Type ) -> Optional [TypeInfo ]:
4036
+ """Gets the TypeInfo for a type, indirecting through things like type variables and tuples."""
4037
+
4038
+ if isinstance (typ , FunctionLike ) and typ .is_type_obj ():
4039
+ return typ .type_object ()
4040
+ if isinstance (typ , TypeType ):
4041
+ typ = typ .item
4042
+ if isinstance (typ , TypeVarType ):
4043
+ typ = typ .upper_bound
4044
+ if isinstance (typ , TupleType ):
4045
+ typ = tuple_fallback (typ )
4046
+ if isinstance (typ , Instance ):
4047
+ return typ .type
4048
+
4049
+ # A complicated type. Too tricky, give up.
4050
+ # TODO: Do something more clever here.
4051
+ return None
0 commit comments