@@ -187,7 +187,7 @@ def analyze_var(name: str, var: Var, itype: Instance, info: TypeInfo, node: Cont
187
187
# methods: the former to the instance, the latter to the
188
188
# class.
189
189
functype = cast (FunctionLike , t )
190
- check_method_type (functype , itype , node , msg )
190
+ check_method_type (functype , itype , var . is_classmethod , node , msg )
191
191
signature = method_type (functype )
192
192
if var .is_property :
193
193
# A property cannot have an overloaded type => the cast
@@ -228,17 +228,29 @@ def lookup_member_var_or_accessor(info: TypeInfo, name: str,
228
228
return None
229
229
230
230
231
- def check_method_type (functype : FunctionLike , itype : Instance ,
231
+ def check_method_type (functype : FunctionLike , itype : Instance , is_classmethod : bool ,
232
232
context : Context , msg : MessageBuilder ) -> None :
233
233
for item in functype .items ():
234
234
if not item .arg_types or item .arg_kinds [0 ] not in (ARG_POS , ARG_STAR ):
235
235
# No positional first (self) argument (*args is okay).
236
236
msg .invalid_method_type (item , context )
237
- else :
237
+ elif not is_classmethod :
238
238
# Check that self argument has type 'Any' or valid instance type.
239
239
selfarg = item .arg_types [0 ]
240
240
if not subtypes .is_equivalent (selfarg , itype ):
241
241
msg .invalid_method_type (item , context )
242
+ else :
243
+ # Check that cls argument has type 'Any' or valid class type.
244
+ # (This is sufficient for the current treatment of @classmethod,
245
+ # but probably needs to be revisited when we implement Type[C]
246
+ # or advanced variants of it like Type[<args>, C].)
247
+ clsarg = item .arg_types [0 ]
248
+ if isinstance (clsarg , CallableType ) and clsarg .is_type_obj ():
249
+ if not subtypes .is_equivalent (clsarg .ret_type , itype ):
250
+ msg .invalid_class_method_type (item , context )
251
+ else :
252
+ if not subtypes .is_equivalent (clsarg , AnyType ()):
253
+ msg .invalid_class_method_type (item , context )
242
254
243
255
244
256
def analyze_class_attribute_access (itype : Instance ,
@@ -370,7 +382,9 @@ def class_callable(init_type: CallableType, info: TypeInfo, type_type: Instance)
370
382
callable_type = init_type .copy_modified (
371
383
ret_type = self_type (info ), fallback = type_type , name = None , variables = variables )
372
384
c = callable_type .with_name ('"{}"' .format (info .name ()))
373
- return convert_class_tvars_to_func_tvars (c , len (initvars ))
385
+ cc = convert_class_tvars_to_func_tvars (c , len (initvars ))
386
+ cc .is_classmethod_class = True
387
+ return cc
374
388
375
389
376
390
def convert_class_tvars_to_func_tvars (callable : CallableType ,
0 commit comments