@@ -254,7 +254,6 @@ class ClassNameCheck(BaseASTCheck):
254254 Classes for internal use have a leading underscore in addition.
255255 """
256256 N801 = "class name '{name}' should use CapWords convention"
257- N808 = "type variable name '{name}' should use CapWords convention and an optional suffix '_co' or '_contra'"
258257 N818 = "exception name '{name}' should be named with an Error suffix"
259258
260259 @classmethod
@@ -276,40 +275,6 @@ def superclass_names(cls, name, parents: Iterable, _names=None):
276275 names .update (cls .superclass_names (base .id , parents , names ))
277276 return names
278277
279- def visit_module (self , node , parents : Iterable , ignore = None ):
280- for body in node .body :
281- try :
282- if len (body .targets ) != 1 :
283- continue
284- name = body .targets [0 ].id
285- func_name = body .value .func .id
286- args = [a .value for a in body .value .args ]
287- keywords = {kw .arg : kw .value .value for kw in body .value .keywords }
288- except AttributeError :
289- continue
290-
291- if func_name != "TypeVar" or _ignored (name , ignore ):
292- continue
293-
294- if len (args ) == 0 or args [0 ] != name :
295- yield self .err (body , 'N808' , name = name )
296-
297- if not name [:1 ].isupper ():
298- yield self .err (body , 'N808' , name = name )
299-
300- parts = name .split ('_' )
301- if len (parts ) > 2 :
302- yield self .err (body , 'N808' , name = name )
303-
304- suffix = parts [- 1 ] if len (parts ) > 1 else ''
305- if suffix and suffix != 'co' and suffix != 'contra' :
306- yield self .err (body , 'N808' , name = name )
307- elif keywords .get ('covariant' ) and suffix != 'co' :
308- yield self .err (body , 'N808' , name = name )
309- elif keywords .get ('contravariant' ) and suffix != 'contra' :
310- yield self .err (body , 'N808' , name = name )
311-
312-
313278 def visit_classdef (self , node , parents : Iterable , ignore = None ):
314279 name = node .name
315280 if _ignored (name , ignore ):
@@ -535,6 +500,44 @@ def function_variable_check(func, var_name):
535500 return 'N806'
536501
537502
503+ class TypeVarNameCheck (BaseASTCheck ):
504+ N808 = "type variable name '{name}' should use CapWords convention " \
505+ "and an optional '_co' or '_contra' suffix"
506+
507+ def visit_module (self , node , parents : Iterable , ignore = None ):
508+ for body in node .body :
509+ try :
510+ if len (body .targets ) != 1 :
511+ continue
512+ name = body .targets [0 ].id
513+ func_name = body .value .func .id
514+ args = [a .value for a in body .value .args ]
515+ keywords = {kw .arg : kw .value .value for kw in body .value .keywords }
516+ except AttributeError :
517+ continue
518+
519+ if func_name != "TypeVar" or _ignored (name , ignore ):
520+ continue
521+
522+ if len (args ) == 0 or args [0 ] != name :
523+ yield self .err (body , 'N808' , name = name )
524+
525+ if not name [:1 ].isupper ():
526+ yield self .err (body , 'N808' , name = name )
527+
528+ parts = name .split ('_' )
529+ if len (parts ) > 2 :
530+ yield self .err (body , 'N808' , name = name )
531+
532+ suffix = parts [- 1 ] if len (parts ) > 1 else ''
533+ if suffix and suffix != 'co' and suffix != 'contra' :
534+ yield self .err (body , 'N808' , name = name )
535+ elif keywords .get ('covariant' ) and suffix != 'co' :
536+ yield self .err (body , 'N808' , name = name )
537+ elif keywords .get ('contravariant' ) and suffix != 'contra' :
538+ yield self .err (body , 'N808' , name = name )
539+
540+
538541def _extract_names (assignment_target ):
539542 """Yield assignment_target ids."""
540543 target_type = type (assignment_target )
0 commit comments